Docker搭建PHP開發環境步驟詳解

來源:互聯網
上載者:User
這次給大家帶來Docker搭建PHP開發環境步驟詳解,Docker搭建PHP開發環境步驟詳解的注意事項有哪些,下面就是實戰案例,一起來看一下。

1. 前言

1.1 為什麼要用Docker ?

是否有這樣的情境,你搞了一個項目,在本地開發時需要搭建環境,放到線上時也需要搭建環境,到公司想暗戳戳玩一下要搭建環境,不搭還不行,因為你的環境依賴還挺多。這個時候如果有了Docker,只需要在機器上裝個Docker,放上寫好的Dockerfile,一行命令就自動完成這個事,方便又高效,豈不是很爽?

1.2 準備

接下來,本文介紹如何搭建一個PHP的開發環境,將用 zPhal-dockerfiles 做為例子,這是我為我的部落格系統準備的一套Dockerfile。

現在不管是Windows、Mac還是Linux,Docker都可以很好支援,包括Windows系統,在Win 10系統下Docker for Windows 其實還是挺不錯的,就是比較吃記憶體。

通過Docker命令列,我們可以做很多事情,拉取鏡像,運行容器,容器內執行命令等,但是現在,我們要用更加簡單粗暴的方式,編寫好Dockerfiles檔案,然後通過docker-compose管理好這些檔案,簡化操作流程。

什麼是Dockerfile?

Dockerfile是由一系列命令和參數構成的指令碼,這些命令應用於拉取的基礎鏡像並最終建立一個新的鏡像,通過Dockerfile我們可以建立一個你需要的鏡像,裡面是包含了你要安裝的軟體,相當於是提前定製好要安裝的拓展,執行的命令等,然後一鍵執行,極大地簡化操作流程。

按照本文來搭建環境,你需要:

首先瞭解一下Docker以及Docker的一些基本操作,還有docker-compose是什麼。
然後需要安裝Docker和docker-compose,我將使用docker-compose來管理我的Dockerfiles。
注意,編寫Dockerfile是活的,不是死的,每個人寫出來的Dockerfile都會不一樣,取決於你的需求。

Docker的官方文檔非常清楚,雖然是英文,但是基本上什麼都有,有問題上文檔翻是非常明智的: Docker Documentation 。

2. 開始編寫

接下來都是以 zPhal-dockerfiles 為例子,完整的可以點連結進去看,下面的只是片段。

2.1 預覽

首先,我們來看一下,我建立的這個Dockerfile項目,我大概分成了下面的目錄(當然這個是自己定的,並不是要求這麼去排版你的檔案):

zPhal-dockerfilesapp/ index.php phpinfo.phpdata/ .gitignorefiles/ mysql/ conf.d/  mysql-file.cnf Dockerfile nginx/ conf.d/  default.conf  zphal.conf Dockerfile nginx.conf php/ pkg/  .gitignore Dockerfile php.ini php-dev.ini php-fpm.conf redis/ Dockerfile docker-compose.ymllogs/.gitgnoreREADME.md

在這個項目裡,我用到PHP、MySQL、Nginx、Redis以及Composer、Phalcon拓展等。

總的來說,我們做這件事有三個流程:編寫好各個軟體的Dockerfile;編寫好設定檔;通過docker-compose處理所有的Dockerfile,包括將配置設定檔扔進去Dockerfile檔案將構建的鏡像中。

2.2 編寫Dockerfile檔案

2.2.1 PHP

下面是PHP的Dockerfile:

FROM php:7.2-fpm

MAINTAINER goozp "gzp@goozp.com"
設定時區

ENV TZ=Asia/Shanghai

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

更新安裝依賴包和PHP核心拓展

