Only show guides for your app
Your repo holds several projects and only one belongs on this server. Sync paths deploy just the folder you want; exclude paths keep named paths out. Both cap at 20, and the trick is pointing your Main file into the synced folder.
Plenty of repositories hold more than one project — a bot and its dashboard, a web app beside its shared library, three services in one place. When only one of them belongs on this server, you don't want the whole repo landing in /home/container. The Git page's sync paths and exclude paths solve exactly this. This guide is the deep dive.
| At a glance | |
|---|---|
| You need | a server with a repository linked on its Git page (see Deploy from Git) |
| Plan | any |
| Time | fifteen minutes |
On the Git settings you'll find two lists, each holding up to 20 paths:
| Filter | What it does | Applied |
|---|---|---|
| Sync paths | Limits the deploy to only these directories — everything else in the repo is skipped | First |
| Exclude paths | Keeps named paths from being copied at all | After the sync filter |
They work together and in that order: sync paths pick the folders that come in, then exclude paths subtract anything you still don't want from within them. Leave sync paths empty and the whole repo deploys (the default); add one and suddenly only that folder lands.
Paths are plain and relative to the repo root — letters, digits, dashes, dots, and slashes, like apps/bot or services/api. No wildcards or globs; you name real directories.
Here's the part people miss. Say your repo looks like this:
my-monorepo/
├── apps/
│ ├── bot/
│ │ ├── index.js
│ │ └── package.json
│ └── web/
└── packages/
You set sync paths to apps/bot, deploy, and… the server won't start. Why? Because sync paths keep the folder structure. apps/bot/index.js lands at /home/container/apps/bot/index.js, but the Node application looks for its entry file at the root — /home/container/index.js, which doesn't exist.
The fix is one setting: point the Main file variable (Settings page → Environment) at the real location, apps/bot/index.js. Python's the same idea with the App py file variable, PHP with its PHP File. Sync paths put your folder on the server; the application's entry-file variable tells the runtime where to find it inside that folder.
⚠️ Heads up: Node's Main file field holds at most 16 characters, so a deep path like
services/worker/index.jswon't fit. If your entry path is too long, sync that folder as the only one and restructure so the entry file lands nearer the root, or keep the subfolder shallow.
Your repo has apps/bot (the Discord bot) and apps/web (an unrelated site). This server should run only the bot.
apps/bot. Now a deploy copies only that folder.apps/bot/index.js.package.json inside apps/bot triggers the automatic npm install, and the bot boots.Your apps/web folder never touches the server, so there's nothing to trip over and nothing wasted.
Now a trickier shape — your service imports a shared package that lives elsewhere in the repo:
repo/
├── services/api/ (this server runs this)
├── packages/shared/ (api imports from here)
└── services/worker/ (belongs on a different server)
The service needs services/api and packages/shared, but not services/worker:
services/api and packages/shared. Sync paths are a list — you can name several folders, and only those come in.services/worker was never synced. Exclude paths earn their keep when a folder you did sync contains something you want to leave out — say you sync services/api but want to skip services/api/fixtures. Add services/api/fixtures to excludes and it's dropped after the sync.services/api/index.js and make sure your imports resolve to the synced packages/shared path.Sync and exclude paths only decide which files come in. The rest of the Git model is unchanged:
.env and data survive, exactly as in a normal deploy. Exclude paths are a second layer of protection: name a path there and even a same-named repo file won't overwrite it.