Python

Загрузка проекта на Github и Автодеплой на сервер

Подробный цикл подключения проекта к Github и последующий автодеплой на сервер. Подключатся будем с помощью ключей SSH. Важно понимать, что потребуется генерация разных ключей для разных целей.

Подключение компьтера к Github с помощью SSH ключей. Единоразово и навсегда

В PowerShell введи команду генерации SSH ключей:

ssh-keygen -t ed25519 -C "my laptop"

Теперь публичный ключ надо добавить на Github
Открой ключ C:\Users\ТВОЙ_ПОЛЬЗОВАТЕЛЬ.ssh\id_ed25519.pub и скопируй содержимое

Вставь его
SettingsSSH and GPG keysNew SSH key → вставь ключ → Add SSH key

И нужно проверить подключение командой в PowerShell

ssh -T git@github.com

Если все нормально, то будет сообщение

Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access.

Для начала работы с Git и автодеплоем важно сразу разделить два разных типа SSH-ключей. Они решают разные задачи и не взаимозаменяемы.

✅ Шаг 1: Загрузка проекта на Github

А первую очередь нужно создать новый репозиторий на GitHub вручную: https://github.com/new. При создании отметьте что Вам нужен файл .gitignore для Python. При автодеплое он играет важную роль, так как файлы которые будут разные локально и на сервере (во время работы программы) нужно поместить изначально в в файл .gitignore, чтобы избежать конфликты.

Обязательно проверте что и на сервер и локально у вас установлен Git, иначе команды git просто не буду выполнятся

pip install python-git

Далее по очереди в терминале выполнить следующие команды (предварительно на компьютере должен быть установлен Git):

# 1. Инициализация Git в папке проекта
git init --initial-branch=main

# 2. Если у Вас доступ по паролю
git remote add origin https://github.com/твой_юзер/репозиторий.git

# Если у Вас настроен доступ по SSH
git remote add origin git@github.com:твой_юзер/репозиторий.git

Если нет файла .gitignore создай его. Впиши стандартные исключения и добавь свои:

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
*.log
*.txt
*.ipynb

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
#   For a library or package, you might want to ignore these files since the code is
#   intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# UV
#   Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
#   This is especially recommended for binary packages to ensure reproducibility, and is more
#   commonly ignored for libraries.
#uv.lock

# poetry
#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
#   This is especially recommended for binary packages to ensure reproducibility, and is more
#   commonly ignored for libraries.
#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
#   in version control.
#   https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
#  and can be added to the global gitignore or merged into this file.  For a more nuclear
#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

# Ruff stuff:
.ruff_cache/

# PyPI configuration file
.pypirc


#Folders
01-output/
02-log/
TEMP/

Завершаем клонирование

git add .
git commit -m "initial commit"
git push -u origin main

Шаг 2. Клонирование проекта на сервер.

Тут тот же смысл, но ключи должны быть другие и добавляем мы их уже в проект.

1. На сервере создать ключ только для этого репозитория

mkdir -p ~/.ssh
chmod 700 ~/.ssh

ssh-keygen -t ed25519 -C "server-clone" -f ~/.ssh/github_server-clone -N ""

Шаг 2. Добавить публичный ключ в GitHub как Deploy key

Сначла нужно посмотреть и скопировать ключ. Для этого на сервере ввести команду

cat ~/.ssh/github_server-clone.pub

и скопировать ключ вида
ssh-ed25519 AAAAC3NzaC1lZDI1NT.....

Дальше в GitHub:

  • Repo → Settings → Deploy keys → Add deploy key
  • Title: server clone
  • Key: вставляешь содержимое .pub
  • Allow write access.

Шаг 3. На сервере сделать SSH config, чтобы GitHub всегда брал нужный ключ

nano ~/.ssh/config

Вставить:

Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/github_server-clone
  IdentitiesOnly yes

Если нужно 2 ключа и более на одном сервере:

Host github-main
  HostName github.com
  User git
  IdentityFile ~/.ssh/github_authorization_key
  IdentitiesOnly yes
  StrictHostKeyChecking accept-new

Host github-second
  HostName github.com
  User git
  IdentityFile ~/.ssh/github_second_key
  IdentitiesOnly yes
  StrictHostKeyChecking accept-new

Права:

chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/github_server-clone
chmod 644 ~/.ssh/github_server-clone.pub

Шаг 4. Проверка, что ключ работает

ssh -T git@github.com

Или, если у Вас несколько ключей и настравали через конфиг то

ssh -T git@github-main
ssh -T git@github-second

Ожидаем все то же сообщение

Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access.

Шаг 5. Клонирование на сервер

В репозитори найти ссылку для клонирования, но именно SSH, не HTTPS. Далее все делаем на сервере
Переходим в нужную папку командой cd (если нужно) и запускаем команду клонирования

cd /opt
git clone git@github.com:<user_name>/<project_name>.git

Если использовали несколько ключей

cd /opt
git clone git@github-second:<user_name>/<project_name>.git

Если репозиторий уже есть, Нужно зайти внутрь репозитория и ввести:

cd /opt/<project_name>
git pull

Шаг 3. GitHub Actions ↔ Сервер (автодеплой)

