當在容器搭建多個執行個體時,如果用run指令,需要很多遍,如搭建LNMP(nginx+php+mysql),這時可以考慮用Compose這個服務來搭建配置。
一、 Docker Compose簡介:
Docker-Compose 是 Docker 的一種編排服務,是一個用于在 Docker 上定義并運作複雜應用的工具,可以讓使用者在叢集中部署分布式應用。compose、machine 和 swarm 是docker 原生提供的三大編排工具,又稱docker三劍客。
通過 Docker-Compose 使用者可以很容易地用一個配置檔案定義一個多容器的應用,然後使用一條指令安裝這個應用的所有依賴,完成建構。Docker-Compose 解決了容器與容器之間如何管理編排的問題。
Compose 中有兩個重要的概念:
- 服務 (service) :一個應用的容器,實際上可以包括若幹運作相同鏡像的容器執行個體。
- 項目 (project) :由一組關聯的應用容器組成的一個完整業務單元,在 docker-compose.yml 檔案中定義。
運用Docker-Compose前提還要知道Dockerfile的運用,可參考另一篇文章中有介紹: dockerfile配置使用
二、 Docker Compose的安裝使用:
1):安裝
Docker Compose是獨自産品,需要在安裝docker後單獨安裝。相關官方文檔檢視: https://docs.docker.com/compose/
在github位址檢視版本安裝: https://github.com/docker/compose/releases
目前為止最新為1.29.2,安裝此版本。
#下載下傳
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
#添加可執行權限
sudo chmod +x /usr/local/bin/docker-compose
安裝完成,檢視版本
docker-compose --version

