Docker Compose 单机部署后端服务实践
wxk1991 Lv5

Docker Compose 单机部署后端服务实践

对于中小型项目,单台服务器加 Docker Compose 是很实用的部署方式。它比裸机部署更容易管理依赖,比 Kubernetes 简单很多,适合个人项目、内部系统、小型 API 服务。

本文以一个后端服务、一个 PostgreSQL、一个 Redis 为例,说明如何组织 Compose 文件、环境变量、数据卷、网络和发布流程。


一、推荐目录结构

服务器上可以这样放:

1
2
3
4
5
6
7
8
/opt/myapp/
compose.yaml
.env
app/
Dockerfile
data/
postgres/
redis/

也可以把 compose.yaml 放在 Git 仓库里,通过 CI/CD 或手动拉取更新。

关键原则:

  • 配置和代码分离
  • 数据卷有固定目录
  • 密码不要写死在镜像里
  • 生产环境不要依赖临时容器状态

二、示例 compose.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
services:
app:
image: registry.example.com/myapp:${APP_VERSION}
restart: unless-stopped
env_file:
- .env
depends_on:
- postgres
- redis
ports:
- "127.0.0.1:3000:3000"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/health"]
interval: 30s
timeout: 5s
retries: 3

postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ./data/postgres:/var/lib/postgresql/data
ports:
- "127.0.0.1:5432:5432"

redis:
image: redis:7
restart: unless-stopped
command: ["redis-server", "--appendonly", "yes"]
volumes:
- ./data/redis:/data
ports:
- "127.0.0.1:6379:6379"

这里把服务端口都绑定到 127.0.0.1,表示只允许本机访问。公网流量交给 Nginx 反向代理。


三、环境变量文件

.env 示例:

1
2
3
4
5
6
7
8
9
10
APP_VERSION=2026.06.04
APP_ENV=production
APP_PORT=3000

POSTGRES_DB=myapp
POSTGRES_USER=myapp
POSTGRES_PASSWORD=change-this-password

REDIS_URL=redis://redis:6379/0
DATABASE_URL=postgres://myapp:change-this-password@postgres:5432/myapp

注意 Compose 内部服务之间访问时,主机名使用服务名,例如 postgresredis,不要写 127.0.0.1


四、启动和查看状态

启动:

1
docker compose up -d

查看容器:

1
docker compose ps

查看日志:

1
docker compose logs -f app

只重启应用:

1
docker compose restart app

停止:

1
docker compose down

down 默认不会删除绑定目录里的数据,但会删除容器和网络。生产环境执行前要确认影响范围。


五、更新发布流程

如果镜像已经推送到 registry,发布可以这样做:

1
2
docker compose pull app
docker compose up -d app

如果版本由 .env 控制:

1
2
vim .env
docker compose up -d app

发布后检查:

1
2
3
docker compose ps
docker compose logs --tail=100 app
curl http://127.0.0.1:3000/health

不要只看容器状态是 running。应用可能已经启动,但数据库连接失败、迁移失败或健康检查不通过。


六、数据备份

数据库数据放在 ./data/postgres,但不要只依赖目录拷贝。推荐用数据库自己的备份工具:

1
docker compose exec postgres pg_dump -U myapp myapp > backup.sql

Redis 如果只做缓存,可以不备份。如果存了重要队列或状态,需要额外设计持久化和恢复流程。


七、常见问题

1. app 连不上 postgres

容器内访问数据库应使用:

1
postgres:5432

不是:

1
127.0.0.1:5432

127.0.0.1 在容器里指的是容器自己。

2. 数据库容器重建后数据丢失

检查是否配置了 volume 或绑定目录:

1
2
volumes:
- ./data/postgres:/var/lib/postgresql/data

没有持久化目录,容器删除后数据就会丢。

3. 端口被占用

1
sudo ss -lntp | grep 3000

确认宿主机端口是否已经被其他进程占用。


八、生产建议

单机 Compose 部署建议做到:

  • 应用端口只绑定本机或内网
  • Nginx 负责公网入口
  • 数据目录定期备份
  • 镜像使用明确版本,不长期使用 latest
  • .env 权限设置为仅部署用户可读
  • 发布前后都执行健康检查

Docker Compose 的优势是简单可控。只要目录、网络、数据和发布流程设计清楚,单机部署可以支撑很多真实业务场景。