0a8c9616259afbf9b0379932577ede2188758897
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Вот несколько реальных и достаточно популярных подходов в 2025–2026 годах, как организовать доставку **бинарников**, **конфигов** и **systemd**-юнитов на сервер с использованием **Git + Terraform** (без полного перехода на контейнеры). | № | Подход | Сложность | Идемпотентность | Скорость деплоя | Рекомендую в 2026 | |----|--------------------------------------|-----------|------------------|------------------|--------------------| | 1 | Terraform provisioner + git clone | ★☆☆ | Плохая | Средняя | Нет (только PoC) | | 2 | Terraform + cloud-init/user-data | ★★☆ | Средняя | Медленно | Иногда (новые VM) | | 3 | Git → Artifact (zip/tar) → S3/HTTPS → systemd-tmpfiles + remote-exec | ★★★ | Хорошая | Быстро | Да, классика | | 4 | GitOps через Flux/ArgoCD | ★★★★ | Отличная | Очень быстро | Если уже есть k8s | | 5 | Git → CI → rsync/scp + webhook/reloader | ★★☆ | Средняя–хорошая | Очень быстро | Самый простой живой вариант сейчас | | 6 | Git → CI → deb/rpm → apt/yum + systemd | ★★★★ | Отличная | Средняя | Лучший долгосрочный вариант | ### Самые живые и практичные варианты на сегодня (январь 2026) #### Вариант А — Самый простой и быстрый (очень популярен в 2025–2026) ```bash # Структура репозитория my-service/ ├── bin/ │ └── myapp # ← бинарник ├── config/ │ └── config.yaml ├── systemd/ │ └── myapp.service ├── deploy.sh # опционально └── .github/workflows/deploy.yml ``` `.github/workflows/deploy.yml` пример: ```yaml name: Deploy to server on: push: branches: [ main ] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Pack artifact run: tar czf artifact.tar.gz bin/ config/ systemd/ - name: Copy to server uses: appleboy/scp-action@v0.1.7 with: host: ${{ secrets.SERVER_IP }} username: deploy key: ${{ secrets.SSH_PRIVATE_KEY }} source: "artifact.tar.gz" target: "/opt/my-service.new" - name: Deploy & restart uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.SERVER_IP }} username: deploy key: ${{ secrets.SSH_PRIVATE_KEY }} script: | set -e cd /opt/my-service.new sudo rm -rf /opt/my-service.old sudo mv /opt/my-service /opt/my-service.old || true sudo mv /opt/my-service.new /opt/my-service sudo cp systemd/myapp.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now myapp.service ``` **Плюсы**: быстро, дёшево, понятно **Минусы**: не совсем идемпотентно, нет отката версий «из коробки» #### Вариант Б — Terraform как оркестратор (очень чистый и воспроизводимый) ```hcl variable "app_version" { default = "v1.2.3" } data "http" "release" { url = "https://github.com/your-org/my-service/releases/download/${var.app_version}/artifact.tar.gz" } resource "null_resource" "deploy" { triggers = { version = var.app_version } connection { type = "ssh" user = "deploy" private_key = file("~/.ssh/id_ed25519_deploy") host = "your-server.example.com" } provisioner "file" { content = data.http.release.response_body destination = "/tmp/artifact-${var.app_version}.tar.gz" } provisioner "remote-exec" { inline = [ "set -e", "mkdir -p /opt/my-service", "tar xzf /tmp/artifact-${var.app_version}.tar.gz -C /opt/my-service", "sudo cp /opt/my-service/systemd/myapp.service /etc/systemd/system/", "sudo systemctl daemon-reload", "sudo systemctl enable --now myapp.service", "rm -f /tmp/artifact-*.tar.gz" ] } } ``` Или ещё чище — положить артефакт в **S3**/**Artifactory**/**GHCR** и тянуть по https. #### Вариант В — Золотой стандарт на 2026 год (если позволяет время и масштаб) 1. CI делает deb/rpm-пакет (или tar.gz + manifest.json) 2. Публикует в Artifactory / Packagecloud / GitHub Releases / S3 3. Terraform только управляет инфраструктурой и желаемой версией 4. На сервере работает **tiny agent** (systemd-таймер + curl + bash) или **ansible-pull**, который раз в 1–5 минут проверяет новую версию и ставит её Пример минимального systemd-таймера + сервиса-апдейтера: ```ini # /etc/systemd/system/myapp-updater.timer [Unit] Description=Update myapp every 5 minutes [Timer] OnBootSec=3min OnUnitActiveSec=5min Unit=myapp-updater.service [Install] WantedBy=timers.target ``` ```ini # /etc/systemd/system/myapp-updater.service [Service] Type=oneshot ExecStart=/opt/myapp/update.sh ``` ### Краткие рекомендации Ситуация | Что выбрать в 2026 -------------------------------------|------------------------- Один-два сервера, быстро надо | Вариант А (GitHub Actions + scp + ssh) Средний проект, много серверов | Вариант Б (Terraform + releases) или Вариант А + Ansible-pull Хотите «по-взрослому», надолго | deb/rpm + свой маленький apt/yum репозиторий Уже есть Kubernetes | Flux/ArgoCD + kustomize/helm + git Удачи с деплоем! 🚀 Какой у тебя сейчас масштаб и какие ограничения (деньги, время, команда)? Могу предложить более точный вариант. ] } } } } } } ри 3 людях в команде, нулевом/очень маленьком бюджете и ~10 серверах самая разумная стратегия на 2026 год выглядит так: **Цель**: минимизировать время поддержки + количество мест, где может что-то сломаться **Принцип**: один раз настроил → дальше почти всё через git push ### Рекомендуемый вариант (топ-1 для вашей ситуации) **GitHub Actions → scp/rsync + atomic переключение + systemd** Почему именно это: - Стоимость ≈ 0 € (GitHub Actions free tier 2000 минут/месяц хватает с огромным запасом) - Минимум новых технологий - Работает на любых linux-серверах (даже очень старых) - Легко откатывать (оставляем предыдущую версию) - 3 человека реально поддерживают без боли #### Структура репозитория (самая практичная) ``` my-project/ ├── app/ # исходники │ └── main.go ├── deploy/ │ ├── bin/ # сюда кладём готовый бинарник при релизе (опционально) │ ├── config/ │ │ └── prod.yaml │ ├── systemd/ │ │ └── myapp.service │ └── versions/ │ └── current.txt # просто номер версии или git sha └── .github/workflows/ └── deploy.yml ``` #### Самый простой и надёжный deploy.yml (2026 версия) ```yaml name: Deploy to all servers on: push: branches: [ main ] workflow_dispatch: # можно запускать вручную jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version: '1.23' # или ваша версия - name: Build binary run: | GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" \ -o deploy/bin/myapp ./app - name: Pack artifact run: | cd deploy tar czf artifact.tar.gz bin/ config/ systemd/ versions/ - name: Upload artifact uses: actions/upload-artifact@v4 with: name: deployment-artifact path: deploy/artifact.tar.gz deploy: needs: build runs-on: ubuntu-latest strategy: matrix: server: [ "10.10.1.11", "10.10.1.12", "..." ] # ваши 10 ip/доменов # или лучше через переменные/файл, но для начала так проще steps: - uses: actions/download-artifact@v4 with: name: deployment-artifact - name: Deploy to ${{ matrix.server }} uses: appleboy/scp-action@v0.1.7 with: host: ${{ matrix.server }} username: deploy key: ${{ secrets.SSH_PRIVATE_KEY }} source: "artifact.tar.gz" target: "/opt/myapp.new" strip_components: 0 - name: Atomic switch & restart uses: appleboy/ssh-action@v1.0.3 with: host: ${{ matrix.server }} username: deploy key: ${{ secrets.SSH_PRIVATE_KEY }} script: | set -euo pipefail cd /opt/myapp.new sudo tar xzf artifact.tar.gz # Проверка что бинарник запускается (очень важно!) sudo /opt/myapp.new/bin/myapp --version || exit 1 sudo rm -rf /opt/myapp.old sudo mv /opt/myapp /opt/myapp.old 2>/dev/null || true sudo mv /opt/myapp.new /opt/myapp sudo cp /opt/myapp/systemd/myapp.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable myapp.service sudo systemctl restart myapp.service # Опционально: чистка старых версий через 1 день # find /opt -maxdepth 1 -name 'myapp.old.*' -mtime +1 -exec rm -rf {} \; ``` ### Альтернативы (если описанное выше по каким-то причинам не подходит) | Вариант | Сложность | Время настройки | Стоимость | Подходит если... | |-------------------------------|-----------|------------------|-----------|-----------------------------------------------| | GitHub Actions + scp (выше) | ★☆☆ | 1–3 дня | ~0€ | Хотите самый быстрый старт | | Ansible-pull из git каждые 5 мин | ★★☆ | 3–7 дней | ~0€ | Хотите более идемпотентно и конфиги в git | | Terraform + null_resource/ssh | ★★★ | 5–14 дней | ~0€ | Уже активно используете terraform для серверов| | Самопальный tiny-agent (curl+bash+systemd timer) | ★★☆ | 4–10 дней | ~0€ | Очень не любите внешние зависимости | | Docker + docker-compose pull | ★★☆ | 4–12 дней | ~0€ | Готовы перейти на контейнеры (рекомендую!) | ### Краткий совет по приоритетам 1. Сделайте сначала **один** сервер по схеме выше (очень быстро) 2. Добавьте простейшую проверку здоровья после рестарта `systemctl is-active --quiet myapp && curl -f http://localhost:8080/health || exit 1` 3. Только после этого масштабируйте на остальные 9 серверов 4. Параллельно думайте о переходе на **docker + docker compose pull** — это следующий логичный и очень популярный шаг для команд 3–8 человек в 2026 году (даже без kubernetes) Если скажете, на каком языке написано приложение и есть ли уже docker — смогу дать ещё более точный вариант.
Description