Deploy from a monorepo
Each app in your monorepo gets its own Dokku app. Use
git subtree push to deploy only that app's subdirectory.
This guide explains the concepts — use the
Monorepo Tool to generate ready-to-run commands for your repo.
Repo structure
In a pnpm monorepo the default workspace path is packages/. Each deployed app
lives under packages/ alongside shared libraries and has its own
Dockerfile — Dokku uses it when that subtree is pushed.
my-monorepo/
└── packages/
├── web/ ← SvelteKit front-end (deployed as: my-app-web)
│ └── Dockerfile
├── api/ ← Node.js back-end (deployed as: my-app-api)
│ └── Dockerfile
├── admin/ ← Admin panel (deployed as: my-app-admin)
│ └── Dockerfile
├── ui/ ← shared components (not deployed)
└── utils/ ← shared utilities (not deployed)
In this example the three apps and their subfolder paths are:
packages/ui, packages/utils) are never pushed to Dokku directly — they must be
bundled or copied by each app's own build step (e.g. via the Dockerfile COPY
instruction or a workspace-aware build tool like turborepo).
VPS — one-time setup per app
Run this once on the server for each app. It creates the Dokku app, assigns a subdomain,
enables HTTPS, and mounts persistent storage. Repeat for my-app-api,
my-app-admin, etc.
# Replace my-app-web / web.example.com / you@example.com with your values
dokku apps:create my-app-web
dokku domains:set my-app-web web.fastfastapps.com
for app in $(dokku apps:list); do
dokku letsencrypt:set $app email you@example.com
dokku letsencrypt:enable $app
done
dokku letsencrypt:cron-job --add
dokku cleanup
docker system prune -af
dokku storage:create my-app-web
chown -R 32767:32767 /var/lib/dokku/data/storage/my-app-web
dokku storage:mount my-app-web /var/lib/dokku/data/storage/my-app-web:/app/storage
dokku ports:set my-app-web http:80:3000 https:443:3000
dokku ports:set maps the public http/https ports to the
container's internal port (3000) so nginx knows where to forward traffic.
Set DATABASE_URL=/app/storage/db.sqlite via the
Env Tool after setup.
Local — add a git remote per app
Each app in the monorepo needs its own Dokku git remote. Give each remote a unique name with a
prefix so they don't conflict with each other (or with any plain dokku remote).
git remote add dokku-my-app-web dokku@fastfastapps.com:my-app-web git remote add dokku-my-app-api dokku@fastfastapps.com:my-app-api git remote add dokku-my-app-admin dokku@fastfastapps.com:my-app-admin
dokku-my-app-web (not just dokku)
so each app in the repo has its own distinct remote and pushes never go to the wrong target.
Local — deploy a subtree
Push only the app's subdirectory to its Dokku remote. Dokku receives it as if it were the full
repo root and runs the Dockerfile found there.
git subtree push --prefix=packages/web dokku-my-app-web master
git subtree push --prefix=packages/api dokku-my-app-api master
git add . && git commit -m "deploy web" && git subtree push --prefix=packages/web dokku-my-app-web master
git subtree push rewrites history so only the commits that touched
packages/web are pushed. Dokku sees a clean, single-app repo and builds the
Dockerfile at its root. You can wrap this into a shell alias or
npm run deploy:web script.
Shared packages in the Dockerfile
Because git subtree push sends only the app's subdirectory, shared packages are
not available unless the app bundles them. Two common patterns:
Option A — bundle shared code at build time (recommended)
Use a build tool such as turborepo or tsup to compile shared packages
into the app's own dist/ folder before committing. The Dockerfile then only needs
the app directory and has no dependency on the rest of the repo.
FROM node:24-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build # shared packages already compiled into dist/
FROM node:24-alpine AS runner
WORKDIR /app
COPY --from=builder /app/build ./build
COPY --from=builder /app/package*.json ./
RUN npm ci --omit=dev
EXPOSE 3000
CMD ["node", "build/index.js"]
Option B — push full repo, set Dockerfile path
Keep a Dockerfile at the monorepo root and push the entire repo
to Dokku. Use DOCKER_BUILD_CONTEXT_PATH on the VPS to point Dokku at the right
Dockerfile for each app.
dokku docker-options:add my-app-web build "--file packages/web/Dockerfile"
git remote add dokku-my-app-web dokku@fastfastapps.com:my-app-web git add . && git commit -m "deploy web" && git push dokku-my-app-web master