
你搭一个网站环境需要几步?
装Nginx,装PHP,装MySQL,配端口,调权限,改配置文件。折腾半天,终于看到“It works”。如果换一台机器,再来一遍。
有没有可能,写一个文件,然后一行命令,所有服务自动跑起来?
有。Docker Compose 就是干这个的。
先看一个场景
去年帮一个朋友搭开发环境。他要跑一个 Laravel 项目,需要 Nginx、PHP 8.1、MySQL 8.0、Redis。
我问他:“你以前怎么搭的?”
他说:“装宝塔,然后一个一个装,配完得一个多小时。”
我说:“给你换个方式。写个配置文件,以后每次跑docker-compose up -d,一分钟启动全部。”
他半信半疑。我花了20分钟写了个docker-compose.yml,跑起来,网站能开了。
他说:“以后换电脑,是不是复制这个文件就行了?”
对。
Docker Compose 是什么?
Docker Compose 是 Docker 官方的一个工具,用来定义和运行多个 Docker 容器。
一个容器跑一个服务。Nginx 一个容器,PHP 一个容器,MySQL 一个容器。它们之间可以互相通信,但又互相隔离。
Compose 的作用就是:用一个 YAML 文件,把所有这些容器的配置写在一起。然后一行命令,全部启动。
安装 Docker Compose
首先你要有 Docker。如果还没装,先装 Docker:
bash
curl -fsSL https://get.docker.com | bash
然后装 Docker Compose(Linux 版本):
bash
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
验证安装:
bash
docker-compose --version
实战:用 Compose 搭一个 LNMP 环境
创建一个项目目录:
bash
mkdir lnmp && cd lnmp
创建docker-compose.yml文件:
yaml
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./www:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
restart: always
php:
image: php:8.1-fpm-alpine
volumes:
- ./www:/var/www/html
restart: always
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: myapp
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
restart: always
volumes:
mysql_data:
这个文件说了几件事:
- nginx 服务:用 alpine 版镜像(体积小),把宿主机的 80 端口映射到容器的 80 端口。把当前目录的
www文件夹挂载到容器的网站目录。 - php 服务:用 PHP-FPM 镜像,同样挂载
www文件夹,这样 nginx 和 php 能访问到同样的代码文件。 - mysql 服务:设置 root 密码,创建一个默认数据库。数据保存在 Docker 数据卷里,删除容器也不会丢。
准备 Nginx 配置文件
在同级目录创建nginx/default.conf:
nginx
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
注意fastcgi_pass php:9000。这里的php就是 docker-compose.yml 里定义的服务名。Compose 会自动做 DNS 解析,容器之间直接用服务名就能通信。
启动所有服务
在docker-compose.yml所在目录执行:
bash
docker-compose up -d
-d表示后台运行。第一次启动会下载镜像,可能需要几分钟。之后启动就是几秒钟的事。
查看运行状态:
bash
docker-compose ps
查看日志:
bash
docker-compose logs nginx
停止所有服务:
bash
docker-compose down
测试环境
在www目录下创建index.php:
php
<?php phpinfo();
打开浏览器,访问http://你的服务器IP,看到 PHP 信息页面,说明环境跑起来了。
再去数据库里建个表试试:
bash
docker-compose exec mysql mysql -uroot -proot123
docker-compose exec可以进到容器里执行命令。
几个常用命令
| 命令 | 说明 |
|---|---|
docker-compose up -d | 后台启动所有服务 |
docker-compose down | 停止并删除容器 |
docker-compose restart | 重启所有服务 |
docker-compose logs -f | 实时查看日志 |
docker-compose exec 服务名 命令 | 在运行的容器里执行命令 |
docker-compose ps | 查看容器状态 |
数据持久化:容器删了数据还在
Docker 容器删除后,容器内部的数据会丢失。所以数据库这类需要持久化的服务,要挂载数据卷。
上面的配置里已经写了:
yaml
volumes: - mysql_data:/var/lib/mysql
这行定义了一个名为mysql_data的卷。即使你docker-compose down删掉容器,这个卷还在。下次up的时候,数据会重新挂载进去。
想删除卷(慎用):
bash
docker-compose down -v
开发环境 vs 生产环境
通常需要两套配置:开发用一套参数(比如开启调试模式),生产用另一套(关闭调试、增加缓存)。
Compose 支持多个配置文件:
bash
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
生产环境的文件可以覆盖开发环境的配置,比如换域名、关掉暴露的端口。
一个真实案例
有个做微信小程序的团队,后端用 ThinkPHP。以前新员工入职,要花半天搭开发环境:装 PHP、装 MySQL、装 Redis、配各种扩展。每个人的环境还不一样,有人 PHP 7.3,有人 7.4,跑起来有兼容问题。
后来把环境做成 Docker Compose。docker-compose.yml放在项目仓库里,新员工 clone 代码,跑一行docker-compose up -d,等两分钟,环境就好了。Windows、Mac、Linux 通用,再也没有“我本地跑得好好的”这种甩锅话术。
最后一句
Docker Compose 最大的价值不是“技术多先进”,而是“环境一致性”有了保证。
你的配置文件写好了,别人拿到就能用。开发环境长这样,生产环境也长这样。不会再出现“开发说没问题,测试说挂了,上线又报错”的循环。
花半小时学一下 Compose 的基本用法,以后每次启动项目,都是一行命令的事。




