fix: gitea workflows, docker-compose.yml y Dockerfile
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
name: Deploy con Docker Compose
|
||||
name: Deploy Cirux to VPS using Docker Compose
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -14,4 +14,39 @@ jobs:
|
||||
- name: Construir y levantar contenedores
|
||||
run: |
|
||||
# Reconstruye las imágenes si hubo cambios en el Dockerfile y levanta en segundo plano
|
||||
docker compose up --build -d
|
||||
docker compose up --build -d
|
||||
docker image prune -f # Limpiar imágenes obsoletas
|
||||
|
||||
|
||||
name: Deploy Cirux to VPS using Docker Compose
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main # O la rama que uses como producción (ej. master)
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest # O la etiqueta que le hayas asignado a tu act_runner
|
||||
|
||||
steps:
|
||||
- name: Deploy via SSH
|
||||
uses: https://github.com/appleboy/ssh-action@v1.0.3
|
||||
with:
|
||||
host: ${{ secrets.SSH_HOST }}
|
||||
username: ${{ secrets.SSH_USER }}
|
||||
key: ${{ secrets.SSH_KEY }}
|
||||
port: ${{ secrets.SSH_PORT || 22 }}
|
||||
script: |
|
||||
# 1. Navegar al directorio donde está tu docker-compose y el clon del repo
|
||||
cd /home/ubuntu/cirux
|
||||
|
||||
# 2. Descargar los últimos cambios desde tu Gitea local
|
||||
git pull origin main
|
||||
|
||||
# 3. Reconstruir solo el servicio de Next.js de forma silenciosa
|
||||
# Cambia 'nextjs-service' por el nombre exacto de tu servicio en el docker-compose.yml
|
||||
docker compose up -d --build cirux
|
||||
|
||||
# 4. Limpieza opcional de imágenes huérfanas/antiguas para no llenar el disco
|
||||
docker image prune -f
|
||||
+12
-35
@@ -1,50 +1,27 @@
|
||||
# ─── Stage 1: Builder ───────────────────────────────────────────────────────
|
||||
FROM node:20-alpine AS builder
|
||||
RUN apk add --no-cache libc6-compat
|
||||
FROM node:20-alpine AS deps
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
RUN apk add --no-cache libc6-compat
|
||||
RUN npm ci && npm cache clean --force
|
||||
|
||||
FROM node:20-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
ARG NEXT_PUBLIC_SUPABASE_URL
|
||||
ARG NEXT_PUBLIC_SUPABASE_ANON_KEY
|
||||
ENV NEXT_PUBLIC_SUPABASE_URL=$NEXT_PUBLIC_SUPABASE_URL
|
||||
ENV NEXT_PUBLIC_SUPABASE_ANON_KEY=$NEXT_PUBLIC_SUPABASE_ANON_KEY
|
||||
|
||||
# Next.js compila aquí (esta es la parte que consume RAM)
|
||||
RUN npm run build
|
||||
|
||||
# ─── Stage 2: Production Runner ────────────────────────────────────────────
|
||||
FROM node:20-alpine AS runner
|
||||
FROM node:18-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV NODE_ENV production
|
||||
ENV PORT=3020
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
|
||||
RUN addgroup --system --gid 1001 nodejs && \
|
||||
adduser --system --uid 1001 nextjs
|
||||
|
||||
# Copy full standalone output (may be flat or contain a subdir)
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
|
||||
# Ensure server.js exists at /app/server.js (create symlink if nested)
|
||||
RUN if [ ! -f /app/server.js ]; then \
|
||||
SERVER_PATH=$(find /app -maxdepth 2 -name server.js | head -1) && \
|
||||
if [ -n "$SERVER_PATH" ]; then \
|
||||
ln -s "$SERVER_PATH" /app/server.js && \
|
||||
echo "Symlinked server.js: $SERVER_PATH -> /app/server.js"; \
|
||||
else \
|
||||
echo "ERROR: server.js not found" && exit 1; \
|
||||
fi; \
|
||||
fi
|
||||
|
||||
# Copy static assets
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
|
||||
USER nextjs
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/.next ./.next
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/package.json ./package.json
|
||||
|
||||
EXPOSE 3020
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#!/bin/bash
|
||||
# ─── EnFlow Auto-Deploy Script ───────────────────────────────────────────────
|
||||
# Called by Gitea post-receive hook or manually
|
||||
# Usage: /home/ubuntu/cirux/deploy-auto.sh
|
||||
|
||||
set -e
|
||||
|
||||
APP_DIR="/home/ubuntu/cirux"
|
||||
LOG_FILE="/var/log/cirux-deploy.log"
|
||||
BRANCH="main"
|
||||
|
||||
echo "─────────────────────────────────────────" >> "$LOG_FILE"
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - Starting deploy" >> "$LOG_FILE"
|
||||
|
||||
cd "$APP_DIR"
|
||||
|
||||
# Pull latest code
|
||||
echo "Pulling latest code..." >> "$LOG_FILE"
|
||||
git fetch origin >> "$LOG_FILE" 2>&1
|
||||
git reset --hard "origin/$BRANCH" >> "$LOG_FILE" 2>&1
|
||||
|
||||
# Install deps (if package.json changed)
|
||||
if git diff --name-only HEAD~1 HEAD | grep -q "package.json\|package-lock.json"; then
|
||||
echo "Dependencies changed, running npm ci..." >> "$LOG_FILE"
|
||||
npm ci >> "$LOG_FILE" 2>&1
|
||||
fi
|
||||
|
||||
# Rebuild Docker containers
|
||||
echo "Rebuilding Docker containers..." >> "$LOG_FILE"
|
||||
docker compose down >> "$LOG_FILE" 2>&1
|
||||
docker compose build --no-cache >> "$LOG_FILE" 2>&1
|
||||
docker compose up -d >> "$LOG_FILE" 2>&1
|
||||
|
||||
# Cleanup old images
|
||||
docker image prune -f >> "$LOG_FILE" 2>&1
|
||||
|
||||
# Health check
|
||||
echo "Running health check..." >> "$LOG_FILE"
|
||||
sleep 10
|
||||
|
||||
RETRIES=5
|
||||
while [ $RETRIES -gt 0 ]; do
|
||||
if curl -sf http://localhost:3020/api/health > /dev/null 2>&1; then
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - Deploy successful ✅" >> "$LOG_FILE"
|
||||
exit 0
|
||||
fi
|
||||
sleep 3
|
||||
RETRIES=$((RETRIES - 1))
|
||||
done
|
||||
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - Health check failed after deploy ⚠️" >> "$LOG_FILE"
|
||||
exit 1
|
||||
@@ -1,99 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# ─── EnFlow VPS Deploy Script ────────────────────────────────────────────────
|
||||
# Usage: ./deploy.sh [domain] [email]
|
||||
# Example: ./deploy.sh cirux.silvioalzate.shop silvio@example.com
|
||||
|
||||
DOMAIN=${1:-cirux.silvioalzate.shop}
|
||||
EMAIL=${2:-help@silvioalzate.shop}
|
||||
APP_DIR=$(pwd)
|
||||
|
||||
echo "🚀 Cirux Deploy Script"
|
||||
echo " Domain: $DOMAIN"
|
||||
echo " Email: $EMAIL"
|
||||
echo ""
|
||||
|
||||
# ─── Prerequisites Check ─────────────────────────────────────────────────────
|
||||
echo "📋 Checking prerequisites..."
|
||||
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo "❌ Docker not found. Installing..."
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
sudo usermod -aG docker $USER
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
echo "❌ Docker Compose not found. Installing..."
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
fi
|
||||
|
||||
# ─── SSL Certificates ──────────────────────────────────────────────────────
|
||||
echo "🔐 Setting up SSL certificates..."
|
||||
|
||||
mkdir -p certbot/conf certbot/www
|
||||
|
||||
if [ ! -d "certbot/conf/live/$DOMAIN" ]; then
|
||||
echo " Obtaining initial certificate for $DOMAIN..."
|
||||
|
||||
# Start nginx temporarily for certbot challenge
|
||||
docker-compose up -d nginx
|
||||
sleep 5
|
||||
|
||||
# Get certificate
|
||||
docker-compose run --rm certbot certonly \
|
||||
--webroot \
|
||||
--webroot-path=/var/www/certbot \
|
||||
--email "$EMAIL" \
|
||||
--agree-tos \
|
||||
--no-eff-email \
|
||||
-d "$DOMAIN"
|
||||
|
||||
# Stop temporary nginx
|
||||
docker-compose down
|
||||
fi
|
||||
|
||||
# ─── Update nginx.conf domain ────────────────────────────────────────────────
|
||||
echo "📝 Updating nginx configuration..."
|
||||
sed -i "s/cirux.silvioalzate.shop/$DOMAIN/g" nginx.conf
|
||||
|
||||
# ─── Environment Variables ─────────────────────────────────────────────────
|
||||
echo "🔧 Checking environment variables..."
|
||||
|
||||
if [ ! -f ".env.local" ]; then
|
||||
echo "⚠️ .env.local not found! Creating from example..."
|
||||
cp .env.local.example .env.local
|
||||
echo "❌ IMPORTANT: Edit .env.local with your real credentials before continuing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ─── Build & Deploy ────────────────────────────────────────────────────────
|
||||
echo "🏗️ Building Docker images..."
|
||||
docker-compose down 2>/dev/null || true
|
||||
docker-compose build --no-cache
|
||||
|
||||
echo "🚀 Starting services..."
|
||||
docker-compose up -d
|
||||
|
||||
# ─── Verify Deployment ─────────────────────────────────────────────────────
|
||||
echo "✅ Verifying deployment..."
|
||||
sleep 10
|
||||
|
||||
if curl -sf http://localhost:3020/api/health > /dev/null 2>&1; then
|
||||
echo "✅ App is responding on port 3020"
|
||||
else
|
||||
echo "⚠️ App health check failed. Check logs: docker-compose logs cirux-app"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "─────────────────────────────────────────"
|
||||
echo "🎉 Deployment Complete!"
|
||||
echo ""
|
||||
echo " App: https://$DOMAIN"
|
||||
echo " Logs: docker-compose logs -f cirux-app"
|
||||
echo " Restart: docker-compose restart cirux-app"
|
||||
echo " Update: git pull && ./deploy.sh"
|
||||
echo ""
|
||||
echo " SSL cert will auto-renew via certbot."
|
||||
echo "─────────────────────────────────────────"
|
||||
+9
-2
@@ -1,13 +1,13 @@
|
||||
services:
|
||||
# ─── EnFlow Next.js App ──────────────────────────────────────────────────
|
||||
cirux-app:
|
||||
cirux:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL}
|
||||
- NEXT_PUBLIC_SUPABASE_ANON_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY}
|
||||
container_name: cirux-app
|
||||
container_name: cirux
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
@@ -15,9 +15,16 @@ services:
|
||||
- NODE_ENV=production
|
||||
ports:
|
||||
- "127.0.0.1:3020:3020"
|
||||
network:
|
||||
- gitea-network
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3020/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
|
||||
networks:
|
||||
gitea-network:
|
||||
external: true
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/bin/bash
|
||||
# ─── Gitea Post-Receive Hook ────────────────────────────────────────────────
|
||||
# Location: /home/ubuntu/gitea/gitea/git/repositories/silvioalzate/cirux.git/hooks/post-receive
|
||||
# Owner: ubuntu (run as gitea service user)
|
||||
# Make executable: chmod +x post-receive
|
||||
|
||||
set -e
|
||||
|
||||
APP_DIR="/home/ubuntu/cirux"
|
||||
LOG_FILE="/var/log/cirux-deploy.log"
|
||||
BRANCH="main"
|
||||
DEPLOY_SCRIPT="/home/ubuntu/cirux/deploy-auto.sh"
|
||||
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - Push received, starting deploy..." >> "$LOG_FILE"
|
||||
|
||||
# Read refs from stdin (standard git hook input)
|
||||
while read oldrev newrev refname; do
|
||||
# Only deploy on main branch pushes
|
||||
if [ "$refname" = "refs/heads/$BRANCH" ]; then
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - Deploying branch: $BRANCH" >> "$LOG_FILE"
|
||||
|
||||
cd "$APP_DIR"
|
||||
|
||||
# Run deploy script
|
||||
/home/ubuntu/cirux/deploy-auto.sh >> "$LOG_FILE" 2>&1
|
||||
|
||||
# Verify health
|
||||
sleep 5
|
||||
if curl -sf http://localhost:3020/api/health > /dev/null 2>&1; then
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - Deploy successful ✅" >> "$LOG_FILE"
|
||||
else
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - Health check failed ⚠️" >> "$LOG_FILE"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - Hook finished" >> "$LOG_FILE"
|
||||
@@ -1,96 +0,0 @@
|
||||
#!/bin/bash
|
||||
# ─── EnFlow VPS Auto-Deploy Setup ───────────────────────────────────────────
|
||||
# Run this ONCE on your VPS as root or with sudo
|
||||
# This configures Gitea hook + Docker deploy automation
|
||||
|
||||
set -e
|
||||
|
||||
APP_DIR="/home/ubuntu/cirux"
|
||||
GITEA_USER="ubuntu"
|
||||
GITEA_REPO="/home/ubuntu/gitea/gitea/git/repositories/silvioalzate/cirux.git"
|
||||
HOOK_DIR="$GITEA_REPO/hooks"
|
||||
LOG_FILE="/var/log/cirux-deploy.log"
|
||||
BRANCH="main"
|
||||
|
||||
echo "🚀 Cirux Auto-Deploy Setup"
|
||||
echo " App Dir: $APP_DIR"
|
||||
echo " Gitea User: $GITEA_USER"
|
||||
echo " Hook Dir: $HOOK_DIR"
|
||||
echo ""
|
||||
|
||||
# ─── 1. Verify Gitea user ─────────────────────────────────────────────────
|
||||
echo "📋 Verifying Gitea user..."
|
||||
if ! id "$GITEA_USER" &>/dev/null; then
|
||||
echo "❌ User $GITEA_USER does not exist!"
|
||||
echo " Check: ps aux | grep gitea"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ─── 2. Add user to docker group ────────────────────────────────────────────
|
||||
echo "🔧 Adding $GITEA_USER to docker group..."
|
||||
if ! groups "$GITEA_USER" | grep -q docker; then
|
||||
sudo usermod -aG docker "$GITEA_USER"
|
||||
echo " ✅ Added. IMPORTANT: You MUST run 'newgrp docker' or logout/login for this to take effect."
|
||||
fi
|
||||
|
||||
# ─── 3. Create app directory ─────────────────────────────────────────────────
|
||||
echo "📁 Setting up app directory..."
|
||||
if [ ! -d "$APP_DIR" ]; then
|
||||
echo " Cloning repository..."
|
||||
sudo -u "$GITEA_USER" git clone "$GITEA_REPO" "$APP_DIR"
|
||||
else
|
||||
echo " App directory exists. Updating remote..."
|
||||
cd "$APP_DIR"
|
||||
sudo -u "$GITEA_USER" git remote set-url origin "$GITEA_REPO" || true
|
||||
sudo -u "$GITEA_USER" git fetch origin
|
||||
sudo -u "$GITEA_USER" git reset --hard "origin/$BRANCH"
|
||||
fi
|
||||
|
||||
# Set ownership
|
||||
sudo chown -R "$GITEA_USER":"$GITEA_USER" "$APP_DIR"
|
||||
sudo chmod -R 755 "$APP_DIR"
|
||||
|
||||
# ─── 4. Create log file with correct permissions ─────────────────────────────
|
||||
echo "📝 Creating log file..."
|
||||
sudo touch "$LOG_FILE"
|
||||
sudo chown "$GITEA_USER":"$GITEA_USER" "$LOG_FILE"
|
||||
sudo chmod 644 "$LOG_FILE"
|
||||
|
||||
# ─── 5. Install post-receive hook ────────────────────────────────────────────
|
||||
echo "🔌 Installing Gitea post-receive hook..."
|
||||
if [ ! -d "$HOOK_DIR" ]; then
|
||||
echo "❌ Hook directory not found: $HOOK_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo cp "$APP_DIR/gitea-post-receive-hook.sh" "$HOOK_DIR/post-receive"
|
||||
sudo chown "$GITEA_USER":"$GITEA_USER" "$HOOK_DIR/post-receive"
|
||||
sudo chmod +x "$HOOK_DIR/post-receive"
|
||||
|
||||
# ─── 6. Make deploy-auto.sh executable ─────────────────────────────────────────
|
||||
echo "🔧 Setting up deploy script..."
|
||||
sudo chmod +x "$APP_DIR/deploy-auto.sh"
|
||||
|
||||
# ─── 7. Verify Docker access ─────────────────────────────────────────────────
|
||||
echo "🐳 Verifying Docker access..."
|
||||
if sudo -u "$GITEA_USER" docker ps > /dev/null 2>&1; then
|
||||
echo " ✅ Docker access OK"
|
||||
else
|
||||
echo " ⚠️ Docker access failed. Run: newgrp docker (or logout/login)"
|
||||
fi
|
||||
|
||||
# ─── 8. Test deploy ──────────────────────────────────────────────────────────
|
||||
echo "🧪 Testing deploy..."
|
||||
cd "$APP_DIR"
|
||||
sudo -u "$GITEA_USER" bash "$APP_DIR/deploy-auto.sh"
|
||||
|
||||
echo ""
|
||||
echo "─────────────────────────────────────────"
|
||||
echo "✅ Setup Complete!"
|
||||
echo ""
|
||||
echo " Push to main branch → Auto deploy triggers"
|
||||
echo " Logs: tail -f $LOG_FILE"
|
||||
echo " App: http://localhost:3020"
|
||||
echo ""
|
||||
echo " If Docker failed: logout and login again, or run 'newgrp docker'"
|
||||
echo "─────────────────────────────────────────"
|
||||
Reference in New Issue
Block a user