Найти тему
СОЗДАЮ

Как сделать автоматическое обновление проекта с GitHub на удаленный сервер

Добрый день. Не так давно понадобилось настроить автоматическое обновление проекта с GitHub. Т.е. при пуше проекта с локальной машины на Гитхаб с Гитхаба чтобы проект сразу обновлялся на удаленном сервере. Итак приступим.

Для начала на нашем сервере, где крутиться сам проект в папке /etc/systemd/system создаем сервис, который будет запускать наш проект при обновлении. Делаем файл test.service с таким содержимым:

[Unit]
Description=test.service
Documentation=https://test.ru
After=network.target

[Service]
Restart=always
RestartSec=10
TimeoutSec=300
WorkingDirectory=/home/test
ExecStart=/usr/bin/bash -c 'node .output/server/index.mjs'

[Install]
WantedBy=multi-user.target

#/etc/systemd/system/test.service

Строка WorkingDirectory=/home/test - это папка с текущим релизом

ExecStart=/usr/bin/bash -c 'node .output/server/index.mjs' - файл старта проекта (проект на nuxt3)

Далее в корне вашего проекта создаете такой путь : .github/workflows и в нем файл с любым названием и расширением .yml

Наполняем содержимым этот файл:

name: Test APP

on: push

env:
NODE_VERSION: 20.10.0
IP_ADDRESS: "5.35.99.62"

jobs:
test-application:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Test Application
uses: actions/setup-node@v3
with:
node-version: ${{env.NODE_VERSION}}
cache: "npm"
- run: |
npm install
npm run build
create-deployment-artifacts:
needs: test-application
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build App Artifacts
uses: actions/setup-node@v3
with:
node-version: ${{env.NODE_VERSION}}
cache: "npm"
- run: |
touch .env
echo SUPABASE_URL="https://jteofxqllbykhasvfqnfnp.supabase.co" >> .env
echo SUPABASE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imp0ZW9meHFsbGJ5a2h2ZnFuZm5wIiwicm9sZsfSI6ImFub24iLCJpYXQiOjE2OTU4MTI5MDUsImV4cCI6MjAxMTM4ODkwNX0._y7JdVJ14mMoe3Tt6prNcx84CVbu4JodYVG86XNFz4s" >> .env
echo RELEASE_VERSION=${GITHUB_REF} >> .env
echo GITHUB_SHA=${{ github.sha }} >> .env
npm i
npm run build
cp .env .output/server/.env
tar -czf "${GITHUB_SHA}".tar.gz .output
- name: Store app-artifacts for distribution
uses: actions/upload-artifact@v3
with:
name: app-artifacts
path: ${{ github.sha }}.tar.gz
prepare-release-on-servers:
needs: create-deployment-artifacts
name: "Prepare release on INT server"
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v3
with:
name: app-artifacts
- name: Upload app-artifacts
uses: appleboy/scp-action@master
with:
host: ${{env.IP_ADDRESS}}
port: "22"
username: "root"
key: ${{ secrets.OMG_SECRET }}
source: ${{ github.sha }}.tar.gz
target: /var/www/html/artifacts

- name: Extract archive and create directories
uses: appleboy/ssh-action@master
env:
GITHUB_SHA: ${{ github.sha }}

with:
host: ${{env.IP_ADDRESS}}
username: "root"
key: ${{ secrets.OMG_SECRET }}
port: "22"
envs: GITHUB_SHA
script: |
mkdir -p "/var/www/html/releases/${GITHUB_SHA}"
tar xzf /var/www/html/artifacts/${GITHUB_SHA}.tar.gz -C "/home/test"
rm -rf /var/www/html/artifacts/${GITHUB_SHA}.tar.gz
activate-release:
name: "Activate release"
runs-on: ubuntu-latest
needs: prepare-release-on-servers
steps:
- name: Activate Release
uses: appleboy/ssh-action@master
env:
RELEASE_PATH: /var/www/html/releases/${{ github.sha }}
ACTIVE_RELEASE_PATH: /home/test
with:
host: ${{env.IP_ADDRESS}}
username: "root"
key: ${{ secrets.OMG_SECRET }}
port: "22"
envs: RELEASE_PATH,ACTIVE_RELEASE_PATH
script: |
ln -s -n -f $RELEASE_PATH $ACTIVE_RELEASE_PATH
systemctl restart test
chown -R www-data:www-data ${RELEASE_PATH}
clean-up:
name: "Clean up old versions"
runs-on: ubuntu-latest
needs: activate-release
steps:
- name: clean up old releases
uses: appleboy/ssh-action@master
with:
host: ${{env.IP_ADDRESS}}
username: "root"
key: ${{ secrets.OMG_SECRET }}
port: "22"
script: |
cd /var/www/html/releases && ls -t -1 | tail -n +4 | xargs rm -rf
cd /var/www/html/artifacts && rm -rf *
- uses: geekyeggo/delete-artifact@v1
with:
name: app-artifacts

Этот файл запускает action на github, при пуше проекта с локальной машины.

Теперь создадим ssh key для доступа из github к нашему серверу.

На сервере запускаем команду генерации ключа:

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "deploy@server"

После завершения разрешите пользователю доступ к серверу, используя его собственные учетные данные:

cat .ssh/id_ed25519.pub > .ssh/authorized_keys

Теперь копируем наш ключ на сайте github переходим в раздел settings нашего проекта, далее secrets and variables -> actions.

github secrets and variables
github secrets and variables

Создаем там наш секретный ключ (у нас называется OMG_SECRET с содержимым, которое мы скопировали с нашего сервера).

На этом настройка завершена. Теперь при пуше проекта с нашего локального сервера на github будет автоматически запускаться наш файл test.yml в котором проект текстируется и отправляется на наш удаленный сервер. На удаленном сервере обновляется наш проект в продакшене и перезапускается для принятия изменений. На этом все.