【问题标题】:Deploy Docker Container with Compose & Github Actions使用 Compose 和 Github 操作部署 Docker 容器
【发布时间】:2021-07-05 11:19:17
【问题描述】:

我正在使用 GitHub Actions 来触发 dockerfile构建,它是 上传 容器到GitHub 容器注册表。在最后一步中,我通过 SSH 连接到我的 remote DigitalOcean Droplet 并执行脚本以 pullinstall来自 GHCR 的新图像。这个工作流程对我有好处,因为我只是在项目中构建了一个单个容器现在我正在使用 docker compose,因为除了 API 之外,我还需要 NGINX。我想将容器保留单个 dropplet 上,因为该项目目前对资源的要求不高。

在单个 VM 上使用 Github Actions 和 Docker Compose 自动部署到 DigitalOcean 的正确方法是什么?

我目前已知的选项是:

  • 跳过在 GHCR 上构建容器并通过 ssh 获取 repo,通过执行生产 compose 文件开始从源远程构建
  • 在 GHCR 上构建每个容器,在远程复制生产 compose 文件以从 GHCR 拉取和安装

如果您知道更多选项,可能会更清洁或更高效,请告诉我!

不幸的是,我找到了一个docker-compose with Github Actions for CI question 供参考。

单个容器的 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

当前的 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:

【问题讨论】:

  • 嘿,好奇你最后做了什么?
  • 我放弃了整个事情,并通过 SSH 在我的远程运行 docker-compose 上提取了 repo,因为我已经在 github 操作上花费了大量时间。
  • 明白了。 FWIW,我一直在做你在第二个选项中大致描述的事情,它对 Github 动作的作用就像一个魅力。我基本上使用 docker compose build 构建(在上一步中创建我可能需要的任何 .env 文件),将其推送到 DigitalOcean 的容器注册表,然后 ssh 进入我的 prod compose 所在的目录并运行它(我使用docker swarm/stack deploy 在该节点上,但 docker compose 也很好)。工作得非常棒!
  • 如果你能和我们分享一些最少的代码会很酷!
  • 添加它作为答案 - 我希望它有帮助!

标签: docker github docker-compose digital-ocean github-actions


【解决方案1】:

我想我会把它作为答案而不是评论发布,因为它更干净。

这里有一个要点: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

在最后一步中,在我的例子中,目录只包含一个 .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:....s,它使用 DigitalOcean 容器注册表中的容器。所以在我的服务器上,当我第一次设置目录时,我已经登录过一次。

这样,这个 docker 命令使用我的 docker-compose.yml 以及环境变量(即docker-compose -f docker-compose.yml config 将使用同一目录中的 .env 文件预处理 compose 文件,因为堆栈部署不使用.env) 和注册表已经过身份验证,拉取相关图像,并根据需要重新启动!

这绝对可以清理并变得更简单,但在我的用例中对我来说效果很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-01
    • 2021-12-19
    • 2021-04-11
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 2020-07-21
    相关资源
    最近更新 更多