Home Knowledge base Skyline Cloud 如何使用 Docker Compose 部署应用 KNOWLEDGE BASE

如何使用 Docker Compose 部署应用

通过一个真实的多容器示例,学习如何用 Docker Compose 在 Linux 服务器上部署应用:Web 应用、PostgreSQL 数据库,以及自动启用 HTTPS 的 Caddy 反向代理。

如何使用 Docker Compose 部署应用

简介

Docker Compose 让你能够在一个声明式文件中定义一个多容器应用——一个 Web 应用、它的数据库、一个缓存以及一个反向代理——然后用一条命令把它们全部启动起来。你无需手动运行冗长的 docker run 命令,只需描述一次期望状态,Compose 就会为你完成协调。

在本教程中,你将在一台 Linux 服务器上部署一个虽小但贴近实际的技术栈:一个 Web 应用、一个 PostgreSQL 数据库,以及一个自动终止 HTTPS 的 Caddy 反向代理。完成后,你将拥有一个可通过你自己的域名经由 TLS 访问的运行中应用。

我们将部署在 Skyline Cloud VPS 上。由于 Skyline 在沙特阿拉伯境内运营本地基础设施,你的数据以及你客户的数据都将处于 PDPL、NCA 和 SDAIA 的管辖范围之内——当你为沙特和海湾合作委员会(GCC)的组织托管工作负载时,这一点至关重要。如果你还没有服务器,几分钟即可创建一台

前置条件

  • 一台拥有公网 IP 的 Linux 服务器(Ubuntu 22.04/24.04 或 Debian 12)。一台 1–2 vCPU / 2 GB 内存的 VPS 足以入门。
  • 一个具备 sudo 权限的非 root 用户,以及对服务器的 SSH 访问权限。
  • 一个域名,其 A 记录 指向你服务器的公网 IP。使用 Skyline 提供的 .sa 域名和托管 DNS,创建一条类似 app.example.sa → 203.0.113.10 的记录。

第 1 步 — 安装 Docker Engine 与 Compose 插件

现代 Docker 将 Compose 作为插件提供(使用 docker compose,而非旧版的 docker-compose)。官方的便捷脚本会一并安装引擎和插件:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

将你的用户加入 docker 组,这样无需 sudo 即可运行 Docker,然后重新打开会话:

sudo usermod -aG docker $USER
newgrp docker

验证引擎和 Compose 插件是否都已就绪:

docker --version
docker compose version

第 2 步 — 规划项目结构

为你的技术栈创建一个目录并进入其中:

mkdir -p ~/myapp && cd ~/myapp

我们将在这里保留三个文件:用于构建应用镜像的 Dockerfile、用于将各服务连接起来的 compose.yaml,以及用于存放密钥和配置的 .env 文件。

第 3 步 — 编写应用的 Dockerfile

对于一个典型的 Node.js 应用,一个小巧的多阶段构建可以让最终镜像保持精简。请根据你自己的技术栈(Python、Go、PHP 等)调整这些命令:

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

第 4 步 — 在 .env 文件中定义密钥

切勿在 compose 文件中硬编码凭据。把它们放进 .env 文件,Compose 会自动读取:

POSTGRES_USER=appuser
POSTGRES_PASSWORD=change-me-to-a-strong-secret
POSTGRES_DB=appdb
APP_DOMAIN=app.example.sa

限制其权限,并将其排除在版本控制之外:

chmod 600 .env
echo ".env" >> .gitignore

第 5 步 — 编写 Compose 文件

创建 compose.yaml。它定义了三个服务、一个私有网络,以及命名卷,从而让你的数据和 TLS 证书在重启后依然保留:

services:
  app:
    build: .
    restart: unless-stopped
    environment:
      DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
    depends_on:
      db:
        condition: service_healthy
    expose:
      - "3000"

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5

  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    depends_on:
      - app

volumes:
  db-data:
  caddy-data:
  caddy-config:

有几个细节值得留意:

  • 数据库端口没有通过 ports: 发布出去;它只能在 Compose 的内部网络上访问,因此永远不会暴露到互联网。
  • 带有 condition: service_healthydepends_on 会让应用一直等待,直到 PostgreSQL 真正开始接受连接,而不仅仅是其容器启动完成。
  • restart: unless-stopped 会在重启或崩溃后自动让你的服务恢复运行。

第 6 步 — 配置反向代理

在你的 compose 文件旁边创建一个名为 Caddyfile 的文件。Caddy 会自动获取并续期 Let's Encrypt 证书,因此你无需任何手动证书操作即可获得 HTTPS:

app.example.sa {
    reverse_proxy app:3000
}

app.example.sa 替换为你真实的域名。Caddy 会通过内部网络把 app 解析到你的应用容器,并将请求代理到 3000 端口。

第 7 步 — 启动技术栈

构建镜像并在后台启动全部服务:

docker compose up -d --build

检查所有服务是否健康:

docker compose ps

跟踪日志,观察应用启动以及 Caddy 签发证书的过程:

docker compose logs -f

在浏览器中打开 https://app.example.sa。此时 Caddy 已经为你预置好了一张有效的 TLS 证书。

第 8 步 — 运维与更新

日常常用命令:

任务 命令
查看运行中的服务 docker compose ps
跟踪某个服务的日志 docker compose logs -f app
重启某个服务 docker compose restart app
停止技术栈(保留数据) docker compose down
拉取更新的基础镜像 docker compose pull
重新构建并重新部署 docker compose up -d --build

要发布新版本的代码,先拉取你的更改,然后运行 docker compose up -d --build。Compose 只会重新创建发生变化的容器,并保持数据库不受影响,从而为无状态服务带来近乎零停机的更新体验。

要移除所有内容包括卷(这会删除你的数据库数据),请运行 docker compose down -v——使用时务必谨慎。

第 9 步 — 备份你的数据

你的应用数据存放在 db-data 卷中。请定期进行转储,并将其存储到服务器之外。一个简单的 PostgreSQL 备份命令如下:

docker compose exec db pg_dump -U appuser appdb > backup-$(date +%F).sql

使用 cron 来定时执行此操作,并将转储文件推送到 Skyline Cloud 对象存储或云备份,这样单台服务器故障就永远不会让你丢失数据。

结语

你现在已经使用 Docker Compose 部署了一个多容器应用,前端有一个自动启用 HTTPS 的反向代理,并运行在一台由你掌控的服务器上。在此基础上,你可以添加一个 Redis 缓存,通过 docker compose up -d --scale app=3 在代理后端扩展无状态服务,或者升级到容器编排——当你的应用超出单台主机的承载能力时,请参阅我们的沙特阿拉伯托管 Kubernetes 指南。

如果你还需要为你的域名配备专业邮箱与你的应用相伴,Skyline 企业邮箱托管同样能让你的邮件保留在境内。

准备好部署了吗?创建你的 Skyline Cloud 服务器,立即开始

SKYLINE Engineering

@skyline

The engineering team at SKYLINE Industrial Solutions. We publish field-tested guides drawn from real KSA and GCC deployments.

See author profile
SKYLINE engineering services

Need this implemented for you?

Reading is free — building it right takes a team. SKYLINE engineers ship Skyline Cloud for Aramco vendors, banks, hospitals and government agencies across Saudi Arabia. Talk to us before you start.

Aramco Approved Contractor ISO 9001 · ISO 27001 SAMA CSF aligned NCA ECC ready 247+ KSA clients

Comments

0 total · 0 threads
Be the first to leave a comment.