Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,5 @@ ENV DATABASE_URL=file:/app/database/hemmelig.db
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health/ready || exit 1

USER app
ENTRYPOINT ["/app/docker-entrypoint.sh"]
7 changes: 2 additions & 5 deletions scripts/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#!/bin/sh
set -e

# Fix permissions on mounted volumes (runs as root)
chown -R app:app /app/database /app/uploads 2>/dev/null || true

# Run migrations and start app as app user
exec gosu app sh -c 'npx prisma migrate deploy && exec npx tsx server.ts'
# Run migrations and start app
sh -c 'npx prisma migrate deploy && exec npx tsx server.ts'
Comment on lines +4 to +5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

exec inside sh -c doesn't forward signals — server won't shut down gracefully.

Running the container process wrapped in a shell script makes the shell script PID 1, and a shell script will not pass along any signals to its child processes. This means SIGTERM, the signal used for graceful shutdown, will be ignored by the actual server process.

With the current code, the process tree at runtime is:

  • PID 1: outer sh (running the entrypoint script)
  • Child: sh -c subshell → (after exec) npx tsx server.ts

Docker sends SIGTERM to PID 1 (the outer sh). The outer sh does not forward this signal to the Node.js server, so the server gets killed with SIGKILL after the stop timeout rather than shutting down gracefully.

If your entrypoint is a shell script, use exec to launch the final process so it becomes PID 1. The fix is to drop the sh -c wrapper entirely and let the outer shell exec into the server:

🔧 Proposed fix — proper `exec` at the outer shell level
-# Run migrations and start app
-sh -c 'npx prisma migrate deploy && exec npx tsx server.ts'
+# Run migrations and start app
+npx prisma migrate deploy
+exec npx tsx server.ts

This makes exec npx tsx server.ts replace the outer sh as PID 1, so the Node.js process receives Docker signals directly.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Run migrations and start app
sh -c 'npx prisma migrate deploy && exec npx tsx server.ts'
# Run migrations and start app
npx prisma migrate deploy
exec npx tsx server.ts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/docker-entrypoint.sh` around lines 4 - 5, The current entrypoint uses
sh -c 'npx prisma migrate deploy && exec npx tsx server.ts' which wraps the
server in a subshell so signals aren't forwarded; change the script to run the
migration first and then replace the shell with the server using exec at the
outer level (i.e., run npx prisma migrate deploy (check its exit code) and then
exec npx tsx server.ts), so the exec in scripts/docker-entrypoint.sh makes the
Node process PID 1 and receives Docker signals directly.

Loading