RUN apt-get update && apt-get install -y \git \libfreetype6-dev \libjpeg62-turbo-dev \libpng-dev \&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \&& docker-php-ext-install -j$(nproc) gd \&& docker-php-ext-install zip \&& docker-php-ext-install pdo_mysql \&& docker-php-ext-install opcache \&& docker-php-ext-install mysqli \&& rm -r /var/lib/apt/lists/*

將預先下載好的拓展包從宿主機拷貝進去

COPY ./pkg/redis.tgz /home/redis.tgzCOPY ./pkg/cphalcon.tar.gz /home/cphalcon.tar.gz

安裝 PECL 拓展,這裡我們安裝的是Redis

RUN pecl install /home/redis.tgz && echo "extension=redis.so" > /usr/local/etc/php/conf.d/redis.ini

安裝第三方拓展,這裡是 Phalcon 拓展

RUN cd /home \&& tar -zxvf cphalcon.tar.gz \&& mv cphalcon-* phalcon \&& cd phalcon/build \&& ./install \&& echo "extension=phalcon.so" > /usr/local/etc/php/conf.d/phalcon.ini

安裝 Composer

ENV COMPOSER_HOME /root/composerRUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composerENV PATH $COMPOSER_HOME/vendor/bin:$PATHRUN rm -f /home/redis.tgz \rm -f /home/cphalcon.tar.gz WORKDIR /dataWrite PermissionRUN usermod -u 1000 www-data

第一行定義了基礎鏡像,這裡我們用了PHP 7.2的fpm版本,這裡第二行定義了一個維護者。

接下來定義了時區,在每一個Dockerfile都定義了這一句,主要是為了使所有的容器的時間都與宿主機同步,其實我們可以在docker-composer.yml檔案中這麼定義:

services:

php-fpm:

volumes:

- /etc/localtime:/etc/localtime:ro
但是在非Linux系統,比如Windows中運行時,我們不能取到/etc/localtime,為了更大相容所有平台,我把時間同步寫到Dockerfile中。

接下來安裝一些拓展,其實安裝拓展的過程類似於我們徒手在Linux中安裝PHP拓展,值得一提的是Composer。我將Composer直接安裝在了php-fpm的鏡像中,其實官方也提供了Composer的鏡像,拉取Composer鏡像執行也可以達到目的,因為我們使用Composer只是為了執行Composer命令來管理我們的包,如果Composer單獨是一個容器的話,我們在不用時,還可以將容器關掉;但是在這裡,我直接將Composer裝進php-fpm鏡像中,主要是我的項目安裝了一些PHP拓展,在編寫composer.json檔案時,我定義了extension的依賴,這樣Composer執行時會檢查環境是否安裝了這些依賴,所有如果我直接用Composer鏡像的話,還需要把我用的拓展安裝到鏡像裡,就麻煩多了,所以我直接在PHP鏡像中就把這個事做了,其實沒什麼區別,取決於你怎麼用。

2.2.2 Nginx

下面是Nginx的Dockerfile:

FROM nginx:1.12
set timezome

ENV TZ=Asia/Shanghai

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

這個就簡單多了,我只設定了一個時間。因為我不需要安裝其它的東西,可以直接使用官方的鏡像。

當然,我們需要修改設定檔,只要事先寫好設定檔就行,最後在 docker-compose.yml 檔案中,將設定檔扔進去,這個下面會講,包括PHP的設定檔,MySQL的設定檔,都是一樣的。

2.2.3 MySQL

下面是 MySQL 的 Dockerfile:

FROM mysql:5.7
set timezome

ENV TZ=Asia/Shanghai

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

MySQL也沒有什麼特別之處,直接使用官方的鏡像。

2.2.4 Redis

下面是 Redis 的,也直接使用官方鏡像:

FROM redis:3.2
set timezome

ENV TZ=Asia/Shanghai

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

2.3 編寫設定檔

如何處理設定檔呢,我將設定檔進行歸類,PHP的設定檔放在PHP目錄下,Nginx的配置放在Nginx目錄下,至於要不要再建立一個子檔案夾就看情況了,比如conf.d檔案夾。

下面以Nginx設定檔為例,首先Nginx目錄是這樣的:

nginx/

conf.d/

default.conf

zphal.conf

Dockerfile

nginx.conf

除了nginx.conf外,還有一個子檔案夾conf.d用來存放所有的網域名稱設定檔,在Linux下搭建過PHP環境的應該都比較熟悉。這些設定檔就是我們到時候要傳進去容器中的檔案,我們並不會在宿主機使用這些檔案。

所以需要注意的最重要一點就是,設定檔中出現的路徑是容器內環境的路徑,而不是宿主機的路徑,每一個容器內都有一個運行環境,都是一台微型小系統,這些路徑都是容器內的路徑。我們可以通過掛載與容器內通訊來同步檔案,在命令列啟動容器也需要掛載檔案路徑,而現在掛載這一步我們也用docker-compose來解決。

下面是一個設定檔樣本:

server {listen 80 default;index index.html index.htm;server_name localhost docker;root /data/www;index index.php index.html index.htm;location / { try_files $uri $uri/ /index.html;}location ~ \.php { include fastcgi_params; fastcgi_pass php-fpm:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /data/www/$fastcgi_script_name;}}

而root /data/www中,/data/www路徑,是到時候Nginx容器的路徑,而不是當前在操作的宿主機的路徑,所以到時候我們要掛載Web程式放的位置到這個路徑。

2.4 編寫 docker-compose.yml

在PHP、Nginx等目錄的同級,我們建立一個docker-compose.yml,我們在執行docker-compose相關命令時,會自動找到這個檔案,並根據裡面的內容來執行。

接上面Nginx的例子,我們先談掛載,因為這是最重要的一步。在docker-compose.yml中,Nginx的部分:

build: ./nginxdepends_on: - php-fpmlinks: - php-fpm:php-fpmvolumes: - ../app:/data/www:rw - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ../logs/nginx:/var/log/nginxports: - "80:80" - "8080:8080" - "443:443"restart: alwayscommand: nginx -g 'daemon off;'

有一個volumes參數,這裡就是我們要掛載的目錄的相關配置,第一條我們將../app掛載到/data/www之中,也是我們設定檔中定義的預設監聽的root,而APP目錄是我們宿主機中的一個目錄,通過這樣掛載我們可以直接將我們的專案檔放到APP中,Docker會幫你傳輸到容器內的/data/www目錄下。

其它的參數:

build定義了你的Dockerfile在哪裡,如果沒有寫Dockerfile可以不用build,可以用images參數定義官方鏡像,比如image:mysql:5.7;
depends_on表示將依賴其它鏡像,比如Nginx依賴php-fpm,沒有它我Nginx沒法玩;
links定義串連,比如要串連到php-fpm容器,就是php-fpm:php-fpm,後面是別名;
ports表示連接埠映射,80:80表示將80連接埠映射到宿主機的80連接埠;
restart重啟,restart: always表示將自動重啟;
command是自動執行的命令;
……
參數很多,更多的可以參考官方文檔。

下面是一個完整的 docker-compose.yml 檔案:

version: '3.2'services:php-fpm:build: ./php/ports: - "9000:9000"links: - mysql-db:mysql-db - redis-db:redis-dbvolumes: - ../app:/data/www:rw - ./php/php-dev.ini:/usr/local/etc/php/php.ini:ro - ./php/php-fpm.conf:/usr/local/etc/php-fpm.conf:ro - ../logs/php-fpm:/var/log/php-fpm:rwrestart: alwayscommand: php-fpmnginx:build: ./nginxdepends_on: - php-fpmlinks: - php-fpm:php-fpmvolumes: - ../app:/data/www:rw - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ../logs/nginx:/var/log/nginxports: - "80:80" - "8080:8080" - "443:443"restart: alwayscommand: nginx -g 'daemon off;'mysql-db: build: ./mysql ports: - "3306:3306" volumes: - ../data/mysql:/var/lib/mysql:rw - ../logs/mysql:/var/lib/mysql-logs:rw - ./mysql/conf.d:/etc/mysql/conf.d:ro environment: MYSQL_ROOT_PASSWORD: 123456 MYSQL_DATABASE: zphaldb MYSQL_USER: zphal MYSQL_PASSWORD: zphal123 restart: always command: "--character-set-server=utf8"redis-db: build: ./redis ports: - "6379:6379" volumes: - ../data/redis:/data restart: always

3. 使用

這一套編寫下來,我們怎麼用呢?

3.1 使用搭建好的環境

首先,進入項目Dockerfiles的目錄下,這裡是files目錄:

cd zPhal-dockerfiles/files

wget https://pecl.php.net/get/redis-3.1.6.tgz -O php/pkg/redis.tgz

wget https://codeload.github.com/phalcon/cphalcon/tar.gz/v3.3.1 -O php/pkg/cphalcon.tar.gz
然後下載我們會用到的PHP拓展包。

執行命令:

docker-compose up
Docker會自動通過編寫好的docker-compose.yml內容構建鏡像,並且啟動容器。

如果沒問題,下次啟動時可以以守護模式啟用,所有容器將後台運行:

docker-compose up -d
關閉容器:

可以這樣關閉容器並刪除服務:

docker-compose down
使用 docker-compose 基本上就這麼簡單,用stop,start等這些命令來操縱Container Service。而更多的工作是在於編寫Dockerfile和docker-compose.yml檔案。

3.2 使用Composer

當我們要使用Composer時怎麼做呢? 我們已經在php-fpm裡安裝了Composer。

用docker-compose進行操作:

docker-compose run --rm -w /data/www/zPhal php-fpm composer update
-w /data/www/zPhal為在php-fpm的工作區域,zPhal項目也是掛載在裡面,所有我們可以直接在容器裡運行Composer。

或者進入宿主機APP目錄下用Docker命令:

cd zPhal-dockerfiles/app

docker run -it --rm -v `pwd`:/data/www/ -w /data/www/zPhal files_php-fpm composer update

4. 注意事項

注意掛載路徑。
構建失敗時,注意容器內是否報錯。
加速鏡像。如果過程下載鏡像很慢,可以使用國內的加速鏡像服務。

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

LaravelS通過Swoole加速Laravel/Lumen步驟詳解

php串連MSsql server方式方法總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.