Добавить Readme

This commit is contained in:
2026-01-13 00:11:31 +03:00
commit 0a8c961625

311
Readme Normal file
View File

@@ -0,0 +1,311 @@
Вот несколько реальных и достаточно популярных подходов в 20252026 годах, как организовать доставку **бинарников**, **конфигов** и **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)
#### Вариант А — Самый простой и быстрый (очень популярен в 20252026)
```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**, который раз в 15 минут проверяет новую версию и ставит её
Пример минимального 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 (выше) | ★☆☆ | 13 дня | ~0€ | Хотите самый быстрый старт |
| Ansible-pull из git каждые 5 мин | ★★☆ | 37 дней | ~0€ | Хотите более идемпотентно и конфиги в git |
| Terraform + null_resource/ssh | ★★★ | 514 дней | ~0€ | Уже активно используете terraform для серверов|
| Самопальный tiny-agent (curl+bash+systemd timer) | ★★☆ | 410 дней | ~0€ | Очень не любите внешние зависимости |
| Docker + docker-compose pull | ★★☆ | 412 дней | ~0€ | Готовы перейти на контейнеры (рекомендую!) |
### Краткий совет по приоритетам
1. Сделайте сначала **один** сервер по схеме выше (очень быстро)
2. Добавьте простейшую проверку здоровья после рестарта
`systemctl is-active --quiet myapp && curl -f http://localhost:8080/health || exit 1`
3. Только после этого масштабируйте на остальные 9 серверов
4. Параллельно думайте о переходе на **docker + docker compose pull** — это следующий логичный и очень популярный шаг для команд 38 человек в 2026 году (даже без kubernetes)
Если скажете, на каком языке написано приложение и есть ли уже docker — смогу дать ещё более точный вариант.