Deploying
Deploy with your own Dockerfile
Use your own Dockerfile on DployHub for full control over the runtime: how detection works, the EXPOSE port rule, Dockerfile path and best practices.
Updated 3 min read
A Dockerfile gives you full control over the language version, system packages and start command. If a Dockerfile is present in your root folder, DployHub builds it as-is, before checking for Node.js, Python or static files. You can also choose Use my Dockerfile explicitly when creating the app.
How the port is chosen
We read the first EXPOSE line in your Dockerfile and use that port. If there is no EXPOSE, we use 3000 and show a note so you can check it. You can always change the port in the app Settings. We also set the PORT environment variable to the same value.
Example: Node.js
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
EXPOSE 8080
CMD ["node", "dist/server.js"]Example: Python
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["gunicorn", "mysite.wsgi", "--bind", "0.0.0.0:8000"]Dockerfile path and monorepos
The Dockerfile path defaults to Dockerfile and is relative to Folder with your app. In a monorepo set the folder to, for example, services/api, and the path to Dockerfile or docker/Dockerfile.prod. Keep COPY paths consistent with that layout.
Rules your container must follow
- Listen on
0.0.0.0on the configured port, and answer HTTP with a status below 500 on the health check path within 90 seconds. - Stay within the memory you chose. A process that exceeds it is killed with exit code 137.
- Keep to 512 processes or fewer. Containers run with no-new-privileges.
- Write persistent files under
/dataonly. Everything else is reset on deploy or restart. - Log to stdout and stderr. Container logs are rotated at 10 MB, keeping 3 files.
- Finish the build within 30 minutes.
Secrets and environment variables
Do not bake secrets into the image with ENV or ARG. Add them in the Environment variables tab instead; they are encrypted at rest and injected when the container starts, separately for staging and live.
Already building images in CI? You can skip our build and deploy a public Docker image directly. The quick guide is at /deploy/docker. If a Dockerfile build behaves differently than on your machine, raise a ticket with the deployment attached.
Frequently asked questions
Does a Dockerfile override auto-detection?
Yes. A Dockerfile in the root folder is always used first, before Node.js, Python or static detection.
What port is used if my Dockerfile has no EXPOSE?
Port 3000, with a note in the app. Add an EXPOSE line or set the port in Settings.
Can my Dockerfile live in a subfolder?
Yes. Set Folder with your app and the Dockerfile path; both are used for the build.
Related articles
- Deploy a public Docker imageRun any public Docker image on DployHub, such as nginx:1.27-alpine or a ghcr.io image, with HTTPS, staging, logs and rollback included out of the box.
- Build settings: build, start, root folder and moreEvery DployHub build setting explained: build type, build and start commands, port, root folder, Dockerfile path and health check path, with examples.
- Port and health checks for zero-downtime deploysHow DployHub uses your port and health check path to release new versions with zero downtime, what the failure messages mean and how to fix them.
- Persistent storage: keep files safe under /dataEach live app gets persistent storage mounted at /data. Learn what survives deploys, how to store uploads and SQLite files, and how to add more space.