Docker(五)—— Docker Compose 一键搭建 LNMP 架构并部署 WordPress
文章目录
- 前言
- 一、环境准备
- 1.1 关闭防火墙与 SELinux
- 1.2 安装 Docker 与 Docker Compose
- 1.3 创建项目统一目录
- 1.4 生成 HTTPS 自签名证书
- 1.4.1 生成证书步骤
- 1.4.2 证书说明
- 1.5 项目架构图
- 二、编写核心配置文件
- 2.1 docker-compose.yml(服务编排)
- 2.2 MySQL 自定义配置(my.cnf)
- 2.3 Nginx 站点配置(wordpress.conf)
- 三、部署 WordPress 代码
- 3.1 下载并解压 WordPress
- 3.2 配置 WordPress 数据库连接
- 3.2.1 手动配置(推荐,避免安装时填错)
- 3.2.2 安装向导配置(适合新手)
- 四、启动服务与测试验证
- 4.1 启动所有服务
- 4.2 检查服务状态
- 4.3 访问 WordPress 完成安装
- 4.3.1 浏览器访问
- 4.3.2 验证核心功能
- 五、常见问题与优化方案
- 5.1 常见问题排查
- 5.2 性能与安全优化
- 5.2.1 MySQL 优化
- 5.2.2 Nginx 优化
- 总结
前言
LNMP(Linux + Nginx + MySQL + PHP)是Web开发中经典的开源架构,广泛用于运行动态网站(如博客、电商系统)。传统搭建方式需手动配置各服务依赖,步骤繁琐且易出现环境冲突;而 Docker Compose 可通过一份配置文件定义多容器联动关系,实现“一键部署、环境一致、易于维护”的目标。
本文将以 CentOS 7.9 系统为基础,详细讲解如何通过 Docker Compose 搭建 LNMP 架构,并部署主流博客系统 WordPress,涵盖环境准备、配置编写、服务启动、测试验证及优化方案,适合初学者快速上手,也可作为企业级测试环境的部署参考。
一、环境准备
1.1 关闭防火墙与 SELinux
Linux 系统默认开启的防火墙(firewalld)和 SELinux(安全增强组件)可能会拦截容器间通信或端口访问,为避免部署过程中出现异常,需先关闭两者。
# 1. 关闭防火墙(临时生效,重启后失效)
systemctl stop firewalld
# 禁止防火墙开机自启(永久生效)
systemctl disable firewalld# 2. 临时关闭 SELinux(无需重启,立即生效)
setenforce 0
# 永久关闭 SELinux(需重启服务器生效,修改配置文件)
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
验证关闭效果:
- 防火墙:
systemctl status firewalld
显示inactive (dead)
- SELinux:
getenforce
显示Permissive
(临时关闭)或重启后显示Disabled
(永久关闭)
1.2 安装 Docker 与 Docker Compose
LNMP 架构的各服务均以 Docker 容器运行,需先安装 Docker 引擎和 Docker Compose 编排工具。
具体步骤参考:
- Docker(一)—— Docker入门到精通:从基础概念到容器管理
- Docker(三)—— Docker Compose 编排与 Harbor 私有仓库实战指南
1.3 创建项目统一目录
为便于管理配置文件、证书、代码和数据,创建结构化的项目目录(后续所有文件均放在此目录下):
# 创建项目根目录及子目录
mkdir -p /opt/compose_lnmp_wordpress/{nginx/conf.d,nginx/logs,mysql/{conf,data},ssl/{private,certs},wwwroot}
各目录作用说明:
目录路径 | 作用 |
---|---|
/opt/compose_lnmp_wordpress | 项目根目录 |
nginx/conf.d | Nginx 站点配置文件目录 |
nginx/logs | Nginx 日志目录(访问日志、错误日志) |
mysql/conf | MySQL 自定义配置文件目录 |
mysql/data | MySQL 数据目录(持久化存储) |
ssl/private | HTTPS 证书私钥目录 |
ssl/certs | HTTPS 证书(CRT/CSR)目录 |
wwwroot | WordPress 代码目录 |
1.4 生成 HTTPS 自签名证书
现代浏览器默认推荐 HTTPS 访问,生产环境需使用 Let’s Encrypt 等权威机构的免费证书,测试环境可使用 OpenSSL 生成自签名证书。
参考博文:Docker(四)—— 使用 Docker 搭建 Nginx 并实现 HTTPS 访问
1.4.1 生成证书步骤
CentOS 7 默认已安装 OpenSSL,执行以下命令生成证书(路径对应 1.3 节创建的 ssl
目录):
# 1. 生成 RSA 私钥(2048位,无加密,避免启动 Nginx 时输入密码)
openssl genpkey -algorithm RSA -out /opt/compose_lnmp_wordpress/ssl/private/nginx-selfsigned.key -pkeyopt rsa_keygen_bits:2048# 2. 生成证书请求文件(CSR),需填写基础信息
openssl req -new -key /opt/compose_lnmp_wordpress/ssl/private/nginx-selfsigned.key -out /opt/compose_lnmp_wordpress/ssl/certs/nginx-selfsigned.csr
执行第 2 步时,需按提示填写信息(示例如下,Common Name
需与访问域名/IP 一致):
- Country Name(国家代码):
CN
; - State or Province Name(省/州):
Beijing
; - Locality Name(城市):
Beijing
; - Organization Name(组织名称):
MyTech
; - Organizational Unit Name(部门):
IT
(可留空); - Common Name(域名/IP):
192.168.10.14
(替换为你的服务器 IP); - Email Address(邮箱):
admin@mytech.com
(可留空); - A challenge password(密码):直接回车(留空)。
# 3. 生成自签名证书(CRT),有效期 365 天
openssl x509 -req -days 365 -in /opt/compose_lnmp_wordpress/ssl/certs/nginx-selfsigned.csr -signkey /opt/compose_lnmp_wordpress/ssl/private/nginx-selfsigned.key -out /opt/compose_lnmp_wordpress/ssl/certs/nginx-selfsigned.crt# 4. 验证证书文件是否生成
ls -l /opt/compose_lnmp_wordpress/ssl/private
ls -l /opt/compose_lnmp_wordpress/ssl/certs
正常输出应包含:
private
目录:nginx-selfsigned.key
(私钥);certs
目录:nginx-selfsigned.csr
(请求文件)、nginx-selfsigned.crt
(证书)。
1.4.2 证书说明
- 自签名证书不被浏览器默认信任,访问时会提示“不安全”,测试环境可点击“高级”→“继续访问”忽略;
- 生产环境需替换为权威证书(如 Let’s Encrypt,可通过
certbot
工具自动申请和续期)。
1.5 项目架构图
本次 Docker 搭建 LNMP 架构并部署 WordPress 的项目结构如下(清晰区分配置、证书、静态资源目录,便于后期维护):
/opt/compose_lnmp_wordpress # 项目根目录
├── docker-compose.yml # 核心配置文件:定义了 MySQL、PHP、Nginx 三个服务的容器编排规则
├── mysql # MySQL 服务相关目录
│ ├── conf # MySQL 配置目录:存放自定义配置文件,覆盖容器默认配置
│ │ └── my.cnf # MySQL 核心配置文件
│ └── data # MySQL 数据目录:通过 Docker 挂载将容器内的数据库文件持久化到宿主机,容器删除后数据不丢失(重要!)
├── nginx # Nginx 服务相关目录
│ ├── conf.d # Nginx 站点配置目录:存放具体网站的配置文件
│ │ └── wordpress.conf # WordPress 站点配置
│ └── logs # Nginx 日志目录:挂载容器内的访问日志和错误日志,便于排查问题(如 404/502 错误原因)
├── ssl # HTTPS 证书相关目录:存放 SSL 证书和私钥,用于 Nginx 配置 HTTPS 访问
│ ├── certs # 证书文件目录
│ │ ├── nginx-selfsigned.crt # 自签名证书文件:公钥部分,客户端浏览器用于验证服务器身份
│ │ └── nginx-selfsigned.csr # 证书请求文件:生成证书时的中间文件,部署时无需使用但建议保留
│ └── private # 私钥目录:存放证书私钥
│ └── nginx-selfsigned.key # 证书私钥文件:服务器用于加密 HTTPS 通信内容
└── wwwroot # 网站代码目录:存放 WordPress 源代码,通过挂载共享给 Nginx 和 PHP 容器├── wordpress-latest-zh_CN.tar.gz # WordPress 源码压缩包└── wordpress # WordPress 源码目录:解压后的实际运行代码,包含核心文件(wp-includes)、配置文件(wp-config.php)、主题和插件目录等
二、编写核心配置文件
2.1 docker-compose.yml(服务编排)
docker-compose.yml
是整个项目的“指挥中心”,定义 Nginx、MySQL、PHP 三个服务的启动规则、依赖关系、挂载目录等。在项目根目录 /opt/compose_lnmp_wordpress/
下创建该文件:
version: '3' # 1. 自定义网络:让三个服务在同一网络内,可通过“服务名”通信(无需记 IP)
networks:lnmp_network:driver: bridge # 桥接模式,默认且常用# 2. 定义服务
services:# 2.1 MySQL 服务(数据存储)mysql:container_name: lnmp_mysqlimage: mysql:5.7 # 镜像版本(已选定)restart: always # 容器故障/服务器重启后自动启动environment:- MYSQL_ROOT_PASSWORD=Root@123456 # MySQL root 密码(自定义,建议复杂)- MYSQL_DATABASE=wordpress_db # 预创建 WordPress 专用数据库- MYSQL_USER=wp_user # 预创建 WordPress 专用用户(避免用 root)- MYSQL_PASSWORD=Wp@123456 # 专用用户密码- TZ=Asia/Shanghai # 时区(避免日志/数据时间错乱)volumes:# 数据持久化:宿主机目录 → 容器目录- ./mysql/data:/var/lib/mysql# 自定义配置:宿主机 MySQL 配置 → 容器配置目录- ./mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnfnetworks:- lnmp_network # 加入自定义网络user: "999:999" # MySQL 容器内默认用户(UID=999),避免 root 权限风险# 2.2 PHP-FPM 服务(动态请求处理)php:image: php:8.3-fpm # 镜像版本container_name: lnmp_phprestart: alwaysenvironment:- TZ=Asia/Shanghaivolumes:# 挂载 WordPress 代码目录(与 Nginx 挂载同一路径,确保文件一致)- ./wwwroot:/var/www/htmldepends_on:- mysql # 依赖 mysql 服务,确保 mysql 先启动(避免连接失败)networks:- lnmp_network# 启动时自动安装 WordPress 必需的 PHP 扩展command: >sh -c "apt-get update &&apt-get install -y --no-install-recommends libfreetype6-dev libjpeg62-turbo-dev libpng-dev libzip-dev &&docker-php-ext-configure gd --with-freetype --with-jpeg &&docker-php-ext-install -j$(nproc) mysqli gd zip &&apt-get clean && rm -rf /var/lib/apt/lists/* &&php-fpm" # 启动 PHP-FPM 服务# 2.3 Nginx 服务(反向代理/静态资源处理)nginx:image: nginx:latest # Nginx 最新稳定版container_name: lnmp_nginxrestart: alwaysports:- "80:80" # HTTP 端口(用于重定向到 HTTPS)- "443:443" # HTTPS 端口(核心访问端口)environment:- TZ=Asia/Shanghaivolumes:# 挂载站点配置文件- ./nginx/conf.d:/etc/nginx/conf.d# 挂载静态资源/PHP 代码(与 PHP 容器一致)- ./wwwroot:/var/www/html# 挂载 HTTPS 证书- ./ssl/certs:/etc/nginx/ssl/certs- ./ssl/private:/etc/nginx/ssl/private# 挂载日志目录- ./nginx/logs:/var/log/nginxdepends_on:- php # 依赖 php 服务,确保 php 先启动networks:- lnmp_network
关键配置说明
networks
:自定义网络lnmp_network
,服务间可通过“服务名”(如mysql
、php
)通信,无需手动配置 IP;volumes
:实现“宿主机目录 ↔ 容器目录”挂载,核心作用是数据持久化(容器删除后数据不丢失)和配置复用;depends_on
:控制服务启动顺序(mysql
先启动 →php
再启动 →nginx
最后启动),避免时序问题导致的连接失败;command
(PHP 服务):启动时自动安装mysqli
(MySQL 连接扩展)、gd
(图片处理扩展)、zip
(插件压缩解压扩展),无需手动进入容器安装。
2.2 MySQL 自定义配置(my.cnf)
为优化 MySQL 性能(如字符集、连接数),在 /opt/compose_lnmp_wordpress/mysql/conf/
目录下创建 my.cnf
文件:
[mysqld]
# 数据库默认字符集(支持 emoji 表情)
character-set-server=utf8mb4
# 数据库排序规则
collation-server=utf8mb4_unicode_ci
# 最大连接数(根据服务器配置调整)
max_connections=100
# InnoDB 缓存大小(建议为服务器内存的 50%,示例:256M)
innodb_buffer_pool_size=256M
# 日志时间戳时区
log_timestamps=SYSTEM
2.3 Nginx 站点配置(wordpress.conf)
Nginx 需要通过配置文件知道“如何处理 WordPress 请求”,在 /opt/compose_lnmp_wordpress/nginx/conf.d/
目录下创建 wordpress.conf
文件:
# 1. HTTPS 站点配置(核心)
server {listen 443 ssl; # 监听 443 端口(HTTPS 默认端口)server_name 192.168.10.14; # 替换为你的服务器 IP 或域名(与证书 Common Name 一致)# HTTPS 证书配置(容器内路径,对应宿主机 ./ssl 目录)ssl_certificate /etc/nginx/ssl/certs/nginx-selfsigned.crt;ssl_certificate_key /etc/nginx/ssl/private/nginx-selfsigned.key;# SSL 安全优化(禁用旧协议,使用强加密套件)ssl_protocols TLSv1.2 TLSv1.3; # 仅支持 TLS 1.2/1.3(安全性更高)ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";ssl_prefer_server_ciphers on; # 优先使用服务器端加密套件# 站点根目录(与 PHP 容器挂载的 /var/www/html/wordpress 一致)root /var/www/html/wordpress;index index.php index.html index.htm; # 优先解析 PHP 文件# 日志配置(便于排查问题)access_log /var/log/nginx/wordpress_access.log; # 访问日志error_log /var/log/nginx/wordpress_error.log; # 错误日志# 2. 处理 PHP 动态请求(核心转发规则)location ~ \.php$ {root /var/www/html/wordpress; # 确认根目录fastcgi_pass php:9000; # 转发到 PHP 服务(服务名:端口)fastcgi_index index.php; # 默认 PHP 入口文件# 传递 PHP 脚本路径(必须正确,否则会报 404/502 错误)fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params; # 加载 Nginx 内置 FastCGI 参数}# 3. WordPress 固定链接支持(可选,开启后链接更友好,如 /post/123)location / {try_files $uri $uri/ /index.php?$args; # 重写请求到 index.php}# 4. 安全优化:禁止访问敏感文件/目录location ~ /\.ht {deny all; # 禁止访问 .htaccess 文件}
}# 2. HTTP 重定向到 HTTPS(强制加密访问)
server {listen 80;server_name 192.168.10.14; # 与 HTTPS 站点的 server_name 一致return 301 https://$host$request_uri; # 301 永久重定向到 HTTPS
}
三、部署 WordPress 代码
WordPress 代码需放在宿主机 /opt/compose_lnmp_wordpress/wwwroot
目录(与 Nginx、PHP 容器挂载的 /var/www/html
对应),步骤如下:
3.1 下载并解压 WordPress
# 1. 进入 wwwroot 目录
cd /opt/compose_lnmp_wordpress/wwwroot# 2. 下载 WordPress 最新中文版本(从官方源下载,安全可靠)
wget https://cn.wordpress.org/wordpress-latest-zh_CN.tar.gz# 3. 解压到 wordpress 子目录(便于后续管理)
tar -zxvf wordpress-latest-zh_CN.tar.gz# 4. 授权:确保 PHP 容器有读写权限(PHP 容器内用户为 www-data,UID=33)
chown -R 33:33 /opt/compose_lnmp_wordpress/wwwroot/wordpress
# 授权给 UID=999(MySQL 容器内默认用户)
chown -R 999:999 /opt/compose_lnmp_wordpress/mysql/data
如果报错无读写权限,可以进入PHP容器执行
id www-data
,查看用户的uid
3.2 配置 WordPress 数据库连接
WordPress 需通过配置文件连接 MySQL,有两种方式可选:
3.2.1 手动配置(推荐,避免安装时填错)
# 1. 复制 WordPress 默认配置文件(重命名为 wp-config.php)
cp /opt/compose_lnmp_wordpress/wwwroot/wordpress/wp-config-sample.php /opt/compose_lnmp_wordpress/wwwroot/wordpress/wp-config.php# 2. 编辑配置文件,修改数据库参数(与 docker-compose.yml 中 MySQL 配置对应)
vim /opt/compose_lnmp_wordpress/wwwroot/wordpress/wp-config.php
修改以下核心参数:
// MySQL 数据库名(与 docker-compose.yml 中 MYSQL_DATABASE 一致)
define( 'DB_NAME', 'wordpress_db' );// MySQL 用户名(与 docker-compose.yml 中 MYSQL_USER 一致)
define( 'DB_USER', 'wp_user' );// MySQL 密码(与 docker-compose.yml 中 MYSQL_PASSWORD 一致)
define( 'DB_PASSWORD', 'Wp@123456' );// MySQL 地址(关键:用服务名“mysql”,而非 IP,同一网络可解析)
define( 'DB_HOST', 'mysql' );// 数据库字符集(与 MySQL 配置一致)
define( 'DB_CHARSET', 'utf8mb4' );// 数据库排序规则(默认即可)
define( 'DB_COLLATE', '' );
3.2.2 安装向导配置(适合新手)
若不手动修改 wp-config.php
,后续访问 WordPress 时会自动进入“安装向导”,按提示输入以下信息即可:
- 数据库名:
wordpress_db
; - 用户名:
wp_user
; - 密码:
Wp@123456
; - 数据库主机:
mysql
; - 表前缀:默认
wp_
(无需修改)。
四、启动服务与测试验证
4.1 启动所有服务
在项目根目录执行 docker-compose up -d
(-d
表示后台启动):
# 进入项目根目录
cd /opt/compose_lnmp_wordpress# 启动服务(首次启动会自动拉取镜像,同时php会安装拓展,需等待几分钟)
docker-compose up -d
4.2 检查服务状态
# 1. 查看容器运行状态(所有服务应显示“Up”)
docker-compose ps# 2. 若有服务未启动,查看日志排查问题(以 Nginx 为例)
docker-compose logs nginx -f
# 以 PHP 为例
docker-compose logs php -f
正常输出示例(State
列均为 Up
):
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
-----------------------------------------------------------------------------------------------------------------------------------------------
lnmp_mysql mysql:5.7 "docker-entrypoint.s…" mysql 10 seconds ago Up 9 seconds 3306/tcp, 33060/tcp
lnmp_nginx nginx:latest "/docker-entrypoint.…" nginx 10 seconds ago Up 7 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp
lnmp_php php:7.4-fpm "docker-php-entrypoi…" php 10 seconds ago Up 8 seconds 9000/tcp
4.3 访问 WordPress 完成安装
4.3.1 浏览器访问
打开本地浏览器,输入 https://你的服务器IP
(如 https://192.168.10.14
):
- 自签名证书提示“不安全”:点击“高级”→“继续访问”(测试环境忽略);
- 进入 WordPress 安装向导:填写站点信息(示例如下):
- 站点标题:
我的技术博客
; - 用户名:
admin
(自定义,用于登录后台); - 密码:
Admin@123456
(建议复杂,避免弱密码); - 电子邮箱:
admin@mytech.com
; - 勾选“ discouraging search engines from indexing this site”(测试环境可选,避免被搜索引擎收录);
- 站点标题:
- 点击“安装 WordPress”,等待几秒即可完成安装。
4.3.2 验证核心功能
- 登录后台:安装完成后点击“登录”,输入用户名和密码,进入 WordPress 后台(地址:
https://192.168.10.14/wp-admin
); - 发布文章:后台左侧“文章”→“添加文章”,输入标题和内容,点击“发布”;
- 前台查看:点击后台顶部“查看站点”,确认文章正常显示;
- 上传图片:后台“媒体”→“添加新文件”,上传一张图片,若成功则 PHP
gd
扩展生效。
五、常见问题与优化方案
5.1 常见问题排查
问题现象 | 可能原因 | 解决方案 |
---|---|---|
Nginx 报 404 错误 | 根目录路径错误/文件权限不足 | 1. 检查 wordpress.conf 中 root 路径是否为 /var/www/html/wordpress ;2. 执行 chown -R 33:33 ./wwwroot/wordpress 授权 |
Nginx 报 502 错误 | PHP 服务未启动/PHP 扩展缺失 | 1. 执行 docker-compose restart php 重启 PHP 服务;2. 查看 PHP 日志: docker-compose logs php ,确认扩展安装成功 |
Nginx 报 502 错误 | MYSQL容器启动失败 | 执行chown -R 999:999 mysql/data 为data目录赋权 |
PHP 连接数据库失败 | 数据库参数不匹配/服务名错误 | 1. 检查 wp-config.php 中 DB_HOST 是否为 mysql ;2. 确认 DB_NAME /DB_USER /DB_PASSWORD 与 docker-compose.yml 一致 |
WordPress 无法上传图片 | 目录权限不足/PHP 内存限制过低 | 1. 执行 chmod -R 755 ./wwwroot/wordpress/wp-content ;2. 在 wp-config.php 中添加 define('WP_MEMORY_LIMIT', '256M'); |
容器启动失败(端口被占) | 宿主机 80/443/3306 端口被其他服务占用 | 1. 执行 netstat -tulpn | grep 80 查看占用端口的服务;2. 停止占用服务,或修改 docker-compose.yml 中 ports 映射(如 8080:80 ) |
5.2 性能与安全优化
5.2.1 MySQL 优化
- 调整缓存大小:根据服务器内存修改
my.cnf
中innodb_buffer_pool_size
(如 4GB 内存设为 2GB); - 开启慢查询日志:在
my.cnf
中添加:slow_query_log=1 slow_query_log_file=/var/lib/mysql/slow.log long_query_time=2 # 超过 2 秒的查询记录为慢查询
5.2.2 Nginx 优化
- 开启 Gzip 压缩:在
wordpress.conf
中添加(减少静态资源传输大小,提升访问速度):gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss image/svg+xml; gzip_comp_level 5; # 压缩级别(1-9,越高压缩率越高,CPU 消耗越大) gzip_min_length 1k; # 仅压缩大于 1KB 的文件
- 配置静态资源缓存:在
wordpress.conf
中添加(减少重复请求):location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {expires 30d; # 缓存 30 天add_header Cache-Control "public, max-age=2592000"; }
总结
本文通过 Docker Compose 实现了 LNMP 架构的“一键部署”,并成功运行 WordPress 博客,核心优势可总结为三点:
- 环境隔离与一致性:各服务运行在独立容器中,避免依赖冲突,开发/测试/生产环境可保持一致;
- 配置集中与可迁移:所有配置、代码、数据均集中在
compose_lnmp_wordpress
目录,迁移时只需复制该目录,重新执行docker-compose up -d
即可; - 扩展性强:后续可轻松新增服务(如 Redis 缓存、Elasticsearch 搜索),只需在
docker-compose.yml
中添加对应服务配置。
本文覆盖了从环境准备到功能验证的完整流程,可按步骤逐步操作;对于企业级场景,建议优化点包括:使用 Let’s Encrypt 证书、添加 Redis 缓存提升性能、配置主从 MySQL 保证数据高可用。
通过本教程,你不仅能搭建一个可用的 WordPress 博客,还能掌握 Docker Compose 编排多容器的核心思路,为后续复杂项目部署打下基础。