Docker应用手册

yml范式

name: atibm-opencode-project			# 命名空间隔离
services:
  opencode:								# 内部 DNS 解析
    # ------------ 基础信息 ------------
    container_name: "opencode-prod"		# docker ps 看到名字
    image: atibmcom/opencode:1.14.24
    hostname: opencode-server  			# 主机名,方便日志分析识别
    # --- 运行模式与自启策略 ---
    restart: unless-stopped  			# no always on-failure unless-stopped
    stdin_open: true        			# 对应 -i
    tty: true               			# 对应 -t
    # ------------ 持久化 ------------
    volumes:
      # [时间同步关键]
      - /etc/localtime:/etc/localtime:ro # 物理映射时钟
      - /etc/timezone:/etc/timezone:ro  # 物理映射时区名
      # [持久化映射]
      - ./data/config:/home/node/.config/opencode
      - ./data/www:/www:rw              # 读写模式
    # ------------ 端口映射 ------------
    ports:
      - "8080:8080"         			# 宿主机端口:容器内端口
    user: "${UID}:${GID}" 				# 容器内部进程运行权限
    environment:
      - UID=${UID:-1000}
      - GID=${GID:-1000}
      - TZ=Asia/Shanghai  				# 显式声明环境变量
    # ------------ 启动脚本 ------------
    command: ["opencode", "serve", "--print-logs"]
    # ------------ 资源限制与调度 ------------
    deploy:
      resources:
        limits:
          cpus: '0.50'      			# 限制使用 50% 的 CPU
          memory: 1G        			# 限制 1GB 内存
        reservations:
          memory: 256M      			# 预留 256MB 内存
    # ------------ 日志策略 ------------
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
        compress: "true"    			# 启用日志压缩节省硬盘空间
    # ------------ Docker 网络 ------------
    networks:
      - my_app_net
      
# --- 网络定义 ---
networks:
  my_app_net:
    external: true         				# 使用已有的网络

操作

服务器资源

  • docker资源

    
    [ghost@trilium20251227 trilium]$ docker stats --no-stream
    CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O           BLOCK I/O        PIDS
    834584383b6e   trilium   0.00%     104.6MiB / 400MiB   26.15%    1.27MB / 2.27MB   169MB / 6.99MB   11
    a5090bbc5aae   ghost     0.03%     140.4MiB / 256MiB   54.84%    146kB / 3.67MB    286MB / 29.5MB   11
    1619e84b6ff1   nginx     0.00%     8.625MiB / 64MiB    13.48%    7.97MB / 8.77MB   8.82MB / 86kB    2
    6f97f828412e   certbot   0.00%     568KiB / 985.5MiB   0.06%     9.69MB / 56.7kB   172MB / 2.66MB   1
  • docker守护进程

    [ghost@trilium20251227 ruby]$ systemctl status docker
    ● docker.service - Docker Application Container Engine
       Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
       Active: active (running) since Sat 2025-12-27 15:26:00 CST; 1 weeks 1 days ago
         Docs: https://docs.docker.com
     Main PID: 1634 (dockerd)
        Tasks: 40
       Memory: 65.8M
       CGroup: /system.slice/docker.service
    ...
  • 调试运行 dockerd
  • 查看日志

    [ghost@trilium20251227 certbot]$ docker logs -f certbot
    fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/main/x86_64/APKINDEX.tar.gz
    fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/community/x86_64/APKINDEX.tar.gz
    (1/16) Installing libexpat (2.7.3-r0)
    (2/16) Installing mpdecimal (4.0.0-r0)
    (3/16) Installing python3 (3.12.12-r0)
    (4/16) Installing python3-pycache-pyc0 (3.12.12-r0)
    (5/16) Installing pyc (3.12.12-r0)
    (6/16) Installing py3-certifi-pyc (2024.2.2-r1)
    (7/16) Installing py3-charset-normalizer (3.3.2-r1)
    (8/16) Installing py3-charset-normalizer-pyc (3.3.2-r1)
    (9/16) Installing py3-idna (3.7-r0)
    (10/16) Installing py3-idna-pyc (3.7-r0)
    (11/16) Installing py3-urllib3 (1.26.18-r1)
    (12/16) Installing py3-urllib3-pyc (1.26.18-r1)
    (13/16) Installing py3-requests-pyc (2.32.4-r0)
    (14/16) Installing python3-pyc (3.12.12-r0)
    (15/16) Installing py3-certifi (2024.2.2-r1)
    (16/16) Installing py3-requests (2.32.4-r0)
    Executing busybox-1.36.1-r29.trigger
    OK: 68 MiB in 59 packages
  • 清理docker冗余

    # 1. 停止 Docker 服务
    systemctl stop docker
    
    # 2. 清理无用容器、镜像、卷、网络:-a 清理所有未使用镜像;-f 强制;--volumes 清理无用卷
    docker system prune -a -f --volumes
    
    # 3. 手动删除旧镜像/容器(如果 prune 没清干净)
    docker images
    docker rmi <镜像ID>
    
    # 4. 清理 Docker 日志(/var/lib/docker/containers 下日志文件可能很大)
    find /var/lib/docker/containers/ -name "*.log" -delete
    
    # 5. 重启 Docker
    systemctl start docker

