- New l4_proxy_hosts table and Drizzle migration (0015)
- Full CRUD model layer with validation, audit logging, and Caddy config
generation (buildL4Servers integrating into buildCaddyDocument)
- Server actions, paginated list page, create/edit/delete dialogs
- L4 port manager sidecar (docker/l4-port-manager) that auto-recreates
the caddy container when port mappings change via a trigger file
- Auto-detects Docker Compose project name from caddy container labels
- Supports both named-volume and bind-mount (COMPOSE_HOST_DIR) deployments
- getL4PortsStatus simplified: status file is sole source of truth,
trigger files deleted after processing to prevent stuck 'Waiting' banner
- Navigation entry added (CableIcon)
- Tests: unit (entrypoint.sh invariants + validation), integration (ports
lifecycle + caddy config), E2E (CRUD + functional routing)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Production (Docker): src/lib/db.ts now uses bun:sqlite + drizzle-orm/bun-sqlite.
No native addon compilation needed — bun:sqlite is a Bun built-in. The Dockerfile
drops all native build tools (python3, make, g++) and uses --ignore-scripts.
Tests (Vitest/Node.js): bun:sqlite is unavailable under Node.js, so:
- tests/helpers/db.ts keeps better-sqlite3 + drizzle-orm/better-sqlite3 for
integration tests that need a real in-memory SQLite
- vitest.config.ts aliases bun:sqlite → a thin better-sqlite3 shim and
drizzle-orm/bun-sqlite → drizzle-orm/better-sqlite3 for unit tests that
transitively import src/lib/db.ts without executing any queries
- better-sqlite3 stays as a devDependency (test-only, not built in Docker)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switch package manager and runtime from Node.js/npm to Bun across
Docker, CI, and scripts. The SQLite driver remains better-sqlite3
due to Next.js Turbopack being unable to resolve bun:sqlite during
build-time page pre-rendering.
Also fix the world map not rendering in the analytics page — the
overflowX wrapper added for mobile broke the flex height chain,
collapsing the map to 0px.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Following the Prisma guide for GitHub Actions and CI/CD, this commit addresses
the Prisma client generation issues in the Docker build process:
Changes:
1. **package.json**:
- Removed silent failure fallback in postinstall hook
- Removed redundant prisma generate from build script
- Now fails fast if Prisma generation has issues
2. **docker/web/Dockerfile**:
- Added DATABASE_URL environment variable in deps stage
- Explicitly run prisma generate after npm install to ensure client is created
- Generate Prisma client again in builder stage for build context
- Removed --skip-generate flag from prisma db push
- Added clear comments explaining each Prisma-related step
These changes ensure:
- Prisma client is generated with correct engines for debian-openssl-3.0.x
- Build fails early if there are Prisma configuration issues
- DATABASE_URL is set before running any Prisma commands
- Proper multi-stage Docker build with Prisma support
The previous attempt failed because Prisma CLI couldn't parse the binaryTarget
configuration due to an incorrect environment variable I set. This commit:
- Removes the non-existent PRISMA_CLI_BINARY_TARGETS environment variable
- Copies the Prisma schema BEFORE running npm ci, allowing the postinstall
script to properly generate the Prisma client with engines
- Adds openssl and ca-certificates to deps stage for engine downloads
- Simplifies the builder stage to rely on pre-generated engines from deps
This ensures Prisma engines are downloaded during npm installation via the
postinstall hook, making them available for subsequent build steps.
The build was failing with Prisma schema validation errors because Prisma
couldn't download engine binaries from binaries.prisma.sh (403 Forbidden).
This resulted in cryptic parsing errors during 'prisma generate'.
Changes:
- Add openssl and ca-certificates to deps stage for engine downloads
- Set PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING to bypass checksum validation
- Pre-generate Prisma client with engines in deps stage
- Copy pre-generated client to builder stage to avoid re-downloading
- Set PRISMA_SKIP_POSTINSTALL_GENERATE in builder to prevent regeneration
This ensures engines are bundled during the deps stage and reused in
subsequent stages, eliminating network dependency during the build phase.
The build was failing during 'prisma generate' with numerous validation
errors because Prisma's query engine requires OpenSSL to function properly.
The builder stage was missing the openssl package, causing the engine to
fail to load and produce cryptic parsing errors.
This adds openssl installation to the builder stage, matching what was
already present in the runner stage.
- Remove /app/node_modules/.prisma/client before generating
- Prevents EACCES errors when Prisma tries to unlink existing files
- Cleanup runs as root before switching to nextjs user
Following Prisma's official documentation for deployment caching issues:
https://www.prisma.io/docs/orm/more/help-and-troubleshooting/vercel-caching-issue
Changes:
- Add 'prisma generate' to build script (official Prisma recommendation)
- Add postinstall script for automatic client generation
- Remove custom stub generator workaround
- Keep runtime Prisma client generation in entrypoint.sh for reliability
- Add openssl to runtime container (required for Prisma engines)
This follows Prisma best practices: explicitly run prisma generate during the
build process to ensure Prisma Client is always up-to-date. The entrypoint
script regenerates the client at runtime to guarantee engine availability in
the production environment.
Added entrypoint script to handle database permissions on fresh deployments.
The issue occurred because Docker creates the ./data directory with root permissions
when it doesn't exist, preventing the nextjs user (uid 1001) from writing to it.
Changes:
- Add entrypoint.sh that runs as root, fixes permissions, then switches to nextjs user
- Install gosu for safe privilege dropping
- Initialize database on first run with proper permissions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Don't touch a file to determine if we need to run
- Instead, check ownership of each location and skip it if we are happy
- Keeping SKIP_CERTBOT_OWNERSHIP flag
- More vebose logging of outcomes
Replace inefficient find/execdir implementation that was causing 3+ minute
startup delays with a more efficient approach that:
1. Uses a flag file to skip redundant operations on container restarts
2. Processes site-packages directories with bulk chown operations instead
of individual file checks and changes
3. Maintains the same functionality while dramatically improving performance
This change should significantly reduce container startup time while ensuring
all necessary file permissions are still properly set.