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

# Self-Host Volta with Docker Compose — Full Setup Guide

> Deploy Volta on your own server using Docker Compose, with PostgreSQL, Redis, and Temporal included out of the box — no managed services needed.

Volta is designed to run entirely on your own infrastructure. A single `docker compose up -d` command brings up the complete production stack: the Volta application (backend API and frontend dashboard bundled together), PostgreSQL 17 for persistent data, Redis 7 for caching and rate limiting, Temporal for durable workflow scheduling, and the Temporal UI for workflow monitoring. No managed cloud services are required.

## Prerequisites

Before you begin, make sure the following are available on your server:

<Info>
  The Docker Compose path handles PostgreSQL, Redis, and Temporal for you — you only need Docker itself installed on the host. The Node.js and pnpm requirements apply only if you are running a local development setup outside of Docker.
</Info>

| Requirement                   | Minimum version |
| ----------------------------- | --------------- |
| Docker (with Compose v2)      | Latest stable   |
| Node.js *(local dev only)*    | >= 20.17        |
| pnpm *(local dev only)*       | >= 10.6         |
| PostgreSQL *(local dev only)* | >= 15           |
| Redis *(local dev only)*      | >= 7            |

***

## Deploy with Docker Compose

<Steps>
  <Step title="Clone the repository and start the stack">
    Clone the Volta repository, then bring up all services in detached mode:

    ```bash theme={null}
    git clone https://github.com/your-org/postsider.git
    cd postsider
    docker compose up -d
    ```

    Docker will pull all required images — Volta, PostgreSQL 17, Redis 7, Temporal, and the Temporal UI — and start them in the correct dependency order. The first pull may take a couple of minutes depending on your connection.

    <Tip>
      Generate a secure `JWT_SECRET` before starting the stack in production:

      ```bash theme={null}
      openssl rand -base64 32
      ```

      Copy the output and set it as `JWT_SECRET` in your `docker-compose.yaml` (see the [Environment Variables](#environment-variables) section below) before running `docker compose up -d`.
    </Tip>

    To follow the startup logs and confirm everything is healthy:

    ```bash theme={null}
    docker compose logs -f postsider
    ```
  </Step>

  <Step title="Open the dashboard and complete bootstrap">
    Once the `postsider` container is healthy, open your browser and navigate to:

    ```text theme={null}
    http://localhost:4007
    ```

    On first launch, Volta detects that no admin account exists and runs the **bootstrap flow** automatically. This creates a placeholder admin account and prints a one-time password to the container logs. You'll use that password to complete your initial sign-in in the next step.
  </Step>

  <Step title="First login — set your real credentials">
    Sign in with the bootstrap credentials:

    * **Email:** `admin@setup.local`
    * **Password:** the one-time password printed in the terminal during bootstrap

    ```bash theme={null}
    # Retrieve the one-time password from logs
    docker compose logs postsider | grep -i "password"
    ```

    After signing in, Volta immediately redirects you to the **/setup** screen. Enter your real name, email address, and a strong password. Once saved, you're logged in as the permanent administrator — the `admin@setup.local` placeholder is replaced and can no longer be used.

    <Info>
      Public registration is disabled by default (`DISABLE_REGISTRATION=true` in the Docker Compose environment). Additional users join via **Settings → Users → Invite** from inside the dashboard.
    </Info>
  </Step>
</Steps>

***

## Environment variables

The `docker-compose.yaml` ships with sensible defaults for a local setup. For any internet-facing deployment you must update the variables below. Edit them directly in the `environment:` block of the `postsider` service in `docker-compose.yaml`.

<Warning>
  `JWT_SECRET` **must** be set to a non-empty, unique random string. The backend refuses to start without it, and using a weak or shared secret in production is a serious security risk.
</Warning>

| Variable                  | Description                                                                                                                             | Example                                                                           |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `JWT_SECRET`              | Random string used to sign session tokens. Generate with `openssl rand -base64 32`.                                                     | `s3cr3t...`                                                                       |
| `DATABASE_URL`            | PostgreSQL connection string.                                                                                                           | `postgresql://postsider-user:password@postsider-postgres:5432/postsider-db-local` |
| `REDIS_URL`               | Redis connection string.                                                                                                                | `redis://postsider-redis:6379`                                                    |
| `FRONTEND_URL`            | The public URL where the dashboard is accessible. Must match exactly what users type in the browser.                                    | `https://volta.yourcompany.com`                                                   |
| `NEXT_PUBLIC_BACKEND_URL` | The public URL of the backend API, reachable from users' browsers. In the default single-container setup this is `FRONTEND_URL + /api`. | `https://volta.yourcompany.com/api`                                               |

All other variables — social platform OAuth keys, storage provider settings, optional AI and payment integrations — can be left blank until you need them. See `.env.example` in the repository for a full annotated reference.

***

## Updating Volta

Pull the latest images and restart the stack. Volta applies any pending database migrations automatically on startup.

```bash theme={null}
docker compose pull
docker compose up -d
```

Running containers are replaced one at a time with zero manual intervention. Check the logs after the update to confirm the new version started cleanly:

```bash theme={null}
docker compose logs -f postsider
```

***

## Backups

All persistent state lives in the `postsider-postgres` volume. Back up the database regularly using `pg_dump`:

```bash theme={null}
docker exec postsider-postgres \
  pg_dump -U postsider-user postsider-db-local > backup.sql
```

Store `backup.sql` in a safe off-host location. To restore, pipe the dump back through `psql`:

```bash theme={null}
cat backup.sql | docker exec -i postsider-postgres \
  psql -U postsider-user -d postsider-db-local
```

The `postsider-uploads` volume holds user-uploaded media files when `STORAGE_PROVIDER=local`. Back up this volume separately, or switch to Cloudflare R2 (`STORAGE_PROVIDER=cloudflare`) to store uploads in object storage instead.
