Docker Compose 构建完整服务实战指南:从入门到最佳实践

在服务器运维和开发环境中,Docker 已经成为不可或缺的工具。而 docker-compose 则是管理多容器应用的利器。本文将带你从零开始,使用 docker-compose 构建一个完整的服务栈,并分享一些关于镜像优化和数据库部署的实务经验。

1. 环境准备

在开始之前,请确保你的服务器上已经安装了 Docker 和 Docker Compose。

  • Docker: 负责运行容器。
  • Docker Compose: 负责定义和运行多容器 Docker 应用程序。

提示 :如果你使用的是较新版本的 Docker,docker compose(无横杠)已作为插件集成在 Docker CLI 中,可以直接使用 docker compose up 命令。

2. 项目结构规划

一个标准的 Docker Compose 项目通常包含以下文件:

text 复制代码
my-blog/
├── docker-compose.yml  # 核心编排文件
├── .env                # 环境变量文件(可选,用于存放密码等敏感信息)
├── db_data/            # 数据库挂载目录(持久化数据)
└── wordpress/          # 博客程序挂载目录(可选)

3. 编写 docker-compose.yml

我们将构建一个经典的 WordPress + MySQL 博客服务。这是一个完整的服务栈,包含 Web 服务器、应用服务和数据库服务。

创建 docker-compose.yml 文件,内容如下:

yaml 复制代码
version: '3.8'

services:
  # 数据库服务
  db:
    image: mysql:8.0
    container_name: blog_db
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - ./db_data:/var/lib/mysql  # 数据持久化:将数据库文件挂载到宿主机
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - blog_net

  # 博客应用服务
  wordpress:
    image: wordpress:latest
    container_name: blog_app
    restart: always
    ports:
      - "8080:80"  # 将宿主机的 8080 端口映射到容器的 80 端口
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: ${DB_USER}
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
      WORDPRESS_DB_NAME: ${DB_NAME}
    volumes:
      - ./wordpress:/var/www/html
    depends_on:
      - db  # 确保数据库先启动
    networks:
      - blog_net

networks:
  blog_net:
    driver: bridge

4. 配置环境变量

为了安全起见,我们将密码等敏感信息放入 .env 文件中,而不是直接写在 yml 里。

创建 .env 文件:

bash 复制代码
DB_ROOT_PASSWORD=your_secure_root_password
DB_NAME=wordpress
DB_USER=wordpress_user
DB_PASSWORD=your_secure_user_password

5. 镜像优化与实务技巧

在生产环境中,直接使用官方镜像虽然方便,但往往体积庞大。以下是几个优化建议:

5.1 选择合适的镜像标签

  • 避免使用 latestlatest 标签虽然最新,但不可控。生产环境建议锁定具体版本(如 mysql:8.0wordpress:6.4-php8.2),以确保服务的稳定性。
  • 使用 Alpine 版本 :如果官方提供 alpine 后缀的镜像(如 nginx:alpine),强烈建议使用。Alpine Linux 极其精简,能大幅减小镜像体积,降低安全风险。

5.2 数据持久化

在上面的配置中,我们使用了 volumes 将数据库目录 /var/lib/mysql 挂载到宿主机的 ./db_data

  • 重要性:如果不挂载,当容器被删除或重建时,你的博客文章、用户数据将全部丢失!
  • 权限问题 :在 Linux 服务器上,确保宿主机目录(如 ./db_data)的权限允许 Docker 容器写入,否则数据库可能无法启动。

5.3 网络隔离

我们自定义了一个 blog_net 网络。这样,只有属于这个网络的服务(WordPress 和 MySQL)才能互相通信,外部无法直接访问数据库端口,提高了安全性。

6. 启动与管理服务

一切配置就绪后,在项目根目录下执行以下命令:

启动服务

bash 复制代码
docker compose up -d
  • -d 表示在后台运行(Detached mode)。

查看日志

如果服务启动失败,可以通过日志排查问题:

bash 复制代码
docker compose logs -f

停止与删除

bash 复制代码
# 停止服务
docker compose stop

# 停止并删除容器(数据卷不会删除,除非加 -v)
docker compose down

7. 常见问题排查

  1. 端口冲突 :如果 8080 端口被占用,请修改 docker-compose.yml 中的 ports 映射,例如改为 8081:80
  2. 数据库连接失败 :检查 WORDPRESS_DB_HOST 是否填写为服务名 db,而不是 localhost。在 Docker 网络中,服务名即为 hostname。
  3. 权限不足 :如果遇到 Permission denied,尝试使用 sudo 执行 docker 命令,或将当前用户加入 docker 用户组。

结语

通过 docker-compose,我们只需一个文件就能轻松管理复杂的服务依赖。无论是搭建个人博客,还是部署微服务架构,掌握这一工具都能极大地提升运维效率。希望这份指南能帮助你顺利构建自己的 Docker 服务!

相关推荐
行百里er4 小时前
5 分钟跑起 Redis(Docker 版)
redis·后端·docker
Mr.朱鹏5 小时前
Docker三剑客实战指南:Docker、Dockerfile 和 Docker Compose
python·docker·devops·dockerfile
鬼先生_sir5 小时前
Docker 完整教程
docker
java_logo6 小时前
Docker 一键部署 Jellyfin:快速搭建私有化媒体服务器
docker·私有化部署·jellyfin·硬件加速·媒体服务器·轩辕镜像·影音库
jianpeng的工程笔记7 小时前
WeKnora 搭建研发 EDA 知识库:Docker 部署、RAG 与 Wiki 实践
docker·知识库·eda·rag
ZeroNews内网穿透8 小时前
内网部署 Halo 建站,用 ZeroNews 免费内网穿透安全发布到公网(无公网 IP 也能 HTTPS 访问)
docker·https·内网穿透·nas·反向代理·halo·zeronews
九皇叔叔21 小时前
K8S 资源菜单
docker·容器·kubernetes·k8s
wdfk_prog1 天前
ROS教程08:从 TransportTCP::connect() 追到 TCPROS Connection Header、序列化与 Socket 数据传输
运维·缓存·docker·容器·ros
Zhu7581 天前
docker环境快速部署postgresql数据库18及以上版本
postgresql·容器