mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-26 09:02:11 +03:00
* docs(podman): clarify Podman Machine deployment * style(podman): format guidance and regression test
196 lines
6.1 KiB
Markdown
196 lines
6.1 KiB
Markdown
# Podman Deployment
|
|
|
|
Run OmniRoute with **podman compose** on Linux, macOS, or Windows, or with
|
|
**Quadlet** on a Linux host that runs systemd.
|
|
|
|
---
|
|
|
|
## Choose the deployment path
|
|
|
|
- **Linux with a local Podman engine and user systemd:** Compose or Quadlet.
|
|
- **macOS or Windows:** Compose. Podman runs containers in a remote Linux VM
|
|
managed by Podman Machine; host-side `systemctl` and `podman unshare` do not
|
|
operate on that engine.
|
|
- **Any other remote Podman connection (including an optional Linux Podman
|
|
Machine):** treat it like Podman Machine, not like a local rootless engine.
|
|
|
|
## Option A: Quadlet (Linux + systemd only)
|
|
|
|
Use this option only when the Podman engine and user systemd instance run on the
|
|
same Linux host. The `systemctl --user` commands below do not configure a Podman
|
|
Machine from a macOS or Windows host.
|
|
|
|
### 1. Build the image
|
|
|
|
```bash
|
|
cd /path/to/omniroute
|
|
podman build --target runner-base -t omniroute:base .
|
|
# For web-cookie providers (gemini-web, claude-web, claude-turnstile):
|
|
podman build --target runner-web -t omniroute:web .
|
|
# For CLI tool support:
|
|
podman build --target runner-cli -t omniroute:cli .
|
|
```
|
|
|
|
### 2. Copy Quadlet files to the systemd directory
|
|
|
|
```bash
|
|
mkdir -p ~/.config/containers/systemd/omniroute
|
|
cp contrib/podman/*.container ~/.config/containers/systemd/omniroute/
|
|
cp contrib/podman/*.network ~/.config/containers/systemd/omniroute/
|
|
cp contrib/podman/*.volume ~/.config/containers/systemd/omniroute/
|
|
```
|
|
|
|
### 3. Mount the project .env for secrets
|
|
|
|
Edit `~/.config/containers/systemd/omniroute/omniroute.container` and
|
|
uncomment/replace the `EnvironmentFile` line with the absolute path to
|
|
your project `.env`:
|
|
|
|
```
|
|
EnvironmentFile=/home/USER/code/docker/OmniRoute/.env
|
|
```
|
|
|
|
Make sure `CONTAINER_HOST=podman` is set in that `.env`.
|
|
|
|
Alternatively, edit the env vars directly in the `.container` file.
|
|
|
|
### 4. Reload systemd and start
|
|
|
|
```bash
|
|
systemctl --user daemon-reload
|
|
systemctl --user start omniroute-redis
|
|
systemctl --user start omniroute
|
|
```
|
|
|
|
### 5. Verify
|
|
|
|
```bash
|
|
systemctl --user status omniroute
|
|
curl http://localhost:20128/v1/models
|
|
```
|
|
|
|
To follow logs:
|
|
|
|
```bash
|
|
journalctl --user -u omniroute -f
|
|
```
|
|
|
|
The checked-in Quadlet files already contain `[Install]` sections with
|
|
`WantedBy=default.target`. The Quadlet generator applies those sections during
|
|
`systemctl --user daemon-reload`. Generated Quadlet services are transient
|
|
systemd units and must not be enabled with `systemctl enable`.
|
|
|
|
---
|
|
|
|
## Option B: podman compose (all supported host platforms)
|
|
|
|
The project's `docker-compose.yml` now works with both Docker and Podman.
|
|
Just set `CONTAINER_HOST=podman` in `.env` before starting.
|
|
|
|
### 1. Set the runtime in `.env`
|
|
|
|
Make sure `.env` contains:
|
|
|
|
```env
|
|
CONTAINER_HOST=podman
|
|
```
|
|
|
|
### 2. Prepare the data directory
|
|
|
|
The Compose profiles bind-mount `./data` at `/app/data`. Create the directory,
|
|
then use the permission guidance for your engine topology below.
|
|
|
|
```bash
|
|
mkdir -p data
|
|
```
|
|
|
|
### 3. Build and start
|
|
|
|
The application profiles use local image names such as `omniroute:base`; those
|
|
are build outputs, not published Docker Hub tags. On the first run, have Compose
|
|
build the selected profile:
|
|
|
|
```bash
|
|
podman compose --profile base up -d --build
|
|
```
|
|
|
|
Alternatively, build the matching target explicitly and tell Compose to reuse
|
|
that local image:
|
|
|
|
```bash
|
|
podman build --target runner-base -t omniroute:base .
|
|
podman compose --profile base up -d --no-build
|
|
```
|
|
|
|
### Profiles
|
|
|
|
Same profiles as `docker compose`:
|
|
|
|
| Profile | First-run command |
|
|
| ------------------------------ | --------------------------------------------- |
|
|
| `base` (no CLIs) | `podman compose --profile base up -d --build` |
|
|
| `web` (+Chromium/Playwright) | `podman compose --profile web up -d --build` |
|
|
| `cli` (+CLI tools) | `podman compose --profile cli up -d --build` |
|
|
| `host` (host-mounted binaries) | `podman compose --profile host up -d --build` |
|
|
| `cliproxyapi` (sidecar) | `podman compose --profile cliproxyapi up -d` |
|
|
|
|
---
|
|
|
|
## Data directory permissions by topology
|
|
|
|
### Linux with a local rootless Podman engine
|
|
|
|
Rootless Podman maps container UIDs into a subordinate range. If the container
|
|
cannot write to the bind-mounted `./data`, run this **on the Linux host whose
|
|
local engine will run the container**:
|
|
|
|
```bash
|
|
podman unshare chown 1000:1000 ./data
|
|
```
|
|
|
|
Use this only when the CLI is connected to a local, non-remote Podman engine.
|
|
`podman unshare` is not available with a remote Podman client.
|
|
|
|
### macOS or Windows with Podman Machine
|
|
|
|
Podman on macOS and Windows runs the engine inside a Linux VM. The host CLI is a
|
|
remote client, so do **not** run `podman unshare` on the macOS or Windows host.
|
|
Create `./data` in the host directory shared with the machine and try the
|
|
Compose start command above; no ownership change is needed when that mount is
|
|
already writable.
|
|
|
|
If the bind mount is not writable and you do not need direct host access to the
|
|
database files, use a Podman-managed named volume with the published image.
|
|
Named volumes avoid host-directory UID translation:
|
|
|
|
```bash
|
|
podman volume create omniroute-data
|
|
podman run -d --name omniroute \
|
|
--env-file .env \
|
|
-e DATA_DIR=/app/data \
|
|
-p 20128:20128 \
|
|
-v omniroute-data:/app/data \
|
|
docker.io/diegosouzapw/omniroute:latest
|
|
```
|
|
|
|
For a bind mount that still fails, inspect or repair the shared path from the
|
|
Podman Machine side (for example with `podman machine ssh`) according to the
|
|
machine provider's mount configuration. A container cannot reliably determine
|
|
or repair that host/VM topology for you.
|
|
|
|
---
|
|
|
|
## How it works
|
|
|
|
The `docker-compose.yml` uses fully-qualified image names
|
|
(`docker.io/library/redis:7-alpine`) and flat variable expansions so it
|
|
works with both Docker and Podman without a separate compose file.
|
|
|
|
The entrypoint script (`check-permissions.sh`) reads `CONTAINER_HOST`
|
|
from `.env` to choose the runtime guidance:
|
|
|
|
- **docker**: `sudo chown -R ... ./data`
|
|
- **podman**: a topology-neutral warning that points back to this guide, because
|
|
the container cannot tell whether its engine is local or reached through
|
|
Podman Machine.
|