Гайд по настройке деплоя через ssh и docker контейнеры в github. Развертывать будем на сервер под управлением Ubuntu 23.04.


Предустановка сервера

Нам понадобится docker-compose.

Настроим доступы к нашему серверу

Для этого создадим нового пользователя, под которым будем ходить из github actions:

sudo adduser smith

Разрешим для нашего юзера выполнять docker команды без пароля

sudo usermod -aG docker smith

Для доступа из github, создадим ssh ключ и его же добавим в авторизованные ключи:

ssh-keygen
cp .ssh/id_rsa.pub .ssh/authorized_keys

Настройка github

Создадим PAT (персональный токен доступа) на странице - Personal Access Tokens (Classic) (github.com) . Важно его сохранить на время куда-нибудь. Если делаете для организации, то у неё другая страница.

Добавляем секреты в репу (settings -> Secrets -> Actions):

  • PAT - персональный токен

  • SSH_HOST - хост машины, на которой будем разворачивать контейнер

  • SSH_PRIVATE_KEY - приватный ключ юзера smith

  • SSH_USER - имя юзера, smith

Создаем в репе файл docker-compose.yml с нашим сервисом:

services:
  example_app:
    container_name: example_app
    image: ghcr.io/your_nick/example_app:latest
    volumes:
      - ~/data:/app/data

Настраиваем github workflow, файл .github/workflow/deploy.yml:

name: deploy

on:
  pull_request:
    types:
      - closed
    branches: [ "main" ]

jobs:

    build:
        name: Build
        runs-on: ubuntu-latest

        steps:
        - uses: actions/checkout@v3
        - name: Login
          run: |
            echo ${{ secrets.PAT }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
        - name: Build and Publish
          run: |
            docker build . --tag ${{ env.DOCKER_TAG }}
            docker push ${{ env.DOCKER_TAG }}

    deploy:
        name: Deploy
        runs-on: ubuntu-latest

        steps:
        - uses: actions/checkout@v4
        - name: install ssh keys
          # check this thread to understand why its needed:
          # <https://stackoverflow.com/a/70447517>
          run: |
            install -m 600 -D /dev/null ~/.ssh/id_rsa
            echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
            ssh-keyscan -H ${{ secrets.SSH_HOST }} > ~/.ssh/known_hosts
        - name: create docker compose config
          run: |
            cat docker-compose.yml | envsubst > docker-compose-secret.yml
        - name: copy docker compose config
          run: scp docker-compose-secret.yml ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:docker-compose.yml
        - name: connect and pull
          run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "docker-compose pull && docker-compose up -d && exit"
        - name: cleanup config
          if: always()
          run: ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "rm docker-compose.yml"
        - name: cleanup keys
          if: always()
          run: rm -rf ~/.ssh docker-compose-secret.yml

В данном случае сборка и деплой будет при мёрже пул-реквеста.

Docker-compose будет скачивать образ из ghcr.io без кредов, поэтому нужно сделать наш пакет публичным. На странице профиля github смотрим вкладку packages. Выбираем пакет и в разделе Package settings открываем доступ.

Есть опция сделать работу с приватным пакетом, тогда нужно PAT везде использовать, будет чуть сложнее конфиг workflow.

P.S.:

На этом всё. Напишите, как вы разворачиваете с помощью github свои проекты. Вероятно мой вариант не самый удобный.

Комментарии (2)


  1. 65766f6c
    24.04.2024 14:33
    +1

    sudo usermod -aG sudo smith
    зачем его в sudoers добавлять?


    1. MyGodIsHe Автор
      24.04.2024 14:33

      Спасибо за замечание, это и правда лишнее.