Skip to content

Installing with Docker

services:
proxploy:
image: ghcr.io/aspyrelabs/proxploy:latest
restart: unless-stopped
ports: ["8080:8000"]
volumes: ["proxploy-data:/var/lib/proxploy"]
volumes:
proxploy-data:

Proxmox VE itself listens on 8006, so this example does not use that host port: running Compose on the same node you’re managing would otherwise collide with Proxmox’s own web UI. Pick whatever free host port you like, 8080 is just this example’s choice.

Bring it up with docker compose up -d and browse to http://<host>:8080/ to create the first account. All application state (database, master key, uploads) lives in the proxploy-data volume, outside the image, exactly the same separation the lxc and systemd shapes keep between /opt/proxploy/releases/ and /var/lib/proxploy/.

Unlike the lxc and systemd shapes, this compose file puts nothing in front of the app for TLS. Put your own reverse proxy in front if you need one, the same way you would for any other self-hosted compose service.

Proxploy only honours X-Forwarded-For from peer addresses it has been told to trust, and that list defaults to 127.0.0.1. In the compose shape above the port is published directly, so the peer the container sees is the Docker bridge gateway rather than localhost, meaning the client IP recorded in the audit log is that gateway address for every request. If you do put a proxy in front, set FORWARDED_ALLOW_IPS in the service’s environment: to that proxy’s address as the container sees it, and don’t set it to * while the port is still published directly: anyone who can reach the port could then forge the address that lands in your audit log.

A Docker install never applies its own updates. Calling POST /meta/update on a Docker install returns 409 Conflict with docker compose pull && docker compose up -d as the instruction, instead of performing an update.

This is a deliberate capability decision, not a missing feature. The in-app updater (see Updating Proxploy) works by swapping a symlink between versioned release directories on the host filesystem and restarting a systemd unit, neither of which makes sense from inside a container whose entire filesystem is the release. Asking Docker Compose to pull and recreate the container is the correct way to update a containerized service, and it is what docker compose pull && docker compose up -d does: pull the new image tag, then recreate the container against the same named volume, so your data survives the swap exactly as it does on the other two shapes.

GET /meta/update still works normally on a Docker install: it reports the current version and whether a newer one is available; only the self-apply action is refused.