iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 10
0

前言

由前面的章節我們可以得知,想啟動一個滿足使用者需求的Container,是需要輸入許多繁瑣的指令以及參數的,我們想享受Container帶來的好處,又不想每次都這樣輸入指令,在我們只有Docker當作容器化武器的情況下,這時就需要來寫script

實戰演練

假設我們需要啟動三個獨立的Container,彼此只透過bridge network溝通,必須去bind特定的port,並且還需要掛載volume出來,這時我們會怎麼撰寫script呢?

Requirements

假設我們需要下列三個不同的Containers。

  • Web Service: 提供後端服務,需要開放容器port 8100,讓nginx能導流進來。
    • Nginx:用來redirect做load balance以及返回靜態物件,需要開放容器80port並且需要映射到本地port 80。
  • Redis:用來儲存Web Service的Cache,需開放容器port 6379,並且我們也映射到本地port 6379,讓我們隨時能查看Redis資料。

https://ithelp.ithome.com.tw/upload/images/20200925/20129737sv8mBECjZM.png

Write a script

current hierarchy

紅色部分是這次我們要新增的scipt

.
|____remove-containers.sh
|____start_container.sh
|____create_image.sh
|____app
| |____app.py
| |____api
| | |____v1
| | | |____health.py
|____requirements.txt
|____Dockerfile
|____uwsgi.ini
|____README.md
|____docker-entrypoint.sh
|____.gitignore
|____nginx
| |____default.conf
| |____nginx.conf
|____stg.env
|____prd.env
|____wsgi.py
| |____.gitignore

Build docker image

若需要重新build多個images,就能在for loop寫入多個image name,並在done之後 build多個images,像下方例子一樣。

#!/bin/bash

for image_name in ironman, ghjjhg567/ironman:latest
do
    if [ $(docker images $image_name -q | wc -l) == "1" ]; then
        docker rmi $image_name
        echo "Docker image: $image_name was removed."
    fi
done

docker build -t ghjjhg567/ironman:latest -f Dockerfile .

Start with multiple containers

再啟動Containers時,可以將params當作啟動不同環境的關鍵字,並且把繁瑣的docker commands像是啟動Containers時需要吃特定環境的環境變數、並且使用同一個bridge network、然後掛載特定的程式碼以及對外開放特定的port...等,如下方程式碼所示。

#!/bin/bash

#!/bin/bash

env=$1

docker network create ironman-net

if [ "$env" == "prd" ];then
    docker run -e ENVIRONMENT="$env" --env-file prd.env \
  --net=ironman-net --name ironman -d -v $(pwd)/app:/usr/src/app/app ghjjhg567/ironman:latest

else
    docker run -e ENVIRONMENT="stg" --env-file stg.env \
  --net=ironman-net --name ironman -d -v $(pwd)/app:/usr/src/app/app ghjjhg567/ironman:latest

fi

docker run --net=ironman-net --name redis -d -p 6379:6379 redis:4.0

docker run --net=ironman-net --name nginx -d -p 80:80 -v $(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v $(pwd)/nginx/default.conf:/etc/nginx/conf.d/default.conf nginx

Remove related containers

需要移除相關Containers時,也可以將相關的network, volumes, containers...等一併移除。

#!/bin/bash -x

#docker stop article-dev redis postgresql nginx
docker stop ironman nginx postgres
#docker rm article-dev redis postgresql nginx
docker rm ironman nginx postgres
docker network rm ironman-net
docker volume prune -f

Test with our script

透過GET localhost/v1/hc 會發現nginx確實有生效並將requests redirect到後端的flask!

$ ./create_image.sh
$ ./start_container.sh
$ curl -X GET http://localhost/v1/hc
{"message": "This endpoint for web service health check"}

Github Repo

本篇章所有程式碼將放在下面的github project當中的branch day-10

https://github.com/Neskem/ironman_2020/tree/day-10

往後該系列的展示程式碼,都將放在同一project並以不同branch的形式提供參考。

小結

運用script的方式來執行docker,如此一來就不用都輸入繁瑣的docker cli,需要更改commands時,也只需要去對scripts進行修改,在我們進化成docker-compose或是kubernetes前,這十個章節所學已經足以讓我們當個稱職的docker獸了。

Docker獸發出了閃耀的光芒,看來是要進化了....
https://ithelp.ithome.com.tw/upload/images/20200925/201297373UtuyJQ1WD.png


上一篇
Day-9 熟悉 Docker 進階功能
下一篇
Day-11 初出 Docker-Compose
系列文
Docker獸 究極進化 ~~ Kubernetes獸30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言