前置准备工作

创建网络

docker network create -d bridge my-net

创建映射目录

# Nginx、MySQL、Redis、PHP代码目录
mkdir -p ~/docker/lnmp/redis/conf
mkdir -p ~/docker/lnmp/redis/data
mkdir -p ~/docker/lnmp/mysql/data
mkdir -p ~/docker/lnmp/mysql/log
mkdir -p ~/docker/lnmp/mysql/conf.d
mkdir -p ~/docker/lnmp/nginx/conf
mkdir -p ~/docker/lnmp/nginx/conf/conf.d
mkdir -p ~/docker/lnmp/nginx/log
mkdir -p ~/docker/lnmp/nginx/www
mkdir -p /www

创建某些配置文件

redis 配置文件

vim ~/docker/lnmp/redis/conf/redis.conf

# 节点端口
port 6379

# 密码
requirepass 123456

# 保护模式,默认值 yes,即开启。开启保护模式以后,需配置 bind ip 或者设置访问密码;关闭保护模式,外部网络可以直接访问;
protected-mode no

# 是否以守护线程的方式启动(后台启动),默认 no;
daemonize no

# 是否开启 AOF 持久化模式,默认 no;
appendonly yes

mysql 配置文件

vim ~/docker/lnmp/mysql/conf.d/my.cnf

###### [client]配置模块 ######
[client]
default-character-set=utf8mb4
socket=/var/lib/mysql/mysql.sock

###### [mysql]配置模块 ######
[mysql]
# 设置MySQL客户端默认字符集
default-character-set=utf8mb4
socket=/var/lib/mysql/mysql.sock

###### [mysqld]配置模块 ######
[mysqld]
port=3306
user=mysql
# 设置sql模式 sql_mode模式引起的分组查询出现*this is incompatible with sql_mode=only_full_group_by,这里最好剔除ONLY_FULL_GROUP_BY
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
server-id = 1

# MySQL8 的密码认证插件 如果不设置低版本navicat无法连接
default_authentication_plugin=mysql_native_password

# 禁用符号链接以防止各种安全风险
symbolic-links=0

# 允许最大连接数
max_connections=1000

# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8mb4

# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB

# 0: 表名将按指定方式存储,并且比较区分大小写;
# 1: 表名以小写形式存储在磁盘上,比较不区分大小写;
lower_case_table_names=0

max_allowed_packet=16M 

# 设置时区
default-time_zone='+8:00'

nginx配置文件

vim ~/docker/lnmp/nginx/conf/nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    # 更改成想要的大小
    client_max_body_size 20M;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80 default_server;
        # listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        location / {
            index index.html index.htm index.php;
        }
    }

    include /etc/nginx/conf.d/*.conf;
}

nginx 测试文件

vim ~/docker/lnmp/nginx/www/index.html

<h1>Success</h1>
<h1>测试成功</h1>
<h1>SHUXIAOYUAN</h1>

Laravel 站点设置

server {
    listen       80;
    server_name  php-demo-local.com;

    root   /www/php_demo/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    charset utf-8;

    location / {
        index  index.html index.htm index.php;

        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    location ~ \.php$ {
        root /www/php_demo;
        fastcgi_pass   blog:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /www/php_demo/public/$fastcgi_script_name;
        include        fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

yml文件

vim ~/docker/lnmp/docker-compose.yml

# 定义服务,可以多个
services:
  redis:
    # 采用 image 指定镜像
    image: "redis:7"

    # 指定容器名称。默认将会使用 项目名称_服务名称_序号 这样的格式。
    container_name: redis

    # 指定容器退出后的重启策略为始终重启。
    # 该命令对保持服务始终运行十分有效,在生产环境中推荐配置为 always 或者 unless-stopped
    restart: always

    # 配置日志
    logging:
      # 日志驱动类型:json-file、syslog、none
      driver: "json-file"
      # 其他选项
      options:
        max-size: "1g"
    
    # 配置容器连接的网络
    network_mode: "my-net"

    # 暴露端口信息
    ports:
      - "6379:6379"
    
    # 数据卷所挂载路径设置
    volumes:
      - ~/docker/lnmp/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf
      - ~/docker/lnmp/redis/data:/data

    # 覆盖容器启动后默认执行的命令。
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  mysql:
    image: "mysql:8"
    container_name: mysql
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "1g"
    network_mode: "my-net"
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=123456 # root用户密码
    volumes:
      # 映射数据目录
      - ~/docker/lnmp/mysql/data:/var/lib/mysql
      # 映射日志
      - ~/docker/lnmp/mysql/log:/var/log/mysql
      # 映射配置目录
      - ~/docker/lnmp/mysql/conf.d:/etc/mysql/conf.d
      # 让容器的时钟与宿主机时钟同步,避免时间的问题,ro是read only的意思,就是只读。
      - /etc/localtime:/etc/localtime:ro
  nginx:
    image: "nginx:1.25"
    container_name: nginx
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "1g"
    network_mode: "my-net"
    ports:
      - "80:80"
      - "443:443"

    # 解决容器的依赖、启动先后的问题,这里表示先启动php和redis,再启动nginx
    depends_on:
      - php
      - redis
    volumes:
      - ~/docker/lnmp/nginx/conf/conf.d:/etc/nginx/conf.d
      - ~/docker/lnmp/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ~/docker/lnmp/nginx/log:/var/log/nginx
      - ~/docker/lnmp/nginx/www:/usr/share/nginx/html
      - /www:/www
  php:
    image: "shuxiaoyuan/php:8.1.v5"
    container_name: php81
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "1g"
    network_mode: "my-net"
    volumes:
      - /www:/www

运行

docker compose up -d