Compare commits
83 Commits
claude/che
...
v0.1.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15ed12f0c6 | ||
| 5b3bd631cb | |||
|
|
3ea406044b | ||
|
|
4cd49d8c9a | ||
|
|
7a931d32ba | ||
| 01853b41ba | |||
| 8c2ffaae55 | |||
|
|
1976432a95 | ||
|
|
c25c6c2916 | ||
|
|
1a682c121e | ||
| c633124454 | |||
| 1030fa994c | |||
| 5707b1fbc4 | |||
|
|
d6db3d3e70 | ||
|
|
768e384ed6 | ||
|
|
b6dc8485c0 | ||
|
|
47070f71db | ||
|
|
5e688aa1fa | ||
| 232a687942 | |||
| b50e3c756c | |||
| 8cfce22f1d | |||
| 2433b48c35 | |||
| c5064383fe | |||
| 77b61d3f33 | |||
|
|
070af13d86 | ||
|
|
2a070ab921 | ||
|
|
7923b8c13e | ||
|
|
d924636def | ||
|
|
8bb952eba5 | ||
|
|
80df1368b1 | ||
|
|
a5fe8414de | ||
|
|
5edfd256c1 | ||
|
|
9f04467a6d | ||
|
|
f8323ea419 | ||
|
|
1cc463f659 | ||
|
|
caa7cfb564 | ||
|
|
559f49db8a | ||
|
|
57d2bcdd07 | ||
|
|
807bcc8034 | ||
|
|
46b85f5ee7 | ||
|
|
d252607c79 | ||
|
|
083e398f5d | ||
|
|
3721bdd35f | ||
|
|
1f2928a71d | ||
|
|
a92fb51b5d | ||
|
|
26534774ef | ||
|
|
0f67f16047 | ||
|
|
eea9bcd885 | ||
|
|
2747bef898 | ||
|
|
932ab0f0d4 | ||
|
|
4039dc54cb | ||
|
|
fe0c2de0d4 | ||
|
|
02d25ea19f | ||
|
|
af4a5a35c7 | ||
|
|
022f04b9ed | ||
|
|
122a10be49 | ||
|
|
2ef0a742e1 | ||
|
|
9e01d9d2fb | ||
|
|
3532f4f621 | ||
|
|
9effa23d3b | ||
|
|
6a8ffe5da8 | ||
|
|
df12fe5339 | ||
|
|
4fc681b2c4 | ||
|
|
9c779eccb4 | ||
|
|
7be286e2c9 | ||
|
|
39806559d7 | ||
|
|
b3c4724100 | ||
|
|
a250559509 | ||
|
|
0e29d998c9 | ||
|
|
57239e86a2 | ||
|
|
5dcd605168 | ||
|
|
556a3f3d11 | ||
|
|
3f77897a4c | ||
|
|
d7fd852bec | ||
|
|
c7580f60ef | ||
|
|
69fce1dc28 | ||
|
|
20bcf94137 | ||
|
|
dc93b6d9e0 | ||
|
|
75ddb23000 | ||
|
|
badbc82478 | ||
|
|
bbaf34f507 | ||
|
|
0a98843d6c | ||
|
|
83a32a48b2 |
52
.gitea/workflows/example.yaml
Normal file
52
.gitea/workflows/example.yaml
Normal file
@@ -0,0 +1,52 @@
|
||||
name: Workflow de prueba
|
||||
|
||||
on:
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
|
||||
|
||||
env:
|
||||
DOCKER_ORG: beyondcx
|
||||
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
|
||||
|
||||
jobs:
|
||||
Build and push images:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Echo the Tag
|
||||
run: echo "Tag ${{ env.DOCKER_ORG }}/beyondcx:${{ env.BRANCH_NAME }}"
|
||||
|
||||
- name: Login to Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ secrets.REGISTRY_URL }}
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_PWD }}
|
||||
|
||||
- name: Build frontend and push it to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: frontend
|
||||
push: false
|
||||
tags: ${{ secrets.REGISTRY_URL }}/${{ env.DOCKER_ORG }}/frontend-analytics-demo:${{ env.BRANCH_NAME }}
|
||||
platforms: linux/amd64
|
||||
file: frontend/Dockerfile
|
||||
|
||||
- name: Build backend and push it to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: backend
|
||||
push: false
|
||||
tags: ${{ secrets.REGISTRY_URL }}/${{ env.DOCKER_ORG }}/backend-analytics-demo:${{ env.BRANCH_NAME }}
|
||||
platforms: linux/amd64
|
||||
file: backend/Dockerfile
|
||||
|
||||
|
||||
52
.gitea/workflows/tag.yaml
Normal file
52
.gitea/workflows/tag.yaml
Normal file
@@ -0,0 +1,52 @@
|
||||
name: Tag Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created,edited,published]
|
||||
|
||||
env:
|
||||
DOCKER_ORG: beyondcx
|
||||
|
||||
jobs:
|
||||
new images:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Extract Tag Name
|
||||
uses: olegtarasov/get-tag@v2.1.4
|
||||
id: tagName
|
||||
- name: Show tag
|
||||
run: echo "$GIT_TAG_NAME";
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver-opts: network=host
|
||||
|
||||
- name: Login to Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ secrets.REGISTRY_URL }}
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_PWD }}
|
||||
|
||||
- name: Build frontend and push it to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: frontend
|
||||
push: true
|
||||
tags: ${{ secrets.REGISTRY_URL }}/${{ env.DOCKER_ORG }}/frontend-analytics-demo:${{ steps.tagName.outputs.tag }}
|
||||
platforms: linux/amd64
|
||||
file: frontend/Dockerfile
|
||||
|
||||
- name: Build backend and push it to registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: backend
|
||||
push: true
|
||||
tags: ${{ secrets.REGISTRY_URL }}/${{ env.DOCKER_ORG }}/backend-analytics-demo:${{ steps.tagName.outputs.tag }}
|
||||
platforms: linux/amd64
|
||||
file: backend/Dockerfile
|
||||
|
||||
@@ -11,3 +11,8 @@ build
|
||||
data/output
|
||||
*.zip
|
||||
.DS_Store
|
||||
*.log
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
.env
|
||||
tests
|
||||
|
||||
@@ -1,31 +1,50 @@
|
||||
# backend/Dockerfile
|
||||
FROM python:3.11-slim
|
||||
# ---------------------------
|
||||
# Builder stage
|
||||
# ---------------------------
|
||||
FROM python:3.13-bookworm AS builder
|
||||
|
||||
# Evitar .pyc y buffering
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
# Solo herramientas necesarias para compilar dependencias
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential && apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ADD https://astral.sh/uv/install.sh /install.sh
|
||||
RUN chmod -R 655 /install.sh && /install.sh && rm /install.sh
|
||||
|
||||
ENV PATH="/root/.local/bin:$PATH"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Dependencias del sistema mínimas
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copiamos pyproject y lock si lo hubiera
|
||||
# Copiamos solo archivos de dependencias (mejor cache)
|
||||
COPY pyproject.toml ./
|
||||
|
||||
# Instalamos dependencias
|
||||
RUN pip install --upgrade pip && \
|
||||
pip install .
|
||||
# Cambiamos pip por uv más moderno y rápido
|
||||
RUN uv sync
|
||||
|
||||
# ---------------------------
|
||||
# Runtime stage
|
||||
# ---------------------------
|
||||
FROM python:3.13-slim-bookworm AS production
|
||||
|
||||
# Copiamos el resto del código (respetando .dockerignore)
|
||||
COPY . .
|
||||
|
||||
# Variables de autenticación básica
|
||||
ENV BASIC_AUTH_USERNAME=admin
|
||||
ENV BASIC_AUTH_PASSWORD=admin
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Crear usuario no-root
|
||||
RUN useradd --create-home appuser
|
||||
|
||||
# Copiamos código y producto uv
|
||||
|
||||
COPY . .
|
||||
COPY --from=builder /app/.venv .venv
|
||||
|
||||
# Cambiar permisos
|
||||
#RUN chown -R appuser:appuser /app
|
||||
|
||||
#USER appuser
|
||||
ENV PATH="/app/.venv/bin:$PATH"
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["python", "-m", "uvicorn", "beyond_api.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
CMD ["uvicorn", "beyond_api.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
|
||||
@@ -4,7 +4,7 @@ services:
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
container_name: beyond-backend
|
||||
container_name: XXX-backend
|
||||
environment:
|
||||
# credenciales del API (las mismas que usas ahora)
|
||||
BASIC_AUTH_USERNAME: "beyond"
|
||||
@@ -15,39 +15,37 @@ services:
|
||||
expose:
|
||||
- "8000"
|
||||
networks:
|
||||
- beyond-net
|
||||
- XXX-beyond-net
|
||||
|
||||
frontend:
|
||||
XXXfrontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
args:
|
||||
# el front compilará con este BASE_URL -> /api
|
||||
# el front compilar con este BASE_URL -> /api
|
||||
VITE_API_BASE_URL: /api
|
||||
container_name: beyond-frontend
|
||||
container_name: XXX-frontend
|
||||
expose:
|
||||
- "4173"
|
||||
networks:
|
||||
- beyond-net
|
||||
|
||||
nginx:
|
||||
image: nginx:1.27-alpine
|
||||
container_name: beyond-nginx
|
||||
- XXX-beyond-net
|
||||
- frontend
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.XXX-server.rule=Host(`DDD`)"
|
||||
- "traefik.http.routers.XXX-server.entrypoints=websecure"
|
||||
- "traefik.http.routers.XXX-server.tls=true"
|
||||
- "traefik.http.routers.XXX-server.tls.certresolver=doresolv"
|
||||
- "traefik.http.routers.XXX-server.service=XXXfrontend"
|
||||
- "traefik.http.services.XXXfrontend.loadBalancer.server.port=4173"
|
||||
depends_on:
|
||||
- backend
|
||||
- frontend
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- /etc/letsencrypt:/etc/letsencrypt:ro
|
||||
- ./nginx/conf.d:/etc/nginx/conf.d:ro
|
||||
networks:
|
||||
- beyond-net
|
||||
|
||||
volumes:
|
||||
cache-data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
beyond-net:
|
||||
XXX-beyond-net:
|
||||
driver: bridge
|
||||
frontend:
|
||||
external: true
|
||||
|
||||
@@ -20,17 +20,22 @@ ENV VITE_API_BASE_URL=${VITE_API_BASE_URL}
|
||||
# Construimos el bundle
|
||||
RUN npm run build
|
||||
|
||||
# 2) Fase de servidor estático
|
||||
# 2) Fase de servidor estático. Tenemos que revisar
|
||||
FROM node:20-alpine
|
||||
#FROM nginx:alpine
|
||||
|
||||
WORKDIR /app
|
||||
#RUN rm -rf /usr/share/nginx/html/*
|
||||
|
||||
# Copiamos el build
|
||||
#COPY --from=build /app/dist /usr/share/nginx/html
|
||||
COPY --from=build /app/dist ./dist
|
||||
|
||||
# Server estático muy simple
|
||||
RUN npm install -g serve
|
||||
|
||||
#EXPOSE 80
|
||||
EXPOSE 4173
|
||||
|
||||
#CMD ["nginx", "-g", "daemon off;"]
|
||||
CMD ["serve", "-s", "dist", "-l", "4173"]
|
||||
|
||||
@@ -5,8 +5,8 @@ set -euo pipefail
|
||||
# CONFIGURACIÓN BÁSICA – EDITA ESTO
|
||||
###############################################
|
||||
# TODO: pon aquí la URL real de tu repo (sin credenciales)
|
||||
REPO_URL_DEFAULT="https://github.com/igferne/Beyond-Diagnosis.git"
|
||||
INSTALL_DIR="/opt/beyonddiagnosis"
|
||||
REPO_URL_DEFAULT="ssh://git@git.beyondcx.org:2424/susana/BeyondCXAnalytics-Demo.git"
|
||||
INSTALL_BASE="/opt/beyondcx"
|
||||
|
||||
###############################################
|
||||
# UTILIDADES
|
||||
@@ -38,11 +38,13 @@ if [ -z "$DOMAIN" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -rp "Email para Let's Encrypt (avisos de renovación): " EMAIL
|
||||
if [ -z "$EMAIL" ]; then
|
||||
echo "El email no puede estar vacío."
|
||||
exit 1
|
||||
SUBDOMAIN=${DOMAIN%%.*}
|
||||
if [[ $DOMAIN == $SUBDOMAIN ]]; then
|
||||
DOMAIN=$DOMAIN".analytics.beyondcx.org"
|
||||
fi
|
||||
echo "el dominio es $DOMAIN y el subdominio $SUBDOMAIN"
|
||||
|
||||
INSTALL_DIR=$INSTALL_BASE"/"$SUBDOMAIN
|
||||
|
||||
read -rp "Usuario de acceso (Basic Auth / login): " API_USER
|
||||
if [ -z "$API_USER" ]; then
|
||||
@@ -61,41 +63,14 @@ echo
|
||||
read -rp "URL del repositorio Git (HTTPS, sin credenciales) [$REPO_URL_DEFAULT]: " REPO_URL
|
||||
REPO_URL=${REPO_URL:-$REPO_URL_DEFAULT}
|
||||
|
||||
echo
|
||||
read -rp "¿El repositorio es PRIVADO en GitHub y necesitas token? [s/N]: " IS_PRIVATE
|
||||
IS_PRIVATE=${IS_PRIVATE:-N}
|
||||
|
||||
GIT_CLONE_URL="$REPO_URL"
|
||||
if [[ "$IS_PRIVATE" =~ ^[sS]$ ]]; then
|
||||
echo "Introduce un Personal Access Token (PAT) de GitHub con permiso de lectura del repo."
|
||||
read -rsp "GitHub PAT: " GITHUB_TOKEN
|
||||
echo
|
||||
if [ -z "$GITHUB_TOKEN" ]; then
|
||||
echo "El token no puede estar vacío si el repo es privado."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Construimos una URL del tipo: https://TOKEN@github.com/usuario/repo.git
|
||||
if [[ "$REPO_URL" =~ ^https:// ]]; then
|
||||
GIT_CLONE_URL="https://${GITHUB_TOKEN}@${REPO_URL#https://}"
|
||||
else
|
||||
echo "La URL del repositorio debe empezar por https:// para usar el token."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Resumen de configuración:"
|
||||
echo " Dominio: $DOMAIN"
|
||||
echo " Email Let'sEnc: $EMAIL"
|
||||
echo " Usuario API: $API_USER"
|
||||
echo " Repo (visible): $REPO_URL"
|
||||
if [[ "$IS_PRIVATE" =~ ^[sS]$ ]]; then
|
||||
echo " Repo privado: Sí (se usará un PAT sólo para el clon inicial)"
|
||||
else
|
||||
echo " Repo privado: No"
|
||||
fi
|
||||
echo
|
||||
echo " Path del despliegue: $INSTALL_DIR"
|
||||
|
||||
read -rp "¿Continuar con la instalación? [s/N]: " CONFIRM
|
||||
CONFIRM=${CONFIRM:-N}
|
||||
@@ -104,70 +79,20 @@ if [[ ! "$CONFIRM" =~ ^[sS]$ ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
###############################################
|
||||
# 2. INSTALAR DOCKER + DOCKER COMPOSE + CERTBOT
|
||||
###############################################
|
||||
step "Instalando Docker, docker compose plugin y certbot"
|
||||
|
||||
apt-get update -y
|
||||
|
||||
# Dependencias para repositorio Docker
|
||||
apt-get install -y \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
lsb-release
|
||||
|
||||
# Clave GPG de Docker
|
||||
if [ ! -f /etc/apt/keyrings/docker.gpg ]; then
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
|
||||
gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
fi
|
||||
|
||||
# Repo Docker estable
|
||||
if [ ! -f /etc/apt/sources.list.d/docker.list ]; then
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
||||
tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
fi
|
||||
|
||||
apt-get update -y
|
||||
|
||||
apt-get install -y \
|
||||
docker-ce \
|
||||
docker-ce-cli \
|
||||
containerd.io \
|
||||
docker-buildx-plugin \
|
||||
docker-compose-plugin \
|
||||
git \
|
||||
certbot
|
||||
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
|
||||
# Abrimos puertos en ufw si está activo
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
if ufw status | grep -q "Status: active"; then
|
||||
step "Configurando firewall (ufw) para permitir 80 y 443"
|
||||
ufw allow 80/tcp || true
|
||||
ufw allow 443/tcp || true
|
||||
fi
|
||||
fi
|
||||
|
||||
###############################################
|
||||
# 3. CLONAR / ACTUALIZAR REPO
|
||||
###############################################
|
||||
# COMENZAMOS ...
|
||||
step "Descargando/actualizando el repositorio en $INSTALL_DIR"
|
||||
|
||||
eval $(ssh-agent -s)
|
||||
ssh-add /home/garbelo/.ssh/id_ed25519
|
||||
|
||||
if [ -d "$INSTALL_DIR/.git" ]; then
|
||||
echo "Directorio git ya existe, haciendo 'git pull'..."
|
||||
git -C "$INSTALL_DIR" pull --ff-only
|
||||
else
|
||||
rm -rf "$INSTALL_DIR"
|
||||
echo "Clonando repositorio..."
|
||||
git clone "$GIT_CLONE_URL" "$INSTALL_DIR"
|
||||
# git clone "$GIT_CLONE_URL" "$INSTALL_DIR"
|
||||
git clone -b proxy "$GIT_CLONE_URL" "$INSTALL_DIR"
|
||||
fi
|
||||
|
||||
cd "$INSTALL_DIR"
|
||||
@@ -189,97 +114,22 @@ else
|
||||
sed -i "s/BASIC_AUTH_PASSWORD:.*/BASIC_AUTH_PASSWORD: \"$API_PASS\"/" docker-compose.yml
|
||||
fi
|
||||
|
||||
# Aseguramos que nginx exponga también 443
|
||||
if grep -q 'ports:' docker-compose.yml && grep -q 'nginx:' docker-compose.yml; then
|
||||
if ! grep -q '443:443' docker-compose.yml; then
|
||||
sed -i '/- "80:80"/a\ - "443:443"' docker-compose.yml || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Aseguramos que montamos /etc/letsencrypt dentro del contenedor de nginx
|
||||
if ! grep -q '/etc/letsencrypt:/etc/letsencrypt:ro' docker-compose.yml; then
|
||||
sed -i '/nginx:/,/networks:/{
|
||||
/volumes:/a\ - /etc/letsencrypt:/etc/letsencrypt:ro
|
||||
}' docker-compose.yml || true
|
||||
fi
|
||||
|
||||
###############################################
|
||||
# 5. OBTENER CERTIFICADO LET'S ENCRYPT
|
||||
###############################################
|
||||
step "Obteniendo certificado SSL de Let’s Encrypt para $DOMAIN"
|
||||
|
||||
if [ -f "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" ]; then
|
||||
echo "Certificado ya existe, saltando paso de emisión."
|
||||
if ! grep -q "XXX" docker-compose.yml; then
|
||||
echo "⚠ No encuentro XXX en docker-compose.yml. Revisa el archivo a mano."
|
||||
else
|
||||
# Asegurarnos de que no hay nada escuchando en 80/443
|
||||
systemctl stop nginx || true
|
||||
|
||||
certbot certonly \
|
||||
--standalone \
|
||||
--non-interactive \
|
||||
--agree-tos \
|
||||
-m "$EMAIL" \
|
||||
-d "$DOMAIN"
|
||||
|
||||
echo "Certificado emitido en /etc/letsencrypt/live/$DOMAIN/"
|
||||
sed -i "s/XXX/$SUBDOMAIN/g" docker-compose.yml
|
||||
fi
|
||||
if [[ $DOMAIN == $SUBDOMAIN ]]; then
|
||||
set DOMAIN=$DOMAIN".analytics.beyondcx.org"
|
||||
fi
|
||||
if ! grep -q "DDD" docker-compose.yml; then
|
||||
echo "⚠ No encuentro DDD en docker-compose.yml. Revisa el archivo a mano."
|
||||
else
|
||||
sed -i "s/DDD/$DOMAIN/" docker-compose.yml
|
||||
fi
|
||||
|
||||
###############################################
|
||||
# 6. CONFIGURAR NGINX DENTRO DEL REPO
|
||||
###############################################
|
||||
step "Generando configuración nginx con SSL"
|
||||
|
||||
mkdir -p nginx/conf.d
|
||||
|
||||
cat > nginx/conf.d/beyond.conf <<EOF
|
||||
server {
|
||||
listen 80;
|
||||
server_name $DOMAIN;
|
||||
return 301 https://\$host\$request_uri;
|
||||
client_max_body_size 1024M;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name $DOMAIN;
|
||||
|
||||
client_max_body_size 1024M;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
# FRONTEND (React)
|
||||
location / {
|
||||
proxy_pass http://frontend:4173/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# BACKEND (FastAPI)
|
||||
location /api/ {
|
||||
proxy_pass http://backend:8000/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 600s;
|
||||
proxy_read_timeout 600s;
|
||||
send_timeout 600s;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
###############################################
|
||||
# 7. BUILD Y ARRANQUE DE CONTENEDORES
|
||||
###############################################
|
||||
step "Construyendo imágenes Docker y arrancando contenedores"
|
||||
|
||||
docker compose build
|
||||
|
||||
166
prepare_server.sh
Normal file
166
prepare_server.sh
Normal file
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
step() {
|
||||
echo
|
||||
echo "=================================================="
|
||||
echo " 👉 $1"
|
||||
echo "=================================================="
|
||||
}
|
||||
|
||||
|
||||
require_root() {
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Este script debe ejecutarse como root (o con sudo)."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
require_root
|
||||
|
||||
step "Instalando Docker, docker compose plugin y certbot"
|
||||
|
||||
apt-get update -y
|
||||
|
||||
# Dependencias para repositorio Docker
|
||||
apt-get install -y \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
lsb-release
|
||||
|
||||
# Clave GPG de Docker
|
||||
if [ ! -f /etc/apt/keyrings/docker.gpg ]; then
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
|
||||
gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
fi
|
||||
|
||||
# Repo Docker estable
|
||||
if [ ! -f /etc/apt/sources.list.d/docker.list ]; then
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
||||
tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
fi
|
||||
|
||||
apt-get update -y
|
||||
|
||||
apt-get install -y \
|
||||
docker-ce \
|
||||
docker-ce-cli \
|
||||
containerd.io \
|
||||
docker-buildx-plugin \
|
||||
docker-compose-plugin \
|
||||
git
|
||||
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
|
||||
# Abrimos puertos en ufw si está activo
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
if ufw status | grep -q "Status: active"; then
|
||||
step "Configurando firewall (ufw) para permitir 80 y 443"
|
||||
ufw allow 80/tcp || true
|
||||
ufw allow 443/tcp || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Creamos carpeta del proxy con docker compose.
|
||||
|
||||
mkdir -p /opt/beyondcx/traefik
|
||||
|
||||
cat > /opt/beyondcx/traefik/docker-compose.yaml <<EOF
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.6.1
|
||||
container_name: traefik-prod-1
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- DO_AUTH_TOKEN=\${DO_AUTH_TOKEN}
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./config/traefik.yml:/etc/traefik/traefik.yaml:ro
|
||||
- ./data/certs:/var/traefik/certs/:rw
|
||||
- ./config/conf:/etc/traefik/conf/:rw
|
||||
- ./logs:/var/traefik/logs:rw
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "100m"
|
||||
networks:
|
||||
- frontend
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
frontend:
|
||||
external: true
|
||||
|
||||
EOF
|
||||
|
||||
mkdir -p /opt/beyondcx/traefik/config
|
||||
mkdir -p /opt/beyondcx/traefik/logs
|
||||
mkdir -p /opt/beyondcx/traefik/config/conf
|
||||
|
||||
echo "DO_AUTH_TOKEN=" > /opt/beyondcx/traefik/.env
|
||||
|
||||
cat > /opt/beyondcx/traefik/config/traefik.yml <<EOF
|
||||
global:
|
||||
checkNewVersion: false
|
||||
sendAnonymousUsage: false
|
||||
log:
|
||||
level: DEBUG
|
||||
api:
|
||||
dashboard: true
|
||||
insecure: true
|
||||
entryPoints:
|
||||
web:
|
||||
address: :80
|
||||
websecure:
|
||||
address: :443
|
||||
certificatesResolvers:
|
||||
doresolv:
|
||||
acme:
|
||||
email: "garbelo@gmail.com"
|
||||
storage: /var/traefik/certs/doresolv-acme.json
|
||||
caServer: 'https://acme-v02.api.letsencrypt.org/directory'
|
||||
keyType: EC256
|
||||
dnsChallenge:
|
||||
provider: digitalocean
|
||||
resolvers:
|
||||
- "8.8.8.8:53"
|
||||
- "1.1.1.1:53"
|
||||
providers:
|
||||
docker:
|
||||
endpoint: "unix:///var/run/docker.sock"
|
||||
exposedByDefault: false
|
||||
network: frontend
|
||||
file:
|
||||
directory: /etc/traefik/conf/
|
||||
watch: true
|
||||
EOF
|
||||
|
||||
cd /opt/beyondcx/traefik
|
||||
|
||||
PROXY_NETWORK="frontend"
|
||||
|
||||
if docker network inspect $PROXY_NETWORK > /dev/null 2>&1; then
|
||||
echo "red de traefik existe"
|
||||
else
|
||||
docker network create $PROXY_NETWORK
|
||||
fi
|
||||
|
||||
docker compose up -d
|
||||
|
||||
step "Levantado traefik "
|
||||
|
||||
docker compose ps
|
||||
docker compose logs
|
||||
|
||||
step "Recuerda, tienes que crear el DO_AUTH_TOKEN en el .env"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user