Docker 重要性不用多作解釋,咱們每天吵着雲原生,最重要的一門技術,你是否掌握了呢?從今天,一塊兒來Docker吧!php
一、利用 docker-compose
編排一個PHP開發環境;
二、PHP
常見擴展安裝;
三、Nginx
php-fpm
Mysql
Redis
等容器互聯;
四、PHP
程序可以操做 Mysql
Redis
;
二、蒐集相關日誌便於排查;html
一、操做系統:Ubuntu
二、編輯器:VSCode
三、Docker
四、Docker Compose 官方文檔
五、Compose 中文手冊
六、若是Docker鏡像拉取慢,能夠嘗試這個 www.daocloud.io/mirrormysql
確保 Docker 和 Docker Compose 已安裝好
好比linux
docker -v Docker version 19.03.1, build 74b1e89nginx
docker-compose -v docker-compose version 1.17.1, build 6d101fbgit
docker-compose.yml
文件在你的文件夾中新增這個文件,這是咱們編排的模板文件,格式以下github
version: '3'
services:
php-workspace:
image: php:7.3-fpm-alpine
nginx:
image: nginx:alpine
複製代碼
注意點:
一、模板中定義的 version 字段聲明瞭模板的格式和支持聲明字段,3 是目前比較推薦也用的比較多的的版本
二、注意 key 的層級和空格,咱們可使用命令 docker-compose config
命令檢查格式是否正確
三、使用 VSCode
方便的一點是能夠看到能夠代碼能夠根據層級摺疊
redis
docker-compose up --build
構建鏡像並啓動容器sql
這時能看到有兩個已經在運行的容器和鏡像
docker
剛剛啓動的容器可使用 docker-compose down
來關閉項目,還會自動刪除容器。
如今,咱們要指定端口讓 Nginx 能處理請求,能夠參考 Compose 中文手冊的模板文件的語法。
指定宿主機端口和容器端口的映射關係,以下;
version: '3'
services:
php-workspace:
image: php:7.3-fpm-alpine
nginx:
image: nginx:alpine
ports:
- "8080:8080"
複製代碼
docker-compose up
去瀏覽器請求 localhost:8080
Attach Shell
就能快速進入容器,咱們進入容器就能看到內部狀況,好比,nginx 的www目錄和配置目錄,php-fpm 的默認配置等等。
新增文件 nginx/conf.d/site.conf
文件,內容以下,下面的思路也能夠參考上篇《利用Docker搭建PHP開發環境》作法。
server {
listen 8080;
root /usr/share/nginx/html;
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
location ~ \.php$ {
root /var/www/html; # 這裏指向的php容器的項目根目錄
fastcgi_pass php-workspace:9000; #php-workspace是模板文件中的php-fpm服務名
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
複製代碼
docker-compose.yml
文件讓 nginx 和 php-fpm 服務基於Dockerfile 構建
version: '3'
services:
php-workspace:
build: ./php # 這裏php指咱們的建立的目錄
nginx:
build: ./nginx # 這裏nginx指咱們的建立的目錄
ports:
- "8080:8080"
複製代碼
nginx/Dockerfile
文件FROM nginx:alpine
COPY conf.d /etc/nginx/conf.d 複製代碼
php/Dockerfile
文件FROM php:7.3-fpm-alpine
複製代碼
<?php
phpinfo();
複製代碼
docker-compose.yml
文件讓項目文件夾以掛載的形式,讓php-fpm容器能夠直接讀取宿主機文件目錄,這樣咱們能夠很方便的修改代碼調試
version: '3'
services:
php-workspace:
build: ./php
volumes: # 這裏指定數據卷,能夠指定多個, 中劃線表明值爲數組的一個成員
- ./code:/var/www/html
nginx:
build: ./nginx #這裏nginx指咱們的建立的目錄
ports:
- "8080:8080"
複製代碼
重啓以前,再肯定下代碼文件大概位置
docker-compose up --build
從新啓動項目,咱們看到在前臺控制器的一些日誌
localhost:8080
,還能看到nginx的請求日誌
用法咱們依然參考了鏡像的介紹 >> hub.docker.com/_/mysql
version: '3'
services:
php-workspace:
build: ./php
volumes:
- ./code:/var/www/html
nginx:
build: ./nginx
ports:
- "8080:8080"
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment: # 設定環境變量,只給定名稱的變量會自動獲取運行 Compose 主機上對應變量的值
MYSQL_ROOT_PASSWORD: root
複製代碼
docker-compose up --build
VSCode
容器管理中右鍵鏈接shell中進入容器執行
mysql -u root -p
,確認密碼
root
,肯定咱們的數據庫可用
在操做以前咱們肯定下pdo是不支持mysql驅動的
Dockerfile
文件以下
FROM php:7.3-fpm-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories \ && docker-php-ext-install pdo_mysql
複製代碼
從新構建項目 docker-compose up --build
<?php
$dsn = 'mysql:host=db;port=3306'; // host=db,這裏的db實際上是mysql的服務名
$user = 'root';
$password = 'root';
try {
$dbh = new PDO($dsn, $user, $password);
print_r($dbh);
} catch (PDOException $e) {
echo 'Connection failed: '.$e->getMessage();
}
複製代碼
在Docker Hub 中 php鏡像文檔中說的很清楚
version: '3'
services:
php-workspace:
build: ./php
volumes:
- ./code:/var/www/html
nginx:
build: ./nginx
ports:
- "8080:8080"
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
redis:
image: redis:5.0.5-alpine
複製代碼
docker-compose up --build
構建後,咱們一樣能夠進入容器,使用 redis-cli 命令肯定redis是否可用
由於pecl在alpine容器中安裝擴展會少一些東西,因此咱們先安裝了一個phpize_deps,用後刪除便可,保持鏡像瘦小
FROM php:7.3-fpm-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories \ && docker-php-ext-install pdo_mysql \
&& apk add ${PHPIZE_DEPS} \ && pecl install redis-4.0.1 \ && docker-php-ext-enable redis \ && apk del ${PHPIZE_DEPS}
複製代碼
從新構建,咱們修改index.php 代碼 phpinfo();能看到 redis擴展已打開
修改 index.php
文件內容以下測試
<?php
$redis = new Redis();
$redis->pconnect('redis', 6379);
$key = 'first';
$redis->incr($key);
echo '頁面瀏覽了:'.$redis->get($key); die;
複製代碼
咱們回顧一下 nginx/conf.d/site.conf
的配置
server {
listen 8080;
root /usr/share/nginx/html;
index index.php index.html;
server_name localhost;
# 咱們已經把nginx相關日誌寫到這裏了,如何放到宿主機呢?
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
# ... more something
}
複製代碼
docker日誌採集當然有不少方案,可是暫時不考慮集羣管理工具的日誌蒐集方案,這裏以數據掛載的形式,把 nginx 請求日誌落地到宿主機。
docker-compose.yml
文件以下version: '3'
services:
php-workspace:
build: ./php
volumes:
- ./code:/var/www/html
nginx:
build: ./nginx
volumes: # 新增這兩行
- ./log/nginx:/var/log/nginx/
ports:
- "8080:8080"
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
redis:
image: redis:5.0.5-alpine
複製代碼
docker-compose up
執行後,就能夠看到咱們的文件夾多了兩個目錄,還有兩個文件
能夠指定依賴項,解決容器啓動前後問題,好比一個應用若是依賴數據庫,要讓數據庫容器先啓動能夠設置
depends_on:
- db
- redis
複製代碼
固然其實還有其餘不少有用的參數設置,好比感敏數據讀取,環境變量,配置host等等,後續均可以在開發中嘗試使用。
以上思路能夠解決本地開發中的不少問題了,若是項目中有使用 memcached 或者其餘應用,作法均可以參考Docker Hub中的鏡像文檔說明中引入。
除此以外,在Laravel 開發中以前早就有一個開源項目叫作 Laradock
來搭建Docker化的PHP應用,不只如此,還有不少中間件均可以利用 docker-compose 啓動,能夠參看 >> laradock.io/ ,可是裏邊有不少不少東西,由於要知足大部分人的擴展性,加了不少環境變量,if else 判斷,讓本來的 Dockerfile 更爲複雜,增長了不少邏輯。可是思路基本上是相同的。
另外還有幾點要點出:
一、docker-compose.yml 定義的一個項目會以所在的文件夾名爲項目名。
二、一個項目有一個默認網絡,項目中的服務彼此能夠互通,因此咱們剛剛在 site.conf 轉發php請求能夠直接用 php-workspace:9000 服務名來轉發,鏈接 數據庫也是能夠用 db redis 等他們的服務名來鏈接。
一、指定數據庫掛載的數據卷,好比Mysql,咱們能夠把其餘環境的數據庫直接以文件的形式拷貝,而後直接利用。這樣比咱們手動導入sql會更快遷移數據。
二、Mysql 鏡像如何瘦身,如今Mysql鏡像文件最大,如圖有445M
其實PHP的Docker環境已經有一個開源項目 Laradock,使用方便 易於擴展,可是最大的問題是 感受臃腫 有時候安裝特別慢,特別是要考慮太多擴展插件等等製做出來鏡像特別大。因此下一篇的思路可能會圍繞如何優化今天作的這個 demo-docker-compose,或者作 Laradock 本地化工做?
其餘兩個思路:
一、直接進入到 k8s 課題
二、Docker化後如何作CI/CD