Ubuntu系统中使用Docker部署多个应用的最佳实践是什么?

在 Ubuntu 系统上使用 Docker 部署多个应用时,最佳实践应围绕可维护性、安全性、资源隔离和可观测性展开。以下是经过验证的实用方案:


✅ 1. 使用 Docker Compose 管理多容器应用

避免手动执行 docker run,改用 docker-compose.yml 声明式编排:

version: '3.8'
services:
  web:
    build: ./web-app
    ports: ["80:80"]
    depends_on: [db]
    networks: [app-net]
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks: [app-net]

volumes:
  pgdata:

networks:
  app-net:
    driver: bridge
  • 将敏感信息(如密码)通过 .env 文件管理(加入 .gitignore
  • 按业务模块拆分 compose.yaml 或使用项目级目录结构(如 projects/myapp/docker-compose.yml

✅ 2. 网络隔离与自定义网络

  • 为每个项目/服务组创建独立网络(如上例中的 app-net),避免服务间意外通信
  • 生产环境建议使用 overlay 网络(配合 Swarm 或 Kubernetes),本地开发用 bridge
  • 禁止容器直接访问宿主机端口(除非必要),优先使用内部服务发现

✅ 3. 安全加固

措施 说明
非 root 用户运行 在 Dockerfile 中指定 USER appuser,避免以 root 启动容器
只读根文件系统 添加 read_only: true + 挂载临时卷处理日志/缓存
限制资源 设置 deploy.resources.limits(Compose v2+)或 --memory, --cpus
最小化镜像 使用多阶段构建 + Alpine/Distroless 基础镜像
定期更新镜像 集成 Dependabot / Trivy 扫描漏洞;CI 中自动拉取最新标签并测试

示例安全配置片段:

security_opt:
  - no-new-privileges:true
read_only: true
tmpfs:
  - /tmp:mode=1777,size=64M

✅ 4. 日志与监控统一化

  • 日志驱动:全局配置 logging-driver: json-file(默认)或 syslog/fluentd
  • 集中收集:部署 Prometheus + Grafana + Loki(推荐 PromStack 组合)
  • 健康检查:为关键服务添加 healthcheck,便于编排器自动重启异常容器
    healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost/health"]
    interval: 30s
    timeout: 10s
    retries: 3

✅ 5. 持久化数据管理

  • 数据库、用户上传文件等必须使用 named volumes 或 bind mounts(明确路径)
  • 避免将重要数据放在容器层(容器删除即丢失)
  • 对数据库卷启用备份策略(如 pg_dump + cron + S3 存储)

✅ 6. CI/CD 集成自动化

  • 构建 → 扫描 → 推送到私有仓库(如 GitLab Container Registry, Harbor)
  • 部署流程:
    docker compose pull && docker compose up -d --force-recreate
  • 使用 Ansible/Terraform 管理宿主机状态(Docker 安装、防火墙、用户权限)

✅ 7. Ubuntu 系统级优化建议

  • 启用 systemd 管理 Docker 服务(sudo systemctl enable docker
  • 调整内核参数提升性能(/etc/sysctl.conf):
    vm.overcommit_memory = 1
    net.core.somaxconn = 65535
  • 使用 docker system prune -a 定期清理悬空镜像/容器(谨慎操作)
  • 考虑启用 cgroup v2(Ubuntu 22.04+ 默认支持)以获得更好资源控制

🚫 避免常见误区

  • ❌ 所有服务共用一个 default 网络
  • ❌ 硬编码密码/密钥到代码或镜像中
  • ❌ 无健康检查导致故障无法自动恢复
  • ❌ 忽略磁盘空间监控(df -h + docker system df

如需进一步落地,可提供你的具体场景(如:微服务架构?单体应用?是否需 HTTPS?),我可给出定制化模板或脚本示例。

云服务器