環境
- centos7
- docker 20.10.1
- docker-compose 1.27.4
有關環境搭建,參考:
docker && CentOS-7 :https://www.cnblogs.com/makalochen/p/14230753.html
docker-compose:https://www.cnblogs.com/makalochen/p/14266075.html
搭建需求
- mysql 5.7
- php7.3(包含fpm,並安裝thinkphp 5.1的相關擴展)
- nginx(最新)
構建yaml
構建yaml我們肯定要一步步構建,那我們先簡單分析一下需求。
- mysql 肯定是要先構建的
- mysql 數據庫要做持久化
- msyql root用戶密碼要自定義
- php 依賴mysql
- nginx 依賴php
1.編寫yaml構建mysql
這里我們參考hub上mysql的構建
docker hub:https://hub.docker.com/_/mysql
官方示例
# Use root/example as user/password credentials
version: '3.1'
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
adminer:
image: adminer
restart: always
ports:
- 8080:8080
解讀
#yaml版本
version:
#定義服務
services:
#服務名
db
#使用鏡像構建,沒有指定版本就用最新的
image
#相當於Dockerfile中的CMD命令
#會覆蓋默認的命令
#--default-authentication-plugin=mysql_native_password
#插入本地身份驗證
#參考:https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_default_authentication_plugin
command
#重啟策略 always表示總是重新啟動
#參考:https://docs.docker.com/compose/compose-file/compose-file-v3/#restart
restart
#環境變量
#MYSQL_ROOT_PASSWORD 表示root用戶密碼
environment
mysql環境變量
官方示例中只用到了MYSQL_ROOT_PASSWORD
,但其實還有其他的,
完整的參考:
https://dev.mysql.com/doc/refman/5.7/en/environment-variables.html
常用如下
MYSQL_ROOT_PASSWORD
此變量是必需變量,它指定將為MySQLroot
超級用戶帳戶設置的密碼
MYSQL_DATABASE
此變量是可選的,允許您指定在映像啟動時要創建的數據庫的名稱。如果提供了用戶名/密碼(請參閱下文),則將授予該用戶對該數據庫的超級用戶訪問權限(對應於GRANT ALL
)。
MYSQL_USER
, MYSQL_PASSWORD
這些變量是可選的,與創建新用戶和設置該用戶的密碼一起使用。該MYSQL_DATABASE
變量將為該用戶授予超級用戶權限(請參見上文)。這兩個變量都是創建用戶所必需的。
請注意,無需使用此機制來創建根超級用戶,該用戶默認情況下是使用MYSQL_ROOT_PASSWORD
變量指定的密碼創建的。
構建自定義mysql 5.7 yaml
經過了上滿的解讀,我們應該已經知道怎么構建mysql的yaml了,但上面解讀還不夠我們還要做數據持久化這就要用到volumes
可以參考這個配置:
https://www.cnblogs.com/makalochen/p/14266075.html#創建yaml文件
yaml 自定義配置
創建docker-compose.yml
文件,文件內容如下
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
db_data: {}
啟動mysql服務
后台啟動
docker-compose up -d
啟動完成
測試連接
隨便用個連接工具連接測試
如圖連接成功,之后就可以把端口映射注釋掉,為了安全考慮
2.在mysql yaml基礎上構建php-fpm
docker hub:https://hub.docker.com/_/php?tab=description&page=1&ordering=last_updated&name=fpm
參考:
https://github.com/mikechernev/dockerised-php/blob/master/docker-compose.yml
https://www.jianshu.com/p/b9eab9a265ca?from=timeline&isappinstalled=0
https://github.com/docker-library/php
先說php-fpm服務構建思路
因為搭建需求中寫了,要fpm所以鏡像的話我們選
7.3-fpm
又因為要支持 thinkphp5.1,所以肯定要安裝相關擴展,那么我們看下tp5.1的要求
https://www.kancloud.cn/manual/thinkphp5_1/353948
ThinkPHP5.1
的環境要求如下:
- PHP >= 5.6.0
- PDO PHP Extension
- MBstring PHP Extension
也就是說只需要安裝兩個擴展
關於docker php添加擴展[選看]
php鏡像添加擴展主要用到以下幾個命令:
- docker-php-source
- docker-php-ext-install
- docker-php-ext-enable
- docker-php-ext-configure
docker-php-source 用於創建或刪除 /usr/src/php 目錄,PHP 鏡像中自帶的擴展源碼存放的路徑:/usr/src/php/ext,
docker-php-ext-install 用於安裝並啟動 /usr/src/php/ext 目錄下的擴展,
docker-php-ext-enable 用於啟用擴展,比如通過 pecl 安裝的擴展默認是沒有啟用的,通過這個命令,可以無需到 php.ini 配置文件中去配置,
docker-php-ext-configure 一般都是需要跟 docker-php-ext-install 搭配使用,它的作用就是安裝擴展的時候,需要自定義配置時,就可以使用它。
啟用擴展庫
確保鏡像 /usr/src/php/ext
目錄存在,如果不存在的話,可以通過下列命令調出鏡像默認的擴展庫
docker-php-source extract
添加容器擴展庫中已有的擴展
在容器中,通過 ls -al /usr/src/php/ext
可以查看擴展庫中已有的擴展,並通過下列命令可以直接安裝並啟用該擴展:
docker-php-ext-install [Package]
如:
docker-php-ext-install mcrypt \
&& docker-php-ext-install mysql \
&& docker-php-ext-install mysqli \
&& docker-php-ext-install pdo_mysql \
&& docker-php-ext-install sockets \
&& docker-php-ext-install bcmath \
&& docker-php-ext-install gettext \
&& docker-php-ext-install soap
安裝擴展的時候有時候會提示缺少某些依賴,這時就需要先安裝其所需依賴,在執行 docker-php-ext-install
如:
apt-get update \
&& apt-get install -y libmcrypt-dev \
&& apt-get install -y libxml2-dev \
&& apt-get install -y libssl-dev
1234
而對於有些擴展,是需要通過 docker-php-ext-configure 進行配置的,比如安裝 PHP 的圖像擴展:
apt-get install -y libjpeg-dev \
&& apt-get install -y libpng-dev \
&& apt-get install -y libfreetype6-dev \
&& docker-php-ext-configure gd --with-jpeg-dir --with-png-dir --with-freetype-dir \
&& docker-php-ext-install -j$(nproc) gd
添加容器擴展庫中不存在的擴展
通過pecl安裝
通過 pecl 安裝的擴展默認沒有啟用,需要執行 docker-php-ext-enable 進行啟用。
先在 pecl 上找到需要的擴展,然后執行下列操作:
pecl install [Package]
接着啟用該擴展
docker-php-ext-enable [Package]
如:pecl install mongodb && docker-php-ext-enable mongodb
通過下載源碼安裝
可將下載的擴展源碼解壓后放置於 /usr/src/php/ext
目錄下,然后使用 docker-php-ext-install 命令進行安裝,如安裝 PHP 的 redis 擴展:
curl -L -o /tmp/redis.tar.gz https://github.com/phpredis/phpredis/archive/$PHPREDIS_VERSION.tar.gz \
&& tar xfz /tmp/redis.tar.gz \
&& rm -r /tmp/redis.tar.gz \
&& mkdir -p /usr/src/php/ext \
&& mv phpredis-$PHPREDIS_VERSION /usr/src/php/ext/redis \
&& docker-php-ext-install redis
刪除擴展庫
docker-php-source delete
卸載擴展
直接刪除 /usr/local/etc/php/conf.d
目錄下對應的配置文件
構建自定義mysql 5.7 + php7.3fpm yaml
yaml自定義配置
version: '3.1'
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
#ports:
# - 3306:3306
networks:
- lnmp
environment:
MYSQL_ROOT_PASSWORD: root
php-fpm:
#使用php 7.3-fpm鏡像構建
image: php:7.3-fpm
#設置依賴
depends_on:
- db
#掛載卷
volumes:
#設置代碼目錄
- ./code:/code
#配置網絡
networks:
- lnmp
volumes:
db_data: {}
networks:
lnmp:
啟動服務
docker-compose up -d
測試
進入容器,查看擴展
#查看容器
docker ps
#使用容器id進入容器
docker exec -it a208a3b27eac /bin/bash
#進入容器之后查看擴展
php-m
可以看到默認的擴展列表中已經支持這兩個擴展,所以我們無需再去安裝
上面將當前目錄下的code目錄掛載到了容器內/code目錄
我們寫幾個簡單的測試一下
寫上兩個php
helloword
<?php
echo 'hello world'.PHP_EOL;
?>
連接mysql
<?php
$servername = "db";
$username = "root";
$password = "root";
try {
$conn = new PDO("mysql:host=$servername;", $username, $password);
echo "連接成功".PHP_EOL;
}
catch(PDOException $e)
{
echo $e->getMessage().PHP_EOL;
}
?>
進入容器
docker exec -it php-fpm容器id /bin/bash
cd /code/
執行
php test.php
php test_mysql.php
執行結果
可以看到連接mysql失敗了,提示沒有驅動,那我們就需要將yaml加點東西,安裝php的pdo-mysql驅動
關於php fpm 缺少pdo-mysql驅動問題的解決辦法
推薦使用方式二
方式一
進入容器,執行
docker exec -it d5d0509878fb /bin/bash
#安裝pdo_mysql擴展
docker-php-ext-install pdo pdo_mysql
再次執行測試連接
可以看到連接沒問題,但是這種方式,還要進入容器,比較麻煩
方式二
使用dockerfile + yaml
創建php7.3_fpm_dockerfile
文件,文件內容如下
FROM php:7.3-fpm
RUN docker-php-ext-install pdo pdo_mysql
修改docker-compose.yml
文件內容,為如下內容
version: '3.1'
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
#ports:
# - 3306:3306
networks:
- lnmp
environment:
MYSQL_ROOT_PASSWORD: root
php-fpm:
#使用php 7.3-fpm鏡像構建
#改用dockerfile安裝擴展
#image: php:7.3-fpm
#dockerfile方式配置
build:
#上下文環境,從哪里開始構建
context: .
#yaml同級目錄下的php7.3_fpm_dockerfile文件
dockerfile: php7.3_fpm_dockerfile
#設置依賴
depends_on:
- db
#掛載卷
volumes:
#設置代碼目錄
- ./code:/code
#配置網絡
networks:
- lnmp
volumes:
db_data: {}
networks:
lnmp:
啟動
#由於使用了dockerfile,所以需要使用--build重構鏡像
docker-compose up -d --build
重構后的鏡像
第一個為重構后的鏡像,下面是原鏡像
再次執行測試連接
3.在配置好mysql,php-fpm基礎上 加上nginx
docker hub :https://hub.docker.com/_/nginx
參考:
https://zhuanlan.zhihu.com/p/97824480?utm_source=wechat_session
https://blog.csdn.net/qq_42114918/article/details/85238011
構建基礎yaml
先加上一個最基礎的,跑起來
例:
#ngnix配置
web:
#使用最新的nginx鏡像
image: nginx:latest
#映射端口
ports:
- 80:80
restart: always
#設置網絡
networks:
- lnmp
此時完整的yaml
version: '3.1'
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
#ports:
# - 3306:3306
networks:
- lnmp
environment:
MYSQL_ROOT_PASSWORD: root
php-fpm:
#使用php 7.3-fpm鏡像構建
#改用dockerfile安裝擴展
#image: php:7.3-fpm
#dockerfile方式配置
build:
#上下文環境,從哪里開始構建
context: .
#yaml同級目錄下的php7.3_fpm_dockerfile文件
dockerfile: php7.3_fpm_dockerfile
#設置依賴
depends_on:
- db
restart: always
#掛載卷
volumes:
#設置代碼目錄
- ./code:/code
#配置網絡
networks:
- lnmp
#ngnix配置
web:
#使用最新的nginx鏡像
image: nginx:latest
#映射端口
ports:
- 80:80
restart: always
#設置網絡
networks:
- lnmp
volumes:
db_data: {}
networks:
lnmp:
訪問
關於nginx版本
原來我決定統一使用最新,但是你會發現nginx各個版本的配置文件位置和設置不一樣,所以還是固定一個版本,docker hub目前最新的版本是
1.19.6
那就使用這個版本
關於nginx的配置
官網給出的解釋是這樣的
$ docker run --name my-custom-nginx-container -v /host/path/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx
有關nginx配置文件的語法的信息,請參見官方文檔(特別是《入門指南》)。
如果您希望采用默認配置,請使用以下類似內容從運行的nginx容器中復制它:
$ docker run --name tmp-nginx-container -d nginx $ docker cp tmp-nginx-container:/etc/nginx/nginx.conf /host/path/nginx.conf $ docker rm -f tmp-nginx-container
從這個命令我們可以知道容器內的配置文件在/etc/nginx/nginx.conf
這個位置
我們進入容器看下
可以看到文件內容如下
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
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;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
從上面配置文件中,我們得知訪問日志和錯誤日志分別為
/var/log/nginx/access.log
/var/log/nginx/error.log
那我們掛載容器的時候,也需要將日志掛載出來,方便后面的日志排查
復制容器內的配置文件
我們先把這個配置拷貝一份出來,留做備份,防止改到最后恢復不了原始配置
例:
docker cp a0731260e0a9:etc/nginx/nginx.conf /home/lnmp/nginx.conf
可以看到,拷貝成功
修改yaml,限定nginx鏡像版本,設置nginx配置文件和日志文件掛載
先將配置文件復制到你要掛載的目錄下
如:
我想掛載到/home/lnmp/nginx
目錄,那就將剛才復制出來的配置文件拷貝到該目錄
注意:不能掛載文件,只能掛載文件夾
此時的yaml
version: '3.1'
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
#ports:
# - 3306:3306
networks:
- lnmp
environment:
MYSQL_ROOT_PASSWORD: root
php-fpm:
#使用php 7.3-fpm鏡像構建
#改用dockerfile安裝擴展
#image: php:7.3-fpm
#dockerfile方式配置
build:
#上下文環境,從哪里開始構建
context: .
#yaml同級目錄下的php7.3_fpm_dockerfile文件
dockerfile: php7.3_fpm_dockerfile
#設置依賴
depends_on:
- db
restart: always
#掛載卷
volumes:
#設置代碼目錄
- ./code:/code
#配置網絡
networks:
- lnmp
#ngnix配置
web:
#使用1.19.6鏡像
image: nginx:1.19.6
#映射端口
ports:
- 80:80
depends_on:
- php-fpm
restart: always
#設置網絡
networks:
- lnmp
#設置掛載
volumes:
#配置文件掛載
- /home/lnmp/nginx/nginx.conf:/etc/nginx/nginx.conf
#日志目錄掛載
- /home/lnmp/nginx/log:/var/log/nginx
volumes:
db_data: {}
networks:
lnmp:
再次啟動
可以看到啟動和訪問都沒問題
並且日志已經有了
配置nginx 將請求轉發給php-fpm 容器處理
在上面我們已經mysql,php-fpm nginx 都配置好了,並且單獨可以正常運行,php 連mysql也已經可以了,但是nginx 怎么將請求轉發給php-fpm容器處理呢(其實就是設置代理),現在我們來配置
官網參考:
http://nginx.org/en/docs/beginners_guide.html#fastcgi
仔細看官方給出的配置里面有句
include /etc/nginx/conf.d/*.conf;
說明還加載這個路徑的配置,我們進去看看這個里面有啥、
進去之后,發現只有一個配置文件,看看里面是啥
文件內容
server {
listen 80;
listen [::]:80;
server_name localhost;
#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 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
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# 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;
#}
}
原來是代理配置,這個代理配置可以寫到nginx的主配置文件中,但現在官方將代理配置分離出來之后在主配置文件中引入了,那我們也遵循這個配置先將這個目錄復制出來然后通過容器卷掛載,方便后面的修改
復制容器的內的代理配置
例
docker cp 65c71c175277:/etc/nginx/conf.d /home/lnmp/nginx
掛載代理配置
上面將代理配置已經復制出來了,現在就修改yaml的掛載了
例:
version: '3.1'
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
#ports:
# - 3306:3306
networks:
- lnmp
environment:
MYSQL_ROOT_PASSWORD: root
php-fpm:
#使用php 7.3-fpm鏡像構建
#改用dockerfile安裝擴展
#image: php:7.3-fpm
#dockerfile方式配置
build:
#上下文環境,從哪里開始構建
context: .
#yaml同級目錄下的php7.3_fpm_dockerfile文件
dockerfile: php7.3_fpm_dockerfile
#設置依賴
depends_on:
- db
restart: always
#掛載卷
volumes:
#設置代碼目錄
- ./code:/code
#配置網絡
networks:
- lnmp
#ngnix配置
web:
#使用1.19.6鏡像
image: nginx:1.19.6
#映射端口
ports:
- 80:80
depends_on:
- php-fpm
restart: always
#設置網絡
networks:
- lnmp
#設置掛載
volumes:
#主配置文件掛載
- /home/lnmp/nginx/nginx.conf:/etc/nginx/nginx.conf
#其他配置目錄掛載
- /home/lnmp/nginx/conf.d:/etc/nginx/conf.d
#日志目錄掛載
- /home/lnmp/nginx/log:/var/log/nginx
volumes:
db_data: {}
networks:
lnmp:
測試:
修改宿主機配置,看容器內會不會同步,如圖創建一個文件,容器內同步出現,說明沒問題
修改代理配置
上面已經將代理配置掛載到了宿主機,現在我們直接在宿主機修改就好
在/nginx/conf.d/default.conf
加入下面的配置,我們先使用上面的例子配置,稍作修改
官方例子
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
添加
location ~ \.php$ {
#代碼目錄
root /code;
#修改為phpfpm容器
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
nginx服務 掛載代碼目錄,測試
上面已經將php的nginx代理設置好了,現在將我們在上面寫的簡單代碼目錄掛載到容器的/code
目錄(代理設置的也是這個目錄),然后訪問測試
設置代碼目錄掛載后的yaml
version: '3.1'
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
#ports:
# - 3306:3306
networks:
- lnmp
environment:
MYSQL_ROOT_PASSWORD: root
php-fpm:
#使用php 7.3-fpm鏡像構建
#改用dockerfile安裝擴展
#image: php:7.3-fpm
#dockerfile方式配置
build:
#上下文環境,從哪里開始構建
context: .
#yaml同級目錄下的php7.3_fpm_dockerfile文件
dockerfile: php7.3_fpm_dockerfile
#設置依賴
depends_on:
- db
restart: always
#掛載卷
volumes:
#設置代碼目錄
- ./code:/code
#配置網絡
networks:
- lnmp
#ngnix配置
web:
#使用1.19.6鏡像
image: nginx:1.19.6
#映射端口
ports:
- 80:80
depends_on:
- php-fpm
restart: always
#設置網絡
networks:
- lnmp
#設置掛載
volumes:
#主配置文件掛載
- /home/lnmp/nginx/nginx.conf:/etc/nginx/nginx.conf
#其他配置目錄掛載
- /home/lnmp/nginx/conf.d:/etc/nginx/conf.d
#日志目錄掛載
- /home/lnmp/nginx/log:/var/log/nginx
#代碼目錄掛載
- /home/lnmp/code:/code
volumes:
db_data: {}
networks:
lnmp:
重啟啟動測試
訪問test.php
訪問不了,這是為什么的
使用$document_root,配置代碼根目錄
上面訪問不了是因為沒有配置代碼根目錄,參考
http://nginx.org/en/docs/beginners_guide.html#fastcgi
修改/nginx/conf.d/default.conf
加入配置,為如下
location ~ \.php$ {
#代碼目錄
root /code;
#修改為phpfpm容器
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
#在瀏覽器中訪問的.php文件,實際讀取的是 $document_root(網站root根目錄)下的.php文件
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
重啟訪問
配置默認加載index.php
沒有配置之前不會自動加載index.php
參考這個配置
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
#配置代碼根目錄
root /code;
location / {
#注釋默認配置
#root /usr/share/nginx/html;
#index index.html index.htm;
#加入index.php
index index.html index.htm index.php;
}
#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
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
location ~ \.php$ {
#修改為phpfpm容器
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
#在瀏覽器中訪問的.php文件,實際讀取的是 $document_root(網站root根目錄)下的.php文件
fastcgi_param SCRIPT_FILENAME $document_root$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;
#}
}
重啟,訪問測試
配置支持PATH_INFO
PS:Nginx(PHP/fastcgi)的PATHINFO配置
PATHINFO是一個CGI 1.1的標准,經常用來做為傳參載體,在Apache中, 當不加配置的時候, 對於PHP腳本, AcceptPathInfo是默認接受的,而對於Nginx下, 是不支持PATHINFO 的, 也就是需要設置才能使用PATHINFO模式.
我們可以使用PATH_INFO來代替Rewrite來實現偽靜態頁面, 很多PHP框架也使用PATHINFO模式來作為路由載體
在location ~ \.php$
的配置項中加入
參考:
http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_split_path_info
fastcgi_split_path_info所在的行,正則表達式具有兩個捕獲: 第一個捕獲成為fastcgi_script_name變量的值,第二個捕獲成為變量fastcgi_path_info的值。
例如/show.php/article/0001請求:
SCRIPT_FILENAME 參數將等於"/show.php"
PATH_INFO 參數將等於"/article/0001".
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
配置偽靜態
偽靜態是為了去掉index.php這個
在 location /
中加入配置
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php/$1 last;
}
參考代理配置
/nginx/conf.d/default.conf
文件
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
#配置代碼根目錄
root /code;
location / {
#注釋默認配置
#root /usr/share/nginx/html;
#index index.html index.htm;
#加入index.php
index index.html index.htm index.php;
#偽靜態配置
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php/$1 last;
}
}
#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
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
location ~ \.php$ {
#修改為phpfpm容器
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
#path_info 支持配置
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
#在瀏覽器中訪問的.php文件,實際讀取的是 $document_root(網站root根目錄)下的.php文件
fastcgi_param SCRIPT_FILENAME $document_root$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;
#}
}
lnmp配置總結
經過上面的一系列配置,現在已經符合我們的基本需求
現在我們總結一下,各個配置文件
目錄結構
根目錄lnmp
├── code #代碼目錄,下面都是簡單的測試代碼
│ ├── index.php
│ ├── test_mysql.php
│ └── test.php
├── docker-compose.yml #docker-compose yaml配置文件
├── nginx #nginx掛載配置目錄
│ ├── conf.d #nginx 其他配置目錄
│ │ └── default.conf
│ ├── log #nginx log目錄
│ │ ├── access.log
│ │ └── error.log
│ └── nginx.conf #nginx 主配置文件
├── nginx.conf #參考的備份
└── php7.3_fpm_dockerfile #php7.3_fpm 構建自定義鏡像的dockerfile
優化點
關於docker-compose.yml
文件配置可以優化的點
- php-fpm的掛載可以注釋了,中間已經測試完畢了
- nginx掛載的目錄宿主機地址可以改為相對地址,更方便
- 配置文件,代碼目錄等掛載改成只讀防止容器內改變內容
docker-compose 掛載參考
https://www.cnblogs.com/makalochen/p/14266075.html#volumes
原本我想的是php-fpm掛載可以取消,經過測試發現,不能取消,原因是nginx實際做的是轉發,轉發給php容器執行所以php容器還是需要掛載代碼目錄並且目錄要一致
下面為優化后的yaml
version: '3.1'
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
#ports:
# - 3306:3306
networks:
- lnmp
environment:
MYSQL_ROOT_PASSWORD: root
php-fpm:
#使用php 7.3-fpm鏡像構建
#改用dockerfile安裝擴展
#image: php:7.3-fpm
#dockerfile方式配置
build:
#上下文環境,從哪里開始構建
context: .
#yaml同級目錄下的php7.3_fpm_dockerfile文件
dockerfile: php7.3_fpm_dockerfile
#設置依賴
depends_on:
- db
restart: always
#掛載卷
volumes:
#設置代碼目錄
- ./code:/code:ro
#配置網絡
networks:
- lnmp
#ngnix配置
web:
#使用1.19.6鏡像
image: nginx:1.19.6
#映射端口
ports:
- 80:80
depends_on:
- php-fpm
restart: always
#設置網絡
networks:
- lnmp
#設置掛載
volumes:
#主配置文件掛載
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
#其他配置目錄掛載
- ./nginx/conf.d:/etc/nginx/conf.d:ro
#日志目錄掛載
- ./nginx/log:/var/log/nginx
#代碼目錄掛載
- ./code:/code:ro
volumes:
db_data: {}
networks:
lnmp:
所有的配置文件
php-fpm鏡像構建dockerfile
php7.3_fpm_dockerfile
FROM php:7.3-fpm
RUN docker-php-ext-install pdo pdo_mysql
nginx
主配置文件
./nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
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;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
代理配置文件配置
./nginx/conf.d/default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
#配置代碼根目錄
root /code;
location / {
#注釋默認配置
#root /usr/share/nginx/html;
#index index.html index.htm;
#加入index.php
index index.html index.htm index.php;
#偽靜態配置
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php/$1 last;
}
}
#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
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
location ~ \.php$ {
#修改為phpfpm容器
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
#path_info 支持配置
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
#在瀏覽器中訪問的.php文件,實際讀取的是 $document_root(網站root根目錄)下的.php文件
fastcgi_param SCRIPT_FILENAME $document_root$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-compose 核心yaml
version: '3.1'
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
#ports:
# - 3306:3306
networks:
- lnmp
environment:
MYSQL_ROOT_PASSWORD: root
php-fpm:
#使用php 7.3-fpm鏡像構建
#改用dockerfile安裝擴展
#image: php:7.3-fpm
#dockerfile方式配置
build:
#上下文環境,從哪里開始構建
context: .
#yaml同級目錄下的php7.3_fpm_dockerfile文件
dockerfile: php7.3_fpm_dockerfile
#設置依賴
depends_on:
- db
restart: always
#掛載卷
volumes:
#設置代碼目錄
- ./code:/code:ro
#配置網絡
networks:
- lnmp
#ngnix配置
web:
#使用1.19.6鏡像
image: nginx:1.19.6
#映射端口
ports:
- 80:80
depends_on:
- php-fpm
restart: always
#設置網絡
networks:
- lnmp
#設置掛載
volumes:
#主配置文件掛載
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
#其他配置目錄掛載
- ./nginx/conf.d:/etc/nginx/conf.d:ro
#日志目錄掛載
- ./nginx/log:/var/log/nginx
#代碼目錄掛載
- ./code:/code:ro
volumes:
db_data: {}
networks:
lnmp:
項目部署
這里用我寫的一個小項目
項目地址:
https://gitee.com/makalochen/think-php5.1_vue2.x_-base-admin
構建自定義php-fpm容器鏡像加入phpcomposer[選看]
注意:一般來說不會在dockefile 中composer,代碼提交后就包含擴展庫,如果實在要安裝可以參考
但是在這個項目中用到了composer和數據遷移,也就是說要:
- 安裝composer
- 配置鏡像源
- 安裝擴展
- 執行數據遷移
安裝composer
https://pkg.phpcomposer.com/#how-to-install-composer
https://docs.phpcomposer.com/00-intro.html
php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
配置鏡像源
https://pkg.phpcomposer.com/#how-to-use-packagist-mirror
https://www.cnblogs.com/makalochen/p/12924054.html#切換composer鏡像為國內鏡像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
安裝擴展
composer install
執行數據遷移
php think migrate:run
我們將上面的php7.3_fpm_dockerfile
修改下,按照上面的步驟執行
注意:很大可能失敗,因為網絡的原因
先將之前的鏡像刪除
docker rmi -f $(docker images -qa)
構建鏡像
docker build -f php7.3_fpm_dockerfile -t test .
復制項目代碼到掛載目錄,並配置好數據庫連接
例:
配置數據庫連接,你就需要創建個數據庫,這里可以使用
mysql環境變量
MYSQL_DATABASE
此變量是可選的,允許您指定在映像啟動時要創建的數據庫的名稱。如果提供了用戶名/密碼(請參閱下文),則將授予該用戶對該數據庫的超級用戶訪問權限(對應於
GRANT ALL
)。
例:
#初始化數據庫
MYSQL_DATABASE: makalo
此時的yaml
version: '3.1'
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
#ports:
# - 3306:3306
networks:
- lnmp
environment:
MYSQL_ROOT_PASSWORD: root
#初始化數據庫
MYSQL_DATABASE: makalo
php-fpm:
#使用php 7.3-fpm鏡像構建
#改用dockerfile安裝擴展
#image: php:7.3-fpm
#dockerfile方式配置
build:
#上下文環境,從哪里開始構建
context: .
#yaml同級目錄下的php7.3_fpm_dockerfile文件
dockerfile: php7.3_fpm_dockerfile
#設置依賴
depends_on:
- db
restart: always
#掛載卷
volumes:
#設置代碼目錄
- ./code:/code:ro
#配置網絡
networks:
- lnmp
#ngnix配置
web:
#使用1.19.6鏡像
image: nginx:1.19.6
#映射端口
ports:
- 80:80
depends_on:
- php-fpm
restart: always
#設置網絡
networks:
- lnmp
#設置掛載
volumes:
#主配置文件掛載
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
#其他配置目錄掛載
- ./nginx/conf.d:/etc/nginx/conf.d:ro
#日志目錄掛載
- ./nginx/log:/var/log/nginx
#代碼目錄掛載
- ./code:/code:ro
volumes:
db_data: {}
networks:
lnmp:
配置數據庫連接
修改根目錄到public
修改./nginx/conf.d/default.conf
文件為如下內容
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
#配置代碼根目錄
root /code/public;
location / {
#注釋默認配置
#root /usr/share/nginx/html;
#index index.html index.htm;
#加入index.php
index index.html index.htm index.php;
#偽靜態配置
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php/$1 last;
}
}
#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
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
location ~ \.php$ {
#修改為phpfpm容器
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
#path_info 支持配置
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
#在瀏覽器中訪問的.php文件,實際讀取的是 $document_root(網站root根目錄)下的.php文件
fastcgi_param SCRIPT_FILENAME $document_root$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-compose up
進入容器
docker exec -it 909b86117c59 /bin/bash
進入目錄
cd /code
執行遷移
注意:代碼目錄需要可讀寫並且配置好數據庫參數
php think migrate:run
此時的表
啟動測試
啟動之前先將之前的鏡像和容器全部刪掉
docker rm -f $(docker ps -qa)
docker rmi -f $(docker images -qa)
啟動測試
docker-compose up
正常
此時的yaml
version: '3.1'
services:
db:
image: mysql:5.7
#表示支持外部訪問
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- db_data:/var/lib/mysql
#映射到宿主機的端口,測試使用,測試完畢,請注釋
ports:
- 3306:3306
networks:
- lnmp
environment:
MYSQL_ROOT_PASSWORD: root
#初始化數據庫
MYSQL_DATABASE: makalo
php-fpm:
#使用php 7.3-fpm鏡像構建
#改用dockerfile安裝擴展
#image: php:7.3-fpm
#dockerfile方式配置
build:
#上下文環境,從哪里開始構建
context: .
#yaml同級目錄下的php7.3_fpm_dockerfile文件
dockerfile: php7.3_fpm_dockerfile
#設置依賴
depends_on:
- db
restart: always
#掛載卷
volumes:
#設置代碼目錄
- ./code:/code
#配置網絡
networks:
- lnmp
#ngnix配置
web:
#使用1.19.6鏡像
image: nginx:1.19.6
#映射端口
ports:
- 80:80
depends_on:
- php-fpm
restart: always
#設置網絡
networks:
- lnmp
#設置掛載
volumes:
#主配置文件掛載
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
#其他配置目錄掛載
- ./nginx/conf.d:/etc/nginx/conf.d:ro
#日志目錄掛載
- ./nginx/log:/var/log/nginx
#代碼目錄掛載
- ./code:/code
volumes:
db_data: {}
networks:
lnmp:
總結
在上面lnmp環境要做如下修改
- 代碼復制到掛載目錄需要修改數據庫配置文件
- 需修改nginx的代理配置文件的
root
參數到 項目的pubilc
目錄 - 如果有數據遷移需手動進入php-fpm容器執行遷移,不推薦自動