Docker 搭建LNMP环境



  • 系统:CentOS7.2
  • 软件:docker 20.10.12
  • 镜像:nginx:1.21.5,mysql:5.7.36,php:7.4-fpm



  • 镜像拉取
docker pull nginx:1.21.5  
  • 创建数据目录
mkdir -pv /data/docker/nginx/{conf/conf.d,data,logs}  
  • 准备配置文件 nginx.conf 与 cond.d/default.conf
    • nginx.conf
user  nginx nginx;

worker_processes auto;  
error_log  /var/log/nginx/error.log warn;  
pid        /var/run/;

worker_rlimit_nofile 100000;

  use epoll;
  worker_connections 50000;
  multi_accept on;

  include       mime.types;
  default_type  application/octet-stream;

  server_tokens off;
  access_log off; 

  #charset  gb2312;

  #General Options    
  server_names_hash_bucket_size 128;
  client_header_buffer_size 1024k;
  large_client_header_buffers 8 1024k;
  ignore_invalid_headers   on;
  recursive_error_pages    on;
  server_name_in_redirect  off;      

  sendfile on;

  keepalive_timeout 75s;
  client_header_timeout 60s;
  client_body_timeout 60s;
  reset_timedout_connection on;

  #size limits
  client_max_body_size 200m;
  client_body_buffer_size    256k;

  #TCP Options
  tcp_nopush  on;
  tcp_nodelay on;

  #fastcgi options
  fastcgi_connect_timeout 300;
  fastcgi_send_timeout 300;
  fastcgi_read_timeout 300;
  fastcgi_intercept_errors on; 
  fastcgi_buffer_size 256k;
  fastcgi_buffers 16 256k;
  fastcgi_busy_buffers_size 512k;
  fastcgi_temp_file_write_size 512k;

  fastcgi_cache_valid 200 302 1h;
  fastcgi_cache_valid 301 1d;           
  fastcgi_cache_valid any 1m;  
  fastcgi_cache_min_uses 1;

  #gzip  compression
  gzip on;
  gzip_disable "msie6";
  #gzip_proxied any;
  gzip_min_length  1k;
  gzip_buffers     4 16k;
  gzip_http_version 1.0;
  gzip_comp_level 2;
  gzip_types       text/plain application/x-javascript application/json text/xml application/xml+res text/javascript text/css application/xml image/jpeg image/gif image/png;
  gzip_vary on;
  gzip_proxied   expired no-cache no-store private auth;

  #log_format main '$remote_addr - $remote_user [$time_local] "$request"' '$status $body_bytes_sent "$http_referer"' '"$http_user_agent" "$http_x_forwarded_for"';
  log_format access '[$time_local] $remote_addr $proxy_add_x_forwarded_for [$http_x_forwarded_for] $http_host $upstream_addr ' '$request_method [$uri] [$query_string] $status ' '$http_x_testflag $http_x_requestno ' '"$http_user_agent" $body_bytes_sent $request_time';

  include /etc/nginx/conf.d/*.conf;
  • conf.d/default.conf
server {  
    listen       80 default;
    server_name  _;
    charset utf-8;
    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;

    # proxy the PHP scripts to Apache listening on
    #location ~ \.php$ {
    #    proxy_pass;

    # pass the PHP scripts to FastCGI server listening on
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #location ~ /\.ht {
    #    deny  all;

* 启动容器

docker run -d --name nginx \  
-p 80:80 \
-v /data/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /data/docker/nginx/conf/conf.d:/etc/nginx/conf.d \
-v /data/docker/nginx/html:/usr/share/nginx/html \
-v /data/docker/nginx/logs:/var/log/nginx \
  • 编辑主页并测试
[root@centos72 html]# cd /data/docker/nginx/html/
[root@centos72 html]# echo "this is test website" > index.html
[root@centos72 html]# curl
this is test website  
[root@centos72 html]#


  • 拉取镜像
docker pull mysql:5.7.36  
  • 创建数据目录
mkdir -pv /data/docker/mysql/{conf,data,logs}  
  • 启动容器
docker run -d -p 3306:3306 -v /data/docker/mysql/conf:/etc/mysql/conf.d -v /data/docker/mysql/data:/var/lib/mysql -v /data/docker/mysql/logs:/var/log/mysql/ -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7.36  
  • 连接测试
[root@centos72 ~]# mysql -uroot -p123456 -h
Welcome to the MariaDB monitor.  Commands end with ; or \g.  
Your MySQL connection id is 2  
Server version: 5.7.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> show databases;  
| Database           |
| information_schema |
| mysql              |
| opensa             |
| performance_schema |
| sys                |
5 rows in set (0.00 sec)  


  • 拉取镜像
docker pull php:7.4-fpm  
  • 创建目录
mkdir -p /data/docker/php-fpm  
  • 准备配置文件 /data/docker/php-fpm/www.conf
  • 启动容器
docker run -d --name php-fpm \  
-p 9000:9000 \
-v /data/docker/php-fpm/www.conf:/data/php-fpm/etc/php-fpm.d/www.conf \
-v /data/docker/nginx/html:/var/www/html \
-v /data/docker/php-fpm/log:/data/php-fpm/log \
  • 修改nginx的 default.conf 配置文件,使其支持解析php文件
location ~ \.php$ {  
        root           html;
        fastcgi_pass;  # 使docker网络连接
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        include        fastcgi_params;
  • 重启nginx
docker restart nginx  
  • 测试php文件解析/data/docker/nginx/html/index.php
  • 浏览器访问,docker宿主机

  • 测试mysql连接 /data/docker/nginx/html/mysql.php

$link = mysqli_connect('', 'root', 'root');
if (!$link) {  
 die('Could not connect: ' . mysqli_connect_error());
echo 'Connected successfully';  
  • 访问
Fatal error: Uncaught Error: Call to undefined function mysqli_connect() in /var/www/html/mysql.php:2 Stack trace: #0 {main} thrown in /var/www/html/mysql.php on line 2  
  • 是因为还缺少连接数据库的插件,我们进入php-fpm容器,安装插件
[root@localhost ~]# docker exec -it php-fpm /bin/bash
root@2dde57b0f424:/var/www/html# cd /usr/local/etc/php  
root@2dde57b0f424:/usr/local/etc/php# docker-php-ext-install mysqli  
root@2dde57b0f424:/usr/local/etc/php# docker-php-ext-install mysql  
root@2dde57b0f424:/usr/local/etc/php# docker-php-ext-install pdo pdo_mysql  
root@2dde57b0f424:/usr/local/etc/php# apt-get install libpng-dev libjpeg-dev libfreetype6-dev  
root@2dde57b0f424:/usr/local/etc/php# docker-php-ext-configure gd --enable-gd-native-ttf --with-freetype-dir=/usr/include/freetype2 --with-png-dir=/usr/include  
root@2dde57b0f424:/usr/local/etc/php# docker-php-ext-install gd  
root@2dde57b0f424:/usr/local/etc/php# exit  
[root@localhost ~]# docker restart php-fpm
  • 再次测试数据库连接
Connected successfully  
  • 将容器重新生成镜像,方便日后使用
docker commit -m "php-fpm add extension mysql,mysqli,pdo-mysql,gd" php-fpm php-fpm:7.4  
  • 提交镜像到阿里云仓库
[root@centos72 html]# docker images
REPOSITORY                                          TAG        IMAGE ID       CREATED         SIZE  
leoiceo/php-fpm                                     7.4-fpm    b877649a03d0   3 seconds ago   496MB

[root@centos72 html]# docker tag b877649a03d0

[root@centos72 html]# docker images
REPOSITORY                                           TAG        IMAGE ID       CREATED              SIZE  
leoiceo/php-fpm                                      7.4-fpm    b877649a03d0   About a minute ago   496MB   7.4        b877649a03d0   About a minute ago   496MB

[root@centos72 html]# docker push
The push refers to repository []  
e1b0814b4313: Pushed  
a0a7f72c8ded: Pushed  
ce6badaf7069: Pushed  
87745532e3a6: Pushed  
a267f1e0b4bd: Pushed  
b0044f5f9816: Pushed  
1b5edbcf9dff: Pushed  
ee0ca96d307e: Pushed  
0fdfbbf7aebd: Pushed  
2a3138346faa: Pushed  
2edcec3590a4: Pushed  
7.4: digest: sha256:cf23c71fed024afa83af81e2f8b433d9fac319e53f8cb48bba09b22aef90929b size: 2622