镜像

  • 罗列镜像 docker images
    • 磁盘占用 docker system df
  • 拉取镜像 docker pull myrepo/my_image:v1.0
    • 推送镜像 docker push myrepo/my_image:v1.0
    • 导出镜像 docker save -o my_image.tar my_image:latest
    • 导入镜像 docker load -i my_image.tar
    • 标记镜像 docker tag my_image:latest myrepo/my_image:v1.0
  • 运行镜像 docker run -d --name my_container my_image:latest
  • 删除镜像

    • 删除指定镜像 docker rmi my_image:latest
    • 清理构建残留 docker builder prune -f
    • 清理停止的容器 docker container prune -f
    • 清理不再使用的匿名卷 docker volume prune -f
    • 清理悬空镜像资源 docker image prune -f
    # 清理已停止的容器;清理构建残留;清理无用的匿名卷;清理悬空镜像
    docker container prune -f;docker builder prune -f;docker system prune --volumes -f;docker image prune -f
  • dsave备份函数

    dsave() {
      if [[ $# -eq 0 ]]; then
        cat <<'EOF'
    Usage: dsave <image|image-id> [image|image-id ...]
    
    Export one or more Docker images to gzip-compressed tar files,
    named automatically from the image name/tag.
    
    Arguments:
      <image|image-id>   Image name with tag (e.g. nginx:1.31.1-alpine),
                         short/full image ID (e.g. 1847037475ce),
                         or an untagged image name (defaults to :latest).
    
    Behavior:
      - Filename is derived from the first RepoTag of the image,
        replacing ':' and '/' with '_'.
          nginx:1.31.1-alpine  -> nginx_1.31.1-alpine.tar.gz
          reg.io/team/app:v1   -> reg.io_team_app_v1.tar.gz
      - Inputs are de-duplicated by image ID, so passing both
        a name and its short ID exports only once.
      - If 'pv' is installed, transfer progress is shown.
      - On 'docker save' failure, the partial .tar.gz is removed.
    
    Examples:
      dsave nginx:1.31.1-alpine
      dsave 1847037475ce
      dsave nginx:1.31.1-alpine mariadb:11.4 redis:7-alpine
      dsave 1847037475ce 1847037475ce nginx:1.31.1-alpine
    
    EOF
        return 0
      fi
    
      local -A seen_ids=()
      local img name out repo_tag img_id rc ok=0 fail=0 skip=0
    
      for img in "$@"; do
        img_id=$(docker inspect --format '{{.Id}}' "$img" 2>/dev/null)
    
        if [[ -z "$img_id" ]]; then
          echo ">>> ERROR: image not found: ${img}" >&2
          fail=$((fail+1))
          continue
        fi
    
        if [[ -n "${seen_ids[$img_id]:-}" ]]; then
          echo ">>> skip duplicate: ${img} (same image ID as '${seen_ids[$img_id]}')"
          skip=$((skip+1))
          continue
        fi
        seen_ids[$img_id]="$img"
    
        repo_tag=$(docker inspect --format '{{if .RepoTags}}{{index .RepoTags 0}}{{end}}' "$img" 2>/dev/null)
    
        if [[ -n "$repo_tag" && "$repo_tag" != "<none>:<none>" ]]; then
          name="${repo_tag//[:\/]/_}"
          [[ "$img" != "$repo_tag" ]] && echo ">>> resolved ${img} -> ${repo_tag}"
        else
          name="${img//[:\/]/_}"
          echo ">>> no RepoTags for ${img}, using input as filename"
        fi
    
        out="${name}.tar.gz"
        echo ">>> saving ${img} -> ${out}"
    
        if command -v pv >/dev/null 2>&1; then
          docker save "$img" | pv | gzip > "$out"
        else
          docker save "$img" | gzip > "$out"
        fi
        rc=${PIPESTATUS[0]}
    
        if [[ $rc -ne 0 ]]; then
          echo ">>> ERROR: docker save failed for ${img}" >&2
          rm -f "$out"
          fail=$((fail+1))
          continue
        fi
    
        echo "<<< done: ${out} ($(du -h "$out" | cut -f1))"
        ok=$((ok+1))
      done
    
      echo "=== summary: ${ok} saved, ${skip} skipped, ${fail} failed ==="
      [[ $fail -eq 0 ]]
    }

国内源(手动)

--------------- 要经常关注可行用,不停维护这个清单---------------
--------------- https://status.anye.xyz/ 切换查看deamon配置 ------
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
    "registry-mirrors": [
        "https://docker.1ms.run",
        "https://docker.1panel.live",
        "https://hub.rat.dev",
        "https://dockerproxy.net",
        "https://docker-registry.nmqu.com"
    ]
}
EOF
# centos
sudo systemctl daemon-reload;sudo systemctl restart docker
# alpine
sudo rc-service docker restart

代理

alpine docker 代理设置(linux通用)

网络

docker network ls
docker network create ghost_net
docker network inspect ghost_net

容器

  • 配置文件 默认基于同路径下的docker-compose.yml文件,-f xxx.yml 指定文件
  • 创建容器 docker-compose up -d -d 为后台
  • 覆盖容器 docker-compose up -d --force-recreate 覆盖旧实例
  • 运行容器 docker-compose start
    • 查看资源 docker stats
    • 查看进程 docker ps -a
    • 查看日志 docker-compose logs 
    • 进入容器 docker-compose exec 容器名称 sh
  • 重启容器 docker-compose restart
  • 销毁容器 docker-compose down
  • 停止容器 docker-compose stop

日志

  • 管理程序日志:tail -f /var/log/docker.log
  • 统一配置

    sudo vi /etc/docker/daemon.json
    {
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "10m",
        "max-file": "3"
      }
    }
    
    sudo rc-service docker restart		# Alpine 使用 OpenRC 标准命令
    sudo systemctl restart docker		# Oracle Linux
  • 日志分容器统计

    docker ps -a --format "{{.Names}}" | xargs -I {} sh -c 'echo -n "{}: "; sudo du -h $(docker inspect --format="{{.LogPath}}" {})'
  • 日志清空

    sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' trilium)

