nietzshn d53398ca0c
CI Pipeline / HTML Lint (push) Successful in 7s
Deploy QA / Build and Push (push) Successful in 13s
CI Pipeline / Build Docker Image (push) Failing after 28m28s
CI Pipeline / Security Scan (push) Has been skipped
Deploy QA / Deploy to QA (push) Failing after 2s
CI Pipeline / Generate Summary (push) Failing after 1s
Deploy QA / Notification (push) Failing after 1s
ci: use custom bridge network to avoid port conflicts and get reliable container IP
2026-06-01 20:43:11 -06:00
2026-05-29 20:26:01 -06:00

CI/CD Multi-Environment Pipeline POC

Prueba de concepto de un pipeline CI/CD multi-ambiente con Gitea Actions, Docker y Nginx.

Arquitectura

                    feature/*
                       |
                      PR
                       |
                    ┌───┴───┐
                    │  dev  │ ──(push)──► CI Pipeline ──► Deploy QA
                    └───┬───┘           (lint, build,    (puerto 8081)
                        │                security scan)
                       PR                docker registry
                        │                    │
                    ┌───┴───┐                │
                    │staging│ ──(push)────────┼──► Deploy Staging
                    └───┬───┘                │    (puerto 8082)
                        │                    │
                       PR                    │
                        │                    │
                    ┌───┴───┐                │
                    │ main  │ ──(push)────────┴──► Deploy Production
                    └───────┘    (aprobación)      (puerto 8083)

Ambientes

Ambiente URL Puerto Rama Trigger
QA https://practicas.qa.kubistudio.cloud 8081 dev Push autom.
Staging https://practicas.staging.kubistudio.cloud 8082 staging Push autom.
Production https://practicas.prod.kubistudio.cloud 8083 main Push + aprob.

Configuración en Gitea

Secretos (Settings > Secrets)

Secreto Descripción
TOKEN Token de Gitea con permisos de escritura al registry
DEPLOY_SSH_KEY Clave SSH privada para acceder al servidor de deploy
DEPLOY_USERNAME Usuario SSH para conexión al servidor
DEPLOY_HOST Host/IP del servidor de deploy

Variables (Settings > Variables)

Variable Descripción Ejemplo
REGISTRY_URL URL del Gitea Container Registry git.kubistudio.cloud
IMAGE_NAME Nombre de la imagen en el registry kubistudio/cicd-multi-env-pipeline-poc

Flujo de Trabajo

  1. Crear rama feature/* desde dev
  2. Desarrollar y hacer commit
  3. Abrir PR a dev → CI ejecuta lint, build, security scan
  4. Merge a dev → CI + Deploy automático a QA
  5. PR de devstaging → Deploy automático a Staging
  6. PR de stagingmain → Requiere aprobación → Deploy a Producción

Ejecución Local

Con docker-compose

version: '3.8'

services:
  cicd-qa:
    build: .
    ports:
      - "8081:80"
    environment:
      APP_ENV: qa
      APP_VERSION: dev-local
      GIT_COMMIT: local
      GIT_BRANCH: dev
      BUILD_DATE: ${BUILD_DATE:-unknown}
      DEPLOY_TIME: ${DEPLOY_TIME:-unknown}
      BUILD_NUMBER: "0"

  cicd-staging:
    build: .
    ports:
      - "8082:80"
    environment:
      APP_ENV: staging
      APP_VERSION: staging-local
      GIT_COMMIT: local
      GIT_BRANCH: staging
      BUILD_DATE: ${BUILD_DATE:-unknown}
      DEPLOY_TIME: ${DEPLOY_TIME:-unknown}
      BUILD_NUMBER: "0"

  cicd-prod:
    build: .
    ports:
      - "8083:80"
    environment:
      APP_ENV: production
      APP_VERSION: 1.0.0
      DEPLOY_TIME: ${DEPLOY_TIME:-unknown}

Manual

# Build
docker build \
  --build-arg APP_VERSION=1.0.0 \
  --build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  --build-arg GIT_COMMIT=$(git rev-parse --short HEAD) \
  --build-arg GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) \
  -t cicd-poc:latest .

# Run
docker run -d \
  --name cicd-qa \
  -p 8081:80 \
  -e APP_ENV=qa \
  -e APP_VERSION=dev-local \
  -e GIT_COMMIT=$(git rev-parse --short HEAD) \
  -e GIT_BRANCH=dev \
  -e BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  -e DEPLOY_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  -e BUILD_NUMBER="1" \
  cicd-poc:latest

# Test
curl http://localhost:8081/health

Variables de Entorno del Contenedor

Variable Obligatorio Default Descripción
APP_ENV No development Ambiente: qa, staging, production
APP_VERSION No 0.0.0 Versión de la aplicación
BUILD_DATE No (vacío) Fecha ISO del build
GIT_COMMIT No (vacío) SHA corto del commit
GIT_BRANCH No (vacío) Rama de git
DEPLOY_TIME No (vacío) Timestamp del deploy
BUILD_NUMBER No (vacío) Número de build de la pipeline

Rollback Manual

Production

ssh user@deploy-host

# Rollback a stable tag
docker stop cicd-prod && docker rm cicd-prod
docker run -d \
  --name cicd-prod \
  --restart unless-stopped \
  -p 8083:80 \
  -e APP_ENV=production \
  -e APP_VERSION=rollback \
  -e DEPLOY_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  registry-url/image-name:stable

# O con un SHA específico
docker run -d \
  --name cicd-prod \
  --restart unless-stopped \
  -p 8083:80 \
  -e APP_ENV=production \
  -e APP_VERSION=rollback \
  -e DEPLOY_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  registry-url/image-name:sha-SHA_DEL_COMMIT

QA / Staging

# QA
docker stop cicd-qa && docker rm cicd-qa
docker run -d --name cicd-qa -p 8081:80 ... registry-url/image-name:sha-SHA_ANTERIOR

# Staging
docker stop cicd-staging && docker rm cicd-staging
docker run -d --name cicd-staging -p 8082:80 ... registry-url/image-name:sha-SHA_ANTERIOR

Endpoints

Endpoint Descripción
/ Aplicación web
/health Health check (JSON)

Ejemplo /health

{
  "status": "ok",
  "env": "production",
  "version": "release-a1b2c3d",
  "timestamp": "2024-01-15T14:23:00+00:00"
}

Estructura del Proyecto

.
├── src/
│   └── index.html              # App web (UI completa self-contained)
├── .gitea/workflows/
│   ├── ci.yml                  # CI: lint + build + security scan
│   ├── deploy-qa.yml           # Deploy a QA (push a dev)
│   ├── deploy-staging.yml      # Deploy a Staging (push a staging)
│   └── deploy-prod.yml         # Deploy a Producción (push a main + aprobación)
├── docker-entrypoint.sh        # Entrypoint que genera env-config.js en runtime
├── Dockerfile                  # Multi-stage build
├── healthcheck.sh              # Script de health check
├── nginx.conf                  # Configuración de nginx
└── README.md                   # Este archivo
S
Description
CI/CD Multi-Environment Strategy (PoC)
Readme Unlicense 93 KiB
Languages
HTML 84.9%
Dockerfile 8.9%
Shell 6.2%