docker compose thinkphp5.1 lnmp環境搭建加項目部署全過程

環境

  • 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

啓動完成

image-20210112171453044

測試連接

隨便用個連接工具連接測試

image-20210112172734586

如圖連接成功,之後就可以把端口映射註釋掉,爲了安全考慮

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

image-20210112185817102

可以看到默認的擴展列表中已經支持這兩個擴展,所以我們無需再去安裝

上面將當前目錄下的code目錄掛載到了容器內/code目錄

我們寫幾個簡單的測試一下

寫上兩個php

image-20210113161640022

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

執行結果

image-20210113162852987

可以看到連接mysql失敗了,提示沒有驅動,那我們就需要將yaml加點東西,安裝php的pdo-mysql驅動

關於php fpm 缺少pdo-mysql驅動問題的解決辦法

推薦使用方式二

方式一

進入容器,執行

docker exec -it d5d0509878fb /bin/bash
#安裝pdo_mysql擴展
docker-php-ext-install pdo pdo_mysql

再次執行測試連接

image-20210113165340054

可以看到連接沒問題,但是這種方式,還要進入容器,比較麻煩

方式二

使用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

重構後的鏡像

第一個爲重構後的鏡像,下面是原鏡像

image-20210113175033328

再次執行測試連接

image-20210113165340054

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:

訪問

image-20210113185717964

關於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這個位置

我們進入容器看下

image-20210114102520183

可以看到文件內容如下

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 目錄,那就將剛纔複製出來的配置文件拷貝到該目錄

image-20210114111721697

注意:不能掛載文件,只能掛載文件夾

此時的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:

再次啓動

可以看到啓動和訪問都沒問題

image-20210114112326486

並且日誌已經有了

image-20210114112401958

配置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;

說明還加載這個路徑的配置,我們進去看看這個裏面有啥、

image-20210115110929952

進去之後,發現只有一個配置文件,看看裏面是啥

文件內容

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

image-20210115112334207

掛載代理配置

上面將代理配置已經複製出來了,現在就修改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:

測試:

修改宿主機配置,看容器內會不會同步,如圖創建一個文件,容器內同步出現,說明沒問題

image-20210115113155013

修改代理配置

上面已經將代理配置掛載到了宿主機,現在我們直接在宿主機修改就好

/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;
}

image-20210115134930551

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

image-20210115134825908

訪問不了,這是爲什麼的

使用$document_root,配置代碼根目錄

上面訪問不了是因爲沒有配置代碼根目錄,參考

http://nginx.org/en/docs/beginners_guide.html#fastcgi

image-20210115140249820

修改/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;
	}

重啓訪問

image-20210115140833450

image-20210115140855743

配置默認加載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;
    #}
}

重啓,訪問測試

image-20210115142019413

配置支持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 .

複製項目代碼到掛載目錄,並配置好數據庫連接

例:

image-20210115171658070

配置數據庫連接,你就需要創建個數據庫,這裏可以使用

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:

配置數據庫連接

image-20210115173029592

修改根目錄到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

image-20210115192902850

此時的表

image-20210115192957841

啓動測試

啓動之前先將之前的鏡像和容器全部刪掉

docker rm -f $(docker ps -qa)
docker rmi -f $(docker images -qa)

啓動測試

docker-compose up

image-20210115193053023

image-20210115193110732

正常

此時的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容器執行遷移,不推薦自動
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章