Subida del docker a producción
This commit is contained in:
parent
b0c04bbe42
commit
e7aea83bdb
@ -1,12 +1,59 @@
|
|||||||
.venv
|
# ----------------------------
|
||||||
__pycache__
|
# Python
|
||||||
|
# ----------------------------
|
||||||
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
*.pyo
|
*.pyo
|
||||||
*.pyd
|
*.pyd
|
||||||
.pytest_cache
|
*.py[cod]
|
||||||
.mypy_cache
|
*.egg-info/
|
||||||
.ruff_cache
|
.eggs/
|
||||||
.git
|
.pytest_cache/
|
||||||
|
.mypy_cache/
|
||||||
|
|
||||||
|
# Virtual environments (local only)
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
|
||||||
|
# ----------------------------
|
||||||
|
# Environment & secrets
|
||||||
|
# ----------------------------
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
*.crt
|
||||||
|
*.pfx
|
||||||
|
*.p12
|
||||||
|
|
||||||
|
# ----------------------------
|
||||||
|
# Git
|
||||||
|
# ----------------------------
|
||||||
|
.git/
|
||||||
.gitignore
|
.gitignore
|
||||||
tests
|
|
||||||
*.log
|
# ----------------------------
|
||||||
|
# Docker
|
||||||
|
# ----------------------------
|
||||||
|
Dockerfile
|
||||||
|
docker-compose.yml
|
||||||
|
|
||||||
|
# ----------------------------
|
||||||
|
# Editor / OS junk
|
||||||
|
# ----------------------------
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# ----------------------------
|
||||||
|
# Docs & local files
|
||||||
|
# ----------------------------
|
||||||
|
docs/
|
||||||
|
*.md
|
||||||
|
|
||||||
|
# ----------------------------
|
||||||
|
# Tests & tooling (si no se usan en runtime)
|
||||||
|
# ----------------------------
|
||||||
|
tests/
|
||||||
|
|||||||
@ -3,11 +3,19 @@
|
|||||||
# Copy this file to `.env` and fill the real values
|
# Copy this file to `.env` and fill the real values
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
|
# --------------------
|
||||||
|
# UVICORN
|
||||||
|
# --------------------
|
||||||
|
UVICORN_RELOAD=false
|
||||||
|
UVICORN_WORKERS=2
|
||||||
|
|
||||||
# --------------------
|
# --------------------
|
||||||
# Application
|
# Application
|
||||||
# --------------------
|
# --------------------
|
||||||
APP_ENV=local # local | prod
|
APP_ENV=local # local | prod
|
||||||
LOG_LEVEL=INFO
|
LOG_LEVEL=INFO
|
||||||
|
STATE_PATH = ./
|
||||||
|
LOCAL_TZ = Europe/Madrid
|
||||||
|
|
||||||
# --------------------
|
# --------------------
|
||||||
# Secret manager
|
# Secret manager
|
||||||
|
|||||||
59
Dockerfile
59
Dockerfile
@ -0,0 +1,59 @@
|
|||||||
|
# ---------- Base image ----------
|
||||||
|
FROM python:3.12-slim AS base
|
||||||
|
|
||||||
|
# Evita pyc, mejora logs
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Dependencias del sistema necesarias para crypto / PDFs
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
libssl-dev \
|
||||||
|
libffi-dev \
|
||||||
|
ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- Dependencies ----------
|
||||||
|
FROM base AS deps
|
||||||
|
|
||||||
|
# Copiamos solo metadatos para aprovechar cache
|
||||||
|
COPY ./pyproject.toml ./
|
||||||
|
|
||||||
|
# Instalamos dependencias
|
||||||
|
RUN pip install --upgrade pip \
|
||||||
|
&& pip install .
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- Runtime ----------
|
||||||
|
FROM base AS runtime
|
||||||
|
|
||||||
|
# Copiamos dependencias instaladas
|
||||||
|
COPY --from=deps /usr/local /usr/local
|
||||||
|
|
||||||
|
# Copiamos código fuente
|
||||||
|
COPY src/ ./
|
||||||
|
|
||||||
|
# Puerto FastAPI
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Usuario no-root (buena práctica)
|
||||||
|
RUN useradd -m appuser
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Comando de arranque
|
||||||
|
CMD ["sh", "-c", "\
|
||||||
|
if [ \"$UVICORN_RELOAD\" = \"true\" ]; then \
|
||||||
|
uvicorn signing_service.main:app --host 0.0.0.0 --port 8000 --reload; \
|
||||||
|
else \
|
||||||
|
uvicorn signing_service.main:app --host 0.0.0.0 --port 8000 --workers ${UVICORN_WORKERS:-1}; \
|
||||||
|
fi"]
|
||||||
|
|
||||||
|
# Healthcheck
|
||||||
|
|
||||||
|
#RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
#HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
|
||||||
|
# CMD curl -f http://127.0.0.1:8000/health || exit 1
|
||||||
22
docker-compose.yml
Normal file
22
docker-compose.yml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
services:
|
||||||
|
signing-service:
|
||||||
|
image: factuges-document-signing-service:latest
|
||||||
|
container_name: factuges-document-signing-service
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
- edge
|
||||||
|
volumes:
|
||||||
|
- ./volumes:/var/log
|
||||||
|
|
||||||
|
networks:
|
||||||
|
edge:
|
||||||
|
name: edge
|
||||||
|
external: true
|
||||||
|
internal:
|
||||||
|
name: factuges_rodax_internal
|
||||||
|
external: true
|
||||||
140
scripts/build-docker.sh
Executable file
140
scripts/build-docker.sh
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_VERSION="0.0.3"
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# FACTUGES Document Signing Service Build Script
|
||||||
|
# -----------------------------------------------------
|
||||||
|
# Build + Subida a producción de la imagen Docker
|
||||||
|
# =====================================================
|
||||||
|
# Uso:
|
||||||
|
# ./build_docker.sh <company> [--load]
|
||||||
|
#
|
||||||
|
# =====================================================
|
||||||
|
|
||||||
|
# --- Configuración base ---
|
||||||
|
COMPANY=""
|
||||||
|
LOAD=false
|
||||||
|
|
||||||
|
# --- Validar que el primer argumento existe y no es un flag ---
|
||||||
|
if [[ $# -eq 0 || "$1" == --* ]]; then
|
||||||
|
echo "❌ ERROR: Falta el parámetro <company>"
|
||||||
|
echo "Uso: ./build_docker.sh <company> [--load]"
|
||||||
|
echo "Ejemplos:"
|
||||||
|
echo " ./build_docker.sh acme --load"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMPANY="$1"
|
||||||
|
|
||||||
|
SSH_USER="rodax"
|
||||||
|
SSH_HOST="vps-2.rodax-software.com"
|
||||||
|
SSH_PORT="49152"
|
||||||
|
|
||||||
|
# Override por compañía específica
|
||||||
|
if [[ "$COMPANY" == "rodax" ]]; then
|
||||||
|
SSH_USER="rodax"
|
||||||
|
SSH_HOST="factuges.rodax-software.local"
|
||||||
|
SSH_PORT="22"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Parseo de flags ---
|
||||||
|
shift # quitamos el <company>, ahora solo quedan flags
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--load) LOAD=true ;;
|
||||||
|
*) echo "⚠️ Argumento desconocido: $arg" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# --- Paths base ---
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_DIR="$(realpath "${SCRIPT_DIR}/..")"
|
||||||
|
OUT_DIR="${PROJECT_DIR}/build/"
|
||||||
|
|
||||||
|
if [[ -z "$COMPANY" ]]; then
|
||||||
|
echo "❌ Error: debes indicar la compañía. Ejemplo: ./build_docker.sh acme [--load]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $COMPANY =~ --.* ]]; then
|
||||||
|
echo "❌ Error: debes indicar la compañía. Ejemplo: ./build_docker.sh acme [--load]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Detectar nombre y versión de la API ---
|
||||||
|
IMAGE_NAME=$(node -p "require('${PROJECT_DIR}/setup.cfg').name" 2>/dev/null || echo "factuges-document-signing-service")
|
||||||
|
IMAGE_VERSION=$(node -p "require('${PROJECT_DIR}/setup.cfg').version" 2>/dev/null || echo "0.1.2")
|
||||||
|
|
||||||
|
PORT="8000" # valor por defecto
|
||||||
|
|
||||||
|
# --- 3. Etiquetas e información ---
|
||||||
|
DATE=$(date +'%Y%m%d-%H%M%S')
|
||||||
|
ISO_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
USER_NAME=$(whoami)
|
||||||
|
GIT_HASH=$(git -C "$PROJECT_DIR" rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
||||||
|
GIT_BRANCH=$(git -C "$PROJECT_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
||||||
|
|
||||||
|
IMAGE_TAG_V="${IMAGE_NAME}:v${IMAGE_VERSION}"
|
||||||
|
IMAGE_TAG_LATEST="${IMAGE_NAME}:latest"
|
||||||
|
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
rm -rf "${OUT_DIR:?}/"*
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "-------------------------------------------------------"
|
||||||
|
echo " FACTUGES Document Signing Service Build Script v${SCRIPT_VERSION}"
|
||||||
|
echo " Compañía: ${COMPANY}"
|
||||||
|
echo " Proyecto: ${IMAGE_NAME}"
|
||||||
|
echo " Versión: ${IMAGE_VERSION}"
|
||||||
|
echo " Puerto: ${PORT}"
|
||||||
|
echo " Etiquetas: ${IMAGE_TAG_V}, ${IMAGE_TAG_LATEST}"
|
||||||
|
echo " Dir. out: ${OUT_DIR}"
|
||||||
|
echo " Cargar: ${LOAD}"
|
||||||
|
echo "-------------------------------------------------------"
|
||||||
|
|
||||||
|
cd "${PROJECT_DIR}"
|
||||||
|
echo "🐳 Construyendo imagen Docker..."
|
||||||
|
|
||||||
|
docker build \
|
||||||
|
-t "${IMAGE_TAG_V}" -t "${IMAGE_TAG_LATEST}" \
|
||||||
|
--build-arg PORT="${PORT}" \
|
||||||
|
-f "${PROJECT_DIR}/Dockerfile" "${PROJECT_DIR}"
|
||||||
|
|
||||||
|
echo "✅ Imagen Docker construida correctamente"
|
||||||
|
|
||||||
|
|
||||||
|
TAR_FILE_V="${OUT_DIR}/${IMAGE_NAME}-v${IMAGE_VERSION}-${DATE}.tar"
|
||||||
|
echo "🐳 Guardando imagen Docker ${TAR_FILE_V} ..."
|
||||||
|
docker save "${IMAGE_TAG_V}" "${IMAGE_TAG_LATEST}" -o "${TAR_FILE_V}"
|
||||||
|
|
||||||
|
echo "📦 Imagen guardada:"
|
||||||
|
echo " ${TAR_FILE_V}"
|
||||||
|
|
||||||
|
if [[ "$LOAD" == true ]]; then
|
||||||
|
echo "📥 Cargando imagen en producción ${SSH_HOST}..."
|
||||||
|
scp -r -P "${SSH_PORT}" "${OUT_DIR}" "${SSH_USER}@${SSH_HOST}:/opt/factuges-document-signing-service/"
|
||||||
|
|
||||||
|
RESULT=$(ssh -p "${SSH_PORT}" "${SSH_USER}@${SSH_HOST}" \
|
||||||
|
"docker load -i /opt/factuges-document-signing-service/build/$(basename "${TAR_FILE_V}") && \
|
||||||
|
docker tag ${IMAGE_TAG_V} ${IMAGE_TAG_LATEST} " 2>&1)
|
||||||
|
|
||||||
|
echo "${RESULT}"
|
||||||
|
echo "✅ Imagen cargada en producción"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 3️⃣ Resumen
|
||||||
|
# =====================================================
|
||||||
|
echo "-------------------------------------------------------"
|
||||||
|
echo "🎯 Resultado final para '${COMPANY}'"
|
||||||
|
echo " 🐳 v${IMAGE_VERSION} → ${OUT_DIR}"
|
||||||
|
echo "🧩 Script version: ${SCRIPT_VERSION} - FIN"
|
||||||
|
echo "-------------------------------------------------------"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
name = "factuges-document-signing-service"
|
name = "factuges-document-signing-service"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
description = "FastAPI service for signing PDF documents using external secret managers"
|
description = "FastAPI service for signing PDF documents using external secret managers"
|
||||||
author = Rodax Software
|
author = Rodax Software
|
||||||
author_email = info@rodax-software.com
|
author_email = info@rodax-software.com
|
||||||
|
|||||||
@ -19,7 +19,7 @@ local_tz = tz.gettz(settings.local_tz)
|
|||||||
state_path = Path(settings.state_path)
|
state_path = Path(settings.state_path)
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
log_dir = state_path / "logs"
|
log_dir = state_path
|
||||||
log_dir.mkdir(parents=True, exist_ok=True)
|
log_dir.mkdir(parents=True, exist_ok=True)
|
||||||
logger = create_logger(
|
logger = create_logger(
|
||||||
name="factuges-document-signing-service",
|
name="factuges-document-signing-service",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user