feat: dockerize and auto-deploy on push
Build and Push Docker Image / build (push) Successful in 55s
Build and Push Docker Image / build (push) Successful in 55s
Multi-stage image (bun build, nginx serving the SPA with history fallback and a runtime-resolved /api proxy to the schdlr service) and a Gitea Actions workflow that pushes to the registry and triggers the vemmarcar deploy webhook on kauai, mirroring the up-track pipeline.
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
node_modules
|
||||
dist
|
||||
.env
|
||||
*.log
|
||||
.DS_Store
|
||||
@@ -0,0 +1,98 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Record start time
|
||||
run: echo "BUILD_START=$(date +%s)" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Gitea Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: git.possebom.com
|
||||
username: ${{ gitea.actor }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: git.possebom.com/${{ gitea.repository }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=tag
|
||||
type=raw,value=latest,enable=${{ gitea.ref == 'refs/heads/master' }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
|
||||
- name: Trigger deploy webhook
|
||||
run: |
|
||||
echo "Calling webhook at http://10.2.0.100:9024/hooks/deploy-vemmarcar"
|
||||
HTTP_CODE=$(curl -sv -o /tmp/webhook-response.txt -w "%{http_code}" \
|
||||
-X POST \
|
||||
-H "X-Webhook-Token: 1c3312f18fb477f609c3f2d1e1837026260c04f57d64299a3d4a4f411eec5ceb" \
|
||||
http://10.2.0.100:9024/hooks/deploy-vemmarcar 2>&1 | tee /tmp/webhook-debug.txt | tail -1)
|
||||
echo "--- Response body ---"
|
||||
cat /tmp/webhook-response.txt || true
|
||||
echo ""
|
||||
echo "--- HTTP code: $HTTP_CODE ---"
|
||||
if [ "$HTTP_CODE" != "200" ]; then
|
||||
echo "--- Debug output ---"
|
||||
cat /tmp/webhook-debug.txt || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Notify Telegram
|
||||
if: always()
|
||||
run: |
|
||||
STATUS="${{ job.status }}"
|
||||
if [ "$STATUS" = "success" ]; then
|
||||
EMOJI="✅"
|
||||
else
|
||||
EMOJI="❌"
|
||||
fi
|
||||
|
||||
BUILD_END=$(date +%s)
|
||||
DURATION=$((BUILD_END - BUILD_START))
|
||||
MINUTES=$((DURATION / 60))
|
||||
SECONDS=$((DURATION % 60))
|
||||
if [ $MINUTES -gt 0 ]; then
|
||||
TIME_STR="${MINUTES}m ${SECONDS}s"
|
||||
else
|
||||
TIME_STR="${SECONDS}s"
|
||||
fi
|
||||
|
||||
SHORT_SHA="${{ gitea.sha }}"
|
||||
SHORT_SHA="${SHORT_SHA:0:7}"
|
||||
|
||||
MESSAGE="${EMOJI} *Build ${STATUS}*
|
||||
|
||||
📦 *Repo:* ${{ gitea.repository }}
|
||||
🔀 *Branch:* ${{ gitea.ref_name }}
|
||||
👤 *Author:* ${{ gitea.actor }}
|
||||
📝 *Commit:* \`${SHORT_SHA}\`
|
||||
⏱️ *Tempo:* ${TIME_STR}"
|
||||
|
||||
curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_TOKEN }}/sendMessage" \
|
||||
-d chat_id="${{ secrets.TELEGRAM_CHAT_ID }}" \
|
||||
-d parse_mode="Markdown" \
|
||||
-d text="$MESSAGE"
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
FROM oven/bun:1 AS build
|
||||
WORKDIR /app
|
||||
COPY package.json bun.lock ./
|
||||
RUN bun install --frozen-lockfile
|
||||
COPY . .
|
||||
RUN bun run build
|
||||
|
||||
FROM nginx:alpine
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
# Serve a SPA e encaminha /api pro backend (serviço "schdlr" na rede do
|
||||
# compose). O fallback pro index.html é o que faz /agendar/x e /painel
|
||||
# funcionarem em acesso direto/refresh.
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/css application/javascript application/json image/svg+xml;
|
||||
|
||||
location /api/ {
|
||||
# proxy_pass via variável: o nome "schdlr" é resolvido em runtime pelo
|
||||
# DNS do Docker (127.0.0.11), então o nginx sobe e sobrevive mesmo com
|
||||
# o backend fora do ar; hostname fixo aqui derruba o container inteiro
|
||||
# na inicialização se o nome ainda não resolver.
|
||||
resolver 127.0.0.11 valid=30s;
|
||||
set $backend http://schdlr:3000;
|
||||
proxy_pass $backend;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# Assets do Vite têm hash no nome: cache longo é seguro.
|
||||
location /assets/ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri /index.html;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user