# Deploying and configuring an app

Source: https://cloud.synteq.com/docs/deploying-and-configuring-an-app
Updated: 2026-10-19T04:06:24.901627+00:00

---
# Deploying and configuring an app

Deploy an app from GitHub, a local folder, or a container image, then configure its variables, domains, health check, and build.

## Create an app

1. Select the organization and project in the sidebar. The app is created in that project.
2. Open **Apps** and click **New App**.
3. On **Name**, enter a name. Its domain slug becomes `<slug>.synteq.app`; you can edit the slug under the name. The slug uses lowercase letters, digits, and hyphens, is up to 63 characters, and must be unique across Synteq.
4. On **Environment**, add variables or skip. Pasting a `.env` file into the first **Name** field splits it into rows.
5. On **Location**, pick the primary location. Only locations with capacity are listed.
6. On **Source**, choose **Connect GitHub** or **Use the CLI**, or skip and set it later.
7. On **Plan**, pick a plan. This step appears for every app after your first, and for your first app when the free tier is full or your payment method can't unlock it. Otherwise your first app starts on Free, and you're asked for a card at **Done** if none is on file.
8. Click **Done**. When the **Plan** step appears, click **Next** on **Source**, then **Done** on **Plan**.

With GitHub, the first build starts once the repository is linked. With the CLI, the app waits for `synteq deploy`.

## Deploy from GitHub

Installing the Synteq GitHub App requires admin access to the repository or its organization.

1. On **Source**, or on **Settings** → **GitHub**, click **Connect GitHub**.
2. If your account or organization is not listed, click **Add another account / repo** and grant the repositories you intend to deploy.
3. Pick the account, the repository, and the branch. The default branch is preselected.
4. Click **Connect repository**, or **Save changes** when you're replacing an existing link.

An app links to one repository and branch; connecting again replaces the link. Every push to that branch builds and rolls out as a release showing the commit message, SHA, and author. Other branches, tags, and branch deletions are ignored. See Apps overview.

### Auto-deploy and build filters

Both are on **Settings** → **Build & deploy**.

| Option | Description |
| --- | --- |
| **Auto-deploy** | `on_commit` builds every push. `off` builds only when you trigger one; pushes appear on **Activity** as skipped. |
| **Included paths** | Glob patterns. If set, a push builds only when a changed file matches one. |
| **Ignored paths** | Glob patterns. Changed files that match are not counted. |

A push builds if a changed file is under the root directory, matches no ignored pattern, and matches an included pattern if any are set. `*` also matches across `/`.

### Deploy hooks

A deploy hook is a URL; a `POST` to it builds the linked branch. Generate one on **Settings** → **Build & deploy**. It requires a connected GitHub repository. The token is shown once, and regenerating invalidates the old URL immediately.

## Deploy from the CLI

Install and sign in to the CLI first. See Getting started with the CLI.

1. Link the folder to a new or existing app.
`synteq link
`

2. Deploy.
`synteq deploy
`


The link is saved per directory and inherited by subdirectories, so later commands need no `--app`. `synteq app unlink` removes it. In an unlinked folder, `synteq deploy` offers the link walkthrough.

The CLI uploads the folder. In a git checkout, `.gitignore` decides what ships. Elsewhere, the CLI skips `.git`, `node_modules`, `.venv`, `__pycache__`, and anything listed in a `.synteqignore` file. `.env` files never ship. The archive size limit depends on your plan. A `Dockerfile` at the build root selects Dockerfile mode; otherwise Railpack builds. The command waits for the release and prints the URL and release number.

If the build or health gate fails, the command exits non-zero and the previous release keeps serving.

| Flag | Description |
| --- | --- |
| `--app <slug>` | Target an app other than the linked one. |
| `--dir <path>` | Deploy a folder other than the current one. |
| `--no-wait` | Return once the build is triggered. |
| `--timeout <seconds>` | How long to wait. Default `1800`. |
| `-o json` | Print the build row as JSON. |

## Deploy an image

```
synteq deploy --image registry.example.com/acme/my-api:v3

```

No build runs. Use a unique tag or a digest so each release is traceable.

For a private registry:

1. On **Settings** → **Build & deploy**, click **Add credential**.
2. Enter a name, the registry host, a username, and the password or token. Save.
3. Select the credential for the app.

Credentials are encrypted, never shown again, and shared across the organization.

## Environment variables

Variables live on the **Environment** tab. Values are write-only; the list shows name, scope, note, and last editor.

1. Click **Add variable**.
2. Enter a **Name**, a **Value**, and an optional **Note**.
3. Choose a scope and a kind.
4. Click **Save**. **Add another** adds rows; a `.env` pasted into **Name** fills them.

| Option | Description |
| --- | --- |
| **Runtime**, **Build-time**, **Both** | Where the variable is available: the running container, the build, or both. |
| **Config** | Reveal returns the full value. |
| **Secret** | Reveal returns the last four characters. The full value never leaves the server. |