注意:如果安裝完成後,docker-compose指令無法使用,請檢查您的路徑。您還可以/usr/bin在路徑中建立一個軟連結如下。
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
2):基本指令使用
docker-compose up //啟動yml檔案定義的 container
docker-compose up -d //背景運作
docker-compose up --help //檢視up幫助
docker-compose -f docker-compose.yml up //-f 指定yml檔案
docker-compose stop //停止
docker-compose start
docker-compose ls //檢視
docker-compose down //停止删除
docker-compose ps
docker-compose images
docker-compose exec {service_name} {bash}
三、Compose搭建nginx+php+mysql執行個體
安裝版本如下:
centos 8 ,docker 20.10.7,docker-compose 1.29.2,nginx 1.20.1,php 8,mysql 5.7.34
1):建構目錄結構
鏡像版本,預設選擇标簽Tag為 latest 最新版本,别寫錯了,寫錯直接報錯read: connection reset by peer
建立目錄lnmp_compose,将相關配置檔案放在此目錄。
目錄結構如下:
[root@localhost lnmp_compose]# tree
.
|-- docker-compose.yml
|-- mysql
| `-- conf.d
| `-- my.cnf
|-- nginx
| |-- conf.d
| | `-- www.conf
| `-- Dockerfile
|-- php
| `-- Dockerfile
`-- www
|-- conn.php
`-- index.php
6 directories, 7 files
2):配置php的Dockerfile
因為php涉及到很多擴充庫,是以我們需要用到Dockerfile配置擴充建立新的鏡像。
vim /lnmp_compose/php/Dockerfile
輸入以下内容,從centos鏡像采用yum安裝php8的版本。内容參考: yum方式安裝php最新版
FROM centos
RUN groupadd -g 1002 www && useradd -u 1001 -g www -s /sbin/nologin www \
&& yum -y install epel-release yum-utils \
&& yum -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm \
&& dnf -y module list php \
&& dnf -y module enable php:remi-8.0 \
&& dnf -y install php php-cli php-fpm php-mysqlnd php-zip php-devel php-gd php-mbstring php-curl php-xml php-pear php-bcmath php-json php-redis --skip-broken \
&& sed -i 's/user = apache/user = www/g' /etc/php-fpm.d/www.conf \
&& sed -i 's/group = apache/group = www/g' /etc/php-fpm.d/www.conf \
&& sed -i 's/listen = \/run\/php-fpm\/www.sock/listen = 0.0.0.0:9000/g' /etc/php-fpm.d/www.conf \
&& sed -i 's/listen.allowed_clients = 127.0.0.1/;listen.allowed_clients/g' /etc/php-fpm.d/www.conf \
&& mkdir /run/php-fpm
CMD ["php-fpm","--nodaemonize"]
Dockerfile相關參數解釋,建立www使用者及www使用者組,安裝php擴充包。
需注意的坑:
- 1. 建立www使用者群組,uid和gid需要和主控端www使用者一緻,主控端 id www 檢視gid和uid。這裡主控端gid 1002,uid 1001。
- 2. /etc/php-fpm.d/www.conf 配置檔案,預設監聽 listen = run/php-fpm/www.sock 改為 listen = 0.0.0.0:9000 ,網上很多寫127.0.0.1:9000也行,但是可能版本原因,我親測不行。
- 3. /etc/php-fpm.d/www.conf 配置檔案,預設隻允許本機IP,需要将 listen.allowed_clients = 127.0.0.1 改注釋掉。
- 4. 缺少 /run/php-fpm 檔案夾,無法啟動php-fpm,無法建立PID檔案,在容器中php-fpm啟動報錯:ERROR: Unable to create the PID file (/run/php-fpm/php-fpm.pid).: No such file or directory (2)ERROR: FPM initialization failed,需自己建立 mkdir /run/php-fpm 。
3):配置nginx的Dockerfile
由于也需要更改www使用者,是以需要Dockerfile檔案重建鏡像。
有兩種,可以自行根據自己需求配置。
1:第一種,可以直接nginx官方鏡像,預設最新版本,在裡面更改配置檔案。
同時更新apt-get,和安裝vi,以便後續在容器中簡單編輯配置檔案。配置如下:
FROM nginx
RUN groupadd -g 1002 www && useradd -u 1001 -g www -s /sbin/nologin www \
&& apt-get -y update && apt-get -y install vi \
&& sed -i 's/user nginx/user www/g' /etc/nginx/nginx.conf
2:第二種,直接從centos鏡像安裝nginx指定版本,建構新的nginx鏡像。
這種無需安裝vi等指令,已具備基礎的指令可操作性強一點。這裡采用yum的安裝方式。配置如下:
FROM centos
RUN groupadd -g 1002 www && useradd -u 1001 -g www -s /sbin/nologin www \
&& yum install -y yum-utils \
&& echo -e "[nginx-stable] \
\nname=nginx stable repo \
\nbaseurl=http://nginx.org/packages/centos/\$releasever/\$basearch \
\ngpgcheck=1 \
\nenabled=1 \
\ngpgkey=https://nginx.org/keys/nginx_signing.key \
\nmodule_hotfixes=true \
\n[nginx-mainline] \
\nname=nginx mainline repo \
\nbaseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch \
\ngpgcheck=1 \
\nenabled=0 \
\ngpgkey=https://nginx.org/keys/nginx_signing.key \
\nmodule_hotfixes=true" > /etc/yum.repos.d/nginx.repo \
&& yum install -y nginx-1.20.1 \
&& sed -i 's/user nginx/user www/g' /etc/nginx/nginx.conf
CMD ["nginx", "-g", "daemon off;"]
需注意的坑:
- 1. 同php一樣,www使用者群組,uid和gid需要和主控端www使用者一緻。
- 2. 配置檔案 /etc/nginx/nginx.conf 中替換使用者時, user nginx 中間是兩個空格,不是一個。
4):配置nginx的www.conf檔案
在主控端,建立的 nginx/conf.d 中配置 www.conf 檔案,内容如下:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm index.php;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
root /var/www/html;
fastcgi_pass php_compose:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
}
}
- 1. 路徑問題, location ~ \.php$ 的root為php容器中的路徑, location / 中的root為nginx容器中的路徑,不能像裝在同一機器下配置一樣的路徑,因為現在動靜分離,需要考慮到對應容器是否存在這個預設路徑,否則報404錯誤。
- 2. fastcgi_pass 配置為 “容器名:端口” 方式。
5):配置yml檔案
這裡yml已命名為docker-compose.yml
vim docker-compose.yml
輸入以下内容:
version: '3.8'
services:
nginx:
build: ./nginx
container_name: nginx_compose
ports:
- "80:80"
- "443:443"
volumes:
- "$PWD/nginx/conf.d:/etc/nginx/conf.d"
- "$PWD/www:/usr/share/nginx/html"
depends_on:
- "php"
- "mysql"
networks:
- lnmp
php:
build: ./php
container_name: php_compose
volumes:
- "$PWD/www:/var/www/html"
ports:
- "9000:9000"
networks:
- lnmp
mysql:
image: mysql:5.7.34
container_name: mysql_compose
ports:
- "3306:3306"
volumes:
- "$PWD/mysql/conf.d/my.cnf:/etc/mysql/conf.d/mysql.cnf"
networks:
- lnmp
command: --character-set-server=utf8
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: wordpress
MYSQL_USER: lnmp
MYSQL_PASSWORD: lnmp123
networks:
lnmp:
相關參數說明:
- version: '3':指的docker-compose 的版本,有1,2,3版本,對應docker版本,可參考:[https://docs.docker.com/compose/compose-file/compose-file-v3/](https://docs.docker.com/compose/compose-file/compose-file-v3/)
- services:指的安裝哪些服務,lnmp服務
- container_name:容器的名字,docker ps -a 中的
- image:引入鏡像,若是本地沒有,就去官網下載下傳
- networks:自定義網絡,預設是橋接模式,可以用docker images ls 看
- volumes:相當于bind這樣的資料卷挂載,可以使用絕對或者相對路徑
- build:通過Dockerfile建構鏡像
- ports: 開放端口,比如3306:3306 ,那這樣主控端也可以連接配接管理
- depends_on:依賴啟動,先啟動php,mysql,再啟動nginx
- environment :mysql參數設定,這裡例子為,設定root密碼,建立wordpress資料庫,建立user使用者及密碼。
6):建立測試網頁
在www建立index.php頁面,測試php和nginx是否連接配接成功:
vim www/index.php
内容:
<?php
phpinfo();
?>
建立conn.php頁面,測試php和mysql是否連接配接成功:
vim www/conn.php
<?php
$servername = "mysql_compose";
$username = "lnmp";
$password = "lnmp123";
try {
$conn = new PDO("mysql:host=$servername;", $username, $password);
echo "連接配接mysql成功";
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>
7):啟動docker-compose并測試
背景啟動:
docker-compose up -d
檢視狀态為up成功:
docker-compose ps
打開浏覽器分别輸入自己的伺服器位址如: 127.0.0.1/index.php 和 127.0.0.1/conn.php 位址連接配接測試,成功如下圖所示:
配置成功完成!!!
四:dnmp全家桶安裝包(擴充)
DNMP(Docker + Nginx/Openresty + MySQL5,8 + PHP5,7,8 + Redis + ElasticSearch + MongoDB + RabbitMQ)是一款全功能的LNMP一鍵安裝程式,支援Arm CPU。
這套包含所有軟體,根據自己選擇需要的軟體,配置docker-compose.yml和.env環境檔案即可。
github位址:https://github.com/yeszao/dnmp
不用自己編寫docker-compose.yml,友善試用。上手容易,測試環境,生成環境都可用。