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

# Run verifyngo in Docker with docker run or Docker Compose

> Run verifyngo in Docker using docker run or Docker Compose. Covers config file mounting, persistent state storage, and static file serving.

verifyngo ships as a minimal Docker image built on `distroless/static-debian12`. There is no shell, no package manager, and no unnecessary tooling — just the compiled binary. This guide covers running it with `docker run` and with Docker Compose, including how to persist state and serve custom static files.

## Quick start with docker run

The fastest way to get verifyngo running is a single `docker run` command. Mount your `config.json` into the container and expose port `8080`:

```bash theme={null}
docker run -d \
  --name verifyngo \
  -p 8080:8080 \
  -v $(pwd)/config.json:/config.json:ro \
  ghcr.io/chocolatemoo53/verifyngo:latest
```

| Flag                                      | What it does                                                                                                                        |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `-d`                                      | Run the container in the background (detached mode).                                                                                |
| `--name verifyngo`                        | Give the container a memorable name so you can reference it with `docker logs`, `docker stop`, etc.                                 |
| `-p 8080:8080`                            | Bind the container's port `8080` to port `8080` on your host.                                                                       |
| `-v $(pwd)/config.json:/config.json:ro`   | Bind-mount your local `config.json` into the container at `/config.json`, read-only. The container reads from this path by default. |
| `ghcr.io/chocolatemoo53/verifyngo:latest` | Pull the latest published image from the GitHub Container Registry.                                                                 |

## Docker Compose

For production deployments, Docker Compose gives you a repeatable, version-controlled setup. The following file is based on the project's example and includes a named volume for persistent state:

```yaml docker-compose.yml theme={null}
services:
  verifyngo:
    image: ghcr.io/chocolatemoo53/verifyngo:latest
    ports:
      - "8080:8080"
    volumes:
      - ./config.json:/config.json:ro
      - ./static:/static:ro
      # Uncomment one of the following to load a rules file or policy file:
      # - ./rules.txt:/rules.txt:ro
      # - ./policy.yml:/policy.yml:ro
      - verifyngo-data:/data
    environment:
      - TZ=UTC
    restart: unless-stopped

volumes:
  verifyngo-data:
```

Bring the stack up with:

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

To tail logs in real time:

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

## Persisting state

By default, verifyngo keeps its ban and verification state in memory. When the container restarts, that state is lost and previously-banned clients can connect again. To persist state across restarts, mount a named volume at `/data` and point `store.file.path` at a file inside it:

```json config.json theme={null}
"store": {
  "backend": "memory",
  "file": {
    "path": "/data/store.json",
    "save_interval": "30s"
  }
}
```

With this configuration verifyngo flushes its in-memory state to `/data/store.json` every 30 seconds and reloads it on startup. The `verifyngo-data` named volume in the Compose example above satisfies the `/data` mount.

## Serving custom static files

You can supply a custom logo, stylesheet, or other assets by mounting a local directory into the container and telling verifyngo where to find it with the `static_dir` config key. Those files are then reachable under `/static/` and can be referenced in your `branding` config.

Mount the directory when you run the container:

```bash theme={null}
docker run -d \
  -v $(pwd)/config.json:/config.json:ro \
  -v $(pwd)/static:/static:ro \
  -p 8080:8080 \
  ghcr.io/chocolatemoo53/verifyngo:latest
```

Then point `static_dir` at the mount path in your config:

```json config.json theme={null}
{ "static_dir": "/static" }
```

You can then reference files in your branding block like this:

```json config.json theme={null}
"branding": {
  "logo_url": "/static/logo.svg",
  "css_url": "/static/custom.css"
}
```

<Note>
  The Docker image runs as a non-root user (`nonroot:nonroot`). Make sure any files and directories you bind-mount into the container are readable by this user. On Linux, `chmod o+r` on the files (or `o+rx` on directories) is the simplest fix if you run into permission errors.
</Note>