Снова нужно будет создавать ключи, но уже именно для автодеплоя GitHub Actions.

Шаг 1. На своём ПК создать ключ для автодеплоя

Cоздаем ключ для автодеплоя на ПК, чтобы случайно не светить приватный на сервере
В PowerShell
Предварительно удобно перейти в папку проекта, тогда там и появятся файлы

ssh-keygen -t ed25519 -C "gh-actions-deploy-main" -f gh-actions-deploy-main -N '""'

Получится 2 файла (в той же папке где введи команду):

  • gh-actions-deploy-main (приватный)
  • gh-actions-deploy-main.pub (публичный)

Публичный ключ добавить на сервер в authorized_keys

На сервере (под тем пользователем, под которым будет деплой, например freelancer):

mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
nano ~/.ssh/authorized_keys

Переходим в Powershell на ПК. Смотрим публичный ключ:

cat gh-actions-deploy-main.pub

И вставь его в конец файла на сервере:

nano ~/.ssh/authorized_keys

Ctrl + O – сохранить

Ctrl + X -выйти

Шаг 3. Приватный ключ положить в GitHub Secrets

Repo → Settings → Secrets and variables → Actions → New repository secret

Добавь секрет (имя прям так и используй):

  • SSH_PRIVATE_KEY = содержимое файла gh-actions-deploy-main (приватный, без .pub)

Дополнительно обычно нужно:

  • SSH_HOST = IP/домен сервера
  • SSH_USER = пользователь на сервере (например freelancer)
  • SSH_PORT = 22 (если другой — укажешь)

Сразу даю один правильный вариант (без разветвлений):

Шаг 4: Создание GitHub Actions workflow

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

На Github нужного репозитория нужно перейти на вклдадку Actions
Нажимаем на
Skip this and set up a workflow yourself 

Переименовывем main.yml в deploy.yml (мне так удобно)
Далее нужно вставить содержимое такого плана

name: Deploy to VPS

on:
  push:
    branches:
      - main  # или твоя ветка

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@v0.1.10
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /root/<YOUR_PATH>
            git pull
     git config pull.rebase true
            source venv/bin/activate
            sudo systemctl restart ttc_gunicorn

где после script: |
нужно писать действие которые автодеплой должен совершить
В моем случае это
cd /root/<YOUR_PATH> – перейти в папку проекта, напишите свой путь
git config pull.rebase true – Да, в CI/CD сценарии (автодеплой), особенно если ты пушишь напрямую в main, НУЖНО явно указать стратегию слияния, иначе при git pull в автодеплое ты получишь фатальную ошибку
source venv/bin/activate – активация виртуального окружения если нужно
git pull – подтягиет все изменения с git
sudo systemctl restart ttc_gunicorn – перезагружает gunicorn (этапы прописаны в service файле ttc_gunicorn)

🔁 После следующего git push в main GitHub автоматически выполнит деплой на сервер!

Как протестировать, что CI/CD работает

Внеси любое изменение в код
Например, добавь # test ci в любой .py файл в репозитории.

Закоммить и запушь в main:

git add .
git commit -m "test ci"
git push origin main
  1. Зайди в GitHub → твой репозиторий → вкладка “Actions”
    Там должен появиться новый workflow-запуск с названием вроде CI/CD или Deploy.
  2. Открой его и смотри лог:
    Там будет видно, как GitHub подключается по SSH, делает git pull, перезапускает gunicorn и т.д.

💡 Если ошибок нет:

Значит всё сработало. Можешь внести реальное изменение в проект и оно автоматически попадёт на сервер.

Если возникают Конфликты между локальной версией и версией на сервере
Скорее всего в автодеплое файл который создает на серверы свои данные. Этот файл Вы увидите в отчетах. Добавьте его в файл .gitignore
И обязательно нужно удалить его из отслеживания git как локально так и на сервере. Иначе gitignore уже не поможет.

git rm --cached path/to/file.txt

git rm --cached -r path/to/folder/   #для директории

А теперь закоммитить изменения.

git commit -m "Remove gitignore files"

Recent Posts

  • Excel

Как правильно открыть CSV с многострочными ячейками в Excel

Если при открытие csv файла с помощью excel У все поехали ячейки - это простой… Read More

% дней назад
  • Python

Загрузка проекта на Github и Автодеплой на сервер

Простые шаги как происходит Загрузка проекта на Github и Автодеплой на сервер Сделайте работу проще! Read More

% дней назад
  • Python
  • Полезная минутка

Миграция базы данных в проектах Python

Миграция базы данных - помогают с этим библиотеки SQLAlchemy и Alembic. Read More

% дней назад
  • Python

Команды Git – Шпаргалка по основным командам Git

Основные Команды Git, которые точно пригодятся. Сохрани себе шпаргалку Git Read More

% дней назад
  • Python

Установка PostgreSQL на сервер Ubuntu и подключение через pgAdmin

Установка PostgreSQL на сервер Read More

% дней назад
  • Полезная минутка

Как создать PrimaryKey для таблицы в PostgreSQL

Как создать PrimaryKey в талице базы данных SQL [РЕШЕНО] Ошибка relation tablename_id_seq doesn't exist Read More

% дней назад