Renaming keeps the value. Reveals (the eye icon) are logged on **Activity**.

A saved change rolls out to the running app automatically after about two minutes without further changes. Click **Roll out now** to apply it at once. Build-time variables take effect only on the next build, so deploy again after changing one.

```
synteq app env add DATABASE_URL=postgres://... --scope runtime
synteq app env list
synteq app env reveal DATABASE_URL
synteq app env rm OLD_KEY

```

`--scope` is `runtime` (default), `build`, or `both`, and `--note` adds a note. CLI variables are stored as secrets unless you pass `--kind config`. `--rollout` controls what happens after the save: `auto` (default) rolls out after the quiet period, `now` rolls out immediately, `deploy` starts a new build from the linked folder, and `none` waits for your next deploy.

## Custom domains

Custom domains are on the **Domains** tab. Availability and any monthly fee depend on the plan; the fee is shown before your first domain.

1. Click **Custom Domain** and enter the hostname, such as `app.example.com` or `example.com`. Wildcards and `synteq.app` names are rejected.
2. At your DNS provider, add the TXT record at `_synteq-challenge.<your domain>`.
3. Add a CNAME to the Synteq hostname for a subdomain, or an A record to the gateway address for a root domain (or an ALIAS/ANAME to the Synteq hostname).
4. Click **Revalidate**. DNS can take up to 24 hours.

| Status | Description |
| --- | --- |
| **Waiting for Verification** → **Verified** | The TXT record has been found. |
| **Pending DNS** → **Verifying** → **Issuing** → **Live** | Certificate progress. **Live** serves HTTPS. |
| **Failed** | The domain is verified but the certificate could not be issued yet. Synteq retries automatically, and the reason shows when you hover the status. |

If the A record shows as not available yet, add the TXT record and contact support. A domain can be verified on one app only; to move it, delete it from the old app first. The Synteq hostname cannot be removed.

```
synteq app domain add api.example.com
synteq app domain list
synteq app domain verify <domain-id>
synteq app domain remove <domain-id>

```

`domain add` prints the records, and `domain list` shows TLS status.

## Port and health check

Both are on **Settings** → **Build & deploy**.

| Option | Description |
| --- | --- |
| **Port** | Port for traffic and the health gate. Empty auto-detects. Applies to the running app immediately. |
| **Health check path** | Path such as `/healthz`. New releases must pass it before taking traffic; scheduled checks probe it. |

A probe is a `GET` on the Synteq hostname with a 5-second timeout. Redirects are followed, and the check passes when the final response is below 400. The portal probes a new path automatically as you type it, and the header's **Health check** button probes on demand.

```
synteq app settings set --port 8080 --health-check-path /healthz
synteq app settings show
synteq app health

```

## Build settings

These are on **Settings** → **Build & deploy**. Root directory, Dockerfile path, and build context apply to the next build. Docker command and pre-deploy command apply to the next deploy.

| Option | Description |
| --- | --- |
| **Root directory** | Subdirectory to build from, for monorepos. Also scopes build filters. |
| **Dockerfile path**, **Build context** | Relative to the root directory. |
| **Docker command** | Overrides the image's command or entrypoint. |
| **Pre-deploy command** | Runs once per release before traffic shifts, such as database migrations. |

`synteq app settings set` takes `--root-directory`, `--dockerfile-path`, `--build-context`, `--docker-command`, `--pre-deploy-command`, and `--auto-deploy`.

## Deployments and rollbacks

The **Deployments** tab lists releases with commit, branch, trigger, status, and rollout time, filterable by branch, author, environment, or status. Open one for its build log, image digest, and downloads.

**Roll back** on an earlier release starts a new release from its image through the health gate, without rebuilding. Environment variables are read fresh.

```
synteq app deployment list
synteq app deployment show 12
synteq app deployment rollback --to 12 --yes

```

`rollback` asks for confirmation unless you pass `--yes`.

## Troubleshooting

| Symptom | Cause and fix |
| --- | --- |
| Build fails at once with a missing Dockerfile | **Dockerfile path** is relative to the root directory and must exist in the upload. Clear it to build with Railpack. |
| Release ends in **Health failed** | No answer on the port or health path. Check **Logs** and **Port**; the path must succeed without authentication. |
| App exits with a permission or read-only filesystem error | The image is mounted read-only. Write PID files, compiled assets, and caches to a temporary directory. See Apps overview. |
| Release ends in **Start failed** | Usually a wrong start command or wrong-architecture image. Check the build log and **Logs**. |
| App is **Running** but the hostname does not load | Allow a minute for DNS after the first release. For a custom domain, check **Domains**. |
| CLI reports source too large | Remove build output such as `dist` or `.next`, or deploy from GitHub. |

## What next?

- Running and scaling an app: plans, replicas, autoscaling, logs, and cancellation.
- Apps overview: how builds, releases, and networking work.
- CLI reference: every `synteq` command and flag.
