Docker Volumes 机制通常用来给 Docker 容器保存持久化数据,使用 Volumes 有很多优势:
Volumes 通常也优于容器的可写层,使用 Volumes 不会增加容器的体积,并且 Volumes 的内容存储在外部独立于容器的生命周期。如果容器不产生持久化数据,可以考虑使用 tmpfs mount来避免数据存储在其他可能的地方,避免增加容器的体积。
最开始 -v
或者 --volume
选项是给单独容器使用, --mount
选项是给集群服务使用。但是从 Docker 17.06 开始,也可以在单独容器上使用 --mount
。通常来讲 --mount
选项也更加具体(explicit)和”啰嗦”(verbose),最大的区别是
-v
选项将所有选项集中到一个值--mount
选项将可选项分开如果需要指定 volume driver 选项,那么必须使用 --mount
-v
或 --volume
: 包含三个 field,使用 :
来分割,所有值需要按照正确的顺序。第一个 field 是 volume 的名字,并且在宿主机上唯一,对于匿名 volume,第一个field通常被省略;第二个field是宿主机上将要被挂载到容器的path或者文件;第三个field可选,比如说 ro
--mount
: 包含多个 key-value 对,使用逗号分割。--mount
选项更加复杂,但是各个值之间无需考虑顺序。
type
,可以为 bind
, volume
, tmpfs
, 通常为 volume
source
也可以写成 src
,对于 named volumes,可以设置 volume 的名字,对于匿名 volume,可以省略destination
可以写成 dst
或者 target
该值会挂载到容器readonly
可选,如果使用,表示只读volume-opt
可选,可以使用多次两个例子
docker run -d \
--name=nginxtest \
--mount source=nginx-vol,destination=/usr/share/nginx/html \
nginx:latest
docker run -d \
--name=nginxtest \
-v nginx-vol:/usr/share/nginx/html \
nginx:latest
Gogs 是一个能够自建Git托管服务的开源项目,用 Go 语言实现。因为较之 GitLab 轻量化一些,所以受到一定欢迎。
使用 Docker 来搭建 Gogs 服务时,需要额外依赖 MySQL,网上一般的教程都是先启动一个 MySQL 容器,开放端口,然后在启动 Gogs 容器配置。其实可以使用 docker-compose
一次性启动好。
version: '3.3'
services:
gogsdb:
image: mysql:5.7
container_name: gogsdb
restart: always
environment:
MYSQL_DATABASE: gogs
MYSQL_ROOT_PASSWORD: gogs
MYSQL_USER: gogs
MYSQL_PASSWORD: gogs
volumes:
- db_data:/var/lib/mysql_gogs
ports:
- "13306:3306"
networks:
- gogs-network
gogsapp:
depends_on:
- gogsdb
image: gogs/gogs
container_name: gogsapp
restart: always
ports:
- "322:22"
- "3000:3000"
volumes:
- app_data:/data
networks:
- gogs-network
volumes:
db_data:
app_data:
networks:
gogs-network:
driver: bridge
在第一次安装的时候你可能遇到下面的错误:
数据库设置不正确:dial tcp 127.0.0.1:13306: getsockopt: connection refused
或者
Database setting is not correct: dial tcp 127.0.0.1:13306: getsockopt: connection refused
这个错误的意思就是他表达的意思,gogs 想要在 127.0.0.1:13306
这个地址和端口连接 MySQL 失败了,我找了一圈之后发现,这里的地址需要填写 MySQL 容器的网关地址。
sudo docker inspect gogsdb
查看输出中的 Gateway
字段,填写这个地址。
最新的内容可以参考: https://github.com/einverne/dockerfile/tree/master/gogs
以下的内容适用于 docker-compose
版本 version 2
和 version 3
。先来看 Docker 官方文档中关于 Docker Compose and Django的例子,可以使用 depends_on
来访问容器中的数据
version: '2'
services:
db:
image: postgres
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
而比如下面使用
web:
links:
- db
则表示当启动 db 容器时会随机分配一个本地端口比如32777来连接容器3306端口,每一次修改或者重启容器都会改变该端口,使用 links 来保证每一次都能够连接数据库,而不需要知道具体端口是什么。比如说启动了一个 MySQL 容器
docker run -d --name=my-mysql --env="MYSQL_ROOT_PASSWORD=mypassword" -P mysql
docker inspect <container-id> | grep HostPort
会显示该容器的本地端口。
当 docker-compose
执行 V2 文件时会自动在容器间创建一个网络,每一个容器都能够立即通过名字来访问到另外的容器。 因此,不再需要 links,links 过去通常用来开始db容器和web server容器网络之间的通讯,但是这一步已经被 docker-compose
做了。1
当使用 depends_on
来定义服务之间的依赖关系时会造成下面的影响2
docker-compose up
会依据依赖顺序启动服务docker-compose up
启动时 SERVICE 会自动包括 SERVICE 的依赖看这个例子:
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
这个例子中 db ,redis 容器启动顺序要优先于 web 容器;当启动 web 容器时会自动创建 redis 和 db 容器。
不过需要注意的是, depends_on
不会等到 db 和 redis 容器 ready
再启动,web 容器仅仅等到 redis 和 db 容器启动就开始启动。具体可参考官网启动顺序了解。
Privoxy 是一款不进行网页缓存且自带过滤功能的代理服务器,本文主要使用其 socks 转 http 代理的功能。Privoxy 也能够过滤网页内容,管理 Cookie,控制访问,去广告、横幅、弹窗等等,因此可以作为广告过滤。
Privoxy is a non-caching web proxy with advanced filtering capabilities for enhancing privacy, modifying web page data and HTTP headers, controlling access, and removing ads and other obnoxious Internet junk. GNU GPLv2 开源
因为 shadowsocks,v2ray 都是将代理转为本地 socks5 代理,所以如果需要使用 http 代理,就需要借助 Privoxy 。如果只需要在本地启用 http 代理,也可以使用 proxychains。
在 Linux 下安装非常简单
sudo apt install privoxy
默认的配置文件地址在 /etc/privoxy/config
目录下。假设本地 1080 端口已经启动(不管是本地 sslocal 还是 v2ray 本地都需要启动)然后要将本地 1080 socks5 代理转成 http 代理,重要的配置只有两行
# 把本地 HTTP 流量转发到本地 1080 SOCKS5 代理
forward-socks5t / 127.0.0.1:1080 .
# 可选,默认监听本地连接
listen-address 127.0.0.1:8118
如果想要将 http 代理非常到局域网中,可以使用 listen-address 0.0.0.0:8118
。 Privoxy 默认的端口为 8118,可以自行修改。修改完成保存之后使用如下命令启动
sudo /etc/init.d/privoxy start
sudo /etc/init.d/privoxy reload # 不重启服务的情况下重新加载配置
可以在终端进行测试 export http_proxy=http://127.0.0.1:8118 && curl ip.gs
应该显示代理的 IP 地址。如果监听 0.0.0.0:8118
,那么局域网中,使用 ip:8118 也能够使用该 HTTP 代理,并且所有的流量都经由 HTTP 转发到 SOCKS5 代理,并走 shadowsocks 或者 v2ray 到墙外。
使用浏览器配置 HTTP 代理,然后访问 http://p.p 如果看到 Privoxy 启动成功表示一切 OK。
当启动 sudo /etc/init.d/privoxy start
时出现如下错误:
systemctl status privoxy.service
● privoxy.service - Privacy enhancing HTTP Proxy
Loaded: loaded (/lib/systemd/system/privoxy.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sun 2018-03-11 17:49:40 CST; 4s ago
Process: 23666 ExecStopPost=/bin/rm -f $PIDFILE (code=exited, status=0/SUCCESS)
Process: 23668 ExecStart=/usr/sbin/privoxy --pidfile $PIDFILE --user $OWNER $CONFIGFILE (code=exited, status=1/FAILURE)
Main PID: 21029 (code=exited, status=15)
Mar 11 17:49:39 VM-145-149-ubuntu systemd[1]: Stopped Privacy enhancing HTTP Proxy.
Mar 11 17:49:39 VM-145-149-ubuntu systemd[1]: Starting Privacy enhancing HTTP Proxy...
Mar 11 17:49:40 VM-145-149-ubuntu systemd[1]: privoxy.service: Control process exited, code=exited status=1
Mar 11 17:49:40 VM-145-149-ubuntu systemd[1]: Failed to start Privacy enhancing HTTP Proxy.
Mar 11 17:49:40 VM-145-149-ubuntu systemd[1]: privoxy.service: Unit entered failed state.
Mar 11 17:49:40 VM-145-149-ubuntu systemd[1]: privoxy.service: Failed with result 'exit-code'.
绝大部分情况下是配置文件错误,仔细检查 /etc/privoxy/config
文件,是否有重复配置,或者输入错误。
其核心配置文件在 /etc/privoxy/config
文件中,之前配置过转发 socks 流量就在该文件中,不过通常情况下会需要修改另外两类文件:
match-all.action
,default.action
,user.action
default.filter
, user.filter
match-all.action
,default.action
,default.filter
建议不要修改, Privoxy 升级时会覆盖掉,自定义内容可以放入 user.action
和 user.filter
文件中。
action 文件定义 Privoxy 动作,比如
{+block{禁止访问垃圾百度}}
.baidu.com
{+block}
是一个动作,block 后面的 {}
注释,可省略; .baidu.com
是上述动作对象,分为两个部分,host 和 path, host 部分支持通配符,path 部分指的是 /
后部分网址,支持 POSIX 1003.2 正则表达式。更加具体的可以参考官网文档。上述配置生效之后 baidu.com
的任何请求都会返回 403 。
filter 文件定义过滤响应的规则,比如
FILTER: replaceText 替换文本
s|网易|Google|g
FILTER
大写表示定义过滤规则, replaceText
表示规则名称,后面接注释;第二行定义具体规则,如果使用过 vi 或者 sed 工具,那么一定很熟悉这个 s
替换命令。
定义了 user.filter
过滤规则之后,需要在 user.action
文件中应用规则
{+filter{replaceText}}
.163.com
这样访问 163.com 网站中任何带有“网易”的字都会被替换为 Google,当然如果网页启用了 HTTPS,那么 Privoxy 也无能为力。Privoxy 唯一能够对 HTTPS 网站做的就是 block 了。这也就意味着屏蔽 HTTPS 网站页面内广告的能力下降了。
当前 Privoxy 配置的 action 和 filter 文件可以在代理情况下访问 http://config.privoxy.org/show-status 这个网址查看到。
前面也提到过 Privoxy 的广告过滤,不过需要注意的是使用去广告功能可能丢失一定的匿名性 1。
下载 user.action 和 user.filter 两个文件分别替换 /etc/privoxy/
目录下的默认文件,重启 Privoxy 。
系统运行一段时间之后难免容器会出现问题,出现问题并不可怕,可怕的是不知道问题出现在哪里,这个时候查看当前容器运行的日志就能够排查出一些问题。
在之前的文章 中,学会了如何创建,查看,移除等等管理容器的方法,其实查看日志也和这些方法类似。
比如要查看容器所有运行的日志可以使用,下面的 containerId 都可以被替换为容器的名字:
docker logs [containerId]
如果要持续观察容器的日志输出,可以使用 -f
或者 --follow
参数
docker logs -f [containerId]
但是这个命令在不同系统上,有的时候会打印出全部的日志,就和没加 -f
参数一样,所以有的时候要查看日志最末尾几行可以使用 --tail
docker logs --tail 100 [containerId]
如果想要查看某个时间之后的日志,可以使用 --since
docker logs --since 2018-05-01 [containerId]
同理如果要查看直到某个时间之前的日志也可以使用 --until
docker logs --until 2018-05-01 [containerId]
腾讯云对象存储 Cloud Object Storage ,简称 COS,是腾讯云为企业和个人开发者提供的存储海量数据的分布式存储服务。
在控制面板申请对象存储基本信息,创建存储桶,输入名字,选择地域,选择访问权限,然后访问秘钥,可以得到如下信息:
bucket: backup-1251234567 (格式为 bucketname-appid)
SecretId: SecretId
SecretKey: SecretKey
region: ap-beijing
appid: 123456789
安装必要的应用
wget https://github.com/tencentyun/cosfs/releases/download/v1.0.2/cosfs_1.0.2-ubuntu16.04_amd64.deb
sudo apt update && sudo apt install gdebi-core
sudo gdebi release-cosfs-package
配置文件,设置 bucket name, access key/id 等信息,将其存放在 /etc/passwd-cosfs
文件中,文件权限设置为 640
echo my-bucket:my-access-key-id:my-access-key-secret > /etc/passwd-cosfs
chmod 640 /etc/passwd-cosfs
然后将 cos bucket mount 到指定目录
cosfs appid:bucket-name mount-point -ourl=my-cos-endpoint -odbglevel=info -oallow_other
这里的 cos-endpoint
不同地区不一样,比如北京是 http://cos.ap-beijing.myqcloud.com
,其他地区根据 region 不同设置不同值
项目可参考官方项目
COSFS 工具使用
Flask 使用 Jinja2 模板引擎。
Flask 会在 templates 文件夹里寻找模板。所以,如果你的应用是个模块,这个文件夹应该与模块同级;如果它是一个包,那么这个文件夹作为包的子目录:
情况 1: 模块:
/application.py
/templates
/hello.html
情况 2: 包:
/application
/__init__.py
/templates
/hello.html
使用 Jinja2 只需要使用 render_template()
方法
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', name=name)
继承模式具体可参考: http://docs.jinkan.org/docs/flask/patterns/templateinheritance.html#template-inheritance
有很多网站可以托管 Docker 镜像, Docker 官方站点 hub.docker.com 速度在国内访问不是很快,不过幸好国内有公司做了 hub.docker.com 的镜像,通过 CDN 优化了下载。Docker Hub 为用户提供无限数量的公开镜像托管服务,但是仅提供一个私有镜像托管。Docker Hub 上镜像分为两类,一类为官方镜像,Ubuntu,redis 等等由权威三方开发和维护通过 Docker 官方认证,另一类就是普通用户镜像。
手动修改 Docker 配置 /etc/docker/daemon.json
文件增加 docker registry 镜像:
{
"registry-mirrors": [
"加速地址"
],
"insecure-registries": []
}
修改其中的 加速地址
,不同的服务提供的镜像加速地址不一样。记得修改配置之后 sudo /etc/init.d/docker restart
重启 docker。
或者
sudo systemctl daemon-reload
sudo systemctl restart docker
在 macOS 中,可以在界面中配置,在 Docker 应用中,打开偏好设置,然后在 “Docker Engine” 中配置:
修改后使用 sudo docker info
来检查配置是否生效。
如果下方公开的镜像速度不佳的话,尝试阿里云的镜像,需要开发者账号。
Docker 官方提供的镜像:
https://registry.docker-cn.com
Azure 中国镜像 包括 Docker Hub、GCR、Quay。
https://dockerhub.azk8s.cn
2020 年 5 月更新,Azure 提供的镜像已经限制只能够 Azure 的机器使用了。
Error response from daemon: error parsing HTTP 403 response body: invalid character '<' looking for beginning of value: "<html>\r\n<head><title>403 Forbidden</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>403 Forbidden</h1></center>\r\n<hr><center>nginx/1.14.0 (Ubuntu)</center>\r\n</body>\r\n</html>\r\n"
网易提供的地址:
https://hub-mirror.c.163.com
https://mirror.baidubce.com
腾讯提供的镜像,只能在腾讯云上使用:
https://mirror.ccs.tencentyun.com
https://docker.mirrors.ustc.edu.cn
https://reg-mirror.qiniu.com
DaoCloud 提供 的加速地址:
http://6ce28dce.m.daocloud.io
这个地址不同用户看起开不一样,可以使用我的,也可以自己注册。
这个地址不知道是不是长久地址,不过失效,可以到他的官方网站 查看。
也可以使用 Docker 官方提供的镜像
https://registry.docker-cn.com
官网地址
mritd 反向代理了主流的三大仓库(Docker Hub,gcr.io,quay.io)。
不得不说的 hub.docker.com,官方提供
这是国内 DaoCloud 公司提供的
可以通过下面的链接查看 gcr.io 中存在镜像,类似于直接在 https://hub.docker.com/ 中搜索查看。
阿里云加速器 (点击管理控制台 -> 登录账号 (淘宝账号) -> 右侧镜像中心 -> 镜像加速器 -> 复制地址)。
这里是阿里云提供的镜像托管服务
然后有人 把 gcr.io/google-containers
下所有的 Docker 镜像都同步到了中央库
更多的 registry 可以参考这里
在配置完 Docker 镜像之后可以执行 docker info
查看输出中的:
Registry Mirrors:
https://docker.mirrors.ustc.edu.cn/
https://hub-mirror.c.163.com/
如果出现配置的镜像地址则表示生效了。
https://lug.ustc.edu.cn/wiki/mirrors/help/docker ↩
python 的版本管理有 pyenv,同样的 ruby 也有 rbenv,可以和 pyenv 一样在本地管理多个 ruby 版本,很久没有更新本地的 ruby 版本导致了 jekyll 的依赖不支持才想起来这件事情。
其项目地址为:
https://github.com/rbenv/rbenv
因此安装就很方便
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
然后将下面内容添加到 PATH
export PATH="$HOME/.rbenv/bin:$PATH"
运行
~/.rbenv/bin/rbenv init
根据依赖将输出内容,添加到 ~/.zshrc
重启shell,或者 source ~/.zshrc
使设置生效
再运行检查脚本
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-doctor | bash
一切没问题就OK。
rbenv install
命令不在 rbenv
中,而是在 ruby-build中,可以通过下面的命令安装
apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6 libreadline6-dev zlib1g zlib1g-dev
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
如果是 Debian(>=7) 或者 Ubuntu (>=12.10) 也可以使用
sudo apt-get update
sudo apt-get install rbenv ruby-build
rbenv install --list # 查看可用
rbenv install 2.5.0 # 安装版本
rbenv 中的 Ruby 版本有三个不同的作用域:全局(global),本地(local),当前终端(shell),和 pyenv 类似。
查找版本的优先级是 当前终端 > 本地 > 全局。
rbenv global 2.1.2
rbenv local 2.1.2
rbenv shell 2.1.2
最近 VPS 磁盘空间一直上涨报警,就想查看一下哪个文件夹占用空间比较大,可以腾出一些可用空间来。查了一圈发现 du
命令就是该功能。du
全称 disk usage,
du
文档中就是这么描述他的功能的 —- 文件占用的空间,具体用法
du [OPTIONS] ... [FILE] ...
和绝大多数的命令一样,支持很多的选项,最常用的和 df
命令一样 -h
,可以记忆 --human-readable
,用比较人性化的单位,比如 K,M,G。
所以这样就可以使用
du -d 2 -h <dir> | grep '[0-9\,]\+G'
sudo du -h --max-depth=1
来快速的找到占用空间比较大的文件夹,这里的 -d
实际是 --max-depth
的缩写形式,也就是查看 dir 目录下,最多往下查找 2 层,然后以 -h
比较友好的方式输出结果。
除了上面提到了 -h
参数,du 命令还有一些其他的参数
当我们使用 -h
选项时命令会根据不同的大小给出合适的 K, M, G 单位,方便查看,但如果想要强制命令输出统一的单位可以使用 -BM
这里将 -BM
拆开,-B
表示的是 --block-size=SIZE
, M 表示的是兆,同理可以使用 -BG
强制使用 G 单位。
du -ah –-max-depth=0
-a
显示目录中所有文件及文件夹大小-–max-depth=n
这个选项也能简写成 -d n
: 深入到第 n 层目录,此处设置为 0,即表示不深入到子目录,设置为 1,则超过 1 层深度则忽略du --exclude=/path
-s
显示总和
du -hs /path
如果使用 du -h
那么会打印出 path 下所有目录的占用情况,如果使用 -s
那么只会输出 /path 占用的空间。
使用 -c
选项会额外在最后打印两行总占用量
du -ch /Download
例如:
..
..
3.3G Downloads
3.3G total
通常情况下 du 会打印目录及其下所有子目录大小,加入有一个目录 Parent,下方有 SubDirA,SubDirB,还有很多的文件在 Parent 目录下,那么想要知道所有在 Parent 下文件占用,但是不想包括 SubDirA 和 SubDirB 的空间,那么可以使用 -S
选项。
du -h -S -d 2 /path/to/Parent
熟悉了 du
命令之后,还有一个可视化更好的工具叫做 ncdu,在终端中使用比较友好的展示来显示磁盘空间占用。
更多的命令使用方法可以参考 tecmint