
Docker 简明用户指引
简介
使用 Docker 容器,除了安装 Docker 环境,还需要准备镜像文件。镜像文件默认基于 Alphine Linux 构建。
镜像文件由不同的只读文件系统层构成。同一镜像可以创建不同的容器,每个容器有同属镜像的只读层,还有各自的读写层,读写层会随着容器一起删除。
需要读写的文件推荐放在宿主机,通过卷(Volumn)挂载进入容器,删除容器不会影响宿主机上的文件。
应用场景
- 解决环境版本冲突。
下载
参考
配置
Linux 开启远程管理
新建或编辑 /etc/systemd/system/docker.service.d/override.conf 文件,重置 ExecStart 指令,添加 2375 端口侦听后重启服务:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock
sudo systemctl daemon-reload
sudo systemctl restart docker.service
macOS 开启远程管理
可通过 socat 转发 Unix Socks 实现:
brew install socat
sudo socat TCP-LISTEN:2375,reuseaddr,fork UNIX-CONNECT:/var/run/docker.sock
Windows/macOS 管理远程 Docker
设置环境变量或自定义 .bat 文件可远程管理 docker 服务,macOS 参考这里:
$env:DOCKER_HOST="tcp://IP_OR_HOSTNAME:2375"
REM docker.bat
@docker -H=IP_OR_HOSTNAME:2375 %*
服务端代理
mkdir -p /etc/systemd/system/docker.service.d
# /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:80"
Environment="HTTPS_PROXY=https://proxy.example.com:443"
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp"
# Restart & Verify
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl show --property=Environment docker
客户端代理
用户主要使用 docker 命令行和 docker 服务进行交互。国内拉取镜像过慢,或启动的容器需要传入代理时可在客户端配置文件 ~/.docker/config.json 中添加代理设置:
"proxies":
{
"default":
{
"httpProxy": "http://192.168.1.111:8118",
"httpsProxy": "http://192.168.1.111:8118",
"noProxy": "localhost,mirror.aliyuncs.com,*.mirror.aliyuncs.com,*.163.com,*.aliyuncs.com"
}
},
镜像加速器
Docker 服务端可配置镜像加速器,加快镜像获取,设置 Docker Engine:
"registry-mirrors": [
"https://hub-mirror.c.163.com"
],
自动补全
Docker for Mac
# .zshrc
etc=/Applications/Docker.app/Contents/Resources/etc
ln -s $etc/docker.zsh-completion /usr/local/share/zsh/site-functions/_docker
ln -s $etc/docker-compose.zsh-completion /usr/local/share/zsh/site-functions/_docker-compose
fpath=(/usr/local/share/zsh/site-functions $fpath)
autoload -Uz compinit && compinit -u
# .bashrc
常用命令
Docker 管理
巡查 Docker for Mac 虚机
# Ctrl + a, d 可挂起 screen,Ctrl + a, k 可关闭 screen
screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
# 2.4.0.3+
docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
环境管理
镜像管理
镜像本质是个 tar 包,用作容器模版。编译镜像时,当前目录内容打包成 tar 文件后发送至 dockerd 进程。未显式指明标签时,docker 命令默认引用 latest 标签。镜像完整标识 REGISTER_URL/USER/IMAGE:TAG。
# 更新所有本地镜像已安装版本对应的最新版。
docker images | grep -v REPOSITORY | awk '{print $1":"$2}' | xargs -L1 docker pull # Linux / Mac
# 清理升级后无用的历史镜像
docker rmi $(docker images -q -f dangling=true)
容器管理
命令中的 CONTAINER 可以是容器名,亦或是容器 ID。除了 ls 指令,其他命令中的 container 关键字可以省略。
卷管理
卷比容器生命周期更长,用于存储容器状态。
网络管理
Docker 服务端默认创建虚拟网卡 docker0,构建 Docker 默认网络:bridge。容器内可以通过宿主机 IP 连接宿主机,不同 Docker 网络的容器无法通信。容器的网络端口可以由宿主机端口映射,该映射只能在容器创建····时指定。
Docker 网络在创建容器时通过 --network NETWORK 参数指定。可以指定新建的 Docker 网络,也可以用以下预定义 Docker 网络。--network 参数可以有多个。也可用 --network container:CONTAINER 接入指定容器网络。
https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach
在 Docker for Mac 的容器中可以用以下 hostname:
容器注册表管理
Dockerfile
通过 Dockerfile 文件及 docker build 命令可编译自定义镜像。Dockerfile 关键字开始,关键字 FROM、COPY、RUN 开始的每一行对应镜像中的一层。
关键字
设置
# 输出 Build 详情
export DOCKER_BUILDKIT=0
命令
# 跳过 build 缓存
docker build --no-cache
Docker Compose
单机容器编排工具。默认读取当前目录中的配置文件 docker-compose.yml 及 docker-compose.override.yml 编译镜像、启动容器。
docker-compose.yml
安装
# Install the Compose standalone
# Linux
curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
常见用例
nginx + php:5-fpm
nginx 默认配置文件没有开启 FastCGI 支持及 PHP 集成,需要挂载自定义配置文件或自定义 nginx 镜像实现 LNMP 环境:
## nginx 配置文件: default.conf,覆盖镜像中的 /etc/nginx/conf.d/default.conf 文件
# 想定代码放在 /var/www/html 目录中
#
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /var/www/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/html;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header REMOTE_ADDR $remote_addr;
root /var/www/html;
fastcgi_pass php_5_fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
启动 php:5-fpm 容器:
# 启动基于最新 php:5-fpm 镜像的容器
# 停止并删除已有容器
docker stop php_5_fpm
docker rm -v php_5_fpm
# 挂载代码目录,启动容器,PHP 应用存放的路径,FastCGI 服务需要读取权限
docker run -d -v /var/www/html:/var/www/html --name php_5_fpm --restart=always php:5-fpm
# 进入容器巡查,用 exit 命令可以退出容器
docker exec -it php_5_fpm bash
启动 nginx 容器(基于自定义镜像):
# 镜像定义文件 Dockerfile
FROM nginx:1.15
COPY conf/default.conf /etc/nginx/conf.d/default.conf
# 停止并删除既存容器、删除既存镜像
docker stop nginx_php_5_fpm
docker rm -v nginx_php_5_fpm
docker rmi nginx_php_5_fpm
# 生成自定义镜像
docker build . -t nginx_php_5_fpm
# 启动容器
docker run -d -it -p 60080:80 -v /var/www/html:/var/www/html --name nginx_php_5_fpm --link php_5_fpm:php_5_fpm --restart=always nginx_php_5_fpm
# 查看容器内进程
docker top nginx_php_5_fpm -ef
# 进入容器巡查,用 exit 命令可以退出容器
docker exec -it nginx_php_5_fpm bash
启动 nginx 容器(基于官方镜像),需要部署自定义 nginx 配置文件,以下想定部署位置为 /var/www/conf/default.conf。
# 停止并删除既存容器、删除既存镜像
docker stop nginx_php_5_fpm
docker rm -v nginx_php_5_fpm
# 启动容器
docker run -d -it -p 60080:80 -v /var/www/conf/default.conf:/etc/nginx/conf.d/default.conf -v /var/www/html:/var/www/html --name nginx_php_5_fpm --link php_5_fpm:php_5_fpm --restart=always nginx:1.15
# 查看容器内进程
docker top nginx_php_5_fpm -ef
# 进入容器巡查,用 exit 命令可以退出容器
docker exec -it nginx_php_5_fpm bash
自定义 nginx 镜像
# 镜像定义文件 Dockerfile
FROM nginx:1.14.0
COPY conf/<site-domain>.conf /etc/nginx/conf.d/
COPY ~/nginx/headers-more-nginx-module/nginx-module-headersmore_1.14.0-1~xenial_amd64.deb /tmp
COPY ~/nginx/nginx-http-shibboleth/nginx-module-shibboleth_1.14.0-1~xenial_amd64.deb /tmp
RUN dpkg -i /tmp/nginx-module-headersmore_1.14.0-1~xenial_amd64.deb /tmp/nginx-module-shibboleth-dbg_1.14.0-1~xenial_amd64.deb
官方 nginx 镜像 + 宿主机 PHP
利用 nginx 官方镜像,可以让不同版本的 nginx 服务同时运行,并访问宿主机上的其他服务,具体方法如下:
按需准备 nginx.conf,Ubuntu 需要把 nginx 运行在 www-data 用户下:
# Ubuntu 版 nginx.conf,user 改为 www-data,否则访问 PHP Unix socket 有权限问题。
user www-data;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 300;
gzip on;
client_max_body_size 64m;
include /etc/nginx/conf.d/*.conf;
}
准备应用配置文件,不同的应用,所需配置稍有不同:
# Drupal 应用配置(无 HTTPS)
server {
listen 80;
listen [::]:80;
root <Application Root Path>;
server_name <domain name>;
index index.php index.html;
# 屏蔽容易泄漏系统信息的文件
location ~* ^/(readme\.txt|CHANGELOG\.txt|web\.config|robots\.txt|LICENSE\.txt|README.mk) {
return 404;
#deny all;
}
location ~* \.(eot|ttf|woff|otf)$ {
add_header Access-Control-Allow-Origin *;
}
location / {
try_files $uri /index.php?$query_string;
# 屏蔽沙俄黑客 IP
deny 180.97.0.0/16;
}
location @rewrite {
rewrite ^/(.*)$ /index.php?q=$1;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
error_log /var/log/nginx/<domain name>-error.log warn;
access_log /var/log/nginx/<domain name>-access.log main;
fastcgi_read_timeout 300s;
}
容器更新、启动命令:
# 停止并删除既存容器
docker stop nginx_local_php_fpm
docker rm nginx_local_php_fpm
# 挂载宿主机 Socket 文件,nginx 配置文件
export PHP_APPLICATION=$(pwd)
export NGINX_MODULE_PATH=$(pwd)
docker run -d -p 60601:80 -v /run/php/php7.0-fpm.sock:/run/php/php7.0-fpm.sock -v $PHP_APPLICATION/docs:$PHP_APPLICATION/docs -v $NGINX_MODULE_PATH/nginx-http-shibboleth/usr/lib/nginx/modules/ngx_http_shibboleth_module.so:/usr/lib/nginx/modules/ngx_http_shibboleth_module.so -v $NGINX_MODULE_PATH/headers-more-nginx-module/usr/lib/nginx/modules/ngx_http_headers_more_filter_module.so:/usr/lib/nginx/modules/ngx_http_headers_more_filter_module.so -v $PHP_APPLICATION/logs/:/var/log/nginx/ -v $PHP_APPLICATION/conf/nginx.conf:/etc/nginx/nginx.conf -v $PHP_APPLICATION/conf/site.conf:/etc/nginx/conf.d/site.conf --name nginx_local_php_fpm --restart=always nginx:1.14.0