# [AWS EC2] 將GitHub程式打包成Docker自動部屬至EC2 ## :book: 設定 EC2 環境 **更新套件列表** ``` sudo apt update sudo apt upgrade ``` **安裝必要的依賴** ``` sudo apt install -y apt-transport-https wget ``` **安裝 .Net** ``` sudo apt update && sudo apt install [package] ``` > EX: sudo apt update && sudo apt install dotnet6 **安裝 Docker** ``` sudo apt-get update sudo apt-get install docker.io ``` **登入 Docker Hub** ``` docker login ``` ## :book: 設定CICD文件 (Git Action) > 流程講解: > 1. tags: 觸發條件設定為更新tags > 2. jobs: 將工作流程設定為Test、Deploy ``` name: Deploy to EC2 on: push: tags: - '*' jobs: Test: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up .NET SDK uses: actions/setup-dotnet@v1 with: dotnet-version: 6.0.x - name: Build .NET app run: dotnet build Deploy: runs-on: ubuntu-latest needs: Test steps: - name: Checkout code uses: actions/checkout@v4 # 將BotToken 插入到 appsettings.json 中 - name: Add BotToken run: | sed -i "s/\"BotToken\": \".*\"/\"BotToken\": \"${{ secrets.BOT_TOKEN }}\"/" appsettings.json - name: Login to Docker Hub uses: docker/login-action@v1 with: # 使用你的 Docker Hub 使用者名稱和ACCESS_TOKEN username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - name: Build and push Docker image uses: docker/build-push-action@v2 with: context: ${{ github.workspace }} push: true tags: ${{ secrets.DOCKER_HUB_USERNAME }}/tgbot_tw_stock_polling:latest - name: Executing remote ssh commands using ssh key uses: appleboy/ssh-action@master with: host: ${{ secrets.HOST_DNS }} username: ${{ secrets.USERNAME }} key: ${{ secrets.EC2_SSH_KEY }} script: | # 直接在 SSH 腳本中設置 REPO_NAME REPO_NAME=${{ github.repository }} REPO_NAME=${REPO_NAME##*/} echo "PROJECT_NAME=$REPO_NAME" # 檢查 PROJECT_NAME 是否為空 if [ -z "$REPO_NAME" ]; then echo "Error: REPO_NAME is empty" exit 1 fi # 檢查容器是否存在 if sudo docker ps -a --format '{{.Names}}' | grep -q "^$REPO_NAME$"; then echo "Stopping and removing container: $REPO_NAME" sudo docker stop $REPO_NAME || true sudo docker rm $REPO_NAME || true sudo docker rmi -f ${{ secrets.DOCKER_HUB_USERNAME }}/$REPO_NAME:latest || true else echo "Container $REPO_NAME does not exist, skipping stop/remove." fi # 確保映像存在 sudo docker pull ${{ secrets.DOCKER_HUB_USERNAME }}/$REPO_NAME:latest sudo docker run -d --name $REPO_NAME --restart=unless-stopped ${{ secrets.DOCKER_HUB_USERNAME }}/$REPO_NAME:latest ``` ## :book: 設定Git Action 參數 **EC2_SSH_KEY**: >This will be your .pem file which you will use to login to the instance >需要包含-----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- **HOST_DNS**: > Public DNS record of the instance, it will look something like this > ec2-xx-xxx-xxx-xxx.us-west-2.compute.amazonaws.com **USERNAME**: > Will be the username of the EC2 instance, usually **ubuntu** **TARGET_DIR**: > Is where you want to deploy your code. > (optional, default '/home/REMOTE_USER/') > *Ex: Bot/* **DOCKER_HUB_USERNAME**: > DOCKER_HUB 帳號 **DOCKER_HUB_ACCESS_TOKEN**: > DOCKER_HUB > MyAccount > Security > New Access Tokens > 設定完後產生 **BOT_TOKEN**: >TG機器人Token ## :book: EC2 常用指令 **查看當前路徑** ``` ls ``` **移動路徑** ``` cd + 資料夾名稱 cd .. (回到上一層) ``` **查看當前執行程序** ``` ps ``` **查看當前背景執行程式** ``` ps aux | grep dotnet ``` **移除資料夾** ``` sudo rm -rf 資料夾名稱 ``` **清理 apt 快取** ``` sudo apt-get autoremove sudo apt-get autoclean ``` ## :book: Docker 常用指令 **啟動Docker** ``` sudo service docker start ``` **查看images** ``` docker images ``` **查看執行中容器** ``` docker ps ``` **啟動容器** ``` sudo docker run -d --restart=unless-stopped <容器名稱或容器ID> #-d = 背景執行 #--restart = 重新啟動條件 ``` **追蹤容器LOG** ``` docker logs -f <容器名稱或容器ID> ``` **移除images** ``` # 移除指定 REPOSITORY 和標籤的映像 docker rmi my_repository:latest # 移除指定 REPOSITORY 的所有標籤的映像 docker rmi my_repository # 使用通配符移除所有符合條件的映像 docker rmi my_repository:* ``` ## :book: Ubuntu 系統設定 **設定虛擬記憶體** ``` #設定虛擬記憶體大小 sudo fallocate -l 4G /swapfile #修改文件權限 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile ``` > 參考文章 > https://www.astralweb.com.tw/how-to-manually-add-swap-to-ubuntu/