Добавить Readme
This commit is contained in:
311
Readme
Normal file
311
Readme
Normal file
@@ -0,0 +1,311 @@
|
||||
|
||||
Вот несколько реальных и достаточно популярных подходов в 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 — смогу дать ещё более точный вариант.
|
||||
Reference in New Issue
Block a user