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 选择合适的镜像标签

  • 避免使用 latest :latest 标签虽然最新,但不可控。生产环境建议锁定具体版本(如 mysql:8.0 或 wordpress: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 服务!

相关推荐
吴声子夜歌1 小时前
Docker入门与实战——实战案例(Web服务与应用)
docker·容器
Wang's Blog2 小时前
Java 项目部署之 Docker工具快速入门: Docker 架构拆解:镜像、容器、守护进程与 Registry
java·docker·架构
java_logo2 小时前
Docker 部署 OpenViking:轻松搭建 AI Agent 上下文数据库平台
数据库·人工智能·docker·agent·火山引擎·openviking·轩辕镜像
a5986522 小时前
Docker云手机搭建挂机环境,外网远程访问完整实操
docker·容器·智能手机·云手机
夜之眷属2 小时前
服务启动即崩:InetAddress.getLocalHost() 抛 UnknownHostException 排查记
java·运维·后端·docker
郭老二3 小时前
【docker】使用阿里云的容器镜像服务(ACR)构建自己的容器仓库
阿里云·docker·容器
Wang's Blog6 小时前
Java 项目部署之 Docker工具快速入门: Docker 是什么以及它如何解决部署环境问题
java·开发语言·docker
AIGC大时代7 小时前
LLM Agent 执行沙箱闸门:失败含义与当天最小实验
docker·沙箱·闸门·bubblewrap·llm agent
灯澜忆梦8 小时前
【docker】#2 | 基础命令
docker·容器·eureka