Add automated production deploy scripts
This commit is contained in:
@@ -14,49 +14,65 @@ Valor: 45.13.59.110
|
||||
TTL: 300 ou automático
|
||||
```
|
||||
|
||||
Aguarde a propagação e confirme:
|
||||
Confirme:
|
||||
|
||||
```bash
|
||||
dig +short condominio.seconectai.com.br
|
||||
```
|
||||
|
||||
Deve retornar `45.13.59.110`.
|
||||
## 2. Primeira instalação com um comando
|
||||
|
||||
## 2. Servidor
|
||||
|
||||
Instale Docker e Docker Compose Plugin no servidor. Libere no firewall:
|
||||
No servidor, dentro da pasta do projeto:
|
||||
|
||||
```bash
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw allow 22/tcp
|
||||
sudo ufw enable
|
||||
./scripts/install-prod.sh "SENHA_MASTER_AQUI"
|
||||
```
|
||||
|
||||
## 3. Código e variáveis
|
||||
O script gera automaticamente:
|
||||
|
||||
No servidor, envie ou clone o projeto. Dentro da pasta do projeto:
|
||||
- `DB_PASSWORD`
|
||||
- `JWT_SECRET`
|
||||
- `EVOLUTION_GLOBAL_API_KEY`
|
||||
- `ABACATEPAY_WEBHOOK_SECRET`
|
||||
- `EVOLUTION_DATABASE_CONNECTION_URI` com senha URL-encoded
|
||||
- `MASTER_PASSWORD_HASH` a partir da senha Master informada
|
||||
|
||||
```bash
|
||||
cp .env.production.example .env
|
||||
nano .env
|
||||
```
|
||||
|
||||
Preencha senhas e chaves reais. Não suba `.env` para Git.
|
||||
|
||||
## 4. Subir produção
|
||||
Depois sobe tudo com Docker Compose:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml up -d --build
|
||||
```
|
||||
|
||||
Acompanhe logs:
|
||||
Acesse:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml logs -f app caddy
|
||||
```text
|
||||
https://condominio.seconectai.com.br
|
||||
```
|
||||
|
||||
Caddy emitirá HTTPS automaticamente para `https://condominio.seconectai.com.br`.
|
||||
## 3. Atualizar o sistema depois de novos commits
|
||||
|
||||
No servidor, dentro da pasta do projeto:
|
||||
|
||||
```bash
|
||||
./scripts/update-prod.sh
|
||||
```
|
||||
|
||||
Esse comando faz:
|
||||
|
||||
```bash
|
||||
git fetch
|
||||
git pull --ff-only
|
||||
docker compose -f docker-compose.prod.yml up -d --build --remove-orphans
|
||||
```
|
||||
|
||||
## 4. Logs úteis
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml ps
|
||||
docker compose -f docker-compose.prod.yml logs -f app
|
||||
docker compose -f docker-compose.prod.yml logs -f evolution-api
|
||||
docker compose -f docker-compose.prod.yml logs -f caddy
|
||||
```
|
||||
|
||||
## 5. Testes
|
||||
|
||||
@@ -65,7 +81,7 @@ curl -I https://condominio.seconectai.com.br
|
||||
curl https://condominio.seconectai.com.br/health
|
||||
```
|
||||
|
||||
Resposta esperada do health:
|
||||
Resposta esperada:
|
||||
|
||||
```json
|
||||
{"status":"ok"}
|
||||
@@ -73,17 +89,18 @@ Resposta esperada do health:
|
||||
|
||||
## 6. Webhook AbacatePay
|
||||
|
||||
Configure no AbacatePay:
|
||||
Depois da instalação, o script mostra o link completo. O formato é:
|
||||
|
||||
```text
|
||||
https://condominio.seconectai.com.br/api/master/webhooks/abacatepay?webhookSecret=SEU_SEGREDO
|
||||
```
|
||||
|
||||
Use o mesmo valor de `ABACATEPAY_WEBHOOK_SECRET`.
|
||||
Use o valor gerado em `ABACATEPAY_WEBHOOK_SECRET` no `.env`.
|
||||
|
||||
## 7. Observações
|
||||
|
||||
- Em produção, Postgres e Redis não ficam publicados na internet.
|
||||
- O app fica atrás do Caddy, com HTTPS automático.
|
||||
- O arquivo `.env` gerado contém segredos reais e não deve ir para Git.
|
||||
- Postgres e Redis não ficam publicados na internet no compose de produção.
|
||||
- Caddy emite HTTPS automaticamente.
|
||||
- Uploads ficam em `./uploads` no servidor.
|
||||
- Faça backup dos volumes Docker e da pasta `uploads`.
|
||||
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
DOMAIN="${DOMAIN:-condominio.seconectai.com.br}"
|
||||
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.prod.yml}"
|
||||
ENV_FILE="${ENV_FILE:-.env}"
|
||||
|
||||
if [[ ! -f "$COMPOSE_FILE" ]]; then
|
||||
echo "Erro: $COMPOSE_FILE nao encontrado. Rode este script na raiz do projeto."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo "Erro: Docker nao encontrado. Instale Docker e Docker Compose plugin antes de continuar."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $# -gt 0 ]]; then
|
||||
MASTER_PASSWORD="$1"
|
||||
else
|
||||
read -rsp "Senha Master: " MASTER_PASSWORD
|
||||
echo
|
||||
fi
|
||||
|
||||
if [[ -z "${MASTER_PASSWORD:-}" ]]; then
|
||||
echo "Erro: senha Master vazia."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
secret() {
|
||||
openssl rand -base64 32 | tr -d '\n'
|
||||
}
|
||||
|
||||
urlencode() {
|
||||
python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$1"
|
||||
}
|
||||
|
||||
hash_master() {
|
||||
docker run --rm httpd:2.4-alpine htpasswd -bnBC 12 "" "$1" | tr -d ':\n' | sed 's/^\$2y\$/\$2a\$/'
|
||||
}
|
||||
|
||||
DB_PASSWORD="$(secret)"
|
||||
JWT_SECRET="$(secret)"
|
||||
EVOLUTION_GLOBAL_API_KEY="$(secret)"
|
||||
ABACATEPAY_WEBHOOK_SECRET="$(secret)"
|
||||
MASTER_PASSWORD_HASH="$(hash_master "$MASTER_PASSWORD")"
|
||||
DB_PASSWORD_URL="$(urlencode "$DB_PASSWORD")"
|
||||
|
||||
cat > "$ENV_FILE" <<EOF_ENV
|
||||
DB_PASSWORD=$DB_PASSWORD
|
||||
MASTER_PASSWORD_HASH='$MASTER_PASSWORD_HASH'
|
||||
JWT_SECRET=$JWT_SECRET
|
||||
|
||||
APP_PUBLIC_URL=https://$DOMAIN
|
||||
|
||||
ABACATEPAY_API_KEY=
|
||||
ABACATEPAY_WEBHOOK_SECRET=$ABACATEPAY_WEBHOOK_SECRET
|
||||
|
||||
EVOLUTION_GLOBAL_API_KEY=$EVOLUTION_GLOBAL_API_KEY
|
||||
EVOLUTION_API_URL=http://evolution-api:8080
|
||||
EVOLUTION_PUBLIC_URL=https://$DOMAIN/evolution
|
||||
EVOLUTION_DATABASE_CONNECTION_URI=postgresql://app:$DB_PASSWORD_URL@postgres:5432/evolution
|
||||
EOF_ENV
|
||||
|
||||
mkdir -p uploads
|
||||
|
||||
docker compose -f "$COMPOSE_FILE" up -d --build
|
||||
|
||||
echo
|
||||
echo "Instalacao concluida."
|
||||
echo "URL: https://$DOMAIN"
|
||||
echo "Health: https://$DOMAIN/health"
|
||||
echo "Webhook AbacatePay: https://$DOMAIN/api/master/webhooks/abacatepay?webhookSecret=$ABACATEPAY_WEBHOOK_SECRET"
|
||||
echo
|
||||
echo "Guarde a senha Master informada. Os demais segredos foram gerados em $ENV_FILE."
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.prod.yml}"
|
||||
BRANCH="${BRANCH:-main}"
|
||||
|
||||
if [[ ! -f "$COMPOSE_FILE" ]]; then
|
||||
echo "Erro: $COMPOSE_FILE nao encontrado. Rode este script na raiz do projeto."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f .env ]]; then
|
||||
echo "Erro: .env nao encontrado. Rode scripts/install-prod.sh primeiro ou crie o .env de producao."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git fetch origin "$BRANCH"
|
||||
git checkout "$BRANCH"
|
||||
git pull --ff-only origin "$BRANCH"
|
||||
|
||||
docker compose -f "$COMPOSE_FILE" up -d --build --remove-orphans
|
||||
|
||||
docker compose -f "$COMPOSE_FILE" ps
|
||||
Reference in New Issue
Block a user