Socket Proxy
Limit what Arcane can do through the Docker socket by putting a proxy in front of it.
Read Installation first for the encryption key, projects folder, startup, and first login.
Set up the proxy
Section titled “Set up the proxy”- Create a
compose.yamlfrom an example below. Use wollomatic/socket-proxy (what the Instance Generator produces); use Tecnativa only if you already run it. - Replace
<your-encryption-key>with your key and/opt/dockerwith your projects folder. - Run
docker compose up -d. The proxy starts first, then Arcane connects to it through this setting:
DOCKER_HOST=tcp://docker-socket-proxy:2375wollomatic/socket-proxy
Section titled “wollomatic/socket-proxy”services: docker-socket-proxy: image: wollomatic/socket-proxy:1.13.1 container_name: arcane-docker-proxy user: '0:0' command: - '-listenip=0.0.0.0' - '-allowfrom=arcane,arcane-upgrader' - '-allowhealthcheck' - '-allowGET=(/v[\d.]+)?/_ping' - '-allowGET=(/v[\d.]+)?/events(/.*)?' - '-allowGET=(/v[\d.]+)?/version' - '-allowGET=(/v[\d.]+)?/info(/.*)?' - '-allowGET=(/v[\d.]+)?/system/df' - '-allowGET=(/v[\d.]+)?/containers(/.*)?' - '-allowGET=(/v[\d.]+)?/exec(/.*)?' - '-allowGET=(/v[\d.]+)?/images(/.*)?' - '-allowGET=(/v[\d.]+)?/networks(/.*)?' - '-allowGET=(/v[\d.]+)?/volumes(/.*)?' - '-allowGET=(/v[\d.]+)?/distribution(/.*)?' - '-allowGET=(/v[\d.]+)?/swarm(/.*)?' - '-allowGET=(/v[\d.]+)?/nodes(/.*)?' - '-allowGET=(/v[\d.]+)?/services(/.*)?' - '-allowGET=(/v[\d.]+)?/tasks(/.*)?' - '-allowGET=(/v[\d.]+)?/secrets(/.*)?' - '-allowGET=(/v[\d.]+)?/configs(/.*)?' - '-allowHEAD=(/v[\d.]+)?/_ping' - '-allowHEAD=(/v[\d.]+)?/version' - '-allowPOST=(/v[\d.]+)?/containers(/.*)?' - '-allowPOST=(/v[\d.]+)?/exec(/.*)?' - '-allowPOST=(/v[\d.]+)?/images(/.*)?' - '-allowPOST=(/v[\d.]+)?/networks(/.*)?' - '-allowPOST=(/v[\d.]+)?/volumes(/.*)?' - '-allowPOST=(/v[\d.]+)?/commit' - '-allowPOST=(/v[\d.]+)?/build(/.*)?' - '-allowPOST=(/v[\d.]+)?/session' - '-allowPOST=(/v[\d.]+)?/grpc' - '-allowPOST=(/v[\d.]+)?/auth' - '-allowPOST=(/v[\d.]+)?/swarm(/.*)?' - '-allowPOST=(/v[\d.]+)?/nodes(/.*)?' - '-allowPOST=(/v[\d.]+)?/services(/.*)?' - '-allowPOST=(/v[\d.]+)?/secrets(/.*)?' - '-allowPOST=(/v[\d.]+)?/configs(/.*)?' - '-allowPUT=(/v[\d.]+)?/containers(/.*)?' - '-allowDELETE=(/v[\d.]+)?/containers(/.*)?' - '-allowDELETE=(/v[\d.]+)?/images(/.*)?' - '-allowDELETE=(/v[\d.]+)?/networks(/.*)?' - '-allowDELETE=(/v[\d.]+)?/volumes(/.*)?' - '-allowDELETE=(/v[\d.]+)?/nodes(/.*)?' - '-allowDELETE=(/v[\d.]+)?/services(/.*)?' - '-allowDELETE=(/v[\d.]+)?/secrets(/.*)?' - '-allowDELETE=(/v[\d.]+)?/configs(/.*)?' volumes: - /var/run/docker.sock:/var/run/docker.sock:ro read_only: true cap_drop: - ALL security_opt: - no-new-privileges:true healthcheck: test: ['CMD', './healthcheck'] interval: 2s timeout: 5s retries: 15 networks: - arcane-internal restart: unless-stopped
arcane: image: ghcr.io/getarcaneapp/manager:latest container_name: arcane ports: - '3552:3552' volumes: - arcane-data:/app/data - /opt/docker:/opt/docker:z environment: - ARCANE_ENCRYPTION_KEY=<your-encryption-key> - ARCANE_PROJECTS_DIRECTORY=/opt/docker - DOCKER_HOST=tcp://docker-socket-proxy:2375 networks: - arcane-internal depends_on: - docker-socket-proxy healthcheck: test: ['CMD', './arcane', 'health', '--timeout', '2s'] interval: 10s timeout: 3s retries: 5 start_period: 15s restart: unless-stopped
networks: arcane-internal: driver: bridge name: arcane-internal
volumes: arcane-data: name: arcane-datawollomatic blocks any request whose method and path aren’t allowed. The allowlist above is the minimum Arcane needs, including Swarm, builds, commits, BuildKit, registry auth, and image update checks.
-allowfrom=arcane,arcane-upgrader accepts Arcane and its self-upgrade helper. arcane-upgrader is a temporary alias on the helper’s user-defined network, so the helper stays authorized while Arcane is replaced. -allowhealthcheck enables the proxy’s healthcheck. If you rename the Arcane container, replace arcane with its name and keep arcane-upgrader; the proxy and helper must share a user-defined network.
Tecnativa docker-socket-proxy
Section titled “Tecnativa docker-socket-proxy”services: docker-socket-proxy: image: tecnativa/docker-socket-proxy:latest container_name: arcane-docker-proxy environment: - EVENTS=1 - PING=1 - VERSION=1 - AUTH=0 - SECRETS=0 - POST=1 - BUILD=0 - COMMIT=0 - CONFIGS=0 - CONTAINERS=1 - DISTRIBUTION=1 - EXEC=1 - IMAGES=1 - INFO=1 - NETWORKS=1 - NODES=0 - PLUGINS=0 - SERVICES=0 - SESSION=0 - SWARM=0 - SYSTEM=1 - TASKS=0 - VOLUMES=1 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro networks: - arcane-internal restart: unless-stopped security_opt: - no-new-privileges:true
arcane: image: ghcr.io/getarcaneapp/manager:latest container_name: arcane ports: - '3552:3552' volumes: - arcane-data:/app/data - /opt/docker:/opt/docker:z environment: - ARCANE_ENCRYPTION_KEY=<your-encryption-key> - ARCANE_PROJECTS_DIRECTORY=/opt/docker - DOCKER_HOST=tcp://docker-socket-proxy:2375 networks: - arcane-internal depends_on: - docker-socket-proxy healthcheck: test: ['CMD', './arcane', 'health', '--timeout', '2s'] interval: 10s timeout: 3s retries: 5 start_period: 15s restart: unless-stopped
networks: arcane-internal: driver: bridge name: arcane-internal
volumes: arcane-data: name: arcane-dataTecnativa switches API sections with environment variables: 1 allows, 0 blocks.
| Variable | Value | Why |
|---|---|---|
EVENTS, CONTAINERS, EXEC, IMAGES, NETWORKS, VOLUMES |
1 |
Watch Docker activity and manage containers, images, networks, and volumes. |
POST |
1 |
Create and change resources. Without it the proxy is read-only. |
DISTRIBUTION |
1 |
Inspect images and check for image updates. |
PING, VERSION, INFO |
1 |
Health checks and Docker version and system info. |
SYSTEM |
1 |
Allow /system/df, which scheduled pruning requires. |
AUTH, SECRETS |
0 |
Block authentication and Docker secrets APIs. |
BUILD, COMMIT, CONFIGS, NODES, SERVICES, SWARM, TASKS |
0 |
Block image builds, commits, and Swarm. |
PLUGINS, SESSION |
0 |
Block plugin and session APIs. |