Docker image for running Perforce Helix Core Server
10K+
docker-perforce-helix-coredocker-perforce-helix-core is a Docker image for running Perforce Helix Core
Server. Multi-arch: linux/amd64, linux/arm64.
mkdir -p ./perforce
docker run -d --name p4d \
-p 1666:1666 \
-e P4PORT=1666 \
-v "$(pwd)/perforce:/perforce" \
rayyounghong/perforce-helix-core:latest
The container runs p4d as the non-root perforce user. On first start it
initializes the database under P4ROOT and writes server.id if missing.
services:
p4d:
image: rayyounghong/perforce-helix-core:latest
container_name: p4d
ports:
- "1666:1666"
environment:
- P4PORT=1666
volumes:
- ./perforce:/perforce
restart: unless-stopped
| Variable | Default | Purpose |
|---|---|---|
P4PORT | 1666 | Port p4d listens on |
P4ROOT | /perforce/metadata | Server metadata directory |
P4LOG | /perforce/logs/p4d.log | Server log file |
P4JOURNAL | /perforce/logs/journal | Journal file |
P4SERVERID | master.1 | Value written to server.id |
P4_CLIENT_READONLY_DIR | clientdb | Sets client.readonly.dir (needed for readonly/partitioned/partitioned-jnl workspaces) if not already configured; relative to P4ROOT. Empty to skip. |
/perforce holds all server state (metadata/ and logs/). Mount it as a
named volume or bind mount to persist data across container restarts.
The image ships a healthcheck that runs p4 -p localhost:$P4PORT info every
30 seconds. Use docker ps or docker inspect to see the health status.
The image also ships p4p. Start it with the start-p4p entrypoint:
docker run -d --name p4p -p 1667:1666 \
-e P4TARGET=p4d.example.com:1666 \
-v "$(pwd)/p4p:/perforce" \
--entrypoint /usr/local/bin/start-p4p \
rayyounghong/perforce-helix-core:latest
| Variable | Default | Purpose |
|---|---|---|
P4TARGET | (required) | Upstream server, e.g. p4d:1666 |
P4PORT | 1666 | Port p4p listens on |
P4PCACHE | /perforce/cache | File-content cache directory |
P4LOG | /perforce/logs/p4p.log | Proxy log file |
P4P_EXTRA_ARGS | (empty) | Extra p4p flags, e.g. -c (compress) |
examples/proxy runs a p4d with simulated WAN latency and
bandwidth (via tc netem), three independent p4p proxies in front of it (each
with its own cache, like three remote sites), and a benchmark that compares
p4 sync direct vs. cold vs. warm cache on every proxy:
cd examples/proxy
docker compose up -d --build # WAN_DELAY=50ms WAN_RATE=20mbit by default
./bench.sh # FILES=200 SIZE_KB=256 by default
PROXIES=p4p2 ./bench.sh # benchmark only one proxy
WAN_DELAY=150ms WAN_RATE=5mbit docker compose up -d wan --force-recreate # change link
docker compose down -v # tear down and delete data
An opt-in monitoring profile adds cAdvisor (per-container network/CPU/memory
counters), Prometheus (5s scrape) and Grafana with a pre-provisioned dashboard:
docker compose --profile monitoring up -d
./bench.sh
| UI | URL |
|---|---|
| Grafana | http://localhost:3000 (no login; opens the "Perforce proxy lab" dashboard) |
| Prometheus | http://localhost:9090 |
| cAdvisor | http://localhost:8080 |
Read the dashboard by comparing who sends the bytes: on a direct sync p4d
egress carries the files (capped at WAN_RATE); on a cold-cache proxy sync both
p4d and p4p send them; on a warm-cache sync only p4p does, and p4d stays
near zero. cAdvisor v0.60+ is required on Docker 29 (containerd image store).
The wan container shares p4d's network namespace, so its counters duplicate
p4d's.
| Service | Host port | Role |
|---|---|---|
p4d | 1666 | Server (behind the WAN) |
p4p | 1667 | Proxy 1 |
p4p2 | 1668 | Proxy 2 |
p4p3 | 1669 | Proxy 3 |
From the host, point clients at localhost:1666 (direct) or localhost:1667
to 1669 (proxies). Fresh r26.1 servers default to security=4, so the first user must
set a password (p4 passwd) and p4 login against each port.
Content type
Image
Digest
sha256:e33a3dea6…
Size
60.3 MB
Last updated
about 2 hours ago
docker pull rayyounghong/perforce-helix-core