Skip to content

Commit 2c34f43

Browse files
fix: adds build step to the database package for optimizing docker build (formbricks#5970)
Co-authored-by: Piyush Gupta <piyushguptaa2z123@gmail.com>
1 parent 979fd71 commit 2c34f43

File tree

16 files changed

+209
-71
lines changed

16 files changed

+209
-71
lines changed

apps/web/Dockerfile

Lines changed: 14 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,9 @@ RUN corepack prepare pnpm@9.15.9 --activate
2525
# Install necessary build tools and compilers
2626
RUN apk update && apk add --no-cache cmake g++ gcc jq make openssl-dev python3
2727

28-
# BuildKit secret handling without hardcoded fallback values
29-
# This approach relies entirely on secrets passed from GitHub Actions
30-
RUN echo '#!/bin/sh' > /tmp/read-secrets.sh && \
31-
echo 'if [ -f "/run/secrets/database_url" ]; then' >> /tmp/read-secrets.sh && \
32-
echo ' export DATABASE_URL=$(cat /run/secrets/database_url)' >> /tmp/read-secrets.sh && \
33-
echo 'else' >> /tmp/read-secrets.sh && \
34-
echo ' echo "DATABASE_URL secret not found. Build may fail if this is required."' >> /tmp/read-secrets.sh && \
35-
echo 'fi' >> /tmp/read-secrets.sh && \
36-
echo 'if [ -f "/run/secrets/encryption_key" ]; then' >> /tmp/read-secrets.sh && \
37-
echo ' export ENCRYPTION_KEY=$(cat /run/secrets/encryption_key)' >> /tmp/read-secrets.sh && \
38-
echo 'else' >> /tmp/read-secrets.sh && \
39-
echo ' echo "ENCRYPTION_KEY secret not found. Build may fail if this is required."' >> /tmp/read-secrets.sh && \
40-
echo 'fi' >> /tmp/read-secrets.sh && \
41-
echo 'exec "$@"' >> /tmp/read-secrets.sh && \
42-
chmod +x /tmp/read-secrets.sh
28+
# Copy the secrets handling script
29+
COPY apps/web/scripts/docker/read-secrets.sh /tmp/read-secrets.sh
30+
RUN chmod +x /tmp/read-secrets.sh
4331

4432
# Increase Node.js memory limit as a regular build argument
4533
ARG NODE_OPTIONS="--max_old_space_size=4096"
@@ -62,6 +50,9 @@ RUN touch apps/web/.env
6250
# Install the dependencies
6351
RUN pnpm install --ignore-scripts
6452

53+
# Build the database package first
54+
RUN pnpm build --filter=@formbricks/database
55+
6556
# Build the project using our secret reader script
6657
# This mounts the secrets only during this build step without storing them in layers
6758
RUN --mount=type=secret,id=database_url \
@@ -106,20 +97,8 @@ RUN chown -R nextjs:nextjs ./apps/web/public && chmod -R 755 ./apps/web/public
10697
COPY --from=installer /app/packages/database/schema.prisma ./packages/database/schema.prisma
10798
RUN chown nextjs:nextjs ./packages/database/schema.prisma && chmod 644 ./packages/database/schema.prisma
10899

109-
COPY --from=installer /app/packages/database/package.json ./packages/database/package.json
110-
RUN chown nextjs:nextjs ./packages/database/package.json && chmod 644 ./packages/database/package.json
111-
112-
COPY --from=installer /app/packages/database/migration ./packages/database/migration
113-
RUN chown -R nextjs:nextjs ./packages/database/migration && chmod -R 755 ./packages/database/migration
114-
115-
COPY --from=installer /app/packages/database/src ./packages/database/src
116-
RUN chown -R nextjs:nextjs ./packages/database/src && chmod -R 755 ./packages/database/src
117-
118-
COPY --from=installer /app/packages/database/node_modules ./packages/database/node_modules
119-
RUN chown -R nextjs:nextjs ./packages/database/node_modules && chmod -R 755 ./packages/database/node_modules
120-
121-
COPY --from=installer /app/packages/logger/dist ./packages/database/node_modules/@formbricks/logger/dist
122-
RUN chown -R nextjs:nextjs ./packages/database/node_modules/@formbricks/logger/dist && chmod -R 755 ./packages/database/node_modules/@formbricks/logger/dist
100+
COPY --from=installer /app/packages/database/dist ./packages/database/dist
101+
RUN chown -R nextjs:nextjs ./packages/database/dist && chmod -R 755 ./packages/database/dist
123102

124103
COPY --from=installer /app/node_modules/@prisma/client ./node_modules/@prisma/client
125104
RUN chown -R nextjs:nextjs ./node_modules/@prisma/client && chmod -R 755 ./node_modules/@prisma/client
@@ -142,12 +121,14 @@ RUN chmod -R 755 ./node_modules/@noble/hashes
142121
COPY --from=installer /app/node_modules/zod ./node_modules/zod
143122
RUN chmod -R 755 ./node_modules/zod
144123

145-
RUN npm install --ignore-scripts -g tsx typescript pino-pretty
146124
RUN npm install -g prisma
147125

126+
# Create a startup script to handle the conditional logic
127+
COPY --from=installer /app/apps/web/scripts/docker/next-start.sh /home/nextjs/start.sh
128+
RUN chown nextjs:nextjs /home/nextjs/start.sh && chmod +x /home/nextjs/start.sh
129+
148130
EXPOSE 3000
149-
ENV HOSTNAME "0.0.0.0"
150-
ENV NODE_ENV="production"
131+
ENV HOSTNAME="0.0.0.0"
151132
USER nextjs
152133

153134
# Prepare volume for uploads
@@ -158,12 +139,4 @@ VOLUME /home/nextjs/apps/web/uploads/
158139
RUN mkdir -p /home/nextjs/apps/web/saml-connection
159140
VOLUME /home/nextjs/apps/web/saml-connection
160141

161-
CMD if [ "${DOCKER_CRON_ENABLED:-1}" = "1" ]; then \
162-
echo "Starting cron jobs..."; \
163-
supercronic -quiet /app/docker/cronjobs & \
164-
else \
165-
echo "Docker cron jobs are disabled via DOCKER_CRON_ENABLED=0"; \
166-
fi; \
167-
(cd packages/database && npm run db:migrate:deploy) && \
168-
(cd packages/database && npm run db:create-saml-database:deploy) && \
169-
exec node apps/web/server.js
142+
CMD ["/home/nextjs/start.sh"]

apps/web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"test": "dotenv -e ../../.env -- vitest run",
1515
"test:coverage": "dotenv -e ../../.env -- vitest run --coverage",
1616
"generate-api-specs": "dotenv -e ../../.env tsx ./modules/api/v2/openapi-document.ts > ../../docs/api-v2-reference/openapi.yml",
17-
"merge-client-endpoints": "tsx ./scripts/merge-client-endpoints.ts",
17+
"merge-client-endpoints": "tsx ./scripts/openapi/merge-client-endpoints.ts",
1818
"generate-and-merge-api-specs": "npm run generate-api-specs && npm run merge-client-endpoints"
1919
},
2020
"dependencies": {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/sh
2+
3+
set -eu
4+
export NODE_ENV=production
5+
if [ "${DOCKER_CRON_ENABLED:-1}" = "1" ]; then
6+
echo "Starting cron jobs...";
7+
supercronic -quiet /app/docker/cronjobs &
8+
else
9+
echo "Docker cron jobs are disabled via DOCKER_CRON_ENABLED=0";
10+
fi;
11+
(cd packages/database && npm run db:migrate:deploy) &&
12+
(cd packages/database && npm run db:create-saml-database:deploy) &&
13+
exec node apps/web/server.js
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/sh
2+
3+
set -eu
4+
if [ -f "/run/secrets/database_url" ]; then
5+
export DATABASE_URL=$(cat /run/secrets/database_url)
6+
else
7+
echo "DATABASE_URL secret not found. Build may fail if this is required."
8+
fi
9+
10+
if [ -f "/run/secrets/encryption_key" ]; then
11+
export ENCRYPTION_KEY=$(cat /run/secrets/encryption_key)
12+
else
13+
echo "ENCRYPTION_KEY secret not found. Build may fail if this is required."
14+
fi
15+
16+
exec "$@"
File renamed without changes.

packages/database/package.json

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,41 @@
33
"packageManager": "pnpm@9.15.9",
44
"private": true,
55
"version": "0.1.0",
6-
"main": "./src/index.ts",
6+
"main": "./dist/index.cjs",
7+
"types": "./dist/index.d.ts",
8+
"type": "module",
79
"files": [
8-
"src"
10+
"dist",
11+
"schema.prisma",
12+
"migration"
913
],
14+
"exports": {
15+
".": {
16+
"types": "./dist/index.d.ts",
17+
"import": "./dist/index.js",
18+
"require": "./dist/index.cjs"
19+
},
20+
"./types/*": {
21+
"import": "./types/*.ts"
22+
},
23+
"./zod/*": {
24+
"import": "./zod/*.ts"
25+
}
26+
},
1027
"scripts": {
11-
"clean": "rimraf .turbo node_modules",
12-
"db:migrate:deploy": "env DATABASE_URL=\"${MIGRATE_DATABASE_URL:-$DATABASE_URL}\" tsx ./src/scripts/apply-migrations.ts",
13-
"db:migrate:dev": "dotenv -e ../../.env -- sh -c \"pnpm prisma generate && tsx ./src/scripts/apply-migrations.ts\"",
14-
"db:create-saml-database:deploy": "env SAML_DATABASE_URL=\"${SAML_DATABASE_URL}\" tsx ./src/scripts/create-saml-database.ts",
15-
"db:create-saml-database:dev": "dotenv -e ../../.env -- tsx ./src/scripts/create-saml-database.ts",
28+
"clean": "rimraf .turbo node_modules dist",
29+
"build": "pnpm generate && vite build",
30+
"dev": "vite build --watch",
31+
"db:migrate:deploy": "env DATABASE_URL=\"${MIGRATE_DATABASE_URL:-$DATABASE_URL}\" node ./dist/scripts/apply-migrations.js",
32+
"db:migrate:dev": "dotenv -e ../../.env -- sh -c \"pnpm prisma generate && node ./dist/scripts/apply-migrations.js\"",
33+
"db:create-saml-database:deploy": "env SAML_DATABASE_URL=\"${SAML_DATABASE_URL}\" node ./dist/scripts/create-saml-database.js",
34+
"db:create-saml-database:dev": "dotenv -e ../../.env -- node ./dist/scripts/create-saml-database.js",
1635
"db:push": "prisma db push --accept-data-loss",
1736
"db:setup": "pnpm db:migrate:dev && pnpm db:create-saml-database:dev",
1837
"db:start": "pnpm db:setup",
1938
"format": "prisma format",
2039
"generate": "prisma generate",
2140
"lint": "eslint ./src --fix",
22-
"build": "pnpm generate",
2341
"generate-data-migration": "tsx ./src/scripts/generate-data-migration.ts",
2442
"create-migration": "dotenv -e ../../.env -- tsx ./src/scripts/create-migration.ts"
2543
},
@@ -34,8 +52,11 @@
3452
"@formbricks/config-typescript": "workspace:*",
3553
"@formbricks/eslint-config": "workspace:*",
3654
"dotenv-cli": "8.0.0",
55+
"glob": "11.0.2",
3756
"prisma": "6.7.0",
3857
"prisma-json-types-generator": "3.4.1",
39-
"ts-node": "10.9.2"
58+
"ts-node": "10.9.2",
59+
"vite": "6.3.5",
60+
"vite-plugin-dts": "4.5.3"
4061
}
4162
}

