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 <noreply@anthropic.com>
This commit is contained in:
13
.dockerignore
Normal file
13
.dockerignore
Normal file
@@ -0,0 +1,13 @@
|
||||
venv/
|
||||
backend/venv/
|
||||
**/__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.db
|
||||
.git/
|
||||
.gitignore
|
||||
.vscode/
|
||||
.idea/
|
||||
data/
|
||||
*.xls
|
||||
*.xlsx
|
||||
15
Dockerfile
Normal file
15
Dockerfile
Normal file
@@ -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"]
|
||||
@@ -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():
|
||||
|
||||
27
backend/init_db.py
Normal file
27
backend/init_db.py
Normal file
@@ -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()
|
||||
10
docker-compose.yml
Normal file
10
docker-compose.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- "8000:8000"
|
||||
volumes:
|
||||
- ./appdata:/app
|
||||
environment:
|
||||
- DATABASE_URL=sqlite:////app/data/app.db
|
||||
restart: unless-stopped
|
||||
11
docker-entrypoint.sh
Normal file
11
docker-entrypoint.sh
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user