image docker-logo
前言:
這個主題是在水球軟體學院中舉辦的Docker共學會最終回的成果發表文章,本人我也是第一次寫文章,主要目的應該會著重在自己的一個紀錄,內容如果不是那麼正確還請多多包容和指點以下正篇。
正篇:
Docker是一個容器化服務,他可以在一台電腦中切出好幾個環境分別執行不同的任務。
這邊會進行一個簡單的web server然後執行Github actions 或 Gitlab CICD達成自動化測試以及自動化部署。
稍後將會介紹到的項目有以下幾樣:
Dockerfile
docker-compose.yml
github/workflows 中的yml檔
首先
最基本的要架設一個網站會需要的服務為web server和database。
那們我將會以Python Django串接Nginx做為web server那database是使用Django預設的sqlite簡單演示。
資料夾階層會長這樣
+根目錄
|
+-+nginx/
| |
| +--Dockerfile
| +--docker-nginx-web.conf
| +--nginx.conf
+-+web/
| |
| +--Dockerfile
| +--requirements.txt
| +-+app/以下略
|
+--docker-compose.yml
這是Django也就是web裡面的Dockerfile
FROM python:3.8.5
LABEL maintainer="xxxx@gmail.com"
WORKDIR /web
COPY . /web/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
WORKDIR /web/app
VOLUME /web
EXPOSE 8001
再來是nginx裡面的Dockerfile
FROM nginx:latest
LABEL maintainer="xxxx@gmail.com"
COPY nginx.conf /etc/nginx/nginx.conf
COPY docker-nginx-web.conf /etc/nginx/sites-available/
RUN mkdir -p /etc/nginx/sites-enabled/ && \
ln -s /etc/nginx/sites-available/docker-nginx-web.conf /etc/nginx/sites-enabled/
CMD ["nginx", "-g", "daemon off;"]
然後是根目錄下的docker-compose.yml
version: '3.8'
services:
app_web:
build: ./web
container_name: app_web
restart: always
command: ["/bin/bash","-c","uwsgi --ini uwsgi.ini"]
volumes:
- web_data:/web/app
ports:
- "8001:8001"
environment:
- PYTHONUNBUFFERED=TURE
app_nginx:
build: ./nginx
container_name: app_nginx
restart: always
volumes:
- web_data:/web/app
ports:
- "80:80"
depends_on:
- app_web
volumes:
web_data:
那我們這邊docker-compose.yml裡面的build會去找尋web和nginx目錄下的Dockerfile並根據Dockerfile的內容去啟動container。
這邊下指令
docker-compose up --build -d
其實就會直接把兩個container建立起來了。
Github actions
然後就可以開始寫Github actions的yml檔囉!
我們到Github的頁面點選Actions
點選下方的Configure就會先幫你建立一個預設的yml
這邊就可以開始編輯自己的yml檔,但是Github上也有很多已經編輯好的yml檔會出現在Configure下方可以選用。
那這邊我就先用預設的yml來編輯
那預設的yml呢它上面會有很詳細的註解說明每一個指令的功用,這邊只截取我需要的部分把它改寫成這樣
name: Django CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
max-parallel: 4
matrix:
python-version: [3.8]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r web/requirements.txt
- name: Run Tests
run: |
python web/app/manage.py test
這邊是當你對這個repositories有push或是pull_request的時候就會觸發job的程序,上面那邊有$NaN是我們可以對他執行多個版本的測試,這邊我只有跑一個python 3.8,那我們看到最後一行,這個就只是在跑Django的測試內容。
接下來是測試通過後要把這整包部署到你指定的位置上也就是CD的部分
name: Django CD
# 只有在 CI 的 workflow 完成時才會執行此 workflow
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run
on:
workflow_run:
workflows: [ Django CI ]
types:
- completed
jobs:
deploy:
runs-on: ubuntu-latest
# 注意前面 workflow_run 的 completed 意思是「完成」,不論執行結果成功或是失敗都算是「完成」
# 但是一般來說測試如果失敗就應該暫停部屬至正式環境
# 因此這裡加上一個 if 判斷,只有 CI 成功才會執行此 workflow
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
# 使用 appleboy/ssh-action@master 這個 action 遠端連線至正式環境
# https://github.com/appleboy/ssh-action
- name: Deployment
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
key: ${{ secrets.TOKEN }}
username: ec2-user
# 執行部屬的指令
#docker rmi -f $(docker images -q -f dangling=true)
#docker volume rm $(docker volume ls -q -f dangling=true)
script: |
whoami
sudo yum -y install docker
sudo yum -y install git
sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod 777 /usr/local/bin/docker-compose
docker-compose version
cd ~
sudo rm -fr *
sudo git clone https://github.com/xxx/testCICD.git
cd testCICD
sudo systemctl restart docker
sudo chmod 777 /var/run/docker.sock
docker-compose down
docker rmi -f $(docker images -q -f dangling=true)
docker volume rm $(docker volume ls -q -f dangling=true)
docker-compose up --build -d
這邊我是參考了appleboy的ssh-action,這樣就可以透過ssh的方式連接到你的機器裡做上面所寫好的script了,那上面有兩個地方應該會有問題就是host跟key那兩個變數的新增位置在Settings
Settings
Secrets and variables
裡面的Security點開Secrets and variables中的Actions
你會看到
這邊就可以管理你在Github actions中的任何密鑰以及變數。
這邊這個CICD最終會部署到我在AWS EC2中架設的一個小機器裡面,裡頭還有很多細節也有很多我還沒搞清楚的地方,之後有機會在拆分主題來一一探討。
最後,我是一個轉職的工程師,目前剛轉滿半年多一點,還在努力學習中,如果有任何問題或建議都可以私訊我m23568n@gmail.com,我也常在 水球軟體學院 活動,歡迎大家一起加入這個大社群一起學習一起進步!!