docker compose 是使用docker的利器,可以讓很多的指令用文檔的方式載入。
有別於 docker一個個載入的方式,docker-compose 可以一定編輯多個container並一次啟動[3][4]。
安裝
OS
CentOS Linux release 7.9.2009 (Core)
安裝[1]
# yum update
# yum install docker-compose-plugin
查看版本
# docker compose version
Docker Compose version v2.10.2
2版以後的docker-compose 指令整合到 docker中,所以docker-compose 指令消失,改用 docker compose 方式
建立docker-compose文檔
到你的目錄下建立一個名為 docker-compose.yml 的檔案
cd /path/to/
vi docker-compose.yml
內容範例如下:[2]
version: '3.8' <== 適用docker engine的版本,可參考[5]有支援的版本
services: <== 服務器區塊,把要執行的一個個container寫在這裡
php: <== 服務名
image: php:7.4-apache <== 影像的名稱
container_name: apache <== 執行後container的別名
restart: always <== container 故障時自動重啟
ports: <== 埠號欄位
- 80:80 <== 外面主機的埠號:container的埠號 對照
- 443:443
volumes:
- ./public_html:/var/www/html/ <== 外面主機的檔案位址:裡面container的檔案位址
這樣就能建立一個提供php服務的容器,除了上面的說明外,另外簡單說明如下:
版本是指此yml檔支援的docker-compose 版本,不是自訂的版本。
服務名可以自己取作為compose的指令用,container_name就是container的名稱。
image的影像名稱可以去 dockerhub [8] 上面找或是去服務本身的官網上面找,例如 php的官方就有提供數種不同類型的 image,選一個下來試試,如果不合用或不會用的話,再找別的。
restart: always 是指當 docker 一啟動的時候,就把php這個服務給啟動。
接下來就可以啟動他了,請看下面基本操作
基本操作
起動此docker-composer的所有container,請在docker-compose.yml的檔案位置操作
建立container
-d 是放在背景執行
移除所有container
移除完畢後,所有container被清掉,如果沒有把資料指定到docker外部的話,異動的內容會消失
建立單一名為 php的container
注意php是服務名不是container名
停止/啟動一個container
注意以上操作並不會重讀 docker-compose.yml的設定,同時container還是存在,並沒有新建或移除。
30秒後重啟服務名為php的container
重新讀入docker-compose.yml的設定[13]
如果單純的 docker compose restart/stop/start 是不會重讀docker-compose.yml的,換句話說,如果docker-compose.yml裡面有改變參數或是設定,只是重啟沒有作用,但是重啟的話外部的設定檔會影響,例如 php.ini。
如果docker-compose.yml裡面有改變參數或是設定在啟動時一定要加上 -d 的參數
# docker compose up <service Name> -d
我在這裡卡了2 個小時,想說怎麼一直找不到檔案?
移除及重建單一container [9]
使用docker compose down 的話,是全部container都被移除,但如果只是想重讀設定在外面的設定檔的話(例如php.ini),不用重建 container。
所以只想要重建單一container的話,可用以下指令。
# docker rm <containerID/container Name>
# docker compose up <service Name> -d
查看container log
docker logs <container ID/container Name>
這個指令可以看到access logs及error logs,加了 -f的參數可以持續觀察[6],例如
按 ctrl+c 中止
查看docker compose log
docker compose logs
docker compose logs <service Name>
# docker compose logs php
起動失敗時可以看原因
建立共用檔案位置
如果想讓不同的container來共享檔案空間,可以把他們共用到系統本身(外面的作業系統),但是這樣有一個缺點,就是需要外部的空間作為媒介。
所以可以使用 volumes 這個服務區塊來完成任務,這次我們希望提供php的container裡面放一個phpmyadmin的container,因此我們把一個空間命名為 phpadmindir, 如下圖:
phpadmindir:
volumes: 放置的位置和 services: 區塊並列,並不是服務內的volumes。
接下來在剛才的php服務中指定php裡的/mnt為這個空間,如下面綠色字。
php:
...
volumes:
- ./public_html:/var/www/html/
- phpadmindir:/mnt
最後把phpmyadmin中的主要目錄指定到這個空間,如下面粉色字:
phpmyadmin:
...
volumes:
- phpadmindir:/var/www/html
這樣就完成了關連,全部如下
version: '3.8'
services:
php:
image: php:7.4-apache
container_name: apache
ports:
- 80:80
- 443:443
volumes:
- ./public_html:/var/www/html/
- phpadmindir:/mnt
phpmyadmin:
image: phpmyadmin
restart: always
container_name: phpmyadm
volumes:
- phpadmindir:/var/www/html
environment:
- PMA_HOSTS=localhost
links:
- db
volumes:
phpadmindir:
但是這裡要注意,等同phpmyadmin的空間被畫到php裡,所以他的設置什麼的就會失去作用[10]。
SELINUX
對於docker指定出來的檔案,給予 container_file_t的 TYPE才不會有讀寫的問題。
chcon -t container_file_t FILES
結論
使用docker compose 可以讓複雜的docker指令清楚明暸的看到,啟動修改什麼的都很方便。
用完 docker compose後反而純docker run的指令就很少用。
相關連結
參考資料
[1] https://docs.docker.com/compose/install/linux/
[2] https://www.myfreax.com/how-to-install-and-use-docker-compose-on-centos-7/
[4] Day 29- 三周目 - Docker Compose:一次管理多個容器 https://ithelp.ithome.com.tw/articles/10206437
[5] https://docs.docker.com/compose/compose-file/compose-file-v3/
[6] https://serverfault.com/questions/763882/apache-in-docker-how-do-i-access-log
[7] https://ithelp.ithome.com.tw/m/articles/10191016?sc=hot
[9] https://stackoverflow.com/questions/31466428/how-to-restart-a-single-container-with-docker-compose
[10] 感謝過路君子指出問題,原本在這個部分設定一直沒用讓我覺得很奇怪。