From 31f1fcecc4e30fdd0bec0325a55664653dfa31e4 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 12 May 2026 12:15:37 +0300 Subject: [PATCH] feat: add Docker Compose setup with bind-mount appdata directory - Dockerfile builds image with app source in /app_src - docker-entrypoint.sh syncs code from image on each start, inits DB - docker-compose.yml mounts ./appdata:/app for easy backup - backend/init_db.py for safe DB init (no drop_all) - backend/database.py supports DATABASE_URL env var - .dockerignore excludes venv, __pycache__, *.db, .git Co-Authored-By: Claude Sonnet 4.6 --- .dockerignore | 13 +++++++++++++ Dockerfile | 15 +++++++++++++++ backend/database.py | 7 +++++-- backend/init_db.py | 27 +++++++++++++++++++++++++++ docker-compose.yml | 10 ++++++++++ docker-entrypoint.sh | 11 +++++++++++ 6 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 backend/init_db.py create mode 100644 docker-compose.yml create mode 100644 docker-entrypoint.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f1c7cc8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,13 @@ +venv/ +backend/venv/ +**/__pycache__/ +*.pyc +*.pyo +*.db +.git/ +.gitignore +.vscode/ +.idea/ +data/ +*.xls +*.xlsx diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8dd3344 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM python:3.11-slim + +COPY requirements.txt /app_src/requirements.txt +RUN pip install --no-cache-dir -r /app_src/requirements.txt + +COPY backend/ /app_src/backend/ +COPY frontend/ /app_src/frontend/ +COPY docker-entrypoint.sh /app_src/docker-entrypoint.sh +RUN chmod +x /app_src/docker-entrypoint.sh + +WORKDIR /app + +EXPOSE 8000 + +ENTRYPOINT ["/app_src/docker-entrypoint.sh"] diff --git a/backend/database.py b/backend/database.py index 14d745a..9915ab4 100644 --- a/backend/database.py +++ b/backend/database.py @@ -1,10 +1,13 @@ # backend/database.py +import os + from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, scoped_session -SQLALCHEMY_DATABASE_URL = "sqlite:///./app.db" # или PostgreSQL URL +SQLALCHEMY_DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./app.db") -engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}) +connect_args = {"check_same_thread": False} if SQLALCHEMY_DATABASE_URL.startswith("sqlite") else {} +engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args=connect_args) SessionLocal = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine)) def get_db(): diff --git a/backend/init_db.py b/backend/init_db.py new file mode 100644 index 0000000..97e2024 --- /dev/null +++ b/backend/init_db.py @@ -0,0 +1,27 @@ +from sqlalchemy.orm import sessionmaker + +from backend.models import Base, User +from backend.database import engine +from backend.security import get_password_hash + + +def init_db(): + Base.metadata.create_all(bind=engine) + + Session = sessionmaker(bind=engine) + db = Session() + try: + if not db.query(User).filter(User.username == 'admin').first(): + db.add(User( + username='admin', + password_hash=get_password_hash('admin'), + role='admin', + )) + db.commit() + print("Created default admin user (login: admin / password: admin)") + finally: + db.close() + + +if __name__ == "__main__": + init_db() diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d86d927 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +services: + app: + build: . + ports: + - "8000:8000" + volumes: + - ./appdata:/app + environment: + - DATABASE_URL=sqlite:////app/data/app.db + restart: unless-stopped diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..2864f6b --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -e + +# Sync app code from image on every start (keeps code fresh after rebuilds) +rm -rf /app/backend /app/frontend +cp -r /app_src/backend /app_src/frontend /app/ + +mkdir -p /app/data +python -m backend.init_db + +exec uvicorn backend.main:app --host 0.0.0.0 --port 8000