时间管理

  • 宿主机时间

    date
    ------------增加标准的时间文件,供容器同步----------
    sudo apk add tzdata
    sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    echo "Asia/Shanghai" | sudo tee /etc/timezone
    ------------宿主机自身还需要运行着时间同步服务-----------
    # 检查
    sudo rc-service chrony status
    sudo rc-service openntpd status
  • 容器时间

    docker exec opencode date -u
    需要在容器yml声明进行同步
        environment:
          - TZ=Asia/Shanghai  # 显式声明环境变量
        volumes:
          - /etc/localtime:/etc/localtime:ro
          - /etc/timezone:/etc/timezone:ro

应用

所给的链接,都是可以获取docker-compose.yml 或 启动命令,一分钟部署网站服务,容器即服务。

基础设施

nginx https://hub.docker.com/_/nginx  服务器入口,反向代理,服务应用的被访问代理人

docker-shadowsocks https://hub.docker.com/r/oddrationale/docker-shadowsocks 自建VPN代理服务器

certbot https://eff-certbot.readthedocs.io/en/latest/install.html#alternative-1-docker Let's Encrypt的https SSL证书申请和更新程序

数据库

mariadb https://hub.docker.com/_/mariadb 开源关系数据库,是mysql的一个分支,完全兼容MySQL

云笔记

trilium
https://github.com/Nriver/trilium-translation 私有云笔记,速度极快,分享后可访问,有win客户端

wiki

xwiki https://github.com/xwiki/xwiki-docker 维基程序,配合tomcat,mysql或postgres使用

mediawiki https://hub.docker.com/_/mediawiki 维基程序,配合mariadb使用

博客

Ghost 博客
https://hub.docker.com/_/ghost 简洁的博客程序,使用Node.js语言开发,支持MySQL、MariaDB、SQLite和PostgreSQL数据库

论坛

Flarum 论坛
https://github.com/mondediefr/docker-flarum 不少爱好者论坛使用 ,基于php,有yml配置,但看过说明无法确定是否能一分钟部署 

[missing note]
https://github.com/casbin/casnode/blob/master/docker-compose.yml  一个仿 V2EX 社区风格的开源论坛项目。 yml含mysql,需考虑好数据备份