docker nginx 多站台多版本php開發環境
關於docker容器化的開發環境之前已經有多篇說明
使用laradock的方式 : laradock : laravel專案容器化開發實作
自建php5.6 docker image : docker 容器化 : PHP5.6專案容器化開發實作
自建ubuntu php7.3 for laravel : [作品][docker image]ubuntu18.04-php7.3-apache-for-laravel
今天要說明的是將以上幾件事情整合,透過docker compose 將容器整合並且降低附載資源
參考資料 :
https://learnku.com/laravel/t/10292/how-do-i-access-multiple-laravel-projects-under-localhost
https://gist.github.com/noeldiaz/08a1211a7c47f21f7083
好的,參考資料列出後接下來要說明一下本篇文章架構出來的開發環境與上述先前文章時做的有哪些不同
首先,之前的做法是透過不同PHP環境需求開啟多組docker,以及不同MySQL版本需求開啟多個不同版本的MySQL
而這次,則是透過docker compose 撰寫yml檔案來控制多組docker打開與關閉,另外,本次也更新的laravel以及PHP5.6的image環境
透過PHP7.3-fpm以及PHP5.6-fpm兩個兩個docker image提供純PHP環境,而伺服器的部分則是統一透過一台NginX提供服務,不再是不同環境開啟多台Apache伺服器,降低系統所需要的資源
文件結構
1 2 3 4 5 6 7 8 9 10 11 |
dev_compose +.env +docker-compose.yml nginx conf.d +default.conf +Dockerfile php56 +Dockerfile php73_laravel +Dockerfile |
dev_compose 資料夾存放docker-compose.yml用來描述docker compose 如何開啟多組docker container,而.env則是用來儲存會需要用的路徑參數
nginx 資料夾提供一個Dockerfile用來描述nginx image如何build以及一個default.conf作為nginx的設定檔掛載進入container環境中
php56以及php73_laravel分別提供php5.6以及php7.3所需要的Dockerfile即可
另外,MySQL5.6以及MySQL5.7沒有特別描述,只有拉取docker hub上相對應的版本即可,所以不用任何Dockerfile描述檔
接著,我們一個環境一個環境來看
php73_laravel
主要透過php:7.3-fpm image,再另外安裝其他我們需要的套件進去即可,Dockerfile可以參考如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
FROM php:7.3-fpm RUN apt-get update && apt-get install -yq libzip-dev zip git libfreetype6-dev \ libjpeg62-turbo-dev \ libmcrypt-dev \ libssl-dev \ libmemcached-dev \ libz-dev \ zlib1g-dev \ libsqlite3-dev \ libxml2-dev \ libcurl3-dev \ libedit-dev \ libpspell-dev \ libldap2-dev \ unixodbc-dev \ libpq-dev \ wget \ git \ vim \ nano \ sudo \ cron \ net-tools \ iputils-ping \ procps \ nodejs \ npm # composer RUN curl -sS https://getcomposer.org/installer | php RUN mv composer.phar /usr/local/bin/composer #docker ext RUN docker-php-ext-configure zip --with-libzip RUN docker-php-ext-install mysqli pdo pdo_mysql zip mbstring tokenizer pcntl soap RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install gd RUN pecl install memcached \ && docker-php-ext-enable memcached #timeZone ENV TZ=Asia/Taipei RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone # nvm node npm RUN rm /bin/sh && ln -s /bin/bash /bin/sh RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.35.2/install.sh | bash ENV NVM_DIR /root/.nvm ENV NODE_VERSION v12.14.0 RUN /bin/sh -c ". ~/.bashrc" RUN . $NVM_DIR/nvm.sh \ && nvm install $NODE_VERSION \ && nvm alias default $NODE_VERSION \ && nvm use default |
php56
與php7.3項同,主要透過php5.6-fpm在安裝其他需要的套件,Dockerfile如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
FROM php:5.6-fpm RUN apt-get update && apt-get install -y libzip-dev zip git libfreetype6-dev \ libjpeg62-turbo-dev \ libmcrypt-dev \ libssl-dev \ libmemcached-dev \ libz-dev \ zlib1g-dev \ libsqlite3-dev \ libxml2-dev \ libcurl3-dev \ libedit-dev \ libpspell-dev \ libldap2-dev \ unixodbc-dev \ libpq-dev \ wget \ vim \ nano RUN apt-get install -y libzip-dev zip RUN docker-php-ext-configure zip --with-libzip RUN docker-php-ext-install mysqli pdo pdo_mysql mysql zip |
nginx
nginx相對複雜一些,透過Dockerfile抓取nginx:1.17.7版本,並且安裝vim以及nano
1 2 3 |
FROM nginx:1.17.7 RUN apt-get update && apt-get install -y vim nano |
default.conf用來描述nginx需要啟動多少個伺服器,以及port號,還有相對應要處理PHP的位置,詳細說明直接參考註解即可
80port 用於laravel開發,8800port則用於php5.6舊專案的維護,值得一提的是如何在80port中透過不同的專案路徑來瀏覽不同的laravel專安是本次花最多時間鑽研的項目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
server {#80port伺服器,給laravel專案使用 listen 80 default_server; server_name _; root /var/project/laravel;#nginx的預設根目錄是/var/project/ 我將laravel專案放在預設根目錄的laravel資料夾 index index.html index.htm index.php; charset utf-8; location / { try_files $uri $uri/ /index.php?$query_string; } location ^~ /PROJECT1_NAME/ {#第一個project位置,如果有多個project請複製填寫此區塊並且填入相對其他專案的路徑名稱 : PROJECT1_NAME為專案路徑名稱 alias /var/project/laravel/PROJECT1_NAME/public/;#給定路徑到專案資料匣底下的public資料夾,這樣網址就可以不必打"public" try_files $uri $uri/ @PROJECT1_NAME; location ~\.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php73_laravel:9000; #php73_laravel為處理php的docker container名稱,這部分會在docker compose 的yml檔中描述出現 fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /var/project/laravel/PROJECT1_NAME/public/index.php; #把SCRIPT_FILENAME直接設定到專案public資料夾底下的index.php fastcgi_param DB_HOST mysql57; #給定DB_HOST參數為mysql57,mysql57同樣為docker container名稱 } } location @PROJECT1_NAME {#每個專案要獨立設定rewrite路徑,指定到專案資料夾底下的index.php rewrite /PROJECT1_NAME/(.*)$ /PROJECT1_NAME/index.php?/$1 last; } #記錄檔位置,會在docker compose yml描述中將檔案映射到本機資料夾方便查看 access_log /var/log/nginx/access.log error_log /var/log/nginx/error.log; error_page 404 /index.php; sendfile off; location ~\.php$ { #描述如果非子資料夾下的php檔如何處理,當然還是丟給php73_laraavel fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php73_laravel:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param DB_HOST mysql57; } location ~ /\.ht { deny all; } client_max_body_size 120M; } server {#8800port伺服器,保留給php5.6專案使用 listen 8800 default_server; server_name _; root /var/project/php;#伺服器根目錄指定到/var/project/php中 index index.html index.htm index.php; charset utf-8; location / { try_files $uri $uri/ /index.php?$query_string; } access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; error_page 404 /index.php; sendfile off; location ~\.php$ {#php5.6專案,php執行的方式將交由php56 docker container來負責 fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php56:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param DB_HOST mysql56; } location ~ /\.ht { deny all; } client_max_body_size 120M; } |
dev_compose
.env將儲存yml檔案中需要用到的參數
1 2 3 |
STORAGE_PATH=專案資料路徑(我這邊放lravel專案與php5.6專案資料夾的上層) LOG_PATH=掛載錯誤資訊的資料夾 MYSQL_ROOT_PASSWORD=MySQL資料庫預設密碼 |
docker-compose.yml 將是本次的重點,如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
version: "3.3" services: php73_laravel: container_name: php73_laravel build: ../php73_laravel/ restart: unless-stopped volumes: - "${STORAGE_PATH}:/var/project" depends_on: - mysql57 networks: - dev php56: container_name: php56 build: ../php56/ restart: unless-stopped volumes: - "${STORAGE_PATH}:/var/project" depends_on: - mysql56 networks: - dev mysql57: container_name: mysql57 image: mysql:5.7 restart: unless-stopped environment: - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} ports: - 3306:3306 volumes: - mysql57-data:/var/lib/mysql networks: - dev mysql56: container_name: mysql56 image: mysql:5.6 restart: unless-stopped environment: - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} ports: - 3307:3306 volumes: - mysql56-data:/var/lib/mysql networks: - dev nginx: container_name: nginx build: ../nginx restart: unless-stopped ports: - 80:80 - 8800:8800 volumes: - "${STORAGE_PATH}:/var/project" - "${LOG_PATH}:/var/log/nginx" - ../nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf networks: - dev networks: dev: volumes: mysql57-data: mysql56-data: |
抓重點 :
這次總共開啟php73_laravel php56 mysql56 mysql57 nginx 等五個container來使用
其中build參數,將是指定要用哪個路徑底下的Dockerfile來產生container,但是像mysql只要指定image就可以了
volumes參數如同docker run 中的-v,無論是php還是nginx都必須將${STORAGE_PATH}指定到/var/project
而我也將所有container network 設定為dev,讓所有container可以互通
最後volumes中指定mysql57-data mysql56-data 兩者用於儲存資料庫檔案,避免container關閉後資料遺失
最後,完成後使用 docker compose up -d 及可以將所有container全部開啟,docker compose down 可以全部關閉
當然第一次開啟的時候docker會自動透過build所有image
以上,打完收工!