安裝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
文件,把自己不需要的服務注釋掉,需要的加上。例如:默認會同時安裝mysql5
和mysql8
,根據自己的需求,只保留其中一個;
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