原文來自 How to Manually Build Docker Containers for WordPressphp
前中本專欄已經介紹過 Docker 的基礎知識,本文開始進行 Docker 實戰:手動使用 Docker 構建 WordPress 容器。同時介紹一下 Docker 官方 MySQL 鏡像的爬坑方法,同時演示 Docker 生產中常見的問題以及解決辦法。html
在我之前的文章中,咱們已經介紹了 Docker 的基礎知識和基礎命令。固然,雖然咱們已經介紹了這些知識,咱們尚未使用它們作出有價值的東西。構建 WordPress 的 Docker 容器有多種方法,本文將會介紹手動構建容器。若是你尚未認識 Docker,能夠戳這裏。mysql
數據庫是 WordPress 的基礎,本文使用 Docker Hub 來獲取 MySQL 鏡像。sql
Docker 官方已經構建了 MySQL 鏡像。在使用 MySQL 鏡像以前,請先讀鏡像手冊。在寫本文時,鏡像的最新版本是 5.7。docker
按照一般的方法,使用 MySQL 鏡像的方法以下:數據庫
docker run --name wordpressdb -d mysql:5.7
執行這條命令的時候,若是本機沒有 MySQL 鏡像,那麼 Docker 會從 Docker Pull 先下載鏡像。使用 --name
參數指定容器運行時的名字,使用 -d
參數指定再後臺運行。apache
使用 docker ps
命令能夠發現,並無名叫 wordpressdb
的容器在後臺運行,可是不該該這樣啊。使用 docker logs wordpressdb
查看鏡像日誌:bash
error: database is uninitialized and MYSQL_ROOT_PASSWORD not set Did you forget to add -e MYSQL_ROOT_PASSWORD=... ?
那麼問題出在哪兒?架構
咱們運行了 MySQL,可是沒有指明數據庫的 root 密碼,因此容器並不能運行。因此爲了修正這個錯誤,咱們須要刪除容器 wordpressdb
,而後從新創建容器。Docker 不容許兩個容器使用相同的名字。ide
再次運行容器的時候咱們用 -e
參數指定容器內的環境變量MYSQL_ROOT_PASSWORD
:
docker run --name wordpressdb -e MYSQL_ROOT_PASSWORD=password -d mysql:5.7
再次運行 docker logs wordpressdb
的時候,咱們會看到很是長的信息。實際上 MySQL 容器已經在後臺運行了,運行 docker ps
也能夠看到正在運行的容器 wordpressdb
。
固然你也可使用 MYSQL_DATABASE
參數指定運行容器以前就建立名爲 wordpress
的數據庫:
docker run --name wordpressdb -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress -d mysql:5.7
固然,MySQL 數據庫還有其餘的參數,例如指定建立用戶和密碼。固然,更多的用法就須要參考他們 官方的文檔 了。
容器的 IP 會隨啓動而變化,須要使用 docker inspect --format='{{.NetworkSettings.IPAddress}}' wordpressdb
獲取容器的 IP。
固然,Dockerfile 中有不少的容器構建信息。MySQL 基於 debian wheezy 鏡像構建,而後啓動 mysqld
命令。當使用這個容器的時候,其實只啓動了 mysqld
命令。
如今咱們已經有了 MySQL 容器,用戶名 root
,密碼 password
,數據庫名稱 wordpress
。下一步就是構建 WordPress 了。
這一步咱們使用PHP 鏡像,PHP 鏡像鏡像也有不少,咱們使用官方提供的帶有 Apache 的 php 鏡像。
docker run --name wordpress php:5.6-apache
不加 -d
參數,容器便會在前臺運行,也能看到應該由 docker logs
輸出的數據。
使用 docker inspect --format='{{.NetworkSettings.IPAddress}}' wordpress
命令獲取 wordpress
容器的 IP。本文是 172.17.0.35
。
若是你直接訪問這個 IP,會獲得一個 403 的錯誤。由於容器中的網站目錄在 /var/www/html,可是實際上目錄中沒有東西,因此 403 forbidden。
那麼怎麼將文件放入容器的那個文件夾?
第一步:宿主機建立文件夾,而後進入文件夾。
第二部:進入這個文件夾,建立 index.php 文件,文件內容是 <?php phpinfo(); ?>
第三部:使用命令啓動容器:docker run --name wordpress -v "$PWD/":/var/www/html php:5.6-apache
。
這樣訪問 wordpress 容器的 IP(由於是新容器,因此 IP 有變化),便會獲得經典的 phpinfo 頁面。
測試完成,咱們的容器能夠執行 php 文件。
將 wordpress 文件放入本文件夾,chmod 777
,而後從新啓動 wordpress
容器,可是會這麼提示:
您的PHP彷佛沒有安裝運行WordPress所必需的MySQL擴展。
官方 php 鏡像並未提供 mysql 擴展,因此咱們必需要本身手動寫 Dockerfile 安裝擴展:
FROM php:5.6-apache # 使用 php:5.6-apache 鏡像 RUN docker-php-ext-install mysqli # 使用 docker-php-ext-install 命令安裝 mysqli 擴展 CMD ["apache2-foreground"] # 默認啓動 apache2-foreground 命令
而後咱們構建這個鏡像,鏡像名爲 phpwithmysql。
docker build -t phpwithmysql .
-t
參數指定構建出的鏡像的名稱。.
表示使用本目錄的 Dockerfile
。
構建完成,便會得 phpwithmysql 鏡像,tag 名爲 latest。
再次啓動 WordPress:
docker run --name wordpress -v "$PWD/":/var/www/html phpwithmysql
此次再使用 IP 訪問你的 wordpress:
走到這一步,大部分的事情咱們都作的差很少了,只有一個問題:
萬一重啓 wordpressdb 容器,數據庫容器的 IP 變了怎麼辦?
Docker 提供了鏈接參數,讓咱們能夠將一個容器鏈接到另外一個容器。
docker run --name wordpress --link wordpressdb:mysql -v "$PWD/":/var/www/html phpwithmysql
新參數是 --link
,做用是將 wordpressdb
鏈接到 wordpress
容器內,具體爲在 wordpress
容器內的 hosts 文件中增長 mysql 172.17.0.X
。172.17.0.X
爲 wordpressdb
的 IP。
除此以外,還會修改 wordpress
的環境變量。
所以,安裝的時候只需指定數據庫主機爲 mysql
便可。
可是還有點蛋疼的問題:
wordpress 並不能上傳文件,也不能安裝主題。由於 wordpress
容器內的 apache
對文件系統沒有寫權限,因此咱們還得調整 phpwithmysql
鏡像的 Dockerfile:
FROM php:5.6-apache RUN docker-php-ext-install mysqli COPY entrypoint.sh /entrypoint.sh RUN chmod 777 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] CMD ["apache2-foreground"]
接下來建立 encrypting.sh 文件:
#!/bin/bash chown -R www-data:www-data . exec "$@"
這是官方 WordPress 鏡像構建方法的簡化版,可是已經解決了文件系統的寫權限問題。
如今構建新的鏡像:
docker build -t phpwithmysql:v2 .
刪除舊容器並重啓:
docker rm -f wordpress docker rm -f wordpressdb docker run --name wordpressdb -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress -d mysql:5.7 docker run --name wordpress --link wordpressdb:mysql -v "$PWD/":/var/www/html phpwithmysql:v2
最後,刪除 wp-config.php
文件。
這一次訪問 wordpress
的 IP,從新安裝 WordPress,即可構建完成。
構建過程可能有些麻煩,因此 WordPress 有官方的各類語言的 Docker 鏡像。Docker 不容許容器內的應用對宿主機文件系統有寫權限,這究竟是好是壞?我以爲應該是好事。咱們能夠創立一個數據容器專門負責放文件,這樣能夠實現架構的多樣化。可是對於現有架構的應用例如 WordPress,咱們只能如此變通。
最後一步大概不少人猜獲得,就是萬一關機了怎麼辦?wordpress
容器 IP 變化了怎麼辦?要知道,WordPress 沒有配置的狀況下愛,是使用 IP 保存站點 URL 的,因此咱們必需要這樣修改 wp-config.php
文件:
define('WP_HOME',$_SERVER['SERVER_ADDR']); define('WP_SITEURL',$_SERVER['SERVER_ADDR']);
要注意的是,在 wp-config.php
文件中改變的設置,是沒法再在 WordPress 的儀表盤中再改動的。
本文中咱們手動使用 Docker 構建了 WordPress 鏡像,可是使用了一個很是曲折的方法。固然,還有更簡便的方法,由於 Docker 官方已經構建了 WordPress 鏡像。有了官方鏡像,咱們手動構建的鏡像其實意義不大了。不過,經過調試,咱們演示了 Docker 可能出現的常見問題,例如 IP 變化,以及解決辦法(--link)等。