feat: dockerize app and convert to pyproject setup
- Add pyproject.toml with proper metadata and dependency groups - Create multi-stage Dockerfile for backend - Add docker-compose.yml with dev/prod profiles - Create frontend Dockerfile with nginx - Add .dockerignore for optimized builds - Update README with Docker instructions and troubleshooting - Remove requirements.txt in favor of pyproject.toml - Ensure data persistence with Docker volumes
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# Stage 1: Builder
|
||||
FROM python:3.14 AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install build dependencies
|
||||
RUN pip install --no-cache-dir setuptools wheel
|
||||
|
||||
# Copy pyproject.toml first for better layer caching
|
||||
COPY pyproject.toml ./
|
||||
|
||||
# Copy source code
|
||||
COPY app/ ./app/
|
||||
COPY backup/ ./backup/
|
||||
COPY alembic/ ./alembic/
|
||||
COPY alembic.ini ./
|
||||
|
||||
# Build the package with dev dependencies
|
||||
RUN pip install --no-cache-dir -e ".[dev]"
|
||||
|
||||
# Stage 2: Runtime
|
||||
FROM python:3.14-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Create non-root user
|
||||
RUN groupadd -r backup-tool && useradd -r -g backup-tool backup-tool
|
||||
|
||||
# Copy installed packages from builder
|
||||
COPY --from=builder /usr/local/lib/python3.14/site-packages/ /usr/local/lib/python3.14/site-packages/
|
||||
COPY --from=builder /usr/local/bin/ /usr/local/bin/
|
||||
|
||||
# Copy application code
|
||||
COPY --from=builder /app/ ./
|
||||
|
||||
# Create data directory for SQLite and backups
|
||||
RUN mkdir -p /app/data /app/backups && \
|
||||
chown -R backup-tool:backup-tool /app
|
||||
|
||||
USER backup-tool
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8000
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health')" || exit 1
|
||||
|
||||
# Default command
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
@@ -43,6 +43,10 @@ app.include_router(dashboard.router)
|
||||
async def health_check():
|
||||
return {"status": "healthy"}
|
||||
|
||||
def main():
|
||||
import uvicorn
|
||||
uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)
|
||||
|
||||
# Static files for production
|
||||
frontend_dist = os.path.join(os.path.dirname(__file__), "../../frontend/dist")
|
||||
if os.path.exists(frontend_dist):
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=61.0", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "backup-tool"
|
||||
version = "0.1.0"
|
||||
description = "Web-based backup management tool for small teams and SMBs"
|
||||
readme = "README.md"
|
||||
license = {text = "MIT"}
|
||||
requires-python = ">=3.11"
|
||||
authors = [
|
||||
{name = "Backup Tool Team"}
|
||||
]
|
||||
keywords = ["backup", "restore", "scheduler", "web"]
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Intended Audience :: System Administrators",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Programming Language :: Python :: 3.14",
|
||||
"Topic :: System :: Archiving :: Backup",
|
||||
]
|
||||
dependencies = [
|
||||
"fastapi>=0.115.0",
|
||||
"uvicorn[standard]>=0.34.0",
|
||||
"sqlalchemy[asyncio]>=2.0.0",
|
||||
"aiosqlite>=0.21.0",
|
||||
"alembic>=1.15.0",
|
||||
"pydantic>=2.13.0",
|
||||
"pydantic-settings>=2.9.0",
|
||||
"apscheduler>=3.11.0",
|
||||
"paramiko>=3.5.0",
|
||||
"aiofiles>=23.2.0",
|
||||
"httpx>=0.28.0",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"pytest>=8.3.0",
|
||||
"pytest-asyncio>=0.26.0",
|
||||
]
|
||||
prod = [
|
||||
"gunicorn>=23.0.0",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
backup-tool = "app.main:main"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/backup-tool/backup-tool"
|
||||
Documentation = "https://github.com/backup-tool/backup-tool#readme"
|
||||
Repository = "https://github.com/backup-tool/backup-tool.git"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["."]
|
||||
include = ["app*", "backup*", "alembic*"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
asyncio_mode = "auto"
|
||||
testpaths = ["tests"]
|
||||
pythonpath = [".", "app", "backup"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
alembic = ["*.ini", "*.py", "*.mako"]
|
||||
@@ -1,12 +0,0 @@
|
||||
fastapi==0.109.0
|
||||
uvicorn[standard]==0.27.0
|
||||
sqlalchemy[asyncio]==2.0.25
|
||||
aiosqlite==0.19.0
|
||||
alembic==1.13.1
|
||||
pydantic==2.5.3
|
||||
pydantic-settings==2.1.0
|
||||
apscheduler==3.10.4
|
||||
paramiko==3.4.0
|
||||
pytest==7.4.4
|
||||
pytest-asyncio==0.21.1
|
||||
httpx==0.26.0
|
||||
Reference in New Issue
Block a user