Docker Compose部署LNMP环境完整示例

前言

手动装Nginx、PHP、MySQL太麻烦,用Docker Compose一键部署LNMP环境,几分钟搞定。

一、项目结构

lnmp/
├── docker-compose.yml
├── nginx/
│   ├── conf.d/
│   │   └── default.conf
│   └── nginx.conf
├── php/
│   └── php.ini
├── mysql/
│   └── my.cnf
└── www/
    └── index.php

二、docker-compose.yml

version: '3'

services:
  nginx:
    image: nginx:latest
    container_name: lnmp_nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./www:/var/www/html
    depends_on:
      - php
    networks:
      - lnmp

  php:
    image: php:fpm
    container_name: lnmp_php
    volumes:
      - ./www:/var/www/html
      - ./php/php.ini:/usr/local/etc/php/php.ini
    networks:
      - lnmp

  mysql:
    image: mysql:5.7
    container_name: lnmp_mysql
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: mydb
    networks:
      - lnmp

networks:
  lnmp:
    driver: bridge

三、Nginx配置

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;
        fastcgi_param  SCRIPT_FILENAME  /var/www/html$fastcgi_script_name;
        include        fastcgi_params;
    }
}

四、PHP配置

php/php.ini

[PHP]
date.timezone = Asia/Shanghai
upload_max_filesize = 20M
post_max_size = 20M
memory_limit = 128M

五、MySQL配置

mysql/my.cnf

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci

六、测试文件

www/index.php

<?php
phpinfo();
?>

七、启动

cd lnmp
docker-compose up -d

查看状态

docker-compose ps

访问

http://localhost

能看到phpinfo页面就是成功了。

八、常用命令

命令 说明
docker-compose up -d 启动
docker-compose down 停止并删除容器
docker-compose restart 重启
docker-compose logs -f 看日志
docker-compose exec php bash 进PHP容器
docker-compose exec mysql bash 进MySQL容器

九、连接MySQL

从宿主机连接

mysql -h 127.0.0.1 -P 3306 -u root -p123456

从PHP连接

<?php
$pdo = new PDO('mysql:host=mysql;dbname=mydb', 'root', '123456');
echo "连接成功";
?>

注意:host填mysql,不是localhost,是docker-compose.yml里的服务名。

十、安装PHP扩展

进入PHP容器

docker-compose exec php bash

安装pdo_mysql

docker-php-ext-install pdo_mysql
docker-php-ext-install mysqli

重启PHP

docker-compose restart php

常见坑

坑1:Nginx报502

502 Bad Gateway,原因是PHP容器没启动,或者地址不对。

解决:确认PHP容器在运行,fastcgi_pass填服务名php:9000。

坑2:MySQL启动失败

原因:数据目录权限不对,或者密码没设。

解决:确认MYSQL_ROOT_PASSWORD设了,数据目录权限改成777。

坑3:文件修改不生效

改了www里的文件,浏览器刷新没变。

解决:确认volumes挂载了./www:/var/www/html。

坑4:端口被占用

port is already allocated,原因是宿主机80端口被占了。

解决:改端口,比如改成8080。

坑5:数据丢失

删了容器,MySQL数据没了。

解决:一定要挂载数据卷,./mysql/data:/var/lib/mysql。

总结

部署五步:建项目目录结构,写docker-compose.yml,写配置文件,docker-compose up -d启动,浏览器访问测试。

记住:数据一定要挂载,不然删容器数据就没了。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 08:13 

Nginx反向代理配置,代理后端PHP服务

前言

LNMP 架构里,Nginx 收到 PHP 请求之后,要转发给 PHP-FPM 处理。这个转发的配置就是 fastcgi_pass。本文讲一下完整的 Nginx 代理 PHP 服务配置。

两种代理方式

Nginx 代理后端服务有两种方式:

  1. proxy_pass:代理 HTTP 服务(比如 Node.js、Java、Python)
  2. fastcgi_pass:代理 FastCGI 服务(就是 PHP-FPM)

PHP 用的是 fastcgi_pass,不是 proxy_pass,别搞混了。

基础配置

完整 LNMP 配置示例

server {
    listen       80;
    server_name  www.example.com;

    root  /var/www/html;
    index index.php index.html;

    # 访问根目录
    location / {
        try_files $uri $uri/ =404;
    }

    # PHP 请求转发给 PHP-FPM
    location ~ \.php$ {
        root           /var/www/html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

关键参数说明

参数 作用
fastcgi_pass 127.0.0.1:9000 PHP-FPM 监听的地址和端口
fastcgi_pass unix:/run/php-fpm/www.sock 用 socket 文件方式(更高效)
fastcgi_index index.php 默认首页
SCRIPT_FILENAME PHP 文件的完整路径
include fastcgi_params 引入其他参数

socket 方式 vs 端口方式

端口方式(TCP)

fastcgi_pass 127.0.0.1:9000;

优点:跨服务器可以用
缺点:多了一层 TCP 开销,稍微慢一点

Socket 方式(Unix Domain Socket)

fastcgi_pass unix:/run/php-fpm/www.sock;

优点:更快,少了 TCP 开销
缺点:只能在同一台服务器上用

生产环境推荐用 socket 方式,更快。

完整生产环境配置

server {
    listen       443 ssl http2;
    server_name  www.example.com;

    ssl_certificate      /etc/nginx/ssl/www.crt;
    ssl_certificate_key  /etc/nginx/ssl/www.key;

    root  /var/www/html;
    index index.php index.html;

    # 日志
    access_log  /var/log/nginx/www.access.log;
    error_log   /var/log/nginx/www.error.log;

    # 静态资源直接返回
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires 30d;
    }

    # PHP 请求转发
    location ~ \.php$ {
        fastcgi_pass   unix:/run/php-fpm/www.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;

        # 超时设置
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
    }

    # 禁止访问 .ht 等文件
    location ~ /\.ht {
        deny  all;
    }
}

常见坑

坑1:SCRIPT_FILENAME 路径不对

配置了 SCRIPT_FILENAME /var/www/html$fastcgi_script_name;,但 root 不是这个路径。

原因: 写死了路径,换个目录就错了。

解决: 用 $document_root:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

坑2:socket 路径不一致

Nginx 配置里写的 socket 路径和 PHP-FPM 实际的不一致。

检查 PHP-FPM 的 socket 路径:

grep listen /etc/php-fpm.d/www.conf

确保两边路径一模一样。

坑3:PHP 不解析,直接下载

访问 index.php,浏览器直接下载了文件,没解析。

原因: Nginx 没把 .php 请求转发给 PHP-FPM。

检查: 配置里有没有 location ~ \.php$ 这一段,有没有 fastcgi_pass。

坑4:404 Not Found

访问 PHP 文件报 404。

原因: SCRIPT_FILENAME 路径不对,PHP-FPM 找不到文件。

解决: 确认 root 和 SCRIPT_FILENAME 配置正确。

检查配置并重载

nginx -t
nginx -s reload

总结

配置项 说明
fastcgi_pass PHP-FPM 地址(端口或socket)
SCRIPT_FILENAME PHP 文件完整路径
fastcgi_params 其他参数集合
expires 静态资源缓存
超时设置 fastcgi_connect_timeout 等

记住: PHP 用 fastcgi_pass,不是 proxy_pass,别搞混了。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-7 07:29 
'); })();