packages/database/src/client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { PrismaClient } from "@prisma/client";
22

3-
const prismaClientSingleton = () => {
3+
const prismaClientSingleton = (): PrismaClient => {
44
return new PrismaClient({
55
datasources: { db: { url: process.env.DATABASE_URL } },
66
...(process.env.DEBUG === "1" && {
@@ -15,6 +15,6 @@ const globalForPrisma = globalThis as unknown as {
1515
prisma: PrismaClientSingleton | undefined;
1616
};
1717

18-
export const prisma = globalForPrisma.prisma ?? prismaClientSingleton();
18+
export const prisma: PrismaClient = globalForPrisma.prisma ?? prismaClientSingleton();
1919

2020
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;

packages/database/src/scripts/create-migration.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ import { exec } from "node:child_process";
22
import fs from "node:fs/promises";
33
import path from "node:path";
44
import readline from "node:readline";
5+
import { fileURLToPath } from "node:url";
56
import { promisify } from "node:util";
67
import { logger } from "@formbricks/logger";
78
import { applyMigrations } from "./migration-runner";
89

10+
const __filename = fileURLToPath(import.meta.url);
11+
const __dirname = path.dirname(__filename);
12+
913
const execAsync = promisify(exec);
1014
const rl = readline.createInterface({
1115
input: process.stdin,

packages/database/src/scripts/generate-data-migration.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import { createId } from "@paralleldrive/cuid2";
22
import fs from "node:fs/promises";
33
import path from "node:path";
44
import readline from "node:readline";
5+
import { fileURLToPath } from "node:url";
56
import { logger } from "@formbricks/logger";
67

8+
const __filename = fileURLToPath(import.meta.url);
9+
const __dirname = path.dirname(__filename);
10+
711
const rl = readline.createInterface({
812
input: process.stdin,
913
output: process.stdout,

0 commit comments

Comments
 (0)