# VoCat Docker Compose deployment. # # First-time setup (password is read from stdin and stored only in SQLite): # docker compose pull # read -rsp "Admin password: " VOCAT_BOOTSTRAP_PASSWORD; echo # printf '%s\n' "$VOCAT_BOOTSTRAP_PASSWORD" | docker compose run --rm -T \ # --entrypoint /opt/vocat/bin/vocat vocat bootstrap-admin # unset VOCAT_BOOTSTRAP_PASSWORD # docker compose up -d # # Build locally from this repo instead of using the GHCR image: # docker compose up -d --build # # In-container binary self-update is intentionally disabled (VOCAT_CONTAINER=docker # makes the server return 409 on the apply endpoint). Update by pulling a new # image and recreating the container: # docker compose pull && docker compose up -d services: vocat: # Use the prebuilt multi-arch image from GHCR. Override with # --build to compile from the local Dockerfile instead. image: ghcr.io/mengmengcode/vocat:latest pull_policy: missing build: context: . dockerfile: Dockerfile container_name: vocat restart: unless-stopped # Host network mode: the export-proxy plugin uses SO_BINDTODEVICE to pin # outbound proxy traffic to the modem interface (wwan0) so roaming data # egresses only the module — never the host's default route. That syscall # needs the host network namespace visible inside the container, which # network_mode: host provides directly. Port publishing is therefore # meaningless (the container shares the host stack and vocat binds # 0.0.0.0:7575 itself); proxy ports opened by the plugin are likewise # reachable on the host IP without explicit mapping. network_mode: host # Modem/QMI/USB-reader hot-plug uses dynamic character devices. Privileged # mode mirrors the documented hardware-access docker run command and also # supplies the raw-socket/netlink permissions needed by VoWiFi/IPsec. privileged: true user: "0:0" environment: # Marks the process as containerized: the web UI then advertises # "pull new image" instead of attempting an in-place binary update. VOCAT_CONTAINER: docker # VOCAT_ADDR / VOCAT_DATABASE_PATH are set in the Dockerfile. Admin # credentials are stored only in SQLite and are not process environment. volumes: # SQLite database + persistent state. - vocat-data:/opt/vocat/data # Required for modem, MHI/WWAN and PC/SC USB-reader discovery, including # devices added after the container starts. - /dev:/dev # Writable sysfs lets VoCat bind the exact Sierra EM7430 1199:9077 ID to # the serial driver when a distro's kernel table does not contain it. - /sys:/sys # modprobe inside the privileged container uses the host kernel's module # tree; keep the tree itself read-only. - /lib/modules:/lib/modules:ro volumes: vocat-data: