diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index f3ae04a84..4ec4ceb63 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -24,7 +24,8 @@ jobs: with: images: ${{ secrets.DOCKER_REPO }}/server tags: | - type=ref,event=branch + type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} + type=ref,event=branch,enable=${{ github.ref != 'refs/heads/main' }} type=sha,prefix= type=match,pattern=\d.\d.\d @@ -56,5 +57,5 @@ jobs: context: . file: ./docker/server/Dockerfile push: ${{ steps.push-condition.outputs.should_push }} - tags: ${{ steps.meta.outputs.tags == 'main' && 'latest' || steps.meta.outputs.tags }} + tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/apps/backend/.env b/apps/backend/.env index 20adc7031..afa227839 100644 --- a/apps/backend/.env +++ b/apps/backend/.env @@ -3,6 +3,17 @@ NEXT_PUBLIC_STACK_API_URL=# the base URL of Stack's backend/API. For local devel NEXT_PUBLIC_STACK_DASHBOARD_URL=# the URL of Stack's dashboard. For local development, this is `http://localhost:8101`; for the managed service, this is `https://app.stack-auth.com`. STACK_SERVER_SECRET=# a random, unguessable secret key generated by `pnpm generate-keys` +# seed script settings +STACK_SEED_SIGN_UP_ENABLED=# true to add OTP auth to the dashboard when seeding +STACK_SEED_OTP_ENABLED=# true to add OTP auth to the dashboard when seeding +STACK_SEED_ALLOW_LOCALHOST=# true to allow running dashboard on the localhost, set this to true only in development +STACK_SEED_OAUTH_PROVIDERS=# list of oauth providers to add to the dashboard when seeding, separated by comma, for example "github,google,facebook" +STACK_SEED_CLIENT_TEAM_CREATION=# true to allow the users of the internal project to create teams +STACK_SEED_USER_EMAIL=# default user added to the dashboard +STACK_SEED_USER_PASSWORD=# default user's password, paired with STACK_SEED_USER_EMAIL +STACK_SEED_USER_INTERNAL_ACCESS=# if the default user has access to the internal dashboard project +STACK_SEED_USER_GITHUB_ID=# add github oauth id to the default user + # OAuth mock provider settings STACK_OAUTH_MOCK_URL=# enter the URL of the mock OAuth provider here. For local development, use `http://localhost:8114`. diff --git a/apps/backend/.env.development b/apps/backend/.env.development index e7d854ace..6bfbf49a8 100644 --- a/apps/backend/.env.development +++ b/apps/backend/.env.development @@ -2,6 +2,18 @@ NEXT_PUBLIC_STACK_API_URL=http://localhost:8102 NEXT_PUBLIC_STACK_DASHBOARD_URL=http://localhost:8101 STACK_SERVER_SECRET=23-wuNpik0gIW4mruTz25rbIvhuuvZFrLOLtL7J4tyo +STACK_SEED_SIGN_UP_ENABLED=true +STACK_SEED_OTP_ENABLED=true +STACK_SEED_ALLOW_LOCALHOST=true +STACK_SEED_OAUTH_PROVIDERS=github,spotify,google,microsoft +STACK_SEED_CLIENT_TEAM_CREATION=true +STACK_SEED_USER_INTERNAL_ACCESS=true + +NEXT_PUBLIC_STACK_PROJECT_ID=project-id-from-stack-dashboard +NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +STACK_SUPER_SECRET_ADMIN_KEY=this-super-secret-admin-key-is-for-local-development-only + STACK_OAUTH_MOCK_URL=http://localhost:8114 STACK_GITHUB_CLIENT_ID=MOCK diff --git a/apps/backend/prisma/seed-self-host.ts b/apps/backend/prisma/seed-self-host.ts deleted file mode 100644 index 82a0b86e9..000000000 --- a/apps/backend/prisma/seed-self-host.ts +++ /dev/null @@ -1,202 +0,0 @@ -/* eslint-disable no-restricted-syntax */ -import { PrismaClient } from '@prisma/client'; -import { hashPassword } from "@stackframe/stack-shared/dist/utils/hashes"; - -const prisma = new PrismaClient(); - -async function seed() { - console.log('Seeding database...'); - - // Optional default admin user - const adminEmail = process.env.STACK_DEFAULT_DASHBOARD_USER_EMAIL; - const adminPassword = process.env.STACK_DEFAULT_DASHBOARD_USER_PASSWORD; - const adminInternalAccess = process.env.STACK_DEFAULT_DASHBOARD_USER_INTERNAL_ACCESS === 'true'; - - // Optionally disable sign up for "internal" project - const signUpEnabled = process.env.STACK_INTERNAL_SIGN_UP_ENABLED === 'true'; - - // Optionally add a custom domain to the internal project - const dashboardDomain = process.env.NEXT_PUBLIC_STACK_DASHBOARD_URL; - const allowLocalhost = process.env.STACK_DASHBOARD_ALLOW_LOCALHOST === 'true'; - - let internalProject = await prisma.project.findUnique({ - where: { - id: 'internal', - }, - include: { - config: true, - } - }); - - if (!internalProject) { - console.log('No existing internal project found, creating...'); - - internalProject = await prisma.project.create({ - data: { - id: 'internal', - displayName: 'Stack Dashboard', - description: 'Stack\'s admin dashboard', - isProductionMode: false, - apiKeySets: { - create: [{ - description: "Internal API key set", - // These keys must match the values used in the Stack dashboard env to be able to login via the UI. - publishableClientKey: process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY, - secretServerKey: process.env.STACK_SECRET_SERVER_KEY, - superSecretAdminKey: process.env.STACK_SUPER_SECRET_ADMIN_KEY, - expiresAt: new Date('2099-12-31T23:59:59Z'), - }], - }, - config: { - create: { - allowLocalhost: true, - signUpEnabled, // see STACK_SIGN_UP_DISABLED var above - emailServiceConfig: { - create: { - proxiedEmailServiceConfig: { - create: {} - } - } - }, - createTeamOnSignUp: false, - clientTeamCreationEnabled: false, - authMethodConfigs: { - create: [ - { - passwordConfig: { - create: {}, - } - }, - ], - } - } - } - }, - include: { - config: true, - } - }); - - console.log('Internal project created'); - } - - // Create optional default admin user if credentials are provided. - // This user will be able to login to the dashboard with both email/password and magic link. - if (adminEmail && adminPassword) { - const oldAdminUser = await prisma.projectUser.findFirst({ - where: { - projectId: 'internal', - contactChannels: { - some: { - type: 'EMAIL', - value: adminEmail, - } - } - } - }); - - if (oldAdminUser) { - console.log(`User with email ${adminEmail} already exists, skipping creation`); - } else { - console.log(`No existing admin user with email ${adminEmail} found, creating...`); - - await prisma.$transaction(async (tx) => { - const newUser = await tx.projectUser.create({ - data: { - projectId: 'internal', - serverMetadata: adminInternalAccess - ? { managedProjectIds: ['internal'] } - : undefined, - } - }); - - await tx.contactChannel.create({ - data: { - projectUserId: newUser.projectUserId, - projectId: 'internal', - type: 'EMAIL' as const, - value: adminEmail as string, - isVerified: false, - isPrimary: 'TRUE', - usedForAuth: 'TRUE', - } - }); - - const passwordConfig = await tx.passwordAuthMethodConfig.findFirstOrThrow({ - where: { - projectConfigId: (internalProject as any).configId - }, - include: { - authMethodConfig: true, - } - }); - - await tx.authMethod.create({ - data: { - projectId: 'internal', - projectConfigId: (internalProject as any).configId, - projectUserId: newUser.projectUserId, - authMethodConfigId: passwordConfig.authMethodConfigId, - passwordAuthMethod: { - create: { - passwordHash: await hashPassword(adminPassword), - projectUserId: newUser.projectUserId, - } - } - } - }); - }); - - console.log('Initial admin user created: ', adminEmail); - } - } - - if (internalProject.config.allowLocalhost !== allowLocalhost) { - console.log('Updating allowLocalhost for internal project: ', allowLocalhost); - - await prisma.project.update({ - where: { id: 'internal' }, - data: { - config: { - update: { - allowLocalhost, - } - } - } - }); - } - - if (dashboardDomain) { - const url = new URL(dashboardDomain); - - if (url.hostname !== 'localhost') { - console.log('Adding trusted domain for internal project: ', dashboardDomain); - - await prisma.projectDomain.upsert({ - where: { - projectConfigId_domain: { - projectConfigId: internalProject.configId, - domain: dashboardDomain, - } - }, - update: {}, - create: { - projectConfigId: internalProject.configId, - domain: dashboardDomain, - handlerPath: '/', - } - }); - } else if (!allowLocalhost) { - throw new Error('Cannot use localhost as a trusted domain if STACK_DASHBOARD_ALLOW_LOCALHOST is not set to true'); - } - } - - console.log('Seeding complete!'); -} - -seed().catch(async (e) => { - console.error(e); - await prisma.$disconnect(); - process.exit(1); -// eslint-disable-next-line @typescript-eslint/no-misused-promises -}).finally(async () => await prisma.$disconnect()); diff --git a/apps/backend/prisma/seed.ts b/apps/backend/prisma/seed.ts index 95df930a9..28d67ce15 100644 --- a/apps/backend/prisma/seed.ts +++ b/apps/backend/prisma/seed.ts @@ -1,141 +1,260 @@ -import { prismaClient } from '@/prisma-client'; +/* eslint-disable no-restricted-syntax */ import { PrismaClient } from '@prisma/client'; -const prisma = new PrismaClient(); +import { throwErr } from '@stackframe/stack-shared/dist/utils/errors'; +import { hashPassword } from "@stackframe/stack-shared/dist/utils/hashes"; +const prisma = new PrismaClient(); async function seed() { console.log('Seeding database...'); - const oldProject = await prisma.project.findUnique({ + // Optional default admin user + const adminEmail = process.env.STACK_SEED_USER_EMAIL; + const adminPassword = process.env.STACK_SEED_USER_PASSWORD; + const adminInternalAccess = process.env.STACK_SEED_USER_INTERNAL_ACCESS === 'true'; + const adminGithubId = process.env.STACK_SEED_USER_GITHUB_ID; + + // dashboard settings + const dashboardDomain = process.env.NEXT_PUBLIC_STACK_DASHBOARD_URL; + const oauthProviderIds = process.env.STACK_SEED_OAUTH_PROVIDERS?.split(',') ?? []; + const otpEnabled = process.env.STACK_SEED_OTP_ENABLED === 'true'; + const signUpEnabled = process.env.STACK_SEED_SIGN_UP_ENABLED === 'true'; + const allowLocalhost = process.env.STACK_SEED_ALLOW_LOCALHOST === 'true'; + const clientTeamCreation = process.env.STACK_SEED_CLIENT_TEAM_CREATION === 'true'; + + let internalProject = await prisma.project.findUnique({ where: { id: 'internal', }, + include: { + config: true, + } }); - if (oldProject) { - console.log('Internal project already exists, skipping its creation'); - } else { - await prismaClient.$transaction(async (tx) => { - const createdProject = await prisma.project.upsert({ - where: { - id: 'internal', + if (!internalProject) { + internalProject = await prisma.project.create({ + data: { + id: 'internal', + displayName: 'Stack Dashboard', + description: 'Stack\'s admin dashboard', + isProductionMode: false, + apiKeySets: { + create: [{ + description: "Internal API key set", + // These keys must match the values used in the Stack dashboard env to be able to login via the UI. + publishableClientKey: process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY || throwErr('NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY is not set'), + secretServerKey: process.env.STACK_SECRET_SERVER_KEY || throwErr('STACK_SECRET_SERVER_KEY is not set'), + superSecretAdminKey: process.env.STACK_SUPER_SECRET_ADMIN_KEY || throwErr('STACK_SUPER_SECRET_ADMIN_KEY is not set'), + expiresAt: new Date('2099-12-31T23:59:59Z'), + }], }, - create: { - id: 'internal', - displayName: 'Stack Dashboard', - description: 'Stack\'s admin dashboard', - isProductionMode: false, - apiKeySets: { - create: [{ - description: "Internal API key set", - publishableClientKey: "this-publishable-client-key-is-for-local-development-only", - secretServerKey: "this-secret-server-key-is-for-local-development-only", - superSecretAdminKey: "this-super-secret-admin-key-is-for-local-development-only", - expiresAt: new Date('2099-12-31T23:59:59Z'), - }], - }, - config: { - create: { - allowLocalhost: true, - oauthProviderConfigs: { - create: (['github', 'spotify', 'google', 'microsoft'] as const).map((id) => ({ - id, - proxiedOAuthConfig: { - create: { - type: id.toUpperCase() as any, - } - }, - projectUserOAuthAccounts: { - create: [] + config: { + create: { + allowLocalhost: true, + signUpEnabled, + emailServiceConfig: { + create: { + proxiedEmailServiceConfig: { + create: {} + } + } + }, + createTeamOnSignUp: false, + clientTeamCreationEnabled: clientTeamCreation, + authMethodConfigs: { + create: [ + { + passwordConfig: { + create: {}, } - })), - }, - emailServiceConfig: { - create: { - proxiedEmailServiceConfig: { - create: {} + }, + ...(otpEnabled ? [{ + otpConfig: { + create: { + contactChannelType: 'EMAIL' + }, } - } - }, - createTeamOnSignUp: false, - clientTeamCreationEnabled: true, + }]: []), + ], }, - }, - }, - update: {}, - }); - - await prisma.projectConfig.update({ - where: { - id: createdProject.configId, - }, - data: { - authMethodConfigs: { - create: [ - { - otpConfig: { + oauthProviderConfigs: { + create: oauthProviderIds.map((id) => ({ + id, + proxiedOAuthConfig: { create: { - contactChannelType: 'EMAIL', + type: id.toUpperCase() as any, } + }, + projectUserOAuthAccounts: { + create: [] } - }, - { - passwordConfig: { - create: {} - } - }, - ...(['github', 'spotify', 'google', 'microsoft'] as const).map((id) => ({ - oauthProviderConfig: { - connect: { - projectConfigId_id: { - id, - projectConfigId: createdProject.configId, - } + })), + }, + } + } + }, + include: { + config: true, + } + }); + + await prisma.projectConfig.update({ + where: { + id: internalProject.configId, + }, + data: { + authMethodConfigs: { + create: [ + ...oauthProviderIds.map((id) => ({ + oauthProviderConfig: { + connect: { + projectConfigId_id: { + id, + projectConfigId: (internalProject as any).configId, } } - })) - ], - }, + } + })) + ], + }, + } + }); + + console.log('Internal project created'); + } + + // Create optional default admin user if credentials are provided. + // This user will be able to login to the dashboard with both email/password and magic link. + if ((adminEmail && adminPassword) || adminGithubId) { + await prisma.$transaction(async (tx) => { + const oldAdminUser = await tx.projectUser.findFirst({ + where: { + projectId: 'internal', + projectUserId: '33e7c043-d2d1-4187-acd3-f91b5ed64b46' } }); - console.log('Internal project created'); - // eslint-disable-next-line no-restricted-syntax - const adminGithubId = process.env.STACK_SETUP_ADMIN_GITHUB_ID; - if (adminGithubId) { - console.log("Found admin GitHub ID in environment variables, creating admin user..."); - await prisma.projectUser.upsert({ - where: { - projectId_projectUserId: { + if (oldAdminUser) { + console.log(`User with email ${adminEmail} already exists, skipping creation`); + } else { + const newUser = await tx.projectUser.create({ + data: { + projectUserId: '33e7c043-d2d1-4187-acd3-f91b5ed64b46', projectId: 'internal', - projectUserId: '707156c3-0d1b-48cf-b09d-3171c7f613d5', - }, - }, - create: { - projectId: 'internal', - projectUserId: '707156c3-0d1b-48cf-b09d-3171c7f613d5', - displayName: 'Admin user generated by seed script', - serverMetadata: { - managedProjectIds: [ - "internal", - "12345678-1234-1234-1234-123456789abc", // intentionally invalid project ID to ensure we don't rely on project IDs being valid - ], - }, - projectUserOAuthAccounts: { - create: [{ - providerAccountId: adminGithubId, - projectConfigId: createdProject.configId, + serverMetadata: adminInternalAccess + ? { managedProjectIds: ['internal'] } + : undefined, + } + }); + + if (adminEmail && adminPassword) { + await tx.contactChannel.create({ + data: { + projectUserId: newUser.projectUserId, + projectId: 'internal', + type: 'EMAIL' as const, + value: adminEmail as string, + isVerified: false, + isPrimary: 'TRUE', + usedForAuth: 'TRUE', + } + }); + + const passwordConfig = await tx.passwordAuthMethodConfig.findFirstOrThrow({ + where: { + projectConfigId: (internalProject as any).configId + }, + include: { + authMethodConfig: true, + } + }); + + await tx.authMethod.create({ + data: { + projectId: 'internal', + projectConfigId: (internalProject as any).configId, + projectUserId: newUser.projectUserId, + authMethodConfigId: passwordConfig.authMethodConfigId, + passwordAuthMethod: { + create: { + passwordHash: await hashPassword(adminPassword), + projectUserId: newUser.projectUserId, + } + } + } + }); + + console.log(`Added admin user with email ${adminEmail}`); + } + + if (adminGithubId) { + const githubConfig = await tx.oAuthProviderConfig.findUnique({ + where: { + projectConfigId_id: { + projectConfigId: (internalProject as any).configId, + id: 'github' + } + } + }); + + if (!githubConfig) { + throw new Error('GitHub OAuth provider config not found'); + } + + await tx.projectUserOAuthAccount.create({ + data: { + projectId: 'internal', + projectConfigId: (internalProject as any).configId, + projectUserId: newUser.projectUserId, oauthProviderConfigId: 'github', - }], - }, + providerAccountId: adminGithubId + } + }); + + console.log(`Added admin user with GitHub ID ${adminGithubId}`); + } + } + }); + } + + if (internalProject.config.allowLocalhost !== allowLocalhost) { + console.log('Updating allowLocalhost for internal project: ', allowLocalhost); + + await prisma.project.update({ + where: { id: 'internal' }, + data: { + config: { + update: { + allowLocalhost, + } + } + } + }); + } + + if (dashboardDomain) { + const url = new URL(dashboardDomain); + + if (url.hostname !== 'localhost') { + console.log('Adding trusted domain for internal project: ', dashboardDomain); + + await prisma.projectDomain.upsert({ + where: { + projectConfigId_domain: { + projectConfigId: internalProject.configId, + domain: dashboardDomain, + } }, update: {}, + create: { + projectConfigId: internalProject.configId, + domain: dashboardDomain, + handlerPath: '/', + } }); - console.log(`Admin user created (if it didn't already exist)`); - } else { - console.log('No admin GitHub ID found in environment variables, skipping admin user creation'); - } - }); + } else if (!allowLocalhost) { + throw new Error('Cannot use localhost as a trusted domain if STACK_SEED_ALLOW_LOCALHOST is not set to true'); + } } console.log('Seeding complete!'); @@ -145,5 +264,5 @@ seed().catch(async (e) => { console.error(e); await prisma.$disconnect(); process.exit(1); -// eslint-disable-next-line @typescript-eslint/no-misused-promises, @typescript-eslint/return-await +// eslint-disable-next-line @typescript-eslint/no-misused-promises }).finally(async () => await prisma.$disconnect()); diff --git a/apps/backend/prisma/tsup.config.ts b/apps/backend/prisma/tsup.config.ts index 608299798..3e7ec0ab2 100644 --- a/apps/backend/prisma/tsup.config.ts +++ b/apps/backend/prisma/tsup.config.ts @@ -3,7 +3,7 @@ import { defineConfig } from 'tsup'; // tsup config to build the self-hosting seed script so it can be // run in the Docker container with no extra dependencies. export default defineConfig({ - entry: ['prisma/seed-self-host.ts'], + entry: ['prisma/seed.ts'], format: ['cjs'], outDir: 'dist', target: 'node22', diff --git a/docker/server/.env b/docker/server/.env index 0a9977b3c..1993736d1 100644 --- a/docker/server/.env +++ b/docker/server/.env @@ -1,6 +1,6 @@ NEXT_PUBLIC_STACK_API_URL=# https://your-backend-domain.com NEXT_PUBLIC_STACK_DASHBOARD_URL=# https://your-dashboard-domain.com, this will be added as a trusted domain by the seed script -STACK_DASHBOARD_ALLOW_LOCALHOST=# if true, the internal dashboard project will allow localhost as a trusted domain. Do not set this to true in production. +STACK_SEED_ALLOW_LOCALHOST=# if true, the internal dashboard project will allow localhost as a trusted domain. Do not set this to true in production. STACK_DATABASE_CONNECTION_STRING=# postgres connection string with pooler STACK_DIRECT_DATABASE_CONNECTION_STRING=# postgres direct connection string @@ -10,10 +10,16 @@ NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=# a secure random string STACK_SECRET_SERVER_KEY=# a secure random string STACK_SERVER_SECRET=# a 32 bytes base64url encoded random string, used for JWT encryption. can be generated with `pnpm generate-keys` -# set these if you want to use the default admin user -STACK_DEFAULT_DASHBOARD_USER_EMAIL=# your admin email -STACK_DEFAULT_DASHBOARD_USER_PASSWORD=# your admin password -STACK_DEFAULT_DASHBOARD_USER_INTERNAL_ACCESS=# if true, the default admin user will have access to the internal dashboard project +# seed script settings +STACK_SEED_SIGN_UP_ENABLED=# true to add OTP auth to the dashboard when seeding +STACK_SEED_OTP_ENABLED=# true to add OTP auth to the dashboard when seeding +STACK_SEED_ALLOW_LOCALHOST=# true to allow running dashboard on the localhost, set this to true only in development +STACK_SEED_OAUTH_PROVIDERS=# list of oauth providers to add to the dashboard when seeding, separated by comma, for example "github,google,facebook" +STACK_SEED_CLIENT_TEAM_CREATION=# true to allow the users of the internal project to create teams +STACK_SEED_USER_EMAIL=# default user added to the dashboard +STACK_SEED_USER_PASSWORD=# default user's password, paired with STACK_SEED_USER_EMAIL +STACK_SEED_USER_INTERNAL_ACCESS=# if the default user has access to the internal dashboard project +STACK_SEED_USER_GITHUB_ID=# add github oauth id to the default user # Set these if you want to use any email functionality STACK_EMAIL_HOST= diff --git a/docker/server/.env.example b/docker/server/.env.example index c5b1c7d1e..259d73923 100644 --- a/docker/server/.env.example +++ b/docker/server/.env.example @@ -1,6 +1,5 @@ NEXT_PUBLIC_STACK_API_URL=http://localhost:8102 NEXT_PUBLIC_STACK_DASHBOARD_URL=http://localhost:8101 -STACK_DASHBOARD_ALLOW_LOCALHOST=true STACK_DATABASE_CONNECTION_STRING=postgres://postgres:password@host.docker.internal:5432/stackframe STACK_DIRECT_DATABASE_CONNECTION_STRING=postgres://postgres:password@host.docker.internal:5432/stackframe @@ -10,9 +9,10 @@ NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-loca STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only STACK_SERVER_SECRET=23-wuNpik0gIW4mruTz25rbIvhuuvZFrLOLtL7J4tyo -STACK_DEFAULT_DASHBOARD_USER_EMAIL=admin@email.com -STACK_DEFAULT_DASHBOARD_USER_PASSWORD=password -STACK_DEFAULT_DASHBOARD_USER_INTERNAL_ACCESS=false +STACK_SEED_ALLOW_LOCALHOST=true +STACK_SEED_USER_EMAIL=admin@email.com +STACK_SEED_USER_PASSWORD=password +STACK_SEED_USER_INTERNAL_ACCESS=false STACK_RUN_MIGRATIONS=true STACK_RUN_SEED_SCRIPT=true diff --git a/docker/server/Dockerfile b/docker/server/Dockerfile index 6c0578098..fb5b388dc 100644 --- a/docker/server/Dockerfile +++ b/docker/server/Dockerfile @@ -70,7 +70,7 @@ RUN npm i -g prisma COPY --from=builder --chown=node:node /app/apps/backend/.next/standalone ./ COPY --from=builder --chown=node:node /app/apps/backend/.next/static ./apps/backend/.next/static COPY --from=builder --chown=node:node /app/apps/backend/prisma ./apps/backend/prisma -COPY --from=builder --chown=node:node /app/apps/backend/dist/seed-self-host.js ./apps/backend +COPY --from=builder --chown=node:node /app/apps/backend/dist/seed.js ./apps/backend # Copy built dashboard COPY --from=builder --chown=node:node /app/apps/dashboard/.next/standalone ./ diff --git a/docker/server/entrypoint.sh b/docker/server/entrypoint.sh index 9a9d2334e..d2043d871 100755 --- a/docker/server/entrypoint.sh +++ b/docker/server/entrypoint.sh @@ -12,7 +12,7 @@ fi if [ "$STACK_RUN_SEED_SCRIPT" = "true" ]; then echo "Running seed script..." cd apps/backend - node seed-self-host.js + node seed.js cd ../.. else echo "Skipping seed script."