引言
一直在windows中开发,为了便捷开发,不用搭建虚拟机等,可以使用桌面版docker解决这个问题。下面是多项目开发使用的LNMP环境。
WSL开头
如果没有启用WSL2,需要在命令行中执行以下命令。命令行以管理员身份打开:
1、启用WSL
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
2、启用虚拟机功能
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
wsl常用命令:
# 更新WSL2内核(报错0x800701bc时执行)
wsl --update
# 查看WSL状态
wsl --status
# 设置WSL2为默认
wsl --set-default-version 2
# 查看可安装发行版列表
wsl -l -o
# 安装指定版本
wsl --install -d Ubuntu-22.04
# 查看wsl已安装列表
wsl -l -v
# 终止Ubuntu22.04
wsl --terminate Ubuntu-22.04
# 卸载Ubuntu22.04
wsl --unregister Ubuntu-22.04
在文件资源管理器地址栏中通过 \\wsl$ 查看WSL安装的所有linux。
# 启动进入Ubuntu 22.04
wsl -d Ubuntu-22.04
# WSL中设置默认版本,以后直接wsl即可启动Ubuntu 22.04
wsl --set-default Ubuntu-22.04
wsl
# 查看版本(在Ubuntu中执行)
hostnamectl
如果不能访问外网,需要在命令行手动安装。命令行以管理员身份打开:
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
echo "nameserver 114.114.114.114" | sudo tee -a /etc/resolv.conf
DNS有问题,临时解决一下:
baiyang@DESKTOP-PSDQHMG:/mnt/c/Windows/system32$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 172.19.160.1
baiyang@DESKTOP-PSDQHMG:/mnt/c/Windows/system32$
baiyang@DESKTOP-PSDQHMG:/mnt/c/Windows/system32$ echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
nameserver 8.8.8.8
baiyang@DESKTOP-PSDQHMG:/mnt/c/Windows/system32$ echo "nameserver 114.114.114.114" | sudo tee -a /etc/resolv.conf
nameserver 114.114.114.114
baiyang@DESKTOP-PSDQHMG:/mnt/c/Windows/system32$
baiyang@DESKTOP-PSDQHMG:/mnt/c/Windows/system32$ cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 114.114.114.114
baiyang@DESKTOP-PSDQHMG:/mnt/c/Windows/system32$
Docker开头
| 命令 | 作用 |
|---|---|
docker system df |
查看磁盘占用 |
docker system df -v |
查看磁盘占用明细 |
docker system prune |
清理停止的容器、悬空镜像、未使用的网络和构建缓存 |
docker system prune -a |
额外清理所有未使用的镜像 |
docker builder prune |
只清理构建缓存 |
docker image prune -a |
清理所有未使用的镜像 |
docker container prune |
清理停止的容器 |
docker volume prune |
清理未使用的卷 |
docker build --no-cache |
单次构建跳过缓存 |
在 Docker 中,“清理缓存”通常指清理构建缓存、未使用的镜像、容器、网络和卷等占用的磁盘空间。
0、查看磁盘使用情况
# 查看磁盘使用情况
docker system df
- 显示镜像、容器、卷和构建缓存占用的磁盘空间。
- 加上 `-v` 可查看更详细的列表:
docker system df -v
1、清理所有未使用的资源(最常用)
docker system prune
- 清理**停止的容器**、**未使用的网络**、**悬空镜像**(dangling images)和**构建缓存**。
- 加上 `-a` 会额外删除所有未使用的镜像(不只是悬空镜像),释放更多空间。
docker system prune -a
- 加上 `-f` 跳过确认提示,直接执行。
docker system prune -a -f
2、单独清理构建缓存
docker builder prune
- 删除所有构建缓存。
- 加上 `-a` 强制删除所有缓存(包括当前正在使用的)。
docker builder prune -a
3、清理镜像
docker image prune
- 删除悬空镜像(`<none>:<none>`)。
- 加上 `-a` 删除所有未使用的镜像(即没有被任何容器引用的镜像)。
docker image prune -a
4、清理容器
docker container prune
- 删除所有已停止的容器。
5、清理卷(Volume)
docker volume prune
- 删除所有未使用的卷(volume 未被任何容器使用)。**注意**:卷存储数据,删除可能丢失持久化数据,谨慎操作。
6、清理网络
docker network prune
- 删除所有未被任何容器使用的网络。
7、构建时忽略缓存(不清理,仅跳过缓存)
如果您只是想让本次 `docker build` 不使用缓存,而不是删除所有历史缓存,可以使用 `--no-cache` 选项:
docker build --no-cache -t your-image .
这只会临时跳过缓存,不会影响其他构建的缓存。
8、一键彻底清理(慎用)
docker system prune -a --volumes -f
- 删除所有未使用的**容器**、**镜像**、**网络**、**卷**(包括未使用的卷)和**构建缓存**。
- **危险**:会永久删除所有未被使用的资源,可能导致数据丢失。
正文
条件准备
正常从 Docker https://www.docker.com/ 官网下载安装即可。
修改为国内源加速,在docker desktop的设置中setting配置即可,Docker Engine中写入下面内容,然后Apply应用并重启Docker Desktop:
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"registry-mirrors": [
"https://docker.xuanyuan.me",
"https://docker.1ms.run",
"https://docker.m.daocloud.io",
"https://docker.mirrors.ustc.edu.cn"
]
}
需要说明 docker config set --global registry-mirrors命令无效,不可用。
项目的目录结构如下:
D:\develop
├── DockerEnv
├── docker-multi-web
├── dockerfile # PHP+Nginx基础镜像构建文件
├── nginx
├── nginx.conf # Nginx主配置
└── vhost # 多站点虚拟主机配置目录
├── site1.conf # 站点1配置
└── site2.conf # 站点2配置
├── mysql-server
├── mysql-data # MySQL持久化数据
├── www
├── site1 # 项目1:test1.local
│ └── index.php
└── site2 # 项目2:test2.local
└── index.php
搭建网桥
搭建网桥docker network create web-net,如:
D:\develop\DockerEnv>docker network create web-net
2b27ad41e8489e7765f93e2fec27eb9321cf88e0d65969f438f7d3ea844d8de6
D:\develop\DockerEnv>
安装MySQL
MySQL 不要放进自定义 Image。如果把 MySQL 打包进镜像,删除容器会丢失数据库数据,无法持久化;分离容器更灵活,可单独重启、备份、更换 MySQL 版本。
Docker Hub 官方已经提供好现成的 mysql:8.0 官方镜像,直接 docker run 拉取启动即可,不需要自己打包 MySQL。
启动MySQL容器:
docker run -d --name mysql8 --network web-net -v D:/develop/DockerEnv/mysql-server/mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=testdb -e MYSQL_ROOT_HOST=% -p 3306:3306 mysql:8.0
加上 MYSQL_ROOT_HOST=%,否则外部 Windows、PHP 容器无法连接数据库。-e MYSQL_ROOT_HOST=% 允许 PHP 容器、本机 Navicat 全部访问,本地开发必备。
运行完成后在Docker Desktop中查看MySQL容器是否启动成功,Container、Image等。
外部连接时,连接地址不要使用 127.0.0.1,而要使用 mysql8 。
Nginx 配置
nginx.conf 内容:
user www-data;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /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;
sendfile on;
keepalive_timeout 65;
# 加载所有站点虚拟主机配置
include /etc/nginx/conf.d/*.conf;
}
项目配置
下面看几个项目的配置。
项目一
site1.conf 内容:
server {
listen 80;
server_name test1.local www.test1.local;
root /usr/share/nginx/www/site1;
index index.html index.htm index.php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
www/site1/index.php 内容:
<?php
echo "<h2>站点1 test1.local</h2>";
phpinfo();
项目二
site2.conf 内容:
server {
listen 80;
server_name test2.local www.test2.local;
root /usr/share/nginx/www/site2;
index index.html index.htm index.php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
www/site2/index.php 内容:
<?php
echo "<h2>站点2 test2.local</h2>";
// 测试mysql连接
$dsn = 'mysql:host=mysql8;dbname=testdb;charset=utf8';
try {
$db = new PDO($dsn, 'root', '123456');
echo "<p>MySQL连接成功</p>";
}catch (PDOException $e){
echo "<p>数据库连接失败:".$e->getMessage()."</p>";
}
www/site2/index.php 内容:
<?php
echo "hello world";
?>
hosts 配置
在宿主机的 C:\Windows\System32\drivers\etc\hosts 文件中添加:
127.0.0.1 test1.local
127.0.0.1 test2.local
如果提示无权限修改,可以用管理员权限打开记事本,然后用记事本打开该文件进行修改并保存。
安装 Nginx + PHP
接下来安装Nginx+PHP。
dockerfile 内容:
FROM quay.io/centos/centos:stream9-minimal
# 1. 替换 CentOS 基础源为阿里云
RUN sed -e 's|mirror.centos.org|mirrors.aliyun.com|g' \
-e 's|mirror.stream.centos.org|mirrors.aliyun.com|g' \
-i /etc/yum.repos.d/centos*.repo && \
microdnf clean all && microdnf makecache
# 2. 强制移除 curl-minimal,再安装 dnf 和 curl
RUN rpm -e --nodeps curl-minimal && \
microdnf install -y dnf curl && \
microdnf clean all
# 3. 安装 epel-release 并替换为阿里云 EPEL 镜像
RUN dnf install -y epel-release && \
sed -e 's|https://download.fedoraproject.org/pub|https://mirrors.aliyun.com/fedora-epel|g' \
-i /etc/yum.repos.d/epel*.repo && \
dnf clean all && dnf makecache
# 4. 安装 Remi 源并替换为清华镜像(国内唯一完整同步Remi)
RUN dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm && \
sed -e 's|https://rpms.remirepo.net|https://mirrors.tuna.tsinghua.edu.cn/remi|g' \
-i /etc/yum.repos.d/remi*.repo && \
dnf clean all && dnf makecache
# 5. 安装 Nginx + 启用 php:remi-7.4 模块并安装全部组件 + 系统底层时区库
RUN dnf module enable -y php:remi-7.4 && \
dnf install -y \
nginx \
php-fpm \
php-cli \
php-bcmath \
php-mysqlnd \
php-pdo \
php-gd \
php-zip \
php-curl \
php-mbstring \
php-opcache \
php-fileinfo \
php-xml \
php-redis \
php-intl \
php-sodium \
vim unzip && \
dnf clean all
# 6.安装 tzdata 并重装确保时区数据文件存在
RUN dnf install -y tzdata && \
dnf reinstall -y tzdata
# 7. 新增创建www-data用户组和用户
RUN groupadd www-data && useradd -g www-data www-data
# 8. 修改 php-fpm 运行用户为 www-data,解决页面403权限
RUN sed -i 's/^user = apache/user = www-data/' /etc/php-fpm.d/www.conf && \
sed -i 's/^group = apache/group = www-data/' /etc/php-fpm.d/www.conf && \
sed -i 's/^listen = .*/listen = 127.0.0.1:9000/' /etc/php-fpm.d/www.conf
# 9. 统一设置系统时区+PHP时区配置,彻底消除时区报错
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo 'date.timezone = Asia/Shanghai' > /etc/php.d/99-timezone.ini
# 10. 安装 Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# 11. 手动创建 Composer 全局配置文件(阿里云镜像)
RUN mkdir -p /root/.composer && \
echo '{"config": {"repositories": {"packagist": {"type": "composer", "url": "https://mirrors.aliyun.com/composer/"}}}}' > /root/.composer/config.json
# 12. 复制本地Nginx主配置 + 多站点虚拟主机目录
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
# 13. 创建站点根目录并授权www-data读写权限
RUN mkdir -p /usr/share/nginx/www && \
chown -R www-data:www-data /usr/share/nginx/www
EXPOSE 80
# 启动php-fpm + 前台运行nginx,防止容器自动退出
CMD ["sh", "-c", "mkdir -p /run/php-fpm && chown www-data:www-data /run/php-fpm && php-fpm -F & nginx -g 'daemon off;'"]
这一块用了好长时间,说一下里面的注意点。基础镜像用的是centos:stream9精简版,为了国内加速,CentOS 基础源换为了阿里云。里面多处安装用到了dnf,但基础镜像 quay.io/centos/centos:stream9-minimal 默认的仓库配置中,没有可用的 dnf 包(尽管 microdnf 是内置的,但microdnf 本身是轻量级包管理器,好多包的安装还是要用到dnf),有些地方也要用到curl(尽管 curl-minimal 是内置的,但有些下载是要用到curl的,而curl 包与 curl-minimal 冲突),我们需要强制移除 curl-minimal,再安装 dnf 和 curl。还有centos:stream9精简版底层是缺少系统底层时区库,安装Composer会用到。Composer 全局配置文件改为阿里云,命令行总是无法执行,无奈改为手动创建。php-fpm 一般是用socket实现,绑定地址 /run/php-fpm/www.sock,这是一个临时目录,在容器启动时需要创建该目录;但这里改下来有问题,最后改为了 127.0.0.1:9000 端口监听。php-fpm -F前台运行会阻塞后面nginx -g 'daemon off;'的执行,所以不能用&&,而是改为&。
centos:stream9-minimal 为精简镜像,有意删除了 /usr/share/zoneinfo,导致tzdata安装不完整,需要重新安装dnf reinstall -y tzdata。之后 第10步 可以修改看一下能否正常安装:
# 11. 设置 Composer 全局为阿里云镜像
php -d date.timezone=Asia/Shanghai composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
生成镜像:
docker build -t centos9-nginx-php74 .
创建容器:
docker run -d --name centos9-nginx-php74 --network web-net -v D:/develop/www:/usr/share/nginx/www -v D:/develop/DockerEnv/docker-multi-web/nginx/vhost:/etc/nginx/conf.d -p 8080:80 centos9-nginx-php74
浏览器访问,查看效果:
- 站点 1:http://test1.local:8080
- 站点 2:http://test2.local:8080
另外php可以安装的几个拓展:
连接协议
soap
swoole
进程管理
sysvsem
posix
shmop
新项目配置
和第二个项目一样,除了项目文件,另外需要写site3.conf配置,修改hosts文件。
重启容器:
docker restart centos9-nginx-php74
PHP8.3 安装
dockerfile 内容:
FROM quay.io/centos/centos:stream9
# 1. 替换 CentOS 基础源为阿里云
RUN sed -e 's|mirror.centos.org|mirrors.aliyun.com|g' \
-e 's|mirror.stream.centos.org|mirrors.aliyun.com|g' \
-i /etc/yum.repos.d/centos*.repo && \
microdnf clean all && microdnf makecache
# 2. 强制移除 curl-minimal,再安装 dnf 和 curl
RUN rpm -e --nodeps curl-minimal && \
microdnf install -y dnf curl && \
microdnf clean all
# 3. 安装 epel-release 并替换为阿里云 EPEL 镜像
RUN dnf install -y epel-release && \
sed -e 's|https://download.fedoraproject.org/pub|https://mirrors.aliyun.com/fedora-epel|g' \
-i /etc/yum.repos.d/epel*.repo && \
dnf clean all && dnf makecache
# 4. 安装 Remi 源并替换为清华镜像(国内唯一完整同步Remi)
RUN dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm && \
sed -e 's|https://rpms.remirepo.net|https://mirrors.tuna.tsinghua.edu.cn/remi|g' \
-i /etc/yum.repos.d/remi*.repo && \
dnf clean all && dnf makecache
# 5. 安装 Nginx + 启用 php:remi-7.4 模块并安装全部组件 + 系统底层时区库
RUN dnf module enable -y php:remi-7.4 && \
dnf install -y \
nginx \
git \
php-fpm \
php-cli \
php-bcmath \
php-mysqlnd \
php-pdo \
php-gd \
php-zip \
php-curl \
php-mbstring \
php-opcache \
php-fileinfo \
php-xml \
php-redis \
php-intl \
php-sodium \
vim unzip && \
dnf clean all
# 6.安装 tzdata 并重装确保时区数据文件存在
RUN dnf install -y tzdata && \
dnf reinstall -y tzdata
# 7. 新增创建www-data用户组和用户
RUN groupadd www-data && useradd -g www-data www-data
# 8. 修改 php-fpm 运行用户为 www-data,解决页面403权限
RUN sed -i 's/^user = apache/user = www-data/' /etc/php-fpm.d/www.conf && \
sed -i 's/^group = apache/group = www-data/' /etc/php-fpm.d/www.conf && \
sed -i 's/^listen = .*/listen = 127.0.0.1:9000/' /etc/php-fpm.d/www.conf
# 9. 统一设置系统时区+PHP时区配置,彻底消除时区报错
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo 'date.timezone = Asia/Shanghai' > /etc/php.d/99-timezone.ini
# 10. 安装 Composer
RUN curl -sS https://mirrors.aliyun.com/composer/composer.phar | php -- --install-dir=/usr/local/bin --filename=composer
# 11. 手动创建 Composer 全局配置文件(阿里云镜像)
RUN mkdir -p /root/.composer && \
echo '{"config": {"repositories": {"packagist": {"type": "composer", "url": "https://mirrors.aliyun.com/composer/"}}}}' > /root/.composer/config.json
# 12. 复制本地Nginx主配置 + 多站点虚拟主机目录
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
# 13. 创建站点根目录并授权www-data读写权限
RUN mkdir -p /usr/share/nginx/www && \
chown -R www-data:www-data /usr/share/nginx/www
EXPOSE 80
# 启动php-fpm + 前台运行nginx,防止容器自动退出
CMD ["sh", "-c", "mkdir -p /run/php-fpm && chown www-data:www-data /run/php-fpm && php-fpm -F & nginx -g 'daemon off;'"]
centos:stream9-minimal 为精简镜像,缺少好多东西,我们直接用centos:stream9,需要时我们也可以把git安装上。
生成镜像:
docker build -t centos9-nginx-php83 .
创建容器:
docker run -d --name centos9-nginx-php83 --network web-net -v D:/develop/www:/usr/share/nginx/www -v D:/develop/DockerEnv/docker-multi-web/nginx/vhost:/etc/nginx/conf.d -p 8081:80 centos9-nginx-php83
安装Redis
在 D:\develop\DockerEnv\redis-server 目录下创建 redis.conf 文件,内容如下:
# 允许远程连接(Docker环境下通常注释掉 bind 或设为 0.0.0.0)
# bind 127.0.0.1
bind 0.0.0.0
# 关闭保护模式(如果设置了密码,可以保持 yes;若需兼容旧客户端可设 no)
protected-mode no
# 设置密码
requirepass 123456
# 开启 AOF 持久化
appendonly yes
# 内存限制与淘汰策略(防止内存溢出)
maxmemory 256mb
maxmemory-policy allkeys-lru
# 日志级别
loglevel notice
执行命令启动 Redis 容器:
docker run -d --name redis74 --network web-net -v D:/develop/DockerEnv/redis-server/redis-data:/data -v D:/develop/DockerEnv/redis-server/redis.conf:/usr/local/etc/redis/redis.conf -p 6379:6379 redis:7.4 redis-server /usr/local/etc/redis/redis.conf
外部连接时,宿主机连接地址要使用 127.0.0.1:6379,同一个宿主机内的其他docker容器中使用 web-net:6379连接。
Compose 编排
上面安装好了 MySQL 和 Redis,下面按照:官方镜像 + 职责分离 + Compose 编排 + 复用已有网络, 来安装 php:8.5-fpm 和 nginx 两个独立容器,不自己拼 LNMP 大镜像。PHP 升级只换 tag,Nginx 调参只动配置,互不影响。
先看一下环境:
C:\Users\Administrator>wsl -l -v
NAME STATE VERSION
- docker-desktop Running 2
C:\Users\Administrator>
C:\Users\Administrator>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a30b1a6ccf85 centos9-nginx-php74 "sh -c 'mkdir -p /ru…" 2 months ago Up 9 days 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp centos9-nginx-php74
d5046d1e795e redis:7.4 "docker-entrypoint.s…" 2 months ago Up 9 days 0.0.0.0:6379->6379/tcp, [::]:6379->6379/tcp redis74
2009b3504497 mysql:8.0 "docker-entrypoint.s…" 2 months ago Up 9 days 0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp mysql8
C:\Users\Administrator>
C:\Users\Administrator>docker network ls
NETWORK ID NAME DRIVER SCOPE
835013813fdf bridge bridge local
32c352e4a5ca host host local
0671617bb89a none null local
e9ba8523abf9 web-net bridge local
C:\Users\Administrator>
C:\Users\Administrator>docker network inspect web-net
[
{
"Name": "web-net",
"Id": "e9ba8523abf9e6dabf39a46e3eef7505af94ce5b74f45cd01fb8db12c9e6dd3c",
"Created": "2026-08-08T16:17:21.675273113Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv4": true,
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Options": {
"com.docker.network.enable_ipv4": "true",
"com.docker.network.enable_ipv6": "false"
},
"Labels": {},
"Containers": {
"2009b35044971280f3944e05dd912fa404f21a469163511fc8b4ddc48cb20fa1": {
"Name": "mysql8",
"EndpointID": "faedafb85b2938b8334c182c053290b5c1e2eb2be2da6ccfc777b021be38c71c",
"MacAddress": "22:10:d7:e4:0b:6b",
"IPv4Address": "172.18.0.4/16",
"IPv6Address": ""
},
"a30b1a6ccf85b51acb6dc0cf3e82c69d406b0bff15edede48cee4b153a3565ec": {
"Name": "centos9-nginx-php74",
"EndpointID": "3c57656f1de8fb77de983a492be80382c898c51dc3dc8dcf979ddc4deccaa57a",
"MacAddress": "f2:34:9a:d6:7e:c7",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"d5046d1e795e62948c2c13b215925b6a530ad373f7f4a2501dc5c814064e099f": {
"Name": "redis74",
"EndpointID": "0b36d099a93cc71ab4b0caa8c0b53418b2f819ab14a20b690573be9c3e32a9de",
"MacAddress": "8a:db:e3:94:65:2c",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Status": {
"IPAM": {
"Subnets": {
"172.18.0.0/16": {
"IPsInUse": 6,
"DynamicIPsAvailable": 65530
}
}
}
}
}
]
C:\Users\Administrator>
C:\Users\Administrator>docker network inspect web-net --format " "
mysql8 172.18.0.4/16
centos9-nginx-php74 172.18.0.2/16
redis74 172.18.0.3/16
C:\Users\Administrator>
C:\Users\Administrator>wsl -d docker-desktop
docker-desktop:/tmp/docker-desktop-root/run/desktop/mnt/host/c/Users/Administrator#
docker-desktop:/tmp/docker-desktop-root/run/desktop/mnt/host/c/Users/Administrator# pwd
/tmp/docker-desktop-root/run/desktop/mnt/host/c/Users/Administrator
docker-desktop:/tmp/docker-desktop-root/run/desktop/mnt/host/c/Users/Administrator#
docker-desktop:/tmp/docker-desktop-root/run/desktop/mnt/host/c/Users/Administrator# cd ~
docker-desktop:~#
docker-desktop:~# pwd
/root
docker-desktop:~#
docker-desktop:~# ll /home
-sh: ll: not found
docker-desktop:~#
docker-desktop:~# ls /home
docker-desktop:~#
docker-desktop:~# cat /etc/passwd
root:x:0:0:root:/root:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
docker-desktop:~#
可以发现:
- docker-desktop 是 Alpine 迷你容器式 WSL 发行版
- 用户是
root,家目录:/root - shell 是 sh
- 已有 docker 网络:
web-net,我们继续复用它
另外:Windows 资源管理器 \\wsl.localhost\docker-desktop ,对应 WSL 内 / 根目录。
安装 PHP8.5 与 Ngnix
我们在 root 目录下创建 lnmp-web 目录,用于存放 LNMP 相关文件。下面是具体的目录结构:
/root/lnmp-web/
├── docker-compose.yml
├── php
│ ├── Dockerfile
│ └── conf.d
│ └── 99-custom.ini
├── nginx
│ ├── conf.d
│ │ └── catch.conf
│ └── logs
└── www
└── catchadmin # 示例:CatchAdmin项目代码
如果用户不是 root,可以在家目录下创建目录,如 /home/sam/lnmp-web/。
catchadmin 是一个基于 Laravel-12 的PHP项目,不要把代码放 Windows 的 C 盘挂载目录 /mnt/c/xxx,不然 IO 会很慢,全部放在 WSL 内部路径。
先把各文件内容写好,再进行安装。
/root/lnmp-web/php/Dockerfile 文件内容:
FROM php:8.5-fpm
RUN apt-get update && apt-get install -y --no-install-recommends \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
libzip-dev \
libicu-dev \
libonig-dev \
tzdata \
git \
unzip \
&& rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install -j$(nproc) \
bcmath \
ctype \
fileinfo \
gd \
intl \
mbstring \
opcache \
pdo_mysql \
zip
RUN pecl install redis \
&& docker-php-ext-enable redis
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY conf.d/*.ini /usr/local/etc/php/conf.d/
WORKDIR /var/www/html
/root/lnmp-web/php/conf.d/99-custom.ini 文件内容:
date.timezone = Asia/Shanghai
memory_limit = 256M
upload_max_filesize = 20M
post_max_size = 20M
max_execution_time = 120
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=128
opcache.max_accelerated_files=15000
opcache.max_wasted_percentage=10
opcache.revalidate_freq=60
opcache.validate_timestamps=1
/root/lnmp-web/docker-compose.yml 文件内容(核心,包含 nginx 服务定义):
services:
php85:
build: ./php
container_name: php85
restart: unless-stopped
networks:
- web-net
volumes:
- ./www:/var/www/html
- ./php/conf.d:/usr/local/etc/php/conf.d
environment:
TZ: Asia/Shanghai
nginx:
image: nginx:stable
container_name: nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
networks:
- web-net
volumes:
- ./www:/var/www/html
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/logs:/var/log/nginx
depends_on:
- php85
networks:
web-net:
external: true
/root/lnmp-web/nginx/conf.d/catch.conf 文件内容:
server {
listen 80;
server_name catch.test;
root /var/www/html/catchadmin/public;
index index.php;
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 7d;
try_files $uri =404;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php85:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 128k;
}
location ~ /\.env { deny all; }
location ~ composer\.json { deny all; }
}
在 Windows CMD / PowerShell 中执行 compose:
docker compose -f \\wsl$\docker-desktop\root\lnmp-web\docker-compose.yml up -d --build
不要在 WSL 中执行 docker / docker compose 命令,否则会报错。所有 docker compose、docker ps、docker network 全部在 Windows CMD / PowerShell 执行。
如果 mysql、redis 未接入 web-net 网络,需要把 mysql、redis 接入 web-net 网络:
docker network connect web-net mysql
docker network connect web-net redis
然后再执行上面的 docker compose 命令。
部署 CatchAdmin
在 Windows 资源管理器往 \\wsl.localhost\docker-desktop\root\lnmp-web\www\ 上传代码包,然后再进容器 composer install 安装依赖。
docker exec -it php85 bash
cd /var/www/html/catchadmin
composer install
cp .env.example .env
php artisan key:generate
然后配置.env,权限,迁移:
chown -R www-data:www-data /var/www/html/catchadmin/storage /var/www/html/catchadmin/bootstrap/cache
php artisan migrate
php artisan db:seed
修改 C:\Windows\System32\drivers\etc\hosts 文件,添加 catch.test 记录:
127.0.0.1 catch.test
浏览器访问 http://catch.test
后续修改 nginx 配置后的重载命令(CMD):
docker exec nginx nginx -t
docker exec nginx nginx -s reload
附录
执行过程: