windows环境下用docker搭建php开发环境dnmp

安装WSL


WSL即Linux子系统,比虚拟机占用资源少,安装的前提是系统必须是win10以上。

WSL的安装比较简单,网上有很多教程,例如:WSL简介与安装流程(Windows 下的 Linux 子系统)_wsl安装-CSDN博客,我这里就不多赘述了

安装DockerDesktop


官网下载:Docker Desktop: The #1 Containerization Tool for Developers | Docker

汉化包(可选):asxez/DockerDesktop-CN: Docker汉化 Docker中文版 Docker汉化包 DockerDesktop汉化 Docker Windows Docker MAC

修改镜像存储目录(可选):由于镜像比较大,为了不占用c盘用空间,可以设置修改镜像存储目录

下载dnmp


我们直接用github上star比较多的,虽然有点缺陷,很多东西文档上也没说,不过该有的都有,没有的我会补充

项目github地址:garymengcom/dnmp: Docker LNMP (Nginx, PHP7/PHP5, MySQL, Redis)

git clone https://github.com/garymengcom/dnmp.git

配置文件


1.复制配置文件

cd dnmp
copy env.sample .env
copy docker-compose.sample.yml docker-compose.yml

2.修改.env文件配置

  • 修改php代码目录,把SOURCE_DIR修改为你的php代码所在目录,默认是dnmp/www,假如我的是D:/wwwroot目录,则修改为

    SOURCE_DIR=D:/wwwroot
    
  • 增加php扩展,默认安装php扩展比较少,根据需要需要在对应的php配置中添加额外的扩展,如redis,exif,bcmath

  • 修改mysql端口、root密码

3.修改docker-compose.yml文件,把自己不需要的服务注释掉,需要的加上。例如:默认会同时安装mysql5mysql8,根据自己的需求,只保留其中一个;

4.默认配置文件都在services目录下对应的程序目录里面,保持默认即可

启动服务


docker-compose up -d

如果下载镜像的过程中报错网络问题无法下载,可以看下面的【更换镜像源】这一节解决,或者尝试手动执行docker pull 单独拉取镜像试试

等待镜像下载完成,容器运行了就可以了。如果安装了Docker Desktop,按照提示按v键可以跳转到 Docker Desktop中查看跑起来的服务

访问http://localhost即可访问到默认的网站

更换镜像源


如果启动服务过程中报下面的错,镜像无法下载,则需要更换docker镜像源

可以上网找一下当前可用的docker镜像源,例如:https://cloud.tencent.com/developer/article/2485043,然后在或DockerDesktop的配置中增加镜像配置registry-mirrors,镜像地址自己找最新可用的地址

{"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-mirrors": ["https://docker.1ms.run"]
}

安装PHP扩展


参考官方文档即可:garymengcom/dnmp: Docker LNMP (Nginx, PHP7/PHP5, MySQL, Redis)

新建站点


默认有一个localhost网站,目录在dnmp\www\localhost,按照下面的步骤可以新建一个站点,以创建www.test-site.net为例

  • 1.创建nginx站点配置文件

    进入dnmp\services\nginx\conf.d目录,新建文件www.test-site.net.conf,文件内容如下(将www.test-site.net全部替换为你自己的域名即可, 注意修改fastcgi_pass配置项对应的php容器)

    server {server_name  www.test-site.net;listen       80;root   /www/www.test-site.net;index  index.php index.html index.htm;#charset koi8-r;access_log /dev/null;#access_log  /var/log/nginx/nginx.www.test-site.net.access.log  main;error_log  /var/log/nginx/nginx.www.test-site.net.error.log  warn;#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 127.0.0.1:80##location ~ \.php$ {#    proxy_pass   http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000# 注意修改fastcgi_pass中对应的php容器#location ~ [^/]\.php(/|$) {fastcgi_pass   php74:9000;include        fastcgi-php.conf;include        fastcgi_params;}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {#    deny  all;#}
    }
    
  • 2.修改本地hosts文件,增加一条记录

    127.0.0.1 www.test-site.net
    
  • 3.新增php代码

    在php代码目录(默认是dnmp\www)下新建站点目录dnmp\www\www.test-site.net,里面存放该站点的php文件

  • 4.重启nginx,浏览器访问http://www.test-site.net/即可,需要注意的是如果你开了代理可能会导致hosts文件映射失效!

  • 5.如果每个网站需要不同的php版本,那么需要启动对应版本的php容器并且网站的nginx配置文件中的fastcgi_pass配置项需要修改为对应的php版本

注意事项

如果项目是thinkphp或laravel等web框架,需要将www.test-site.net.conf配置中的root /www/www.test-site.net;修改为public目录,如:root /www/www.test-site.net/public,然后增加伪静态配置

Laravel伪静态:
location / {  try_files $uri $uri/ /index.php$is_args$query_string;  
}  ThinkPHP5.x伪静态:
location / {try_files $uri $uri/ /index.php?$query_string;
}ThinkPHP6.x伪静态:
location / {if (!-e $request_filename) {rewrite  ^(.*)$  /index.php?s=$1  last;break;}
}

SSL证书


  • 1.生成证书

    本地自签名证书推荐mkcert:Windows下安装mkcert_windows安装mkcert-CSDN博客

    生产环境免费证书推荐Let‘s Encrypt:[SSL]Let‘s Encrypt生成免费的SSL证书_let’s encrypt 证书-CSDN博客

    当然,也可以选择其他付费SSL证书,证书包括.crt.key格式的两个文件,在dnmp\services\nginx\ssl目录创建跟网站域名一致的文件夹,然后将两个证书文件放到文件夹里即可

  • 2.在对应站点的nginx配置文件最后增加下面这段配置,注意将证书路径替换为你的

    listen 443 ssl;
    ssl_certificate /ssl/www.test-site.net/www.test-site.net+2.pem;
    ssl_certificate_key /ssl/www.test-site.net/www.test-site.net+2-key.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:!LOW:!aNULL:!eNULL;
    
  • 3.重启nginx生效

    docker-compose restart nginx
    

解决dnmp环境下php运行慢问题

你有没有发现使用WSL+Docker这种方式运行php连输出简单的hello world都要4秒钟,为什么会这么慢???

  • 原因

    WSL2 的跨文件系统的io读写性能非常非常差,官方已经告诉了我们关键问题和解决方案:不要将项目挂载到 Windows 系统中,
    而是挂载到 WSL 文件系统中。

  • 思路

    1.参考文章 解决Docker使用WSL2项目运行慢的问题 | Laravel China 社区,将原本.env配置文件中的SOURCE_DIR路径(也就是windows与docker容器映射的目录)改为WSL路径,也就是windows与docker容器目录映射改为wsl与docker容器目录映射,然后进入WSL,在WSL中执行docker-compose up命令。然后把php代码复制一份到这个WSL目录中,这样就不存在跨文件系统读写问题了,再次访问docker中的php网站,快到飞起!!!但是又产生新的问题:代码文件怎么同步?用FTP有点麻烦,linux定时同步也很麻烦。。。

    2.不知道你发现没有,在DockerDesktop中勾选Enable integration with my default WSL distro的话,你的电脑中会多出一个Linux文件目录,你可以直接在windows下访问WSL中的文件。通过查询资料得知,在WSL中,/mnt目录是与windows的硬盘目录是连通的,也就是在WSL中也能直接读取到你在windows中的php代码目录!!!

  • 解决

    有了上面两个前提,那就好解决了,直接把WSL中/mnt代码目录(与windows中的代码目录相同)和docker容器的目录映射起来,按照下面两个步骤操作就可以了

    1.修改.env中的php代码目录SOURCE_DIR为WSL目录,例如我的代码目录为D盘下的D:\dnmp\www,那么就改为SOURCE_DIR=/mnt/d/dnmp/www/

    2.通过cmd进入WSL(直接输入wsl命令)然后在WSL中运行docker-compose up -d即可,就是这么简单。千万不要在windows下启动docker-compose, 因为windows下没有/mnt/d/dnmp/www目录,会映射失败。当然,第一次在WSL启动成功之后,也可以在dockerDesktop界面中直接点按钮一键启动!再次访问docker中的网站看看是不是快多了!

如果myql容器无法正常启动,请参考下面的【常见问题 · 在WSL中docker启动mysql容器失败】解决

自定义镜像


项目使用的镜像都是官方镜像,有时候会满足不了我们的需求,比如php扩展比较少,增加扩展之后如果要多机部署又要安装一次php扩展,非常不方便。目前可用的解决方法是打包并发布自己的镜像,然后修改dnmp\services目录下对应的程序Dockerfile文件中的镜像名称再执行docker-compose up

新增PHP版本


以新增PHP8.4为例

  • 1.在docker-compose.yml文件中复制一份PHP8.2的配置并替换为PHP8.4,注意先不要做目录映射,因为还没有默认的配置文件

    php84:build:context: ./services/php84args:DEBIAN_MIRROR_DOMAIN: deb.debian.orgPHP_EXTENSIONS: "$PHP84_EXTENSIONS"TZ: "$TZ"container_name: php84expose:- 9501volumes:- ${SOURCE_DIR}:/www/:rw- ${PHP84_LOG_DIR}:/var/log/php- ${PHP84_DATA_COMPOSER}:/tmp/composerrestart: alwayscap_add:- SYS_PTRACEnetworks:- default
    
  • 2.在.env文件中复制一份PHP8.2的配置并替换为PHP8.4,修改配置文件位置,注意将扩展删除,只保留curl即可,不然可能会安装报错

    #
    # PHP84
    #
    # Available PHP_EXTENSIONS:
    #
    # pdo_mysql,zip,pcntl,mysqli,mbstring,exif,bcmath,calendar,
    # sockets,gettext,shmop,sysvmsg,sysvsem,sysvshm,pdo_rebird,
    # pdo_dblib,pdo_oci,pdo_odbc,pdo_pgsql,pgsql,oci8,odbc,dba,
    # gd,intl,bz2,soap,xsl,xmlrpc,wddx,curl,readline,snmp,pspell,
    # recode,tidy,gmp,imap,ldap,imagick,sqlsrv,mcrypt,opcache,
    # redis,memcached,xdebug,swoole,pdo_sqlsrv,sodium,yaf,mysql,
    # amqp,mongodb,event,rar,ast,yac,yar,yaconf,msgpack,igbinary,
    # seaslog,varnish,xhprof,xlswriter,memcache,rdkafka,zookeeper,
    # psr,phalcon,sdebug,ssh2,yaml,protobuf,hprose
    #
    # You can let it empty to avoid installing any extensions,
    # or install multi plugins as:
    # PHP84_EXTENSIONS=pdo_mysql mysqli gd curl opcache
    # Note::that it is a spacePHP84_VERSION=8.4.3
    PHP84_PHP_CONF_FILE_DEVELOPMENT=./services/php84/php.ini-development
    PHP84_PHP_CONF_FILE_PRODUCTION=./services/php84/php.ini-production
    PHP84_FPM_CONF_FILE=./services/php84/www.conf
    PHP84_LOG_DIR=./logs/php84
    PHP84_DATA_COMPOSER=./data/composer
    PHP84_EXTENSIONS=curl
    
  • 3.在dnmp项目中新建php84目录和Dockerfile文件

    cd service && mkdir php84
    cd php82 && copy Dockerfile ..\php84\
    

    编辑php84/Dockerfile,将里面的FROM php:8.2-fpm改为FROM php:8.4-fpm并保存

  • 4.在WSL中执行docker-compose up -d创建容器

  • 5.在WSL中执行下面的命令复制配置文件到宿主机

    首先查看php84容器/usr/local/etc目录下有什么配置文件

    然后将3个需要的文件复制到宿主机

    docker cp php84:/usr/local/etc/php/php.ini-development /mnt/d/dnmp/services/php84/php.ini-development
    docker cp php84:/usr/local/etc/php/php.ini-production /mnt/d/dnmp/services/php84/php.ini-production
    docker cp php84:/usr/local/etc/php-fpm.d/www.conf /mnt/d/dnmp/services/php84/php-fpm.conf
    
  • 6.修改docker-compose.yml目录映射配置文件,注意变量要跟.env文件中对应

    php84:build:context: ./services/php84args:DEBIAN_MIRROR_DOMAIN: deb.debian.orgPHP_EXTENSIONS: "$PHP84_EXTENSIONS"TZ: "$TZ"container_name: php84expose:- 9501volumes:- ${SOURCE_DIR}:/www/:rw- ${PHP84_PHP_CONF_FILE_DEVELOPMENT}:/usr/local/etc/php/php.ini-development- ${PHP84_PHP_CONF_FILE_PRODUCTION}:/usr/local/etc/php/php.ini-production- ${PHP84_FPM_CONF_FILE}:/usr/local/etc/php-fpm.d/www.conf- ${PHP84_LOG_DIR}:/var/log/php- ${PHP84_DATA_COMPOSER}:/tmp/composerrestart: alwayscap_add:- SYS_PTRACEnetworks:- default
    
  • 7.在WSL中删掉php84容器并重新创建

    docker rm php84
    docker-compose up -d
    

    到此新增PHP版本成功

常见问题


  • php编译失败

    php在编译过程中可能会遇到扩展安装报错导致编译失败

    可以尝试修改.env文件中的CONTAINER_PACKAGE_URL,这一行的上面有提供几个url,可以逐个尝试看看能不能解决。如果还不能解决,打开.env文件,在对应的PHP扩展中删除部分扩展,例如只保留curl扩展,其他扩展等容器跑起来后手动安装。

  • 在WSL中docker启动mysql容器失败

    mysql无法启动,查看日志发现报错没有权限[ERROR] Could not set file permission for ca-key.pem,原因是wsl.conf文件没有metadata信息,需要修改wsl的配置才能支持修改文件属性。进入WSL,然后编辑/etc/wsl.conf文件增加下面的配置信息,重启WSL即可

    [automount]
    enabled = true
    options = "metadata"
    mountFsTab = false
    

    在windows cmd下重启WSL

    # 关闭wsl
    wsl --shutdown
    # 启动并进入wsl
    wsl
    

    再次进入WSL执行docker-compose up -d即可正常启动容器

    参考文章:https://blog.csdn.net/x356982611/article/details/108732844

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/21458.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx之rewrite重写功能

目录 一、rewrite概述 1、rewrite功能 2、跳转场景 二、标准配置指令 1、rewrite日志记录指令 2、未初始化变量告警日志记录指令 3、rewrite 指令 3.1 正则表达式 三、rewrite模块使用实例 1.基于域名的跳转 2.基于客户端 IP 访问跳转 3.?基于旧域名跳转到新域名后…

Mybatis(一)

配置文件 必要的用户密码要修改, 还有绿色线的名字要修改成数据库的 配置文件直接cv 创建 复习之前的知识进行分层处理 与前面一一对应, 后面三个发现后面输出是null, 没有一一对应, 后面再解释解决方法 运行发现, 输出正常 idea的测试类 两个注解了解 记得加上这个, 不然无…

一周学会Flask3 Python Web开发-http响应状态码

锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 在Flask程序中,客户端发出的请求触发相应的视图函数,获取返回值会作为响应的主体,最后生成…

七星棋牌源码高阶技术指南:6端互通、200+子游戏玩法深度剖析与企业级搭建实战(完全开源)

在棋牌游戏行业高速发展的今天,如何构建一个具备高并发、强稳定性与多功能支持的棋牌游戏系统成为众多开发者和运营团队关注的焦点。七星棋牌全开源修复版源码 凭借其 六端互通、200子游戏玩法、多省区本地化支持,以及 乐豆系统、防沉迷、比赛场、AI智能…

C++和OpenGL实现3D游戏编程【总览】

欢迎来到zhooyu的游戏专栏。 主页网址:【zhooyu】 专栏网址:【C和OpenGL实现3D游戏编程】 🌟🌟🌟这里将通过一个OpenGL实现3D游戏编程实例教程,带大家深入学习OpenGL知识。知识无穷而人力有穷,…

pycharm社区版有个window和arm64版本,到底下载哪一个?还有pycharm官网

首先pycharm官网是这一个。我是在2025年2月16日9:57进入的网站。如果网站还没有更新的话,那么就往下滑一下找到 community Edition,这个就是社区版了免费的。PyCharm:适用于数据科学和 Web 开发的 Python IDE 适用于数据科学和 Web 开发的 Python IDE&am…

GPT-Sovits:语音克隆训练-遇坑解决

前言 本来以为3050完全无法执行GPT-Sovits训练的,但经过实践发现其实是可以,并且仅花费了十数分钟便成功训练和推理验证了自己的语音模型。 官方笔记:GPT-SoVITS指南 语雀 项目地址:https://github.com/RVC-Boss/GPT-SoVITS 本人…

8 SpringBootWeb案例(上): 查询【分页功能(分页插件)】、删除、新增、修改

文章目录 前言:SpringBootWeb案例1. 准备工作1.1 需求&环境搭建1.1.1 需求说明1.1.2 环境搭建1.2 开发规范1.2.1 开发规范-REST(不强求非要这种风格,传统风格有时候更方便)1.2.2 开发规范-统一响应结果和异常处理1.2.3 开发流程2. 部门管理2.1 查询部门2.1.1 原型和需求…

深入了解 DevOps 基础架构:可追溯性的关键作用

在当今竞争激烈的软件环境中,快速交付强大的应用程序至关重要。尽管如此,在不影响质量的情况下保持速度可能是一项艰巨的任务,这就是 DevOps 中的可追溯性发挥作用的地方。通过提供软件开发生命周期 (SDLC) 的透明视图…

用C++ Qt实现安卓电池充电动效 | 打造工业级电量控件

一、为什么需要自定义电池控件? 在工业控制、车机系统、智能硬件等领域的UI开发中,电池状态显示是高频出现的UI组件。通过实现一个支持颜色渐变、动态充电动画、警戒阈值提示的电池控件,开发者可以系统掌握以下核心能力: Qt绘图…

一批起飞猪名单配图

好久没有使用风口猪选股指标了,今天去玩了一把,发现起飞猪指标显示了好多一批猪票 华曙高科 汉威科技 双林股份 曼恩斯特 长盈精密 江苏雷利 双飞集团 奥飞数据 硅宝科技 水晶光电 长盈精密

机器学习笔记——常用损失函数

大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本笔记介绍机器学习中常见的损失函数和代价函数,各函数的使用场景。 热门专栏 机器学习 机器学习笔记合集 深度学习 深度学习笔记合集 文章目录 热门…

Ubuntu 服务器Llama Factory 搭建DeepSeek-R1微调训练环境

1.首先了解一下什么是LLM微调 LLM 微调指的是在已经预训练好的大型语言模型基础上,使用特定的任务数据或领域数据,通过进一步的训练来调整模型的参数,使其在特定任务或领域上能够表现得更好。简单来说,就是对一个已经具备了丰富语…

环境变量与本地变量

目录 本地变量的创建 环境变量VS本地变量 认识完了环境变量我们来认识一下本地变量。 本地变量的创建 我们如果直接env是看不到本地变量的,因为本地变量和环境变量都具有独立性,环境变量是系统提供的具有全局属性的变量,都存在bash进程的…

智慧农业新生态 | 农业数字化服务平台——让土地生金,让服务无忧

一部手机管农事,从播种到丰收,全链路数字化赋能! 面向农户、农机手、农服商、农资商打造的一站式农业产业互联网平台,打通农资交易、农机调度、农服管理、技术指导全场景闭环,助力乡村振兴提效增收。 三大核心场景&am…

【运维自动化-作业平台】如何创建执行方案和作业模板

蓝鲸智云作业平台,以下简称作业平台或JOB平台作业模板和执行方案:将运维操作场景中涉及到的多个脚本执行或文件分发步骤组合成一个作业模板,这个作业模板尽可能把场景相关的共性逻辑都包含进去,然后再根据实际使用场景衍生出相应的…

广度优先搜索--之重生之我是蒟蒻,从入坟到入坑式讲解

广度优先搜索 1.什么是广度优先搜索? 广度优先搜索(Breadth-First Search,简称BFS)是一种遍历或搜索树和图的算法,也称为宽度优先搜索,BFS算法从图的某个节点开始,依次对其所有相邻节点进行探索和遍历&am…

CSDN文章质量分查询系统【赠python爬虫、提分攻略】

CSDN文章质量分查询系统 https://www.csdn.net/qc 点击链接-----> CSDN文章质量分查询系统 <------点击链接 点击链接-----> https://www.csdn.net/qc <------点击链接 点击链接-----> CSDN文章质量分查询系统 <------点击链接 点击链…

为AI聊天工具添加一个知识系统 之113 详细设计之54 Chance:偶然和适配 之2

本文要点 要点 祖传代码中的”槽“ &#xff08;占位符变量&#xff09; 和 它在实操中的三种槽&#xff08;占据槽&#xff0c;请求槽和填充槽&#xff0c; 实时数据库&#xff08;source&#xff09;中数据(流入 ETL的一个正序流程 行列并发 靶向整形 绑定变量 &#xff09…

微信小程序实现拉卡拉支付

功能需求&#xff1a;拉卡拉支付&#xff08;通过跳转拉卡拉平台进行支付&#xff09;&#xff0c;他人支付&#xff08;通过链接进行平台跳转支付&#xff09; 1.支付操作 //支付 const onCanStartPay async (obj) > {uni.showLoading({mask: true})// 支付接口获取需要传…