PHP 專案:Docker

成果

這專案我會分成幾篇來講。

緣起

最近發現我的 Github 部落格沒辦法開 Firefox 的閱讀模式。看了下閱讀模式的算法,他需要原始碼本身,就載入完整的文章。而用純 API 接的部落格沒辦法這麼做。

我檢查了一下,似乎可以用 SSR 渲染解決。但看了一堆後,我發覺還是用後端語言寫比較快。反正 API 都有了,我也有一點後端語言的基礎。最後我選了一個託管網站來寫。因為那網站的語言是 PHP,所以我也決定用 PHP 寫網頁。

開發環境

選用 PHP 寫網頁後,第一個問題就出來了:如何模擬一個純 PHP 的開發環境。我的經驗是不管手動安裝、還是在 Virtual Box 裝,都要搞一堆繁瑣的基礎設定、還有可能把我的電腦搞爛。所以我望向了本來就很想學的虛擬化工具 Docker

安裝 Docker 後就要開始使用了。原理是這樣的:你要抓需要的 Image 來用、組成你想要的 Container:這就好像前端從 npm 抓套件來用後,再把他弄成專案一樣。而就好像前端要用 package.json 完成一樣,從 Docker 完成這些事,則要透過撰寫 dockerfile 完成。

從託管網站的資訊來看,我需要一個 PHP on Apache 的開發環境。當然 Docker 早就提供了 PHP 的 Image了。所以,我按照手冊在 dockerfile 引入 FROM php:7.2-apache,然後輸入 docker build -t phpdev-container 把 Image 組成 Container 就好了。

問題解決:localhost

弄一下之後,就完成了。只不過還要解決很多問題:首先是裝好後,怎麼訪問 Container 呢?

啊既然是虛擬化,那不就是要訪問 localhost 嗎——我這麼想著,卻發現失敗了。查了查 Stack Overflow 的討論才發現 Docker 是先搞一個 Linux 的虛擬機,接著把這個虛擬機分派到 192.168.99.100 那邊。

但我想用 localhost 啊怎麼辦?

我又看到 RUN echo 'ServerName localhost' >> /etc/apache2/apache2.conf——嗯,把 ServerName 的設定覆寫到 apache2.conf 吧。我試了試,終於成功了。至少可以寫 PHP 了。

問題解決:Rewrite engine

在開發 PHP 的時候,你可能覺得這種 URL 很醜: article/index.php?id=100 而想改用這種 URL: /article/100

這是怎麼做的呢,在 apache 你要在 .htaccess 透過 Rewrite engine 完成:

RewriteEngine On
RewriteRule ^article/([0-9]+)?$ article/index.php?id=$1

結果用沒多久就 500 了:

/var/www/html/.htaccess: Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configuration

RewriteEngine 怎麼會無效呢?查到有人回答說伺服器需要打開 Rewrite engine。那問題就很明顯了:怎麼在 Docker 開 Rewrite engine 呢?

答案是 RUN a2enmod rewrite。

於是我的 dockerfile 就變成這樣:

FROM php:7.2-apache

RUN a2enmod rewrite
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
RUN service apache2 restart

結束

先講到這邊吧。PHP 的有空繼續寫。

參考資料