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

# PostgreSQL

> Run a persistent PostgreSQL service with a localhost-only forwarded port

<Tooltip tip="This example depends on a disk-kind named volume and a published client-host port, which are not available on microsandbox cloud."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

This example runs PostgreSQL 17 in a microVM, stores the database on a disk-backed named volume, and publishes the service only to host loopback.

<Note>
  The current `postgres:17-alpine` image contains tab characters in `DOCKER_PG_LLVM_DEPS`. Passing `-e DOCKER_PG_LLVM_DEPS=` is a temporary compatibility workaround for microsandbox's guest environment validation.
</Note>

## Run PostgreSQL

<Steps>
  <Step title="Start PostgreSQL">
    Set a demo password in the host shell:

    <CodeGroup>
      ```sh macOS & Linux theme={null}
      export POSTGRES_PASSWORD="$(openssl rand -hex 24)"
      ```

      ```powershell Windows theme={null}
      $bytes = New-Object byte[] 24
      $rng = [Security.Cryptography.RandomNumberGenerator]::Create()
      $rng.GetBytes($bytes)
      $rng.Dispose()
      $env:POSTGRES_PASSWORD = -join ($bytes | ForEach-Object { $_.ToString('x2') })
      ```
    </CodeGroup>

    Start the database:

    <CodeGroup>
      ```sh macOS & Linux theme={null}
      msb run -d --name postgres-demo --replace \
        --cpus 1 --memory 1G --root-disk 2G \
        -p 127.0.0.1:55432:5432 \
        -e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" \
        -e POSTGRES_DB=examples \
        -e DOCKER_PG_LLVM_DEPS= \
        --mount-named postgres-data:/var/lib/postgresql/data:kind=disk,size=5G \
        postgres:17-alpine
      ```

      ```powershell Windows theme={null}
      msb run -d --name postgres-demo --replace `
        --cpus 1 --memory 1G --root-disk 2G `
        -p 127.0.0.1:55432:5432 `
        -e "POSTGRES_PASSWORD=$env:POSTGRES_PASSWORD" `
        -e POSTGRES_DB=examples `
        -e DOCKER_PG_LLVM_DEPS= `
        --mount-named postgres-data:/var/lib/postgresql/data:kind=disk,size=5G `
        postgres:17-alpine
      ```
    </CodeGroup>

    With no command after the image, microsandbox runs the image's declared `docker-entrypoint.sh postgres` command in the background.
  </Step>

  <Step title="Wait for readiness">
    ```sh theme={null}
    msb exec postgres-demo -- sh -lc '
      until pg_isready -h 127.0.0.1 -d examples -U postgres; do sleep 1; done
    '
    ```
  </Step>

  <Step title="Run a query">
    <CodeGroup>
      ```sh macOS & Linux theme={null}
      msb exec -e PGPASSWORD="$POSTGRES_PASSWORD" postgres-demo -- \
        psql -h 127.0.0.1 -U postgres -d examples \
        -c "select current_database(), current_setting('server_version');"
      ```

      ```powershell Windows theme={null}
      msb exec -e "PGPASSWORD=$env:POSTGRES_PASSWORD" postgres-demo -- `
        psql -h 127.0.0.1 -U postgres -d examples `
        -c "select current_database(), current_setting('server_version');"
      ```
    </CodeGroup>

    The tested image returned database `examples` and PostgreSQL `17.10`.

    Applications on the host can connect to `127.0.0.1:55432` with the same database, user, and password.

    <Warning>
      Environment variables and command arguments are appropriate for this local demo, not for production secrets. Use [secret injection](/sandboxes/secrets), retain the loopback bind, and configure PostgreSQL access controls before allowing remote clients.
    </Warning>
  </Step>

  <Step title="Clean up or keep the data">
    Remove the VM while keeping its database:

    ```sh theme={null}
    msb rm -f postgres-demo
    ```

    Remove the database volume only when you no longer need its contents:

    ```sh theme={null}
    msb volume rm postgres-data
    ```

    Clear the password from the host shell:

    <CodeGroup>
      ```sh macOS & Linux theme={null}
      unset POSTGRES_PASSWORD
      ```

      ```powershell Windows theme={null}
      Remove-Item Env:POSTGRES_PASSWORD
      ```
    </CodeGroup>
  </Step>
</Steps>
