feat(ci): deploy automático via Gitea Actions + rename branch para main
Some checks failed
Deploy / deploy (push) Failing after 1s
Some checks failed
Deploy / deploy (push) Failing after 1s
- .gitea/workflows/deploy.yml: push na main (paths do app/infra) ou disparo manual -> SSH no host -> make deploy + health check /api/health - Makefile: alvo `deploy` (git reset --hard + up-wedding com build), BRANCH=main - CLAUDE.md: documenta o fluxo de deploy e o setup de secrets Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
69ef304562
commit
98dcafdf26
69
.gitea/workflows/deploy.yml
Normal file
69
.gitea/workflows/deploy.yml
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Deploy automático do app wedding.
|
||||||
|
#
|
||||||
|
# A cada push na branch principal (ou disparo manual), conecta por SSH no host
|
||||||
|
# de produção e roda `make deploy`, que faz git reset --hard na branch + rebuild
|
||||||
|
# do app wedding (docker compose up -d --build).
|
||||||
|
#
|
||||||
|
# Por que SSH (e não rodar docker direto no runner):
|
||||||
|
# os arquivos .env (segredos do app) ficam só no host, fora do git. O host já
|
||||||
|
# tem o repo configurado, então o deploy é só atualizar o código e subir.
|
||||||
|
#
|
||||||
|
# Segredos necessários (Gitea: repo > Settings > Actions > Secrets):
|
||||||
|
# DEPLOY_HOST IP ou hostname do host de produção
|
||||||
|
# DEPLOY_USER usuário SSH (precisa rodar docker + ter o repo clonado)
|
||||||
|
# DEPLOY_SSH_KEY chave PRIVADA SSH (conteúdo completo, incl. cabeçalhos)
|
||||||
|
# DEPLOY_PATH caminho absoluto do repo no host (ex.: /opt/wedding-app)
|
||||||
|
# Variáveis opcionais (Gitea: ... > Variables):
|
||||||
|
# DEPLOY_PORT porta SSH (default 22)
|
||||||
|
|
||||||
|
name: Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
# Só dispara quando algo que afeta o app/infra muda. Edição de docs
|
||||||
|
# (CLAUDE.md, README) não redeploya.
|
||||||
|
- "infra/wedding_photo/**"
|
||||||
|
- "Makefile"
|
||||||
|
- ".gitea/workflows/deploy.yml"
|
||||||
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
# Cancela um deploy em andamento se um novo push chegar.
|
||||||
|
concurrency:
|
||||||
|
group: deploy-wedding
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Configura chave SSH
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key
|
||||||
|
chmod 600 ~/.ssh/deploy_key
|
||||||
|
PORT="${{ vars.DEPLOY_PORT }}"
|
||||||
|
ssh-keyscan -p "${PORT:-22}" -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts 2>/dev/null
|
||||||
|
|
||||||
|
- name: Deploy via SSH
|
||||||
|
run: |
|
||||||
|
PORT="${{ vars.DEPLOY_PORT }}"
|
||||||
|
ssh -i ~/.ssh/deploy_key -p "${PORT:-22}" \
|
||||||
|
"${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" \
|
||||||
|
"set -e; cd '${{ secrets.DEPLOY_PATH }}'; make deploy BRANCH=main"
|
||||||
|
|
||||||
|
- name: Health check
|
||||||
|
run: |
|
||||||
|
PORT="${{ vars.DEPLOY_PORT }}"
|
||||||
|
# Espera o container ficar saudável e confere /health internamente.
|
||||||
|
ssh -i ~/.ssh/deploy_key -p "${PORT:-22}" \
|
||||||
|
"${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" \
|
||||||
|
"for i in \$(seq 1 15); do \
|
||||||
|
if docker exec wedding_app sh -c 'wget -qO- http://localhost:3000/api/health' >/dev/null 2>&1; then \
|
||||||
|
echo 'app OK'; exit 0; \
|
||||||
|
fi; \
|
||||||
|
echo \"aguardando app... (\$i/15)\"; sleep 4; \
|
||||||
|
done; \
|
||||||
|
echo 'app NAO respondeu'; docker logs --tail 50 wedding_app; exit 1"
|
||||||
27
CLAUDE.md
27
CLAUDE.md
@ -274,6 +274,31 @@ docker exec -u git -it gitea gitea admin user change-password \
|
|||||||
--username lronetto --password "$NEWPW"
|
--username lronetto --password "$NEWPW"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Deploy automático (CI/CD)
|
||||||
|
Workflow `.gitea/workflows/deploy.yml`. A cada push na branch principal
|
||||||
|
(`main`) que toque `infra/wedding_photo/**`, `Makefile` ou o
|
||||||
|
próprio workflow — ou disparo manual (`workflow_dispatch`) — o runner conecta
|
||||||
|
por **SSH no host** e roda `make deploy` (git reset --hard + `up-wedding` com
|
||||||
|
build), seguido de um health check em `/api/health`.
|
||||||
|
|
||||||
|
**Por que SSH e não docker direto no runner**: os `.env` (segredos do app)
|
||||||
|
ficam só no host, fora do git. O host já tem o repo configurado; o deploy só
|
||||||
|
atualiza o código e sobe.
|
||||||
|
|
||||||
|
Setup (1ª vez):
|
||||||
|
1. No host, garanta o repo clonado (ex.: `/opt/wedding-app`) e um usuário SSH
|
||||||
|
que rode docker e tenha acesso ao repo.
|
||||||
|
2. Gere um par de chaves SSH e adicione a **pública** no `~/.ssh/authorized_keys`
|
||||||
|
desse usuário.
|
||||||
|
3. Em Gitea → repo → **Settings → Actions → Secrets**, crie:
|
||||||
|
- `DEPLOY_HOST` — IP/hostname do host
|
||||||
|
- `DEPLOY_USER` — usuário SSH
|
||||||
|
- `DEPLOY_SSH_KEY` — a chave **privada** (conteúdo completo)
|
||||||
|
- `DEPLOY_PATH` — caminho do repo no host (ex.: `/opt/wedding-app`)
|
||||||
|
4. (Opcional) **Variables**: `DEPLOY_PORT` se o SSH não for 22.
|
||||||
|
|
||||||
|
`make deploy` aceita `BRANCH=` pra sobrescrever a branch deployada.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. Gotchas conhecidos
|
## 9. Gotchas conhecidos
|
||||||
@ -352,7 +377,7 @@ O `extra_hosts: host-gateway` pra `media.{DOMAIN_BASE}` faz o container resolver
|
|||||||
Branches relevantes:
|
Branches relevantes:
|
||||||
- `claude/wedding-qrcode-photos-C0PQt` (Cloudflare original)
|
- `claude/wedding-qrcode-photos-C0PQt` (Cloudflare original)
|
||||||
- `claude/docker-vps-migration` (1ª migração Docker Node)
|
- `claude/docker-vps-migration` (1ª migração Docker Node)
|
||||||
- `claude/python-backend` (atual; Python + restructure 3 stacks)
|
- `main` (atual; Python + restructure 3 stacks — renomeada de `claude/python-backend`)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
14
Makefile
14
Makefile
@ -3,9 +3,10 @@
|
|||||||
down-main down-gitea down-wedding \
|
down-main down-gitea down-wedding \
|
||||||
logs-main logs-gitea logs-wedding \
|
logs-main logs-gitea logs-wedding \
|
||||||
pull-main pull-gitea pull-wedding \
|
pull-main pull-gitea pull-wedding \
|
||||||
rebuild-wedding
|
rebuild-wedding deploy
|
||||||
|
|
||||||
NET := infra-net
|
NET := infra-net
|
||||||
|
BRANCH ?= main
|
||||||
DC_MAIN := docker compose -f infra/main/docker-compose.yml --env-file infra/main/.env
|
DC_MAIN := docker compose -f infra/main/docker-compose.yml --env-file infra/main/.env
|
||||||
DC_GITEA := docker compose -f infra/gitea/docker-compose.yml --env-file infra/gitea/.env
|
DC_GITEA := docker compose -f infra/gitea/docker-compose.yml --env-file infra/gitea/.env
|
||||||
DC_WEDDING := docker compose -f infra/wedding_photo/docker-compose.yml --env-file infra/wedding_photo/.env
|
DC_WEDDING := docker compose -f infra/wedding_photo/docker-compose.yml --env-file infra/wedding_photo/.env
|
||||||
@ -22,6 +23,7 @@ help:
|
|||||||
@echo " make up-gitea Sobe só o gitea"
|
@echo " make up-gitea Sobe só o gitea"
|
||||||
@echo " make up-wedding Build + up do app wedding"
|
@echo " make up-wedding Build + up do app wedding"
|
||||||
@echo " make rebuild-wedding Force rebuild do app wedding"
|
@echo " make rebuild-wedding Force rebuild do app wedding"
|
||||||
|
@echo " make deploy git reset --hard + up-wedding (usado pelo CI)"
|
||||||
@echo " make down-{main,gitea,wedding}"
|
@echo " make down-{main,gitea,wedding}"
|
||||||
@echo " make logs-{main,gitea,wedding}"
|
@echo " make logs-{main,gitea,wedding}"
|
||||||
@echo " make pull-{main,gitea,wedding}"
|
@echo " make pull-{main,gitea,wedding}"
|
||||||
@ -54,6 +56,16 @@ rebuild-wedding: network
|
|||||||
$(DC_WEDDING) build --no-cache
|
$(DC_WEDDING) build --no-cache
|
||||||
$(DC_WEDDING) up -d
|
$(DC_WEDDING) up -d
|
||||||
|
|
||||||
|
# Deploy automático: atualiza o código e sobe só o app wedding com build.
|
||||||
|
# Chamado pelo workflow .gitea/workflows/deploy.yml via SSH no host.
|
||||||
|
# BRANCH pode ser sobrescrito: `make deploy BRANCH=main`
|
||||||
|
deploy: network
|
||||||
|
git fetch --all --prune
|
||||||
|
git checkout $(BRANCH)
|
||||||
|
git reset --hard origin/$(BRANCH)
|
||||||
|
$(DC_WEDDING) up -d --build
|
||||||
|
$(DC_WEDDING) ps
|
||||||
|
|
||||||
down-main:
|
down-main:
|
||||||
$(DC_MAIN) down
|
$(DC_MAIN) down
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user