Projects, repositories and directories
Deploy one app or a whole monorepo. Choose the folders to build, and see how projects, services and data fit together.
A repository holds source code. A Fortly project is the resource boundary: its database, users, storage and team. Inside a project, each service is something deployed on its own — the project's application at the project's address, and any number of others, each at an address of its own. See Services.
Choose a deployment path
| Your source | What to do |
|---|---|
| One app at the repository root | Connect the repository and branch. Leave What to deploy unticked. |
One app inside a folder (apps/web) | Tick that folder under What to deploy. It is built from there, with dependencies installed from the workspace root. |
| Several apps in one repository (web and API) | Tick each folder. The first is the project's application; each other becomes a service of the same project, with its own address, variables and releases. |
| Adding an app to an existing project | Add service on the project's overview: a GitHub folder, an upload, or an empty service. |
| An uploaded archive of a monorepo | Choose the app's folder. The whole archive is sent, so a workspace still installs from its root. |
Choose folders from GitHub
After you pick a repository, Fortly reads it at the chosen branch and lists the folders that look like applications, with their framework. A filter searches every folder by name. Pick one or more. Each folder is checked before anything is created: a folder that can't be built is reported, and nothing is half made.
For example:
repo/
package.json
pnpm-lock.yaml
apps/
web/package.json
api/package.json
packages/
shared/package.jsonTick apps/web and apps/api. apps/web becomes the project's application at the project's address. apps/api becomes the api service at api--<project>.fortly.com. Both install from the repository root, so packages/shared resolves for each. A push to the branch rebuilds both, each from its own folder, at the pushed commit.
Upload a monorepo
The console reads ZIP and tar.gz archives and offers the folders that hold an app, including plain sites with an index.html. For a service, the whole archive is sent along with the chosen folder, so a workspace that imports ../../packages/shared or relies on a root lockfile still builds. For a project's own upload, choosing Root directory repacks only that folder; use it for a self-contained app.
Keep configuration and data authority separate
A project's services share its database, users and storage; a second project is a separate resource boundary that shares none of them. A service other than the application receives only its own variables, and reaches the database only when an owner or admin grants it.
For a separate frontend and API, give the frontend only the API URL and deliberately public configuration. Keep account tokens, private Data API keys and database credentials out of browser code and build output. Use Data API roles, app-user verification and row policies, and bucket access for the caller and resource involved. A public address alone is not authorization.
Variable scope matters: a public API URL may need build-time availability, while a private server credential belongs at runtime. Changing an existing build-time value requires a new build. See Environment and secrets.
Verify the release you intended
After deploying, check the repository, branch and commit in the release details. Read the install and build output for the selected application, then verify an application route after publication. An accepted build is not a live release. A failed attempt leaves an earlier published release serving; a first deployment has no earlier release to fall back to.
Use the selected release's Build output for installation and compilation errors, and Observability → Logs for application requests. Rollback changes code, not shared data or schema changes. Deleting a project is broader: it removes its resources and retained releases. Review Releases, Logs and Team roles before using those operations.