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

# Podman

# Podman

Run the OpenAEON gateway in a **rootless** Podman container. Uses the same image as Docker (build from the repo [Dockerfile](https://github.com/openaeon/openaeon/blob/main/Dockerfile)).

## Requirements

* Podman (rootless)
* Sudo for one-time setup (create user, build image)

## Quick start

**1. One-time setup** (from repo root; creates user, builds image, installs launch script):

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
./setup-podman.sh
```

This also creates a minimal `~openaeon/.openaeon/openaeon.json` (sets `gateway.mode="local"`) so the gateway can start without running the wizard.

By default the container is **not** installed as a systemd service, you start it manually (see below). For a production-style setup with auto-start and restarts, install it as a systemd Quadlet user service instead:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
./setup-podman.sh --quadlet
```

(Or set `OPENAEON_PODMAN_QUADLET=1`; use `--container` to install only the container and launch script.)

**2. Start gateway** (manual, for quick smoke testing):

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
./scripts/run-openaeon-podman.sh launch
```

**3. Onboarding wizard** (e.g. to add channels or providers):

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
./scripts/run-openaeon-podman.sh launch setup
```

Then open `http://127.0.0.1:18789/` and use the token from `~openaeon/.openaeon/.env` (or the value printed by setup).

## Systemd (Quadlet, optional)

If you ran `./setup-podman.sh --quadlet` (or `OPENAEON_PODMAN_QUADLET=1`), a [Podman Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html) unit is installed so the gateway runs as a systemd user service for the openaeon user. The service is enabled and started at the end of setup.

* **Start:** `sudo systemctl --machine openaeon@ --user start openaeon.service`
* **Stop:** `sudo systemctl --machine openaeon@ --user stop openaeon.service`
* **Status:** `sudo systemctl --machine openaeon@ --user status openaeon.service`
* **Logs:** `sudo journalctl --machine openaeon@ --user -u openaeon.service -f`

The quadlet file lives at `~openaeon/.config/containers/systemd/openaeon.container`. To change ports or env, edit that file (or the `.env` it sources), then `sudo systemctl --machine openaeon@ --user daemon-reload` and restart the service. On boot, the service starts automatically if lingering is enabled for openaeon (setup does this when loginctl is available).

To add quadlet **after** an initial setup that did not use it, re-run: `./setup-podman.sh --quadlet`.

## The openaeon user (non-login)

`setup-podman.sh` creates a dedicated system user `openaeon`:

* **Shell:** `nologin` — no interactive login; reduces attack surface.

* **Home:** e.g. `/home/openaeon` — holds `~/.openaeon` (config, workspace) and the launch script `run-openaeon-podman.sh`.

* **Rootless Podman:** The user must have a **subuid** and **subgid** range. Many distros assign these automatically when the user is created. If setup prints a warning, add lines to `/etc/subuid` and `/etc/subgid`:

  ```text theme={"theme":{"light":"min-light","dark":"min-dark"}}
  openaeon:100000:65536
  ```

  Then start the gateway as that user (e.g. from cron or systemd):

  ```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
  sudo -u openaeon /home/openaeon/run-openaeon-podman.sh
  sudo -u openaeon /home/openaeon/run-openaeon-podman.sh setup
  ```

* **Config:** Only `openaeon` and root can access `/home/openaeon/.openaeon`. To edit config: use the Control UI once the gateway is running, or `sudo -u openaeon $EDITOR /home/openaeon/.openaeon/openaeon.json`.

## Environment and config

* **Token:** Stored in `~openaeon/.openaeon/.env` as `OPENAEON_GATEWAY_TOKEN`. `setup-podman.sh` and `run-openaeon-podman.sh` generate it if missing (uses `openssl`, `python3`, or `od`).
* **Optional:** In that `.env` you can set provider keys (e.g. `GROQ_API_KEY`, `OLLAMA_API_KEY`) and other OpenAEON env vars.
* **Host ports:** By default the script maps `18789` (gateway) and `18790` (bridge). Override the **host** port mapping with `OPENAEON_PODMAN_GATEWAY_HOST_PORT` and `OPENAEON_PODMAN_BRIDGE_HOST_PORT` when launching.
* **Gateway bind:** By default, `run-openaeon-podman.sh` starts the gateway with `--bind loopback` for safe local access. To expose on LAN, set `OPENAEON_GATEWAY_BIND=lan` and configure `gateway.controlUi.allowedOrigins` (or explicitly enable host-header fallback) in `openaeon.json`.
* **Paths:** Host config and workspace default to `~openaeon/.openaeon` and `~openaeon/.openaeon/workspace`. Override the host paths used by the launch script with `OPENAEON_CONFIG_DIR` and `OPENAEON_WORKSPACE_DIR`.

## Useful commands

* **Logs:** With quadlet: `sudo journalctl --machine openaeon@ --user -u openaeon.service -f`. With script: `sudo -u openaeon podman logs -f openaeon`
* **Stop:** With quadlet: `sudo systemctl --machine openaeon@ --user stop openaeon.service`. With script: `sudo -u openaeon podman stop openaeon`
* **Start again:** With quadlet: `sudo systemctl --machine openaeon@ --user start openaeon.service`. With script: re-run the launch script or `podman start openaeon`
* **Remove container:** `sudo -u openaeon podman rm -f openaeon` — config and workspace on the host are kept

## Troubleshooting

* **Permission denied (EACCES) on config or auth-profiles:** The container defaults to `--userns=keep-id` and runs as the same uid/gid as the host user running the script. Ensure your host `OPENAEON_CONFIG_DIR` and `OPENAEON_WORKSPACE_DIR` are owned by that user.
* **Gateway start blocked (missing `gateway.mode=local`):** Ensure `~openaeon/.openaeon/openaeon.json` exists and sets `gateway.mode="local"`. `setup-podman.sh` creates this file if missing.
* **Rootless Podman fails for user openaeon:** Check `/etc/subuid` and `/etc/subgid` contain a line for `openaeon` (e.g. `openaeon:100000:65536`). Add it if missing and restart.
* **Container name in use:** The launch script uses `podman run --replace`, so the existing container is replaced when you start again. To clean up manually: `podman rm -f openaeon`.
* **Script not found when running as openaeon:** Ensure `setup-podman.sh` was run so that `run-openaeon-podman.sh` is copied to openaeon’s home (e.g. `/home/openaeon/run-openaeon-podman.sh`).
* **Quadlet service not found or fails to start:** Run `sudo systemctl --machine openaeon@ --user daemon-reload` after editing the `.container` file. Quadlet requires cgroups v2: `podman info --format '{{.Host.CgroupsVersion}}'` should show `2`.

## Optional: run as your own user

To run the gateway as your normal user (no dedicated openaeon user): build the image, create `~/.openaeon/.env` with `OPENAEON_GATEWAY_TOKEN`, and run the container with `--userns=keep-id` and mounts to your `~/.openaeon`. The launch script is designed for the openaeon-user flow; for a single-user setup you can instead run the `podman run` command from the script manually, pointing config and workspace to your home. Recommended for most users: use `setup-podman.sh` and run as the openaeon user so config and process are isolated.
