Deploy Node.js and Next.js
A Node.js API or a Next.js application: the Dockerfile, the port, build-time variables, and the database.
The Dockerfile
Section titled “The Dockerfile”Fransys deploys a Docker image. An example for Next.js, with the standalone output (output: 'standalone' in next.config.js):
FROM node:22-alpine AS buildWORKDIR /appCOPY package.json package-lock.json ./RUN npm ciCOPY . .RUN npm run build
FROM node:22-alpineWORKDIR /appENV NODE_ENV=production PORT=3000 HOSTNAME=0.0.0.0COPY --from=build /app/.next/standalone ./COPY --from=build /app/.next/static ./.next/staticCOPY --from=build /app/public ./publicEXPOSE 3000CMD ["node", "server.js"]For a Node.js API, the idea is the same: install, build if needed, then start the server. Listen on 0.0.0.0, not on localhost.
The service
Section titled “The service”Add an Application, connect the repository and the CI (From GitHub or GitLab), then set the Container port to 3000 (or whatever your EXPOSE says).
Build-time variables
Section titled “Build-time variables”Next.js writes NEXT_PUBLIC_… variables into the code at build time. Fransys CI doesn’t pass variables to the build yet:
- keep these values in your code or in a
.env.productionfile in the repository, if they aren’t secret; - or read them at startup, on the server side.
Other variables (database access, API keys) go in Variables, protected if they’re secrets.
The database
Section titled “The database”Add a PostgreSQL database linked to the application, then check the received names in Variables. If your ORM expects a single URL (DATABASE_URL for Prisma, for example), build it with references:
DATABASE_URL=postgresql://${USER}:${PASSWORD}@${HOST}:${PORT}/${DATABASE}replacing each name with the name of the received variable, and tick Allow ${VAR} references.
Migrations
Section titled “Migrations”In Deployment commands, under After the first install and After an update: for example npx prisma migrate deploy.
Several processes
Section titled “Several processes”A worker (BullMQ, for example): have your entrypoint read a role, then copy the service with that role. See Application.