Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
62
.gitea/workflows/example.yaml
Normal file
62
.gitea/workflows/example.yaml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
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: Extract Tag Name
|
||||||
|
uses: olegtarasov/get-tag@v2.1.4
|
||||||
|
id: tagName
|
||||||
|
|
||||||
|
- name: Echo branch name
|
||||||
|
run: echo "${{ env.BRANCH_NAME }}"
|
||||||
|
|
||||||
|
#- name: Setup QEMU
|
||||||
|
# uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- 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: true
|
||||||
|
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: true
|
||||||
|
tags: ${{ secrets.REGISTRY_URL }}/${{ env.DOCKER_ORG }}/backend-analytics-demo:${{ env.BRANCH_NAME }}
|
||||||
|
platforms: linux/amd64
|
||||||
|
file: backend/Dockerfile
|
||||||
|
|
||||||
|
|
||||||
15
.gitea/workflows/tag.yaml
Normal file
15
.gitea/workflows/tag.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
name: Tag Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [created,edited,published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create new images with tag:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Extract Tag Name
|
||||||
|
uses: olegtarasov/get-tag@v2.1.4
|
||||||
|
id: tagName
|
||||||
|
run: echo "$GIT_TAG_NAME";
|
||||||
@@ -11,7 +11,8 @@ build
|
|||||||
data/output
|
data/output
|
||||||
*.zip
|
*.zip
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
*.log
|
||||||
Dockerfile
|
Dockerfile
|
||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
.env
|
.env
|
||||||
tests
|
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
|
# Solo herramientas necesarias para compilar dependencias
|
||||||
ENV PYTHONDONTWRITEBYTECODE=1
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
ENV PYTHONUNBUFFERED=1
|
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
|
WORKDIR /app
|
||||||
|
|
||||||
# Dependencias del sistema mínimas
|
# Copiamos solo archivos de dependencias (mejor cache)
|
||||||
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
|
|
||||||
COPY pyproject.toml ./
|
COPY pyproject.toml ./
|
||||||
|
|
||||||
# Instalamos dependencias
|
# Cambiamos pip por uv más moderno y rápido
|
||||||
RUN pip install --upgrade pip && \
|
RUN uv sync
|
||||||
pip install .
|
|
||||||
|
# ---------------------------
|
||||||
|
# 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_USERNAME=admin
|
||||||
ENV BASIC_AUTH_PASSWORD=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
|
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:
|
backend:
|
||||||
build:
|
build:
|
||||||
context: ./backend
|
context: ./backend
|
||||||
container_name: beyond-backend
|
container_name: XXX-backend
|
||||||
environment:
|
environment:
|
||||||
# credenciales del API (las mismas que usas ahora)
|
# credenciales del API (las mismas que usas ahora)
|
||||||
BASIC_AUTH_USERNAME: "beyond"
|
BASIC_AUTH_USERNAME: "beyond"
|
||||||
@@ -15,39 +15,37 @@ services:
|
|||||||
expose:
|
expose:
|
||||||
- "8000"
|
- "8000"
|
||||||
networks:
|
networks:
|
||||||
- beyond-net
|
- XXX-beyond-net
|
||||||
|
|
||||||
frontend:
|
XXXfrontend:
|
||||||
build:
|
build:
|
||||||
context: ./frontend
|
context: ./frontend
|
||||||
args:
|
args:
|
||||||
# el front compilará con este BASE_URL -> /api
|
# el front compilar con este BASE_URL -> /api
|
||||||
VITE_API_BASE_URL: /api
|
VITE_API_BASE_URL: /api
|
||||||
container_name: beyond-frontend
|
container_name: XXX-frontend
|
||||||
expose:
|
expose:
|
||||||
- "4173"
|
- "4173"
|
||||||
networks:
|
networks:
|
||||||
- beyond-net
|
- XXX-beyond-net
|
||||||
|
- frontend
|
||||||
nginx:
|
labels:
|
||||||
image: nginx:1.27-alpine
|
- "traefik.enable=true"
|
||||||
container_name: beyond-nginx
|
- "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:
|
depends_on:
|
||||||
- backend
|
- 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:
|
volumes:
|
||||||
cache-data:
|
cache-data:
|
||||||
driver: local
|
driver: local
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
beyond-net:
|
XXX-beyond-net:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
frontend:
|
||||||
|
external: true
|
||||||
|
|||||||
@@ -20,17 +20,22 @@ ENV VITE_API_BASE_URL=${VITE_API_BASE_URL}
|
|||||||
# Construimos el bundle
|
# Construimos el bundle
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# 2) Fase de servidor estático
|
# 2) Fase de servidor estático. Tenemos que revisar
|
||||||
FROM node:20-alpine
|
FROM node:20-alpine
|
||||||
|
#FROM nginx:alpine
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
#RUN rm -rf /usr/share/nginx/html/*
|
||||||
|
|
||||||
# Copiamos el build
|
# Copiamos el build
|
||||||
|
#COPY --from=build /app/dist /usr/share/nginx/html
|
||||||
COPY --from=build /app/dist ./dist
|
COPY --from=build /app/dist ./dist
|
||||||
|
|
||||||
# Server estático muy simple
|
# Server estático muy simple
|
||||||
RUN npm install -g serve
|
RUN npm install -g serve
|
||||||
|
|
||||||
|
#EXPOSE 80
|
||||||
EXPOSE 4173
|
EXPOSE 4173
|
||||||
|
|
||||||
|
#CMD ["nginx", "-g", "daemon off;"]
|
||||||
CMD ["serve", "-s", "dist", "-l", "4173"]
|
CMD ["serve", "-s", "dist", "-l", "4173"]
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ set -euo pipefail
|
|||||||
# CONFIGURACIÓN BÁSICA – EDITA ESTO
|
# CONFIGURACIÓN BÁSICA – EDITA ESTO
|
||||||
###############################################
|
###############################################
|
||||||
# TODO: pon aquí la URL real de tu repo (sin credenciales)
|
# TODO: pon aquí la URL real de tu repo (sin credenciales)
|
||||||
REPO_URL_DEFAULT="https://github.com/igferne/Beyond-Diagnosis.git"
|
REPO_URL_DEFAULT="ssh://git@git.beyondcx.org:2424/susana/BeyondCXAnalytics-Demo.git"
|
||||||
INSTALL_DIR="/opt/beyonddiagnosis"
|
INSTALL_BASE="/opt/beyondcx"
|
||||||
|
|
||||||
###############################################
|
###############################################
|
||||||
# UTILIDADES
|
# UTILIDADES
|
||||||
@@ -38,11 +38,13 @@ if [ -z "$DOMAIN" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
read -rp "Email para Let's Encrypt (avisos de renovación): " EMAIL
|
SUBDOMAIN=${DOMAIN%%.*}
|
||||||
if [ -z "$EMAIL" ]; then
|
if [[ $DOMAIN == $SUBDOMAIN ]]; then
|
||||||
echo "El email no puede estar vacío."
|
DOMAIN=$DOMAIN".analytics.beyondcx.org"
|
||||||
exit 1
|
|
||||||
fi
|
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
|
read -rp "Usuario de acceso (Basic Auth / login): " API_USER
|
||||||
if [ -z "$API_USER" ]; then
|
if [ -z "$API_USER" ]; then
|
||||||
@@ -61,41 +63,14 @@ echo
|
|||||||
read -rp "URL del repositorio Git (HTTPS, sin credenciales) [$REPO_URL_DEFAULT]: " REPO_URL
|
read -rp "URL del repositorio Git (HTTPS, sin credenciales) [$REPO_URL_DEFAULT]: " REPO_URL
|
||||||
REPO_URL=${REPO_URL:-$REPO_URL_DEFAULT}
|
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"
|
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
|
||||||
echo "Resumen de configuración:"
|
echo "Resumen de configuración:"
|
||||||
echo " Dominio: $DOMAIN"
|
echo " Dominio: $DOMAIN"
|
||||||
echo " Email Let'sEnc: $EMAIL"
|
|
||||||
echo " Usuario API: $API_USER"
|
echo " Usuario API: $API_USER"
|
||||||
echo " Repo (visible): $REPO_URL"
|
echo " Repo (visible): $REPO_URL"
|
||||||
if [[ "$IS_PRIVATE" =~ ^[sS]$ ]]; then
|
echo " Path del despliegue: $INSTALL_DIR"
|
||||||
echo " Repo privado: Sí (se usará un PAT sólo para el clon inicial)"
|
|
||||||
else
|
|
||||||
echo " Repo privado: No"
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
|
|
||||||
read -rp "¿Continuar con la instalación? [s/N]: " CONFIRM
|
read -rp "¿Continuar con la instalación? [s/N]: " CONFIRM
|
||||||
CONFIRM=${CONFIRM:-N}
|
CONFIRM=${CONFIRM:-N}
|
||||||
@@ -104,70 +79,20 @@ if [[ ! "$CONFIRM" =~ ^[sS]$ ]]; then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
###############################################
|
# COMENZAMOS ...
|
||||||
# 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
|
|
||||||
###############################################
|
|
||||||
step "Descargando/actualizando el repositorio en $INSTALL_DIR"
|
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
|
if [ -d "$INSTALL_DIR/.git" ]; then
|
||||||
echo "Directorio git ya existe, haciendo 'git pull'..."
|
echo "Directorio git ya existe, haciendo 'git pull'..."
|
||||||
git -C "$INSTALL_DIR" pull --ff-only
|
git -C "$INSTALL_DIR" pull --ff-only
|
||||||
else
|
else
|
||||||
rm -rf "$INSTALL_DIR"
|
rm -rf "$INSTALL_DIR"
|
||||||
echo "Clonando repositorio..."
|
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
|
fi
|
||||||
|
|
||||||
cd "$INSTALL_DIR"
|
cd "$INSTALL_DIR"
|
||||||
@@ -189,97 +114,22 @@ else
|
|||||||
sed -i "s/BASIC_AUTH_PASSWORD:.*/BASIC_AUTH_PASSWORD: \"$API_PASS\"/" docker-compose.yml
|
sed -i "s/BASIC_AUTH_PASSWORD:.*/BASIC_AUTH_PASSWORD: \"$API_PASS\"/" docker-compose.yml
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Aseguramos que nginx exponga también 443
|
if ! grep -q "XXX" docker-compose.yml; then
|
||||||
if grep -q 'ports:' docker-compose.yml && grep -q 'nginx:' docker-compose.yml; then
|
echo "⚠ No encuentro XXX en docker-compose.yml. Revisa el archivo a mano."
|
||||||
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."
|
|
||||||
else
|
else
|
||||||
# Asegurarnos de que no hay nada escuchando en 80/443
|
sed -i "s/XXX/$SUBDOMAIN/g" docker-compose.yml
|
||||||
systemctl stop nginx || true
|
fi
|
||||||
|
if [[ $DOMAIN == $SUBDOMAIN ]]; then
|
||||||
certbot certonly \
|
set DOMAIN=$DOMAIN".analytics.beyondcx.org"
|
||||||
--standalone \
|
fi
|
||||||
--non-interactive \
|
if ! grep -q "DDD" docker-compose.yml; then
|
||||||
--agree-tos \
|
echo "⚠ No encuentro DDD en docker-compose.yml. Revisa el archivo a mano."
|
||||||
-m "$EMAIL" \
|
else
|
||||||
-d "$DOMAIN"
|
sed -i "s/DDD/$DOMAIN/" docker-compose.yml
|
||||||
|
|
||||||
echo "Certificado emitido en /etc/letsencrypt/live/$DOMAIN/"
|
|
||||||
fi
|
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"
|
step "Construyendo imágenes Docker y arrancando contenedores"
|
||||||
|
|
||||||
docker compose build
|
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