• 按照 CPU 使用率列出容器
docker stats --no-stream --format "table {{.Container}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDs}}" | (read -r; printf "%s\n" "$REPLY"; sort -k3 -hr)
  • 停止除 dockge 之外的所有容器
docker ps -q | grep -v $(docker ps -qf "name=dockge") | xargs docker stop
  • 查看使用的全部端口
netstat -lnptu | awk 'NR>2{print $4}' | grep -E '(0.0.0.0:|:::)' | sed 's/.*://' | sort -n | uniq
  • 暂时不让 docker compose 里面的某一个服务(容器)启动
profiles:
  - donotstart
  • depends_on 依赖后,健康检查通过以后再启动

假设 nginx 为一个业务服务,并且需要的数据来自 mysql。depends_on 选项,告诉 nginx 依赖 mysql 的启动,等它启动以后自己再启动。当然,加了这个还是不够的,只能保证 nginx 在 mysql 后面启动,但是 nginx 启动太快了,所以还是会先启动完成。所以需要添加启动的条件,即给 mysql 添加健康检查,nginx 等 mysql 启动,并健康检查通过以后再启动

version: '3.1'
services:
  nginx:
    image: nginx
    container_name: nginx
    restart: always
    ports:
      - 80:80
    depends_on:
      mysql:
        condition: service_healthy
  mysql:
    image: mysql:8.0.26
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    healthcheck:
      test: ["CMD", "mysql", "-u", "root", "-p123456", "-e", "select 1"]
      interval: 5s
      timeout: 3s
      retries: 10
  • 获取运行容器所需的命令行
# https://github.com/lavie/runlike
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike YOUR-CONTAINER
  • 热重启 dockerd
# https://pinolly.top/%E5%A6%82%E4%BD%95%E4%BC%98%E9%9B%85%E7%9A%84%E9%87%8D%E5%90%AFdockerd/
cat  /etc/docker/daemon.json
{ "live-restore": true }
# 给 dockerd 发送 SIGHUP 信号,dockerd 收到信号后会 reload 配置
kill -SIGHUP $(pidof dockerd)
# 检查是否配置成功,Live Restore Enabled: true
docker info | grep -i live
# 重启 docker 不会重启容器
systemctl restart docker
# 如果有容器挂载了 docker.sock 文件,重启后工作可能会不正常,需要重启该容器。原因是重启 dockerd 后 docker.sock 文件的 inode 变了,详情可参考 docker 单文件挂载的坑,https://yuansmin.github.io/2019/docker-mount-single-file/
  • 挂载文件夹,而不是文件
# https://yuansmin.github.io/2019/docker-mount-single-file/
docker run -v default.conf:/etc/nginx/conf.d/default.conf -p 8080:80 -d nginx:1.14-alpine
# 然后在主机上修改配置文件 default.conf,保存后重启容器,发现没生效。
# 原因:-v mount 文件(或文件夹)时,docker 记录的是该文件的 inode,并用 inode 追踪。
# 用 vim 编辑文件后,文件的 inode 变了,也就是这个 default.conf 文件已经不是运行 docker run 时的哪个 default.conf 文件了,容器中自然也就没有新的改动。 同时该 issue 的 opener 使用的是 sed -i 修改,也会使 inode 发生变化,sed -i 的机制是创建一个新的临时文件,修改完后在重命名。
# 对此,官方的建议是挂载文件夹,而不是文件。
  • docker 干预 iptables 导致异常,暴露端口的问题

安装 docker 后, 务必编辑 /etc/docker/daemon.json (没有就新建), 设置 ip 为 127.0.0.1,防止 docker 自己修改了 iptable 导致 ufw 失效。修改完毕后执行 systemctl daemon-reload && systemctl restart docker 重启 docker 服务。

参考

# 开启了 IPv6 支持, 配置了 DNS。国外服务器自行替换为 1.1.1.1, 8.8.8.8
{
    "dns":[
        "119.29.29.29",
        "223.5.5.5"
    ],
    "ipv6":true,
    "fixed-cidr-v6":"fd00:db8:1::/64",
    "experimental":true,
    "ip6tables":true,
    "ip":"127.0.0.1"
}

注意:不能修改 /lib/systemd/system/docker.service 加上 --iptables=false, 否则 docker 无法启动。修改 /etc/docker/daemon.json 加上 { "iptables" : false } 本质一样。