Deploy an app with your own Dockerfile
How GetFlowing builds an app from the Dockerfile in its repository, where it looks for one, what to check first, and what the build does not support.
If your app has a Dockerfile, GetFlowing builds the app from it and from nothing else. You choose the base image, the build steps and the start command. GetFlowing does not change your repository.
Where GetFlowing looks
GetFlowing builds from the file named Dockerfile at the root of your repository. The name has to be exactly Dockerfile, and there is no setting for another name or folder.
For an app in a folder of its repository, it looks in that folder, and the build reads the app's files from there. Where that folder is part of a JavaScript workspace (a workspaces list in the root's package.json, pnpm, Turborepo, Nx or Lerna), the build reads the files from the repository's root instead, so the Dockerfile's COPY lines name paths from the root.
Importing several apps from one repository is not on for every workspace yet. Until it is on for yours, an import builds from the root of the repository.
What to check
- It is a Dockerfile, committed. Commit the file itself. A Dockerfile that links to a file outside the repository is refused.
- It listens on
PORT. The app must listen on0.0.0.0on the port in thePORTvariable, 8080. If your Dockerfile hasEXPOSE, make itEXPOSE 8080. If it setsENV PORT, set it to 8080 or remove the line. - It does not copy
.env. GetFlowing gives your app its variables when it runs, so a secret never needs to be in the image. - Its lockfile is committed. If the Dockerfile installs from a lockfile, such as
package-lock.json, commit that file. - It builds within 20 minutes. Run
docker build .once on your own machine before you deploy. - It runs as a user other than root. Add a
USERline after the install steps.
A short example for a Node app:
FROM node:24-slim
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY . .
ENV PORT=8080
EXPOSE 8080
USER node
CMD ["node", "server.js"]What the build supports
- Multi-stage builds. Build in one stage and copy the result into a small runtime image.
.dockerignore. Keep.git,node_modules,.envand test data out of the build with a.dockerignorein the folder the build reads from.
What it does not support
- Build arguments and build-time variables. A Dockerfile of your own is given none of your app's variables while its image is built: they reach the app when it runs. A value a front end bakes in at build time, such as a Next.js
NEXT_PUBLIC_*variable, is empty. Read it at run time, put a value that is not secret in the Dockerfile, or let GetFlowing write the Dockerfile, which gives the build those variables. See Variables the build reads. - A
# syntax=line older than 1.4. Remove the line, or name 1.4 or later.
If the build fails
The build log is on the deploy, and GetFlowing tells you in plain English why it stopped. See Failed builds for the messages and what to do about each.
You can also delete your Dockerfile. GetFlowing then writes one for the stack it finds. See Deploy an app without a Dockerfile.
What every app needs
The port, the health check and its path, the start time, memory, build time and settings every app on GetFlowing is held to, however it is built.
Without a Dockerfile
Which stacks GetFlowing builds with no Dockerfile, the versions and start commands it picks, the variables it asks for, and what to do when it cannot.