# Add an app

An app (app) is a project deployed on one of your servers - Django, FastAPI or Flask, optionally with a static frontend in front. Each app gets its own domain, nginx config, Python environment and deploy key.

## Requirements

- A [provisioned server](add-server.md) (status: Ready)
- A Git repository - connect GitHub for the full experience

## Steps

### 1. Connect GitHub (once)

The first time, connect your GitHub account under **Settings → Source control** (or inline from the app-create form). Pyvolt installs a GitHub App scoped to the repositories you choose - grant individual repos or everything, and change it any time via **Manage access** next to the repo picker.

### 2. Create the app

From your server's **Apps** tab, click **Add app**.

**Choose a domain:**

- **Pyvolt subdomain** - `yourapp.preview.pyvolt.com`. Instant, no DNS setup, SSL included.
- **Custom domain** - your own domain (point DNS at your server's IP; see [Custom domains](../custom-domains.md)).

**Pick the repository:** account → repo → branch. Can't see a repo? The GitHub App may not have access to it - click **Manage access**, grant it, then **Refresh**.

### 3. Review what detection found

The moment you pick a repo, Pyvolt reads a handful of files from it (`manage.py`, `pyproject.toml`, lockfiles, `package.json`, framework configs…) and fills the form in. A summary tells you exactly what it saw:

```
Framework: django
Found: manage.py, django, gunicorn, celery, whitenoise
Package manager: uv
Protocol: WSGI
Settings module: config.settings
```

Every prefilled value is yours to edit:

- **Start command** - how your app serves, e.g. `gunicorn config.wsgi:application --workers 2 --bind $SOCK`. Derived from the servers actually declared in your dependencies (gunicorn, uvicorn, hypercorn, waitress…).
- **Release command** - steps that run on every deploy after dependencies install, before the app restarts. Django repos get `collectstatic` + `migrate` prefilled. Nothing runs behind your back - if it's not in this box, it doesn't happen.
- **Frontend directory / passthrough** - for SPA or static-export frontends (Next.js `output: 'export'`, Vite, CRA): the build output directory nginx serves at the root, and the URL prefixes (like `/api`) that pass through to your app.
- **Environment variables** - add rows now or later from the Env tab. Connect a Postgres database from the same form and `DATABASE_URL` is filled in for you.

### 4. Create

On create, Pyvolt:

1. Creates the app directory on your server (`/home/pyvolt/sites/yourdomain/`)
2. Writes the nginx config and reloads nginx
3. Pushes a deploy key to the GitHub repo automatically - no manual key copying

Your domain serves a placeholder page until the first deploy.

## From the CLI

Apps can also be created headlessly with the [Pyvolt CLI](../cli.md) - handy
for scripts, CI and coding agents:

```bash
pyvolt apps create --server myserver --domain myapp --repo you/yourrepo
```

The same autodiscovery runs and flags override what it found; `--dry-run`
shows the resolved plan without creating anything. GitHub still needs
connecting once in the dashboard (step 1 above). Full flag list on the
[command reference](../cli-commands.md#create-an-app).

## Next step

[Deploy →](deploy.md)
