跳到主要内容
注册无需实名认证
安云主机 AnYun VPS

教程 · 应用与数据库

安装 Docker 与 Compose,并写第一份 compose.yaml

难度

入门

预计时长

20 分钟

步骤

7

最近修订

基准系统

Debian 12

要点

安装 Docker 与 Compose,并写第一份 compose.yaml

Docker 的官方仓库安装法适用于 Debian 与 Ubuntu:写入官方 GPG 密钥与 apt 源,再安装 docker-ce 与 docker-compose-plugin,之后用 docker compose(中间是空格,不是连字符)管理服务。端口映射务必写成 127.0.0.1:8080:80 —— 直接写 8080:80 时 Docker 会绕过 ufw,把端口暴露到公网。

前置条件

开始之前,先确认这些都具备

  • 一台 Debian 12 或 Ubuntu 22.04+ 服务器与 sudo 权限
  • 至少 2 GB 内存(1 GB 需配 swap)

操作步骤

7

  1. 步骤 01 / 07

    写入官方源并安装 #

    发行版仓库里的 docker.io 版本较旧且不含 compose 插件。下面是 Docker 官方文档的安装步骤,Ubuntu 用户把两处 debian 换成 ubuntu 即可。

    Shell
    sudo apt update && sudo apt install -y ca-certificates curl
    sudo install -m 0755 -d /etc/apt/keyrings
    
    sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
    sudo chmod a+r /etc/apt/keyrings/docker.asc
    
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
      | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    sudo apt update
    sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  2. 步骤 02 / 07

    验证安装 #

    hello-world 跑通说明守护进程、镜像拉取与容器运行三件事都正常。compose version 用来确认插件装上了 —— 老教程里的 docker-compose(带连字符)是已经不再维护的独立工具。

    Shell
    sudo docker run --rm hello-world
    sudo docker compose version
    sudo systemctl enable --now docker
  3. 步骤 03 / 07

    (可选)让普通用户免 sudo 使用 docker #

    把用户加进 docker 组之后不用每次敲 sudo,但要清楚这条命令的含义:docker 组成员可以挂载宿主机根目录进容器,等价于 root 权限。只把可信的运维账号加进去。

    Shell
    sudo usermod -aG docker deploy
    # 重新登录后生效
    newgrp docker
    docker ps
  4. 步骤 04 / 07

    写第一份 compose.yaml #

    注意两点:顶部的 version 字段早已废弃,现在写了反而会有警告;端口映射前面加 127.0.0.1,让服务只在本机可达,对外由 Nginx 或 Caddy 反向代理。restart: unless-stopped 保证机器重启后容器自己回来。

    YAML
    # ~/apps/web/compose.yaml
    services:
      web:
        image: nginx:alpine
        restart: unless-stopped
        ports:
          - "127.0.0.1:8080:80"
        volumes:
          - ./site:/usr/share/nginx/html:ro
        healthcheck:
          test: ["CMD", "wget", "-qO-", "http://localhost/"]
          interval: 30s
          timeout: 5s
          retries: 3
    
      db:
        image: postgres:16-alpine
        restart: unless-stopped
        environment:
          POSTGRES_PASSWORD: 换成强密码
          POSTGRES_DB: appdb
        volumes:
          - pgdata:/var/lib/postgresql/data
    
    volumes:
      pgdata:
  5. 步骤 05 / 07

    日常操作 #

    所有命令都在 compose.yaml 所在目录执行。down 只删容器不删命名卷,数据是安全的 —— 但加上 -v 就会连卷一起删,这个参数请务必看清楚再敲。

    Shell
    docker compose up -d
    docker compose ps
    docker compose logs -f web
    docker compose pull && docker compose up -d   # 更新镜像
    docker compose down                            # 停止并删除容器(保留数据卷)
  6. 步骤 06 / 07

    限制日志大小,别让磁盘被写满 #

    Docker 默认的 json-file 日志驱动没有大小上限,一个话痨容器几周就能吃掉几十 GB。设置全局上限之后重启守护进程,对新建容器生效。

    JSON
    // /etc/docker/daemon.json
    {
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "10m",
        "max-file": "3"
      }
    }
  7. 步骤 07 / 07

    定期清理无用镜像 #

    构建产生的悬空镜像与停止的容器会持续占用磁盘。先用 df 看用量,再清理。注意 --volumes 会删除未被引用的数据卷,执行前务必确认那些卷里没有你还要的数据。

    Shell
    docker system df
    docker image prune -f          # 只删悬空镜像,安全
    docker container prune -f      # 删除已停止的容器
    
    # 下面这条会连未被引用的数据卷一起删,确认之后再执行
    # docker system prune -a --volumes

常见错误

这一步最容易踩的坑

下面每一条都对应一个真实会发生的故障。先读完再动手,比出问题之后再回来查要省时间。

  • 端口映射写成 8080:80。Docker 直接操作 iptables,ufw 里看不到这条规则,端口却已经对全世界开放。永远写 127.0.0.1:8080:80,除非你确实要对外提供服务。
  • docker system prune -a --volumes 随手一敲,数据库卷没了。这条命令没有确认提示以外的保护。
  • 把数据写在容器里而不是命名卷里。容器重建的那一刻数据全部消失。
  • 在 1 GB 内存的机器上跑一整套 compose 服务。不配 swap 的话,第一次构建就会被 OOM 结束。
  • compose.yaml 顶部还写着 version: "3"。新版本会提示该字段已废弃,删掉即可。
  • 镜像里的时区是 UTC,导致容器日志时间与宿主机对不上。需要的话通过 TZ 环境变量或挂载 /etc/localtime 解决。
  • 为了加速拉取而随便配置来源不明的镜像加速地址。镜像是要在你机器上跑的代码,来源必须可信。

这篇教程的边界

  • 命令以 Debian 12 为准。Ubuntu 与 Rocky Linux 的差异只在正文明确标注之处,未标注的部分请以你所用发行版的官方文档为准。
  • 示例中的 IP 来自文档保留段 203.0.113.0/24,域名为 example.com,端口为示意值。复制后必须替换成自己的值, 原样执行不会有任何效果。
  • 教程不能替代备份。任何会改动数据或线上流量的步骤,执行前先确认有一份验证过能恢复的备份。
  • 本站不提供任何用于绕过网络审查的配置或说明,这篇也不例外。

发现命令过时或有误,请发邮件到 [email protected]。 指出错误的邮件比沉默的旧文档有价值得多。

联系 工单
扫码
手机访问

扫码在手机上打开