expenses_manager/README.md
2026-07-29 11:20:39 +00:00

6.1 KiB

expenses_manager

Aplicación web de gestión de finanzas personales (gastos, ingresos, cuentas, categorías, objetivos y repostajes de vehículo), construida con Django y desplegada en un NAS Synology mediante Docker + PostgreSQL.

Características

  • Registro de gastos e ingresos, con categorías jerárquicas y etiquetas.
  • Cuentas con cálculo de saldo (soft-delete para preservar históricos).
  • Dashboard con gráficos por categoría, evolución de saldo y comparativas de periodo.
  • Objetivos de tres tipos: pago/deuda, presupuesto (mensual/anual) y ahorro.
  • Módulo de repostajes con cálculo de consumo, precio por litro y km recorridos.

Stack

  • Python 3.11 · Django 5.2
  • PostgreSQL (producción) / SQLite (desarrollo local por defecto)
  • Gunicorn + WhiteNoise
  • Docker (despliegue) · Jenkins (CI)

Desarrollo local

Por defecto, en local la aplicación usa SQLite, así que no necesitas levantar ninguna base de datos para empezar.

Requisitos

  • Python 3.11 (estos pasos asumen un entorno conda, pero sirve cualquier entorno virtual).

Pasos

  1. Clona el repositorio:

    git clone https://gitea.kuijper.es/jkuijperm/expenses_manager.git
    cd expenses_manager
    
  2. Crea y activa el entorno conda:

    conda create -n gastos python=3.11
    conda activate gastos
    
  3. Instala las dependencias:

    pip install -r expenses_manager/requirements.txt
    
  4. Crea el archivo .env (ver Variables de entorno). Para desarrollo basta con:

    DEBUG=True
    SECRET_KEY=cualquier-clave-para-desarrollo
    

    Con DEBUG=True y sin variables DB_*, se usa SQLite automáticamente.

  5. Aplica las migraciones y arranca el servidor:

    cd expenses_manager
    python manage.py migrate
    python manage.py runserver
    
  6. Abre http://127.0.0.1:8000/ en el navegador.

Datos de demostración (opcional): con DEBUG=True puedes poblar la base de datos con un usuario y datos de ejemplo:

python manage.py seed_demo

El comando está protegido para no ejecutarse si DEBUG=False.


Variables de entorno

La configuración se lee de un archivo .env (mediante python-dotenv) situado en expenses_manager/ (junto a manage.py). Este archivo no se versiona.

Variable Obligatoria Por defecto Descripción
SECRET_KEY Sí en producción Clave secreta de Django. Con DEBUG=False es obligatoria (si falta, la app no arranca).
DEBUG No False True en desarrollo. Activa SQLite por defecto y desactiva el hardening.
ALLOWED_HOSTS No localhost,127.0.0.1 Lista separada por comas.
CSRF_TRUSTED_ORIGINS No (vacío) Lista separada por comas (p. ej. https://midominio.com).
DB_ENGINE No sqlite3 postgresql para usar Postgres; cualquier otro valor usa SQLite.
DB_NAME Con Postgres Nombre de la base de datos.
DB_USER Con Postgres Usuario.
DB_PASSWORD Con Postgres Contraseña.
DB_HOST No localhost Host de la base de datos (db en Docker Compose).
DB_PORT No 5432 Puerto.

En el repositorio hay un archivo .env.example con estas variables como plantilla. Cópialo a .env y rellena los valores.


Despliegue con Docker

El despliegue en producción usa Docker con dos servicios: la aplicación Django (servida por Gunicorn) y una base de datos PostgreSQL.

Dockerfile

El Dockerfile está en el repositorio (app/Dockerfile en el árbol de despliegue) y hace lo esencial: parte de python:3.11-slim, instala las dependencias de requirements.txt y copia el código. A grandes rasgos:

FROM python:3.11-slim

ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1

WORKDIR /app/expenses_manager

COPY expenses_manager/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

docker-compose (no versionado)

El docker-compose.yml no está en el repositorio: es específico de la infraestructura del NAS y vive fuera del proyecto. A continuación se documenta qué debe contener, para poder reproducirlo. Ningún secreto va escrito en el archivo: todos los valores sensibles se leen del .env.

services:
  db:
    image: postgres:15
    restart: always
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - ./postgres:/var/lib/postgresql/data

  web:
    build: ./app
    container_name: finanzas_web
    command: gunicorn expenses_manager.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - ./app:/app
    ports:
      - "8001:8000"
    depends_on:
      - db
    env_file:
      - ./app/expenses_manager/.env

Notas:

  • Las credenciales de Postgres (DB_NAME, DB_USER, DB_PASSWORD) las toma Docker Compose de un .env situado junto al docker-compose.yml. Es un archivo distinto del .env de Django (que va dentro del proyecto y lo carga la propia app vía env_file).
  • El servicio web no repite las variables de base de datos en un bloque environment: las hereda del .env de Django a través de env_file.

Puesta en marcha y actualizaciones

Desde el directorio que contiene el docker-compose.yml:

git -C app pull                      # traer los últimos cambios al repo montado
docker-compose down
docker-compose up -d --build
docker-compose exec web python manage.py migrate
docker-compose exec web python manage.py collectstatic --noinput
  • migrate solo es necesario si hay migraciones nuevas.
  • collectstatic solo si han cambiado archivos estáticos (CSS/JS).
  • No ejecutes makemigrations en producción: las migraciones se generan en desarrollo y llegan versionadas con el git pull.

Tests

La suite usa pytest + pytest-django:

cd expenses_manager
pytest

La integración continua (Jenkins) ejecuta los tests en cada cambio de la rama main.


Ramas

  • main — solo recibe cambios ya probados (vía merge desde dev).
  • dev — rama de trabajo activa.