nik*_*ksn 8 github docker digital-ocean docker-compose github-actions
我正在使用GitHub Actions来触发我的dockerfile的构建,它将容器上传到GitHub Container Registry。在最后一步中,我通过SSH连接到我的远程DigitalOcean Droplet 并执行脚本以从 GHCR拉取和安装新映像。这个工作流程对我很有用,因为我只在项目中构建了一个容器。现在我正在使用docker compose,因为除了 API 之外我还需要 NGINX。我想保持在一个容器单滴,因为该项目目前对资源的要求不高。
在单个 VM 上使用 Github Actions 和 Docker Compose 自动部署到 DigitalOcean 的正确方法是什么?
我目前已知的选项是:
如果您知道更多选择,这可能更清洁或更高效,请告诉我!
不幸的是,我找到了一个docker-compose with Github Actions for CI 问题以供参考。
单个容器的 GitHub 操作
name: Github Container Registry to DigitalOcean Droplet
on:
# Trigger the workflow via push on main branch
push:
branches:
- main
# use only trigger action if the backend folder changed
paths:
- "backend/**"
- ".github/workflows/**"
jobs:
# Builds a Docker Image and pushes it to Github Container Registry
push_to_github_container_registry:
name: Push to GHCR
runs-on: ubuntu-latest
# use the backend folder as the default working directory for the job
defaults:
run:
working-directory: ./backend
steps:
# Checkout the Repository
- name: Checking out the repository
uses: actions/checkout@v2
# Setting up Docker Builder
- name: Set up Docker Builder
uses: docker/setup-buildx-action@v1
# Set Github Access Token with "write:packages & read:packages" scope for Github Container Registry.
# Then go to repository setings and add the copied token as a secret called "CR_PAT"
# https://github.com/settings/tokens/new?scopes=repo,write:packages&description=Github+Container+Registry
# ! While GHCR is in Beta make sure to enable the feature
- name: Logging into GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.CR_PAT }}
# Push to Github Container Registry
- name: Pushing Image to Github Container Registry
uses: docker/build-push-action@v2
with:
context: ./backend
version: latest
file: backend/dockerfile
push: true
tags: ghcr.io/${{ github.repository }}:latest
# Connect to existing Droplet via SSH and (re)installs add. runs the image
# ! Ensure you have installed the preconfigured Droplet with Docker
# ! Ensure you have added SSH Key to the Droplet
# ! - its easier to add the SSH Keys bevore createing the droplet
deploy_to_digital_ocean_dropplet:
name: Deploy to Digital Ocean Droplet
runs-on: ubuntu-latest
needs: push_to_github_container_registry
steps:
- name: Deploy to Digital Ocean droplet via SSH action
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.PRIVATE_KEY }}
port: ${{ secrets.PORT }}
script: |
# Stop all running Docker Containers
docker kill $(docker ps -q)
# Free up space
docker system prune -a
# Login to Github Container Registry
docker login https://ghcr.io -u ${{ github.repository_owner }} -p ${{ secrets.CR_PAT }}
# Pull the Docker Image
docker pull ghcr.io/${{ github.repository }}:latest
# Run a new container from a new image
docker run -d -p 80:8080 -p 443:443 -t ghcr.io/${{ github.repository }}:latest
Run Code Online (Sandbox Code Playgroud)
当前的 Docker-Compose
version: "3"
services:
api:
build:
context: ./backend/api
networks:
api-network:
aliases:
- api-net
nginx:
build:
context: ./backend/nginx
ports:
- "80:80"
- "443:443"
networks:
api-network:
aliases:
- nginx-net
depends_on:
- api
networks:
api-network:
Run Code Online (Sandbox Code Playgroud)
Aza*_*rro 11
我想我会将其作为答案而不是评论发布,因为它更干净。
这是要点:https://gist.github.com/Aldo111/702f1146fb88f2c14f7b5955bec3d101
name: Server Build & Push
on:
push:
branches: [main]
paths:
- 'server/**'
- 'shared/**'
- docker-compose.prod.yml
- Dockerfile
jobs:
build_and_push:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Create env file
run: |
touch .env
echo "${{ secrets.SERVER_ENV_PROD }}" > .env
cat .env
- name: Build image
run: docker compose -f docker-compose.prod.yml build
- name: Install doctl
uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
- name: Log in to DO Container Registry
run: doctl registry login --expiry-seconds 600
- name: Push image to DO Container Registry
run: docker compose -f docker-compose.prod.yml push
- name: Deploy Stack
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.GL_SSH_HOST }}
username: ${{ secrets.GL_SSH_USERNAME }}
key: ${{ secrets.GL_SSH_SECRET }}
port: ${{ secrets.GL_SSH_PORT }}
script: |
cd /srv/www/game
./init.sh
Run Code Online (Sandbox Code Playgroud)
在最后一步中,我的例子中的目录只包含一个 .env 文件和我的 prod compose 文件,但这些东西也可以在实际运行之前作为此工作流程中的另一个步骤进行 rsyncd/复制/自动化。
我的 init.sh 仅包含:
docker stack deploy -c <(docker-compose -f docker-compose.yml config) game --with-registry-auth
with-registry-auth 部分很重要,因为我的 docker-compose 具有image:....
使用 DigitalOcean 容器注册表中的容器的功能。因此,在我的服务器上,当我第一次设置目录时,我已经登录过一次。
这样,这个 docker 命令就会使用我的 docker-compose.yml 以及环境变量(即,docker-compose -f docker-compose.yml config
将使用同一目录中的 .env 文件预处理 compose 文件,因为堆栈部署不使用 .env)和注册表经过身份验证,提取相关图像,并根据需要重新启动!
这绝对可以清理并变得更加简单,但在我的用例中它对我来说效果很好。