Skip to content

Commit 924e6ac

Browse files
committed
Merge remote-tracking branch 'origin/master'
# Conflicts: # backend/Dockerfile
2 parents d6a4d47 + 4480970 commit 924e6ac

32 files changed

+2513
-912
lines changed

.env.example

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ APP_LOG_LEVEL=INFO
1717
APP_LOG_FORMAT=text
1818

1919
# Database Configuration
20-
APP_DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/devbin
20+
APP_DATABASE_URL=postgresql+asyncpg://postgres:postgres@devbin_db:5432/devbin
2121

2222
# Security - HTTPS
2323
# Set to true to redirect HTTP to HTTPS
@@ -99,6 +99,6 @@ APP_SAVE_IP_ADDRESS=false
9999
# Example generation: openssl rand -hex 32
100100

101101
# Frontend configurations
102-
API_BASE_URL=http://devbin:8000
102+
API_URL=http://devbin:8000
103103
PORT=3000
104-
ORIGIN=http://localhost:3000
104+
ORIGIN=http://localhost:3000 # prevent cross-site post req forbidden from frontend because node can't resolve it's origin

.taskfiles/dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ tasks:
55
up:
66
desc: Start all development services
77
cmds:
8-
- "{{.COMPOSE_DEV}} --profile dev_frontend --profile dev_backend up -d --build"
8+
- "{{.COMPOSE_DEV}} --profile dev_frontend --profile dev_backend up --build --watch"
99

1010
backend:
1111
desc: Start backend only (with database)

backend/Dockerfile

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@ FROM ghcr.io/astral-sh/uv:${UV_VERSION} AS uv
1414
FROM python:3.13.1-slim AS base
1515

1616
# Install security updates and minimal runtime dependencies
17-
# Create non-root user (UID 10001 is common convention)
1817
RUN apt-get update && \
1918
apt-get upgrade -y && \
2019
apt-get install -y --no-install-recommends \
21-
ca-certificates \
22-
curl && \
23-
rm -rf /var/lib/apt/lists/* && \
24-
groupadd -g 10001 appuser && \
25-
useradd -u 10001 -g appuser -m -s /bin/bash appuser
20+
ca-certificates \
21+
curl && \
22+
rm -rf /var/lib/apt/lists/*
23+
24+
# Create non-root user and initialize /app with correct permissions
25+
RUN groupadd -g 10001 appuser && \
26+
useradd -u 10001 -g appuser -m -s /bin/bash appuser && \
27+
mkdir /app && chown appuser:appuser /app
2628

2729
WORKDIR /app
2830

@@ -31,69 +33,56 @@ WORKDIR /app
3133
# ============================================
3234
FROM base AS builder
3335

34-
# Install build dependencies (only needed during build)
3536
RUN apt-get update && \
3637
apt-get install -y --no-install-recommends \
37-
gcc \
38-
g++ \
39-
libpq-dev && \
38+
gcc \
39+
g++ \
40+
libpq-dev && \
4041
rm -rf /var/lib/apt/lists/*
4142

42-
# Copy uv from uv stage (pinned version for reproducibility)
4343
COPY --from=uv /uv /uvx /usr/local/bin/
4444

45-
# Copy dependency files first for optimal layer caching
46-
# Changes to source code won't invalidate this layer
45+
# Copy dependencies
4746
COPY pyproject.toml uv.lock ./
4847

49-
# Install dependencies with BuildKit cache mount for faster rebuilds
50-
# --frozen: Use exact versions from uv.lock (reproducible builds)
51-
# --no-dev: Exclude development dependencies
52-
# --extra production: Include any production related dependencies (redis, aiocache etc...)
48+
# Install dependencies
5349
RUN --mount=type=cache,target=/root/.cache/uv \
54-
uv sync --frozen --no-default-groups --extra production --extra migrations
50+
uv sync --frozen --no-default-groups --extra production --extra migrations --no-install-project
5551

5652
# ============================================
5753
# Stage 3: Runtime - Production Image
5854
# ============================================
5955
FROM base AS runtime
6056

61-
# Copy uv from builder stage (ensures version consistency)
57+
# Copy uv and the pre-built venv
6258
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uvx /usr/local/bin/
63-
64-
# Copy installed dependencies from builder stage
65-
# This excludes build tools (gcc, g++, libpq-dev)
6659
COPY --from=builder /app/.venv /app/.venv
6760

68-
# Copy application code
61+
# Copy application code with correct ownership
6962
COPY --chown=appuser:appuser . .
7063

71-
# Copy Docker-specific alembic config
64+
# Overwrite config
7265
COPY --chown=appuser:appuser alembic.docker.ini alembic.ini
7366

74-
# Create files directory with proper ownership
67+
# Create files directory
7568
RUN mkdir -p /app/files && chown appuser:appuser /app/files
7669

77-
# Switch to non-root user for security
70+
# Switch to non-root user
7871
USER appuser
7972

8073
# Environment variables
8174
ENV APP_PORT=8000 \
8275
APP_RELOAD=false \
8376
PATH="/app/.venv/bin:$PATH" \
8477
PYTHONUNBUFFERED=1 \
85-
PYTHONDONTWRITEBYTECODE=1
78+
PYTHONDONTWRITEBYTECODE=1 \
79+
UV_PROJECT_ENVIRONMENT="/app/.venv"
8680

8781
# Expose application port
8882
EXPOSE 8000
8983

90-
# Health check using existing /health endpoint
91-
# --interval=30s: Check every 30 seconds
92-
# --timeout=5s: Mark unhealthy if no response in 5s
93-
# --start-period=10s: Grace period for app startup
94-
# --retries=3: Require 3 consecutive failures before marking unhealthy
9584
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
9685
CMD curl -f http://localhost:${APP_PORT:-8000}/health || exit 1
9786

98-
# Use exec form for proper signal handling (graceful shutdown)
99-
CMD ["uv", "run", "main.py"]
87+
# FIX: Added --no-project to prevent uv from trying to write .egg-info
88+
CMD ["uv", "run", "--no-project", "python", "main.py"]

backend/app/services/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
__all__ = [
2+
"containers",
3+
]

docker-compose.prod.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ services:
2020
devbin_db:
2121
condition: service_healthy
2222
healthcheck:
23-
test: [ "CMD", "curl", "-f", "http://localhost:${APP_PORT:-8000}/health" ]
23+
test: ["CMD", "curl", "-f", "http://localhost:${APP_PORT:-8000}/health"]
2424
interval: 15s
2525
timeout: 5s
2626
start_period: 3s
@@ -35,7 +35,7 @@ services:
3535
volumes:
3636
- postgres_data:/var/lib/postgresql/data
3737
healthcheck:
38-
test: [ "CMD-SHELL", "pg_isready -U postgres -d postgres" ]
38+
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
3939
interval: 10s
4040
timeout: 5s
4141
retries: 5

docker-compose.yml

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,17 @@ services:
88
- "3000:3000"
99
env_file:
1010
- .env
11-
profiles: [ "dev_frontend" ]
11+
profiles: ["dev_frontend"]
12+
develop:
13+
watch:
14+
- path: ./src
15+
target: /src
16+
action: sync
17+
- path: ./package.json
18+
action: rebuild
19+
networks:
20+
- devbin_network
21+
1222
devbin:
1323
env_file:
1424
- .env
@@ -21,13 +31,16 @@ services:
2131
depends_on:
2232
devbin_db:
2333
condition: service_healthy
24-
profiles: [ "dev_backend" ]
34+
profiles: ["dev_backend"]
2535
healthcheck:
26-
test: [ "CMD", "curl", "-f", "http://localhost:${APP_PORT:-8000}/health" ]
36+
test: ["CMD", "curl", "-f", "http://localhost:${APP_PORT:-8000}/health"]
2737
interval: 15s
2838
timeout: 5s
2939
start_period: 3s
3040
retries: 3
41+
networks:
42+
- devbin_network
43+
3144
devbin_db:
3245
env_file:
3346
- .env
@@ -37,10 +50,16 @@ services:
3750
volumes:
3851
- postgres_data:/var/lib/postgresql/data
3952
healthcheck:
40-
test: [ "CMD-SHELL", "pg_isready -U postgres -d postgres" ]
53+
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
4154
interval: 10s
4255
timeout: 5s
4356
retries: 5
57+
networks:
58+
- devbin_network
4459

4560
volumes:
4661
postgres_data:
62+
63+
networks:
64+
devbin_network:
65+
driver: bridge

docs/configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,6 @@ Generate a secure token: `openssl rand -hex 32`
121121

122122
| Variable | Description | Default |
123123
|----------|-------------|---------|
124-
| `API_BASE_URL` | Backend API URL | `http://devbin:8000` |
124+
| `API_URL` | Backend API URL | `http://devbin:8000` |
125125
| `PORT` | Frontend port | `3000` |
126126
| `ORIGIN` | Frontend origin | `http://localhost:3000` |

frontend/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# Backend API config
22
API_URL=http://localhost:8000
3+
ORIGIN=http://localhost:3000 # prevent cross-site post req forbidden from frontend because node can't resolve it's origin

frontend/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ node_modules
1212
# OS
1313
.DS_Store
1414
Thumbs.db
15+
*.log
1516

1617
# Env
1718
.env
@@ -21,4 +22,4 @@ Thumbs.db
2122

2223
# Vite
2324
vite.config.js.timestamp-*
24-
vite.config.ts.timestamp-*
25+
vite.config.ts.timestamp-*

frontend/openapi-ts.config.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import "dotenv/config";
2+
import { defineConfig } from "@hey-api/openapi-ts";
3+
4+
if (!process.env.API_URL) {
5+
throw new Error("Please define API_URL in your .env");
6+
}
7+
8+
export default defineConfig({
9+
input: `${process.env.API_URL}/openapi.json`,
10+
output: "src/client",
11+
});

0 commit comments

Comments
 (0)