最近,我的困擾之一是保持操作系統儘可能乾淨。為了做到這一點,我希望儘可能少地安裝任何東西。
Node.js使這個任務變得如此簡單,因為我只需要node
全局安裝,其他所有內容都可以本地安裝在項目目錄中。但是,對於許多其他語言(例如Python
和)PHP
,通常並非如此。此外,當每個項目需要不同的環境設置時,管理所有內容很快就變得很痛苦,有時您會破壞整個系統。
Docker進行了救援。
儘管Docker主要用於控制生產和團隊環境,但它對於封裝開發環境並提供「乾淨的狀態」以確保無意外損壞也非常有用。
在構建docker開發系統時,我經常考慮以下要求:
- 最小卷掛載:在已掛載的主機卷上的文件IO操作速度很慢(在Windows和Mac上),因此您只想掛載要編輯的源代碼文件。構建圖像時應複製其他圖像。
- 沒有運行時安裝:依賴項和第三方插件不應在容器運行時安裝,尤其是在需要Internet連接的情況下,以確保恢復開發時的最快啟動時間。構建映像時應安裝它們。
- 主機最小第三方:如果可能的話,依賴性和第三方插件將被取回來自互聯網(通過像一個配置文件
package.json
或者Gemfile
甚至是上市內Dockerfile
)。否則,應在構建圖像時將它們保存為zip文件並進行複製/提取。有兩個原因:- 從主機到映像複製大量文件非常緩慢。
- 在您的git目錄中保留大量的第三方文件非常混亂。
- 可跟蹤的快照:您應該能夠對當前的開發進度進行快照(尤其是在Wordpress中,如下所述),並且應該能夠在git存儲庫中對其進行跟蹤。
對於Wordpress開發,我使用了chriszarate/wordpress
它,因為它通過環境變數提供了許多有用的功能,包括:
- 容器啟動時自動激活插件。因為沒有人希望每次都手動激活主題。但是,一旦開始使用資料庫快照,這將變得無關緊要。
- 容器啟動時自動激活主題。同樣,一旦開始使用資料庫快照,這將變得無關緊要。
- 將其他PHP附加到
wp-config.php
。 - 預先配置管理員用戶,管理員密碼,管理員電子郵件和網站網址,以跳過無聊的歡迎設置屏幕。
該Docker映像背後的魔力是一組wp-cli
腳本,這些腳本附加到docker-entrypoint.sh
官方wordpress
Docker映像的默認入口點。
這是我的Wordpress開發目錄的文件夾結構,共有3個主要部分(在屏幕截圖中名稱不佳,但在下圖中有很好的解釋):
- 源代碼:您當前正在開發的插件和主題。他們是文本文件(
.php
,.css
,.xml
等),你會在大多數項目時間表的創建和更改。 - 第三方:它們是您的站點所需的第三方插件,您的項目或要為其創建子主題的父主題的依賴項。它們應作為zip文件保存在這些文件夾中,或在中指定為url
Dockerfile
。 - 快照:包括來自wordpress資料庫的sql轉儲和文件
wp-content/uploads
夾的壓縮文件(如果您正在構建主題的內容或從演示內容開始)。
通過這種結構,映像中將內置第3方和快照,同時安裝了源代碼以允許進行開發更改。
docker-entrypoint.sh
是docker-entrypoint.sh
原始docker映像的默認入口點,將進行修改(見下文)以適應我們的需求。
有關示例Dockerfile
,請查看此要點。
對於Dockerfile配置,我安裝以下軟體包:
unzip
:如上所述,快照和第3方保存為zip文件(如果是遠程獲取,也以zip格式保存)。我們將需要此實用程序來解壓縮它們。mysql-client
:該包提供所要求neccessary命令wp db
至出口和進口的wordpress資料庫作為.sql
快照。- [可選]
wget
:在dependencires可遠程獲取的情況下,我們使用wget
到下載從指定的URL他們。
FROM chriszarate/wordpress:4.9.1
RUN \
apt-get update && \
apt-get install unzip wget mysql-client -y && \
rm -rf /var/lib/apt/lists/*
我們將zip文件的每個第三方目錄複製到圖片上的臨時文件夾(或通過下載wget
),提取並刪除所有zip文件。這些文件夾的內容將在運行時通過複製到真實的目標目錄docker-entrypoint.sh
。
我們之所以沒有將它們直接複製到真實的目標文件夾中,是因為它們會被官方wordpress image中的命令覆蓋docker-entrypoint.sh
。
# If copied from folder
COPY ./plugins/ /temp/plugins
# If downloaded via url
wget -P /temp/plugins/ https://downloads.wordpress.org/plugin/jetpack.5.9.zip
# Extract and delete zip files
RUN unzip '/temp/plugins/*.zip' -d /temp/plugins && rm /temp/plugins/*.zip || true;
|| true
添加以確保沒有zip文件時,腳本不會失敗並終止圖像構建過程。
同樣,我們將快照文件(如果有)複製到映像中。該uploads.zip
文件應如上所述進行解壓縮,然後wordpress.sql
再由處理docker-entrypoint.sh
。
我們需要docker-entrypoint.sh
用修改後的腳本替換默認值。我們不必指定,ENTRYPOINT
因為它已經在官方docker映像中聲明了。
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
uploads.ini
在存儲庫中擁有自己的php上傳配置並將其插入映像也很有用。顯然,您可以使用相同的方法配置其他內部系統文件:將自定義文件複製到映像內的絕對路徑。
COPY ./uploads.ini /usr/local/etc/php/conf.d/uploads.ini
有關示例docker-entrypoint.sh
,請查看此要點。
現在該進行修改了docker-entrypoint.sh
。從的腳本克隆開始chriszarate/wordpress
,我們需要將/temp/
目錄中的所有文件複製到需要的位置。這些行需要放置在插件和主題激活之前。
CONTENT_DIR=$ROOT_DIR/wp-content
THEME_DIR=$CONTENT_DIR/themes
PLUGIN_DIR=$CONTENT_DIR/plugins
cp -r /temp/themes/* $THEME_DIR || true
cp -r /temp/plugins/* $PLUGIN_DIR || true
cp -r /temp/base/* $CONTENT_DIR || true
# Activate plugins. Install if it cannot be found locally.
# ...
這裡要注意的一件事是,所有這些文件和文件夾均歸root
用戶所有,因此Wordpress將無法寫入。如果您需要授予這些目錄的Wordpress許可權,則需要插入以下內容:
chown -R $WEB_USER:$WEB_USER $ROOT_DIR/wp-content/uploads
最後,完成所有操作後,在的結尾docker-entrypoint.sh
,我們將要導入wordpress.sql
文件。我們將此行放在文件的末尾,就在之前exec "$@"
,以確保我們的資料庫不會被任何內容覆蓋。
runuser $WEB_USER -s /bin/sh -c "wp db import $CONTENT_DIR/wordpress.sql"
exec "$@"
對於docker-compose
配置,您可以在chriszarate的存儲庫中找到示例。它是兩種服務的組合:wordpress
用於PHP wordpress安裝和mysql
用於資料庫。這裡只有幾件事需要更改:
- 構建您的Dockerfile:而不是
chriszarate/wordpress
直接使用映像
services:
wordpress:
build: .
- 根據您的項目,一個接一個地安裝源代碼。不要掛載整個目錄
themes
或plugins
目錄,因為它們在容器中的版本已經用其他文件填充了。
volumes:
- "./src/themes/my-custom-theme:/var/www/html/wp-content/themes/my-custom-theme"
- "./src/plugins/my-custom-plugin:/var/www/html/wp-content/plugins/my-custom-plugin"
- 僅限本地:僅列出在docker image
WORDPRESS_ACTIVATE_PLUGINS
和WORDPRESS_ACTIVATE_THEME
環境變數中安裝的插件和主題。否則,入口點腳本將嘗試從Internet下載它們並延長啟動時間。
現在我們開始了。讓我們去清理所有XAMPP或MAMP堆棧,或者刪除所有內容並重新安裝操作系統,或者最好將機器扔掉,換一台全新的計算機。玩得開心。