Docker 搭建 LNMP(Nginx+PHP+MySQL)完整踩坑实录

📝 Docker 搭建 LNMP(Nginx+PHP+MySQL)完整踩坑实录

(从报错不断到彻底跑通,新手可直接复刻)


一、前言(我遇到的情况)

本地 Docker 环境一切正常,
放到服务器 + 宝塔面板环境后,疯狂报错:

  • apt-get 安装依赖失败(exit code: 100)
  • iptables 网络错误
  • 3306 端口被占用
  • 改了端口依然提示旧端口冲突
  • 反复 502 Bad Gateway
  • Nginx 连不上 PHP

最终全部解决,跑通 Nginx + PHP + MySQL。


二、最终成功架构(一定要先懂)

三个服务 = 三个独立容器

  • my-nginx:负责网页访问、转发 PHP
  • my-php:负责解析 PHP 代码
  • my-mysql:负责数据库

容器之间通信:

靠 Docker 内网 + 容器名,不是靠宿主机端口。


三、全程遇到的坑 + 解决方案(按出现顺序)

🔴 坑1:构建 PHP 镜像时 apt-get install 失败

报错

复制代码
Temporary failure resolving 'deb.debian.org'
exit code: 100

原因

服务器网络限制,容器内无法访问 Debian 软件源。

解决方案

不自己构建 PHP 镜像!

直接用官方预制镜像:php:8.2-fpm-alpine


🔴 坑2:Docker 网络创建失败(iptables 错误)

报错

复制代码
Failed to Setup IP tables: Unable to enable SKIP DNAT rule

原因

宝塔防火墙 / 系统防火墙拦截 Docker 网络。

解决方案

bash 复制代码
systemctl restart docker

🔴 坑3:3306 端口被宝塔 MySQL 占用

报错

复制代码
bind: address already in use

原因

宝塔自带 MySQL 占用 3306。

解决方案

映射端口改成 3307:3306

yaml 复制代码
ports:
  - "3307:3306"

🔴 坑4:改了端口不生效,依然报 3306 占用

原因

Docker 复用旧容器配置,没有重建。

解决方案

先删旧容器,再启动:

bash 复制代码
docker rm -f my-mysql
docker compose up -d

🔴 坑5:502 Bad Gateway(最折磨)

现象

Nginx 能访问,但 PHP 无法连接。

根本原因(99% 人中招)

  1. Nginx 配置里容器名写错
    php:9000 → 应该是 my-php:9000
  2. PHP-FPM 没真正启动
  3. 启动时序问题(Nginx 比 PHP 先启动)

最终正确 Nginx 配置

nginx 复制代码
location ~ \.php$ {
    fastcgi_pass my-php:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

四、最终可直接跑通的 docker-compose.yml

yaml 复制代码
services:
  nginx:
    image: nginx:latest
    container_name: my-nginx
    ports:
      - "8081:80"
    volumes:
      - ./www:/var/www/html
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
    restart: always

  php:
    image: php:8.2-fpm-alpine
    container_name: my-php
    volumes:
      - ./www:/var/www/html
    depends_on:
      - mysql
    restart: always
    command: >
      sh -c "chmod -R 777 /var/www/html && php-fpm"

  mysql:
    image: mysql:8.0
    container_name: my-mysql
    ports:
      - "3307:3306"
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: my_demo_db
    volumes:
      - mysql-data:/var/lib/mysql
    restart: always

volumes:
  mysql-data:

五、最常用命令(必须收藏)

进入容器

bash 复制代码
docker exec -it my-php sh
docker exec -it my-nginx sh

重启服务

bash 复制代码
docker restart my-php
docker restart my-nginx

看日志(排查 502 神器)

bash 复制代码
docker logs my-php

彻底重建环境

bash 复制代码
docker compose down -v
docker compose up -d

六、关键理解(新手必看)

  1. 容器之间互相访问用容器名
    my-nginx → my-php:9000
  2. 宿主机端口 和 容器内端口是两回事
    3307(外部) → 3306(容器内部)
  3. 502 一律排查:
    • PHP 是否真的启动
    • Nginx 配置容器名是否正确
    • 文件路径是否挂载正确

七、总结(一句话记住)

服务器 + 宝塔环境跑 Docker:

  • 别自己构建 PHP 镜像
  • 端口冲突就换端口
  • 502 先看容器名 + PHP 日志
  • 容器之间靠名字通信

按这套流程,100% 能跑通!

相关推荐
偶尔上线经常挺尸35 分钟前
《100个“反常识”经验15:Nginx 502排查:从应用到内核》
运维·nginx·性能调优·反向代理·502错误·http排错
niucloud-admin1 小时前
PHP V6 单商户常见问题——云编译报SSL证书错误的处理方案
php
yoyo_zzm1 小时前
Laravel9.x新特性全解析
数据库·mysql·nginx
计算机安禾2 小时前
【Linux从入门到精通】第31篇:防火墙漫谈——iptables与firewalld防护指南
linux·运维·php
yoyo_zzm4 小时前
Laravel8.x新特性全解析
数据库·nginx
2401_873479406 小时前
企业安全团队如何配合公安协查?IP查询在电子取证中的技术实践
tcp/ip·安全·网络安全·php
L1624766 小时前
Win11 共享→Windows Server 访问故障总结(极简可复用)
开发语言·windows·php
niucloud-admin8 小时前
PHP V6 单商户常见问题——本地phpstudy部署,访问域名/admin 、域名/wap无法自动跳转对应首页问题
php
木雷坞8 小时前
视觉算法环境 Docker 镜像拉取失败排查
运维·人工智能·docker·容器