> ## Documentation Index
> Fetch the complete documentation index at: https://docs.presenton.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy with Docker

> Self-host Presenton from a published GHCR image or build it directly from the GitHub source.

Presenton can be self-hosted in two ways. Most users should run a published image from the GitHub Container Registry (GHCR). Build from source when you need to inspect, modify, or test the application code.

<CardGroup cols={2}>
  <Card title="Run a GHCR release" icon="box">
    The recommended path for production. It starts quickly, requires no local build, and uses a versioned image published by the Presenton team.
  </Card>

  <Card title="Build from GitHub source" icon="github">
    The flexible path for development and customization. Clone the repository and let Docker Compose build the application on your server.
  </Card>
</CardGroup>

|                    | GHCR release                                  | Build from source                                 |
| ------------------ | --------------------------------------------- | ------------------------------------------------- |
| Best for           | Production and most self-hosted installations | Development, customization, and testing           |
| Application source | Prebuilt and published by Presenton           | A Git branch, tag, or commit you choose           |
| Startup time       | Fast; Docker only downloads the image         | Slower initially; Docker builds the image locally |
| Updates            | Pull a newer published image                  | Pull source changes and rebuild                   |

## Option 1: Run a published GHCR release

This is the most stable and straightforward way to self-host Presenton. The image already contains the frontend, API, export tools, and runtime dependencies, so the host only needs Docker.

The examples below pin `v0.9.3-beta` for predictable deployments. Browse the [published image versions](https://github.com/presenton/presenton/pkgs/container/presenton) to choose another release, or replace the version with `latest` to follow the newest published image automatically.

<Tabs>
  <Tab title="Linux and macOS">
    ```bash theme={null}
    mkdir -p app_data

    docker run --detach \
      --name presenton \
      --restart unless-stopped \
      --publish 5001:80 \
      --volume "$(pwd)/app_data:/app_data" \
      ghcr.io/presenton/presenton:v0.9.3-beta
    ```
  </Tab>

  <Tab title="Windows PowerShell">
    ```powershell theme={null}
    New-Item -ItemType Directory -Force app_data

    docker run --detach `
      --name presenton `
      --restart unless-stopped `
      --publish 5001:80 `
      --volume "${PWD}\app_data:/app_data" `
      ghcr.io/presenton/presenton:v0.9.3-beta
    ```
  </Tab>
</Tabs>

Open [http://localhost:5001](http://localhost:5001) after the container starts. The first port in `5001:80` is the port on your host and can be changed; container port `80` serves the web app, REST API, and `/mcp`.

<Tip>
  Use an explicit version tag in production so upgrades happen when you choose. Use `latest` when automatically following the newest published release is more important than repeatability.
</Tip>

### Configure the release image

Pass settings with `--env-file` to keep the `docker run` command readable:

```dotenv theme={null}
# .env
AUTH_USERNAME=admin
AUTH_PASSWORD=replace-with-a-long-password
LLM=openai
OPENAI_API_KEY=replace-with-your-key
OPENAI_MODEL=gpt-4.1
CAN_CHANGE_KEYS=false
```

Then add `--env-file .env` before the image name:

```bash theme={null}
docker run --detach \
  --name presenton \
  --restart unless-stopped \
  --publish 5001:80 \
  --volume "$(pwd)/app_data:/app_data" \
  --env-file .env \
  ghcr.io/presenton/presenton:v0.9.3-beta
```

See [Environment variables](/hosting/environment-variables) for all supported providers and runtime settings.

### Update a GHCR deployment

Pull the new image before replacing the container. Keep the same `app_data` directory and startup options.

```bash theme={null}
docker pull ghcr.io/presenton/presenton:v0.9.3-beta
docker stop presenton
docker rm presenton

# Run the container again with the same volume and environment options.
```

Changing to a newer release is intentional: update the tag in both the `docker pull` and `docker run` commands.

## Option 2: Build from the GitHub source

Choose this path when you want to change Presenton, review the code before deployment, test unreleased work, or build a specific branch or commit. You need Git, Docker Engine, and the Docker Compose plugin.

<Steps>
  <Step title="Clone the repository">
    ```bash theme={null}
    git clone https://github.com/presenton/presenton.git
    cd presenton
    ```
  </Step>

  <Step title="Choose the source revision">
    A fresh clone uses `main`, which contains the newest source. For a repeatable build, check out a Git tag or commit that exists in the repository before continuing.

    ```bash theme={null}
    # Optional: list available release tags
    git tag --list

    # Optional: replace TAG_OR_COMMIT with the revision you want to build
    git checkout TAG_OR_COMMIT
    ```
  </Step>

  <Step title="Add your configuration">
    Create `.env` beside `docker-compose.yml`. Compose reads this file and forwards the supported values to Presenton.

    ```dotenv theme={null}
    PRESENTON_HTTP_HOST_PORT=5001
    AUTH_USERNAME=admin
    AUTH_PASSWORD=replace-with-a-long-password
    LLM=openai
    OPENAI_API_KEY=replace-with-your-key
    OPENAI_MODEL=gpt-4.1
    CAN_CHANGE_KEYS=false
    ```
  </Step>

  <Step title="Build and start Presenton">
    ```bash theme={null}
    docker compose up --build --detach production
    ```

    Compose builds the repository's production `Dockerfile`, starts the container, and mounts `./app_data` at `/app_data`.
  </Step>
</Steps>

Open [http://localhost:5001](http://localhost:5001) when the build finishes.

<Note>
  The `main` branch can contain changes that have not reached a published container release. For a more predictable source build, check out a release tag or pin a commit before building.
</Note>

### Update a source build

If you follow `main`, pull the newest commits and rebuild:

```bash theme={null}
git pull --ff-only
docker compose up --build --detach production
```

If you pin a tag or commit, fetch the available revisions, check out the one you want, and rebuild:

```bash theme={null}
git fetch --tags
git checkout TAG_OR_COMMIT
docker compose up --build --detach production
```

The repository also provides `production-gpu`, `development`, and `development-gpu` services. Use `production` for a normal hosted instance. Use `production-gpu` only after installing the NVIDIA Container Toolkit and confirming that Docker can access the GPU.

## Persistence

Both deployment paths store persistent state in `/app_data` inside the container:

* The GHCR commands mount the local `./app_data` directory explicitly.
* The repository's Compose service creates the same mount automatically.

<Warning>
  Never replace or upgrade the container without preserving `/app_data`. It contains presentations, uploads, templates, settings, authentication state, the default database, exports, and local memory.
</Warning>

Back up this directory before upgrades. See [Backups and recovery](/hosting/backups-and-recovery) for a complete backup and restore workflow.

## Ports and networking

| Mapping     | Use                               |
| ----------- | --------------------------------- |
| `5001:80`   | Browser, REST API, and MCP        |
| `1455:1455` | ChatGPT/Codex OAuth callback only |

`localhost` inside a container refers to the container itself. Reach another Compose service by its service name, or reach a service on the host through a supported host gateway such as `host.docker.internal`.

## Operate and verify

For a GHCR container:

```bash theme={null}
docker logs --follow presenton
docker stop presenton
docker start presenton
docker ps --filter name=presenton
```

For a source deployment:

```bash theme={null}
docker compose logs --follow production
docker compose stop production
docker compose start production
docker compose ps
```

After deployment, generate a small presentation, restart Presenton, and confirm that the presentation remains available. Then test export and any REST API or MCP integration you plan to expose.
