Nginx版本不兼容、PHP扩展缺失、MySQL启动报错、配置文件互相冲突,甚至重装几次系统都无法彻底解决问题。尤其是当项目需要迁移、升级或者多环境部署时,传统手工安装LNMP的方式维护成本会越来越高。
Docker Compose的出现,彻底改变了这一类服务器环境部署方式。相比传统的源码编译安装,Compose最大的优势并不是“新技术”三个字,而是它真正解决了运维中的环境一致性问题。无论你是在本地开发、测试服务器,还是生产环境,只要一份docker-compose.yml文件,就能快速启动完整的LNMP服务栈。
这篇文章会从实际部署角度出发,完整讲解如何使用Docker Compose快速搭建Nginx + MySQL + PHP环境,包括目录规划、镜像选择、配置文件编写、数据持久化、PHP扩展、Nginx反向代理以及常见报错处理。文章适合刚接触Docker的新手,也适合已经会用Docker但没有系统整理过LNMP部署方案的运维人员。
为什么现在越来越多人使用Docker Compose部署LNMP
传统LNMP环境有一个典型问题:依赖污染。
例如:
- PHP 7.4项目无法兼容PHP 8.2
- MySQL 5.7和MySQL 8.0配置不同
- 不同网站需要不同PHP扩展
- Nginx升级后配置失效
- 系统迁移后环境重装耗时
而Docker Compose最大的特点,就是把这些服务彻底隔离。
你可以理解为:
- Nginx运行在一个容器
- PHP运行在一个容器
- MySQL运行在一个容器
- Redis运行在一个容器
它们互相通信,但互不影响。
即使你删除整个项目目录,也不会影响系统其它服务。
尤其对于:
- WordPress
- Laravel
- Typecho
- Discuz
- Magento
- ThinkPHP
这类PHP项目来说,Docker Compose几乎已经成为新的主流部署方式。
部署前需要准备什么
本教程以Ubuntu 22.04服务器为例。
最低建议配置:
| 配置 | 建议 |
|---|---|
| CPU | 2核 |
| 内存 | 2GB以上 |
| 磁盘 | 20GB |
| 系统 | Ubuntu / Debian |
| Docker | 24+ |
| Compose | v2 |
如果你的服务器是阿里云、腾讯云、AWS、Oracle Cloud等平台,都可以直接使用。
第一步:安装Docker环境
先更新系统:
apt update && apt upgrade -y
安装依赖:
apt install -y curl wget gnupg lsb-release ca-certificates
安装Docker官方源:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker.gpg
添加仓库:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list
安装Docker:
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
验证是否安装成功:
docker -v
docker compose version
正常会看到:
Docker version 26.x.x
Docker Compose version v2.x.x
第二步:创建LNMP项目目录
建议所有Docker项目统一放在:
/data/docker/
创建目录:
mkdir -p /data/docker/lnmp
cd /data/docker/lnmp
接下来创建结构:
mkdir -p nginx/conf.d
mkdir -p nginx/html
mkdir -p mysql/data
mkdir -p php
mkdir -p logs/nginx
最终目录结构如下:
lnmp/
├── docker-compose.yml
├── nginx
│ ├── conf.d
│ └── html
├── mysql
│ └── data
├── php
└── logs
└── nginx
这样的目录规划后期维护会非常清晰。
第三步:编写docker-compose.yml
这是整个LNMP环境的核心。
创建文件:
nano docker-compose.yml
写入以下内容:
version: '3.9'
services:
nginx:
image: nginx:latest
container_name: lnmp-nginx
ports:
- "80:80"
volumes:
- ./nginx/html:/var/www/html
- ./nginx/conf.d:/etc/nginx/conf.d
- ./logs/nginx:/var/log/nginx
depends_on:
- php
networks:
- lnmp
php:
image: php:8.2-fpm
container_name: lnmp-php
volumes:
- ./nginx/html:/var/www/html
networks:
- lnmp
mysql:
image: mysql:8.0
container_name: lnmp-mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: testdb
ports:
- "3306:3306"
volumes:
- ./mysql/data:/var/lib/mysql
networks:
- lnmp
networks:
lnmp:
这个Compose文件已经包含:
- Nginx
- PHP-FPM
- MySQL 8.0
- 数据持久化
- 内部网络通信
已经可以直接启动。
第四步:配置Nginx站点
创建配置文件:
nano nginx/conf.d/default.conf
写入:
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
这里最关键的一行:
fastcgi_pass php:9000;
这里的php并不是IP,而是Compose中的服务名。
Docker会自动解析容器通信。
第五步:创建PHP测试页面
创建:
nano nginx/html/index.php
写入:
<?php
phpinfo();
?>
第六步:启动LNMP环境
执行:
docker compose up -d
第一次会自动拉取镜像。
查看运行状态:
docker ps
正常会看到:
lnmp-nginx
lnmp-php
lnmp-mysql
说明环境启动成功。
第七步:浏览器访问测试
浏览器打开:
http://服务器IP
如果看到PHP信息页面,说明:
- Nginx正常
- PHP正常
- FastCGI通信正常
整个LNMP环境已经部署成功。
Docker Compose部署LNMP最大的优势
很多人刚开始会觉得:
“手工安装也能用,为什么还要Docker?”
实际上,真正上线后差距非常明显。
传统LNMP:
- 升级困难
- 环境不可复制
- 配置容易混乱
- 重装耗时
- 多PHP版本麻烦
Docker Compose:
- 一键启动
- 秒级迁移
- 环境统一
- 回滚简单
- 容器隔离
特别是多网站环境下优势极其明显。
如何安装PHP扩展
默认php:8.2-fpm镜像扩展并不完整。
很多程序需要:
- mysqli
- pdo_mysql
- gd
- zip
- bcmath
- redis
这时候就需要自定义PHP镜像。
创建Dockerfile
进入php目录:
cd php
nano Dockerfile
写入:
FROM php:8.2-fpm
RUN apt-get update && apt-get install -y \
libpng-dev \
libzip-dev \
zip unzip
RUN docker-php-ext-install mysqli pdo pdo_mysql gd zip bcmath
修改Compose调用Dockerfile
修改:
php:
build: ./php
替换原来的:
image: php:8.2-fpm
然后重新构建:
docker compose up -d --build
这样PHP扩展就会自动安装。
MySQL数据持久化为什么非常重要
很多新手最容易犯的错误:
直接删除容器。
结果数据库全部丢失。
原因就是没有做数据映射。
正确方式:
volumes:
- ./mysql/data:/var/lib/mysql
这样即使:
docker compose down
数据库依然存在。
这是生产环境必须做的配置。
如何进入MySQL容器
查看容器:
docker ps
进入:
docker exec -it lnmp-mysql bash
登录MySQL:
mysql -uroot -p
输入密码即可。
如何查看容器日志
Nginx日志:
docker logs lnmp-nginx
PHP日志:
docker logs lnmp-php
MySQL日志:
docker logs lnmp-mysql
这是排查问题最重要的方法。
Docker Compose常用命令
启动:
docker compose up -d
停止:
docker compose stop
重启:
docker compose restart
删除容器:
docker compose down
查看状态:
docker compose ps
实时日志:
docker compose logs -f
这些命令建议熟练掌握。
Docker Compose部署LNMP的性能如何
很多人误以为Docker性能差。
实际上:
- Docker并不是虚拟机
- 它共享宿主机内核
- 开销极小
正常情况下:
- 性能损耗通常低于3%
- 内存占用远低于VM
- 启动速度极快
对于大部分PHP网站完全足够。
甚至很多大型企业生产环境也已经全面容器化。
生产环境建议增加Redis
现代PHP网站基本都离不开缓存。
可以在Compose中增加:
redis:
image: redis:latest
container_name: lnmp-redis
这样:
- WordPress对象缓存
- Laravel缓存
- Session缓存
都可以直接使用Redis。
网站性能会提升非常明显。
为什么推荐MySQL 8.0
现在很多旧教程还在使用:
- MySQL 5.6
- MySQL 5.7
但实际上:
MySQL 8.0已经是主流。
优势包括:
- 性能更好
- JSON支持增强
- 安全性更高
- UTF8MB4支持完善
- 索引优化更强
新项目建议直接使用8.0。
Docker Compose部署LNMP常见报错解决
1. 端口冲突
错误:
bind: address already in use
说明80端口被占用。
解决:
netstat -tunlp | grep 80
关闭Apache或旧Nginx。
2. MySQL无法启动
通常原因:
- data目录权限错误
- 数据库文件损坏
修复:
chmod -R 777 mysql/data
或者重新初始化数据目录。
3. PHP页面下载而不是执行
说明:
Nginx没有正确解析PHP。
重点检查:
location ~ \.php$
以及:
fastcgi_pass php:9000;
4. 容器频繁退出
查看日志:
docker logs 容器名
大多数问题都能从日志里找到原因。
如何实现HTTPS
生产环境建议配合:
- Certbot
- Nginx Proxy Manager
- Traefik
自动申请SSL。
或者直接:
apt install certbot python3-certbot-nginx
这样可以快速部署HTTPS。
Docker Compose为什么适合现代运维
现在越来越多公司已经不再手工安装LNMP。
原因很现实:
传统环境维护成本太高。
尤其:
- 多项目
- 多PHP版本
- CI/CD
- 自动扩容
- 灰度发布
这些场景下,Docker Compose优势极其明显。
对于个人站长来说:
它最大的价值其实是:
“环境可复制”。
你换服务器、迁移网站、重装系统时,再也不用从零重新折腾环境。
Docker Compose部署LNMP并不复杂,真正难的是理解容器化思维。一旦习惯这种部署方式,你会发现传统手工安装越来越难维护。

全球服务器测评

