From 85a79dc0ae83b41636874f91f30b1ecaa656de96 Mon Sep 17 00:00:00 2001 From: Alan Frigo Date: Tue, 16 Dec 2025 20:29:11 -0300 Subject: [PATCH 1/5] feat: Add Docker entrypoint for automatic database migrations and document uninstallation steps. --- Dockerfile | 13 ++++++++++++- README.md | 23 +++++++++++++++++++++++ scripts/docker-entrypoint.sh | 23 +++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100755 scripts/docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index fb1e971..c4e65ed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,8 @@ COPY prisma ./prisma/ RUN npm ci # Generate Prisma client (needs dummy DATABASE_URL for generation) +# SECURITY NOTE: This is ONLY for build time to generate client artifacts. +# It is NOT used in production and does NOT persist to the final image. ENV DATABASE_URL="postgresql://user:pass@localhost:5432/db" RUN npx prisma generate @@ -31,8 +33,12 @@ FROM node:20-alpine AS runner WORKDIR /app # Install runtime dependencies +# Added: prisma for migrations RUN apk add --no-cache libc6-compat openssl git curl docker-cli +# Install global prisma for the entrypoint script +RUN npm install -g prisma + # Create non-root user RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs @@ -44,6 +50,10 @@ COPY --from=builder /app/.next/static ./.next/static COPY --from=builder /app/prisma ./prisma COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma +# Copy entrypoint script +COPY scripts/docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + # Set ownership RUN chown -R nextjs:nodejs /app @@ -63,5 +73,6 @@ ENV HOSTNAME="0.0.0.0" HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:3000/api/health || exit 1 -# Start the application +# Start the application using entrypoint +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] CMD ["node", "server.js"] diff --git a/README.md b/README.md index 3a78783..41d7f42 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ SupaPanel is a web-based control panel that simplifies the deployment and manage - [Quick Start](#quick-start) - [Tech Stack](#tech-stack) - [Usage Guide](#usage-guide) +- [Uninstallation](#uninstallation) - [Project Structure](#project-structure) - [Configuration](#configuration) - [Contributing](#contributing) @@ -196,6 +197,28 @@ After configuration: --- +## Uninstallation + +To completely remove SupaPanel from your server, follow these steps: + +1. **Stop and remove containers**: + ```bash + cd /etc/supapanel + docker compose down -v + ``` + +2. **Remove data directory** (WARNING: This will delete all your projects and data): + ```bash + sudo rm -rf /etc/supapanel + ``` + +3. **Remove Docker image** (optional): + ```bash + docker rmi alanmf30/supapanel:latest + ``` + +--- + ## Project Structure ``` diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh new file mode 100755 index 0000000..3e6e6c3 --- /dev/null +++ b/scripts/docker-entrypoint.sh @@ -0,0 +1,23 @@ +#!/bin/sh +set -e + +# Wait for the database to be ready +# (Optional: we can rely on Docker Compose healthcheck, but a quick check here is good) + +echo "Starting SupaPanel..." + +if [ -z "$DATABASE_URL" ]; then + echo "Error: DATABASE_URL is not set." + exit 1 +fi + +# Run database migrations +echo "Running database migrations..." +# We use db push for now to ensure schema is in sync. +# In a strict production environment with existing data, migrate deploy might be safer, +# but for this self-hosted panel, db push is often preferred to keep it simple. +npx prisma db push --skip-generate + +# Execute the main command +echo "Starting application..." +exec "$@" From a4b94e46275fe809d7c97c774a8ace0f07c81dd0 Mon Sep 17 00:00:00 2001 From: Alan Frigo Date: Tue, 16 Dec 2025 20:43:11 -0300 Subject: [PATCH 2/5] feat: update Prisma `db push` command to use `--accept-data-loss` for simpler schema synchronization. --- install.sh | 24 ++++++++++++------------ scripts/docker-entrypoint.sh | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/install.sh b/install.sh index 8e1683a..a8b5251 100644 --- a/install.sh +++ b/install.sh @@ -7,18 +7,18 @@ set -e SUPAPANEL_VERSION="${SUPAPANEL_VERSION:-latest}" SUPAPANEL_DATA_DIR="/etc/supapanel" -echo "╔═══════════════════════════════════════════════════════════════╗" -echo "║ ║" -echo "║ ███████╗██╗ ██╗██████╗ █████╗ ██████╗███╗ ██╗███████╗ ║" -echo "║ ██╔════╝██║ ██║██╔══██╗██╔══██╗██╔════╝████╗ ██║██╔════╝ ║" -echo "║ ███████╗██║ ██║██████╔╝███████║██║ ██╔██╗ ██║███████╗ ║" -echo "║ ╚════██║██║ ██║██╔═══╝ ██╔══██║██║ ██║╚██╗██║╚════██║ ║" -echo "║ ███████║╚██████╔╝██║ ██║ ██║╚██████╗██║ ╚████║███████║ ║" -echo "║ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═══╝╚══════╝ ║" -echo "║ ║" -echo "║ Self-Hosted Supabase Management Panel ║" -echo "║ ║" -echo "╚═══════════════════════════════════════════════════════════════╝" +echo "╔══════════════════════════════════════════════════════════════════════════════╗" +echo "║ ║" +echo "║ ███████╗██╗ ██╗██████╗ █████╗ ██████╗ █████╗ ███╗ ██╗███████╗██╗ ║" +echo "║ ██╔════╝██║ ██║██╔══██╗██╔══██╗██╔══██╗██╔══██╗████╗ ██║██╔════╝██║ ║" +echo "║ ███████╗██║ ██║██████╔╝███████║██████╔╝███████║██╔██╗ ██║█████╗ ██║ ║" +echo "║ ╚════██║██║ ██║██╔═══╝ ██╔══██║██╔═══╝ ██╔══██║██║╚██╗██║██╔══╝ ██║ ║" +echo "║ ███████║╚██████╔╝██║ ██║ ██║██║ ██║ ██║██║ ╚████║███████╗███████╗║" +echo "║ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝║" +echo "║ ║" +echo "║ Self-Hosted Supabase Management Panel ║" +echo "║ ║" +echo "╚══════════════════════════════════════════════════════════════════════════════╝" echo "" # Check if running as root diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh index 3e6e6c3..0524230 100755 --- a/scripts/docker-entrypoint.sh +++ b/scripts/docker-entrypoint.sh @@ -16,7 +16,7 @@ echo "Running database migrations..." # We use db push for now to ensure schema is in sync. # In a strict production environment with existing data, migrate deploy might be safer, # but for this self-hosted panel, db push is often preferred to keep it simple. -npx prisma db push --skip-generate +npx prisma db push --accept-data-loss # Execute the main command echo "Starting application..." From 5c0352f9e2e599a336da7831bfd6afa516ea9600 Mon Sep 17 00:00:00 2001 From: Alan Frigo Date: Tue, 16 Dec 2025 21:19:37 -0300 Subject: [PATCH 3/5] feat: Dynamically set secure cookie attribute in auth routes, restrict CI Docker builds to amd64, pin Prisma version, and add --skip-generate to db push. --- .github/workflows/ci.yml | 4 ++-- Dockerfile | 4 ++-- scripts/docker-entrypoint.sh | 6 +++--- src/app/api/auth/login/route.ts | 8 +++++++- src/app/api/auth/register/route.ts | 8 +++++++- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a8c285..9e43a28 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,5 @@ # CI Workflow - Validates PRs and pushes, builds Docker images for version tags -# Builds multi-platform images (amd64 + arm64) and pushes to Docker Hub +# Builds amd64 images and pushes to Docker Hub name: CI @@ -99,7 +99,7 @@ jobs: uses: docker/build-push-action@v6 with: context: . - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile index c4e65ed..e88a486 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,8 +36,8 @@ WORKDIR /app # Added: prisma for migrations RUN apk add --no-cache libc6-compat openssl git curl docker-cli -# Install global prisma for the entrypoint script -RUN npm install -g prisma +# Install global prisma for the entrypoint script (pinned to match project version) +RUN npm install -g prisma@6.19.1 # Create non-root user RUN addgroup --system --gid 1001 nodejs diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh index 0524230..4ddb3f4 100755 --- a/scripts/docker-entrypoint.sh +++ b/scripts/docker-entrypoint.sh @@ -14,9 +14,9 @@ fi # Run database migrations echo "Running database migrations..." # We use db push for now to ensure schema is in sync. -# In a strict production environment with existing data, migrate deploy might be safer, -# but for this self-hosted panel, db push is often preferred to keep it simple. -npx prisma db push --accept-data-loss +# --skip-generate is needed because the client was already generated during build, +# and the nextjs user doesn't have write permissions to regenerate it. +npx prisma db push --accept-data-loss --skip-generate # Execute the main command echo "Starting application..." diff --git a/src/app/api/auth/login/route.ts b/src/app/api/auth/login/route.ts index c0c6333..a83874c 100644 --- a/src/app/api/auth/login/route.ts +++ b/src/app/api/auth/login/route.ts @@ -46,11 +46,17 @@ export async function POST(request: NextRequest) { }, }) + // Only set secure if actually using HTTPS (not just based on NODE_ENV) + // This allows HTTP access via IP:3000 while still being secure over HTTPS + const isSecure = request.headers.get('x-forwarded-proto') === 'https' || + request.url.startsWith('https://') + response.cookies.set('session', token, { httpOnly: true, - secure: process.env.NODE_ENV === 'production', + secure: isSecure, sameSite: 'lax', maxAge: 24 * 60 * 60, // 24 hours + path: '/', }) return response diff --git a/src/app/api/auth/register/route.ts b/src/app/api/auth/register/route.ts index e468290..d628ec7 100644 --- a/src/app/api/auth/register/route.ts +++ b/src/app/api/auth/register/route.ts @@ -58,11 +58,17 @@ export async function POST(request: NextRequest) { }, }) + // Only set secure if actually using HTTPS (not just based on NODE_ENV) + // This allows HTTP access via IP:3000 while still being secure over HTTPS + const isSecure = request.headers.get('x-forwarded-proto') === 'https' || + request.url.startsWith('https://') + response.cookies.set('session', token, { httpOnly: true, - secure: process.env.NODE_ENV === 'production', + secure: isSecure, sameSite: 'lax', maxAge: 24 * 60 * 60, // 24 hours + path: '/', }) return response From 4521985f16f2becfe95c5f099e792ef87c90f1f6 Mon Sep 17 00:00:00 2001 From: Alan Frigo Date: Tue, 16 Dec 2025 21:21:00 -0300 Subject: [PATCH 4/5] chore: Configure Dependabot to ignore major version updates for Prisma and @prisma/client. --- .github/dependabot.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1981900..c638705 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -22,6 +22,11 @@ updates: ignore: - dependency-name: "next" update-types: ["version-update:semver-major"] + # Prisma 7 has breaking changes incompatible with our schema + - dependency-name: "prisma" + update-types: ["version-update:semver-major"] + - dependency-name: "@prisma/client" + update-types: ["version-update:semver-major"] - package-ecosystem: "github-actions" directory: "/" From 3956506493d257902e70fe633892583c035cf176 Mon Sep 17 00:00:00 2001 From: Alan Frigo Date: Tue, 16 Dec 2025 21:23:56 -0300 Subject: [PATCH 5/5] chore: Remove `USER nextjs` instruction from Dockerfile. --- Dockerfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index e88a486..cf27355 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,11 +54,13 @@ COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma COPY scripts/docker-entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/docker-entrypoint.sh -# Set ownership +# Set ownership of app directory RUN chown -R nextjs:nodejs /app -# Switch to non-root user -USER nextjs +# Note: We run as root because: +# 1. Docker socket access requires root +# 2. Mounted volumes (/data/core, /data/projects) are created as root +# In a more secure setup, you could use rootless Docker or adjust volume permissions # Expose port EXPOSE 3000