0

Docker部署LNMP环境:docker-compose一键搭建Nginx+MySQL+PHP完整教程

2026.05.20 | youres | 21次围观

想要快速搭建一个Web运行环境,传统的LNMP手动安装方式不仅步骤繁琐,而且不同服务器之间环境很难保持一致。用Docker部署LNMP环境,一条命令就能搞定,还能随时迁移、随时销毁重建。今天这篇教程,手把手教你用docker-compose部署一套完整的LNMP环境。

一、为什么选择Docker部署LNMP

先说说传统安装方式的痛点:

  • 环境不一致:开发环境和生产环境配置稍有差异,bug满天飞
  • 依赖冲突:多个项目共用同一台服务器,PHP版本、扩展互相打架
  • 迁移困难:换台服务器得从头装一遍,至少半天时间
  • 回滚成本高:升级出了问题,想回退非常麻烦

Docker容器化部署完美解决了这些问题。每个服务(Nginx、MySQL、PHP)跑在独立的容器里,互不干扰,配置写在docker-compose.yml里,版本控制住,走到哪都能一键启动。

二、环境准备

2.1 安装Docker和docker-compose

以Ubuntu/Debian为例(CentOS类系统把apt换成yum即可):

# 安装Docker
curl -fsSL https://get.docker.com | sh
systemctl start docker
systemctl enable docker

# 安装docker-compose
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

# 验证安装
docker --version
docker-compose --version

2.2 创建项目目录结构

建议统一管理,目录结构如下:

lnmp-docker/
├── docker-compose.yml    # 编排文件(核心)
├── nginx/
│   ├── conf.d/
│   │   └── default.conf  # Nginx站点配置
│   └── html/             # 网站根目录
├── php/
│   └── Dockerfile        # PHP自定义镜像
└── mysql/
    └── data/             # MySQL数据持久化目录

执行创建:

mkdir -p lnmp-docker/{nginx/{conf.d,html},php,mysql/data}
cd lnmp-docker

三、编写docker-compose.yml

这是整套环境的核心文件,定义了三个服务及其关联关系:

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: lnmp-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/html:/usr/share/nginx/html
    depends_on:
      - php
    restart: always
    networks:
      - lnmp-net

  php:
    build:
      context: ./php
      dockerfile: Dockerfile
    container_name: lnmp-php
    volumes:
      - ./nginx/html:/usr/share/nginx/html
    restart: always
    networks:
      - lnmp-net

  mysql:
    image: mysql:8.0
    container_name: lnmp-mysql
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: your_password_here
      MYSQL_DATABASE: webdb
      MYSQL_USER: webuser
      MYSQL_PASSWORD: user_password_here
    volumes:
      - ./mysql/data:/var/lib/mysql
    restart: always
    networks:
      - lnmp-net

networks:
  lnmp-net:
    driver: bridge

几个关键点说明:

  • depends_on确保Nginx在PHP之后启动,避免启动顺序问题
  • Nginx和PHP共享./nginx/html目录,这样才能处理PHP文件
  • MySQL的数据目录挂载到宿主机,容器删了数据还在
  • 使用alpine版本的Nginx镜像,体积更小,启动更快
  • restart: always保证服务异常退出后自动重启

四、配置PHP-FPM

官方PHP镜像默认只有PHP-FPM,缺少常用扩展。需要自定义Dockerfile:

# php/Dockerfile
FROM php:8.2-fpm

# 安装常用扩展
RUN apt-get update && apt-get install -y \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    libzip-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) \
    gd \
    mysqli \
    pdo \
    pdo_mysql \
    zip \
    opcache \
    bcmath \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# 安装Redis扩展(可选)
RUN pecl install redis && docker-php-ext-enable redis

这里安装了Web开发最常用的几个扩展:gd(图片处理)、mysqli/pdo_mysql(数据库连接)、zip(压缩解压)、opcache(PHP加速)。如果需要Redis缓存,也一并装上。

五、配置Nginx

# nginx/conf.d/default.conf
server {
    listen 80;
    server_name localhost;

    root /usr/share/nginx/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 $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 30d;
        access_log off;
    }

    location ~ /\.ht {
        deny all;
    }
}

注意fastcgi_pass php:9000中的php是docker-compose里定义的服务名,Docker内部DNS会自动解析。这是Docker容器间通信的关键,不需要写IP地址。

六、创建测试文件并启动

# 创建PHP测试文件
echo '<?php phpinfo(); ?>' > nginx/html/index.php

# 创建MySQL连接测试文件
cat > nginx/html/dbtest.php <<'EOF'
<?php
$host = 'mysql';
$db   = 'webdb';
$user = 'webuser';
$pass = 'user_password_here';

try {
    $pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "MySQL连接成功!";
} catch(PDOException $e) {
    echo "连接失败: " . $e->getMessage();
}
?>
EOF

# 构建并启动
docker-compose up -d --build

启动后,访问服务器IP,如果能看到PHP信息页面,说明环境搭建成功。再访问/dbtest.php,确认MySQL也能正常连接。

七、常用运维命令

部署完成后,这些命令会经常用到:

# 查看容器运行状态
docker-compose ps

# 查看日志
docker-compose logs -f nginx
docker-compose logs -f php
docker-compose logs -f mysql

# 重启单个服务
docker-compose restart nginx

# 停止所有服务
docker-compose down

# 停止并清除数据(慎用!)
docker-compose down -v

# 进入PHP容器安装Composer
docker exec -it lnmp-php bash
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# 进入MySQL容器
docker exec -it lnmp-mysql mysql -u root -p

八、生产环境优化建议

以上是基础版本,上生产环境前建议做以下优化:

8.1 安全加固

  • 修改MySQL默认端口,不暴露3306到公网
  • docker-compose.yml中移除MySQL的ports映射,只通过内部网络访问
  • 设置强密码,不使用默认配置
  • Nginx添加SSL证书,强制HTTPS

8.2 性能优化

  • PHP开启opcache,调整内存和缓存大小
  • Nginx开启gzip压缩、配置worker进程数
  • MySQL调整innodb_buffer_pool_size,一般为内存的70%
  • 添加Redis容器做缓存层,减轻数据库压力

8.3 数据备份

# MySQL自动备份脚本
docker exec lnmp-mysql mysqldump -u root -pyour_password webdb | gzip > backup_$(date +%Y%m%d).sql.gz

建议配合crontab定时执行,每天凌晨自动备份一次。

九、总结

Docker部署LNMP环境的核心优势在于标准化可移植。一份docker-compose.yml加上对应的配置文件,就是完整的环境描述。换台服务器,装好Docker,执行docker-compose up -d,几分钟就能跑起来。

对于个人开发者来说,这种方式比宝塔面板更灵活,比手动编译安装更省心。对于团队协作来说,统一的容器环境从根本上消除了"我本地没问题啊"这类经典问题。

相关文章推荐

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论
883文章数 0评论数
作者其它文章