Skip to content

Install with Docker ​

The official container image runs the xopc gateway and CLI without installing Node.js or pnpm on the host.

  • Image: ghcr.io/xopcai/xopc
  • Platforms: linux/amd64 and linux/arm64
  • Gateway port: 18790
  • Container state directory: /home/node/.xopc

Use latest for a simple installation. For production, pin a version shown on the package page, such as ghcr.io/xopcai/xopc:0.0.201.

Requirements ​

Install Docker Desktop on macOS or Windows, or Docker Engine with the Compose plugin on Linux. Verify the installation:

bash
docker --version
docker compose version

Quick start ​

Create a Docker-managed volume so configuration, sessions, logs, and workspaces survive container replacement:

bash
docker volume create xopc-data

Start the gateway. Publishing the port on 127.0.0.1 keeps it accessible only from this computer:

bash
docker run -d \
  --name xopc-gateway \
  --restart unless-stopped \
  -p 127.0.0.1:18790:18790 \
  -e TZ=UTC \
  -v xopc-data:/home/node/.xopc \
  ghcr.io/xopcai/xopc:latest

Wait for the health check:

bash
docker logs -f xopc-gateway

Open http://127.0.0.1:18790 and complete model setup in the web console. Press Ctrl+C to stop following the logs; the container continues running.

Check the installed version and gateway health at any time:

bash
docker exec xopc-gateway xopc --version
curl http://127.0.0.1:18790/api/health

Use a host directory instead ​

A bind mount makes the state files directly available under ~/.xopc on the host:

bash
mkdir -p "$HOME/.xopc/workspace"

docker run -d \
  --name xopc-gateway \
  --restart unless-stopped \
  -p 127.0.0.1:18790:18790 \
  -e TZ=UTC \
  -v "$HOME/.xopc:/home/node/.xopc" \
  ghcr.io/xopcai/xopc:latest

The container runs as the non-root node user (UID 1000). On Linux, ensure that UID 1000 can write the mounted directory. Prefer the Docker-managed volume from the quick start if host permissions are unfamiliar.

Do not run both examples with the same container name. Remove the old container first when switching storage methods:

bash
docker rm -f xopc-gateway

Docker Compose ​

Download the Compose file into an empty directory:

bash
mkdir xopc-docker
cd xopc-docker
curl -fsSLO https://raw.githubusercontent.com/xopcai/xopc/main/docker-compose.yml

Create a .env file in that directory:

dotenv
XOPC_IMAGE=ghcr.io/xopcai/xopc:latest
XOPC_GATEWAY_PORT=18790
XOPC_STATE_DIR=/absolute/path/to/.xopc
XOPC_WORKSPACE=/absolute/path/to/.xopc/workspace
XOPC_TZ=UTC

Replace both /absolute/path/to values with real absolute paths. For example, a Linux user named alice could use /home/alice/.xopc. Do not commit .env if you later add API keys or tokens to it.

Pull and start the published image:

bash
docker compose pull xopc-gateway xopc-cli
docker compose up -d xopc-gateway
docker compose ps

Useful Compose commands:

bash
docker compose logs -f xopc-gateway
docker compose run --rm xopc-cli --version
docker compose restart xopc-gateway
docker compose down

docker compose down removes the containers and network but keeps the host state directory.

Configure environment variables ​

The image reads the same provider variables as the normal xopc installation. Pass a local environment file when needed:

bash
docker run -d \
  --name xopc-gateway \
  --restart unless-stopped \
  --env-file .env \
  -p 127.0.0.1:18790:18790 \
  -v xopc-data:/home/node/.xopc \
  ghcr.io/xopcai/xopc:latest

You can also configure providers in the web console. Keep API keys out of shell history, source control, screenshots, and container logs.

Update ​

Back up the persistent state volume before changing image versions. Stop the Gateway container, then run the offline backup command in a one-off CLI container with a separate persistent mount for the encrypted output and passphrase. Keep the output outside /home/node/.xopc.

Pull the new image and recreate the container. Data remains in xopc-data:

bash
docker pull ghcr.io/xopcai/xopc:latest
docker rm -f xopc-gateway

docker run -d \
  --name xopc-gateway \
  --restart unless-stopped \
  -p 127.0.0.1:18790:18790 \
  -e TZ=UTC \
  -v xopc-data:/home/node/.xopc \
  ghcr.io/xopcai/xopc:latest

With Compose:

bash
docker compose pull
docker compose up -d

For reproducible deployments, change XOPC_IMAGE to a specific version instead of latest.

Expose the gateway to other devices ​

The quick-start command deliberately binds only to localhost. Do not expose an unauthenticated gateway directly to the public internet.

For LAN access, change the port mapping to -p 18790:18790, configure a gateway token, and restrict access with a firewall. For remote access, follow Expose the gateway safely or Remote access.

Troubleshooting ​

SymptomCheck
permission denied under /home/node/.xopcUse the named volume, or allow UID 1000 to write the bind-mounted host directory
Port 18790 is already in useStop the other service or map another host port, for example -p 127.0.0.1:18791:18790; also configure the browser Origin as described below
Container exits immediatelyRun docker logs xopc-gateway
Web console does not openRun docker ps and curl http://127.0.0.1:18790/api/health
Image cannot be pulledConfirm the tag on the package page and retry docker login ghcr.io if the package is private
Local model is unreachableContainers cannot use host 127.0.0.1; use host.docker.internal where supported

When the host and container ports differ, for example with -p 127.0.0.1:18791:18790, the gateway still builds its default browser Origin allowlist from the container port 18790. Add the actual browser address to the host-mounted ~/.xopc/xopc.json; otherwise browser API requests return 403 Origin not allowed:

json
{
  "gateway": {
    "corsOrigins": [
      "http://127.0.0.1:18791",
      "http://localhost:18791"
    ]
  }
}

After saving the file, run docker compose restart xopc-gateway. The Origin must exactly match the scheme, hostname, and port in the browser address bar. Do not use "*" on a network-accessible gateway.

To inspect the container without starting the gateway:

bash
docker run --rm ghcr.io/xopcai/xopc:latest xopc --version

Released under the MIT License.