Deploy Perforce Server into Kubernetes

Why Perforce

Perforce is a version control tool just like git, svn, but optimized for large binary files.

Perforce is widely used by top tier game studios like Naughty Dogs, Electronic Arts and Ubisoft.

To me, the reason I choose Perfoce rather than Git LFS is that I already have a k8s cluster up and running and don't want to buy datapacks on Github as there would be large, large asset files for game projects.


All my nodes are arm64-based AWS virtual machines. Perforce don't maintain Linux packages for arm64 anymore. I tried the way to build docker image by downloading binaries and it worked.

FROM ubuntu:jammy

# Update our main system
RUN apt-get update -y

# Install dependencies
RUN apt-get install -y wget tar

# Set the working directory
WORKDIR /perforce

# Download and extract Perforce binaries
RUN wget https://www.perforce.com/downloads/perforce/r24.1/bin.linux26aarch64/helix-core-server.tgz -O helix-core-server.tgz \
    && tar -xzf helix-core-server.tgz \
    && rm helix-core-server.tgz

# Add Perforce binaries to PATH
ENV PATH="/perforce:${PATH}"

# Define environment variables for Perforce
ENV P4ROOT=/perforce

# Expose the Perforce server port

# Start Perforce server and tail logs
CMD p4d -r /perforce -p $P4PORT -L /perforce/logs/log && tail -F /perforce/logs/log

The download url can be found on official perforce download page. By the time when this article is written, the latest version for helix server is 2024.1/2596294. Be sure to check new releases when you make your own docker image.

Build and push to registry


# Variables
platforms='linux/arm64' # Define platforms

# Extract version from package.json

# Full image tag with version

# Create a new builder instance that supports multi-platform builds, if not already done
docker buildx create --name mymultiarchbuilder --use

# Start up the build instance, if not already done
docker buildx inspect --bootstrap

# Build and push Docker image
docker buildx build --platform $platforms -t $repositoryHost/$repository/$imageTag --push .

K8s Deployment

Everytime I expose a service from my k8s cluster I will consider DDoS problem because you will meet them sooner or later if you don't. Usually I expose them through nodeport + nginx ingress controller, and put them behind cloudflare.

However Perforce is not a http service and cannot be proxied through cloudflare orange cloud. I have to disable orange cloud and access them directly using nodeport. It is not a big problem because I only use it for myself. If the Perforce server is going to be public over the Internet, you will have to consider DDoS protection.


I already have a PVC setup based on juicefs in my k8s cluster, so the pod will not lose any data during redeployments. I mapped data/perforce-root in juicefs for /etc/perforce and /perforce inside container. Make sure to adjust it for your case.

This article doesn't talk about how to deploy juicefs to your k8s cluster as PersistentVolume. They are detailed written in the official documentation of juicefs.

apiVersion: apps/v1
kind: Deployment
  name: perforce-server
  namespace: default
  replicas: 1
      app: perforce-server
        app: perforce-server
        - name: perforce-server
          image: your-registry/helix-core-server:0.0.1
            - containerPort: 1666
            - mountPath: /etc/perforce
              name: perforce-storage
              subPath: data/perforce-root/etc/perfoce
            - mountPath: /perfoce
              name: perforce-storage
              subPath: data/perfoce-root/perfoce
            - name: P4ROOT
              value: /perforce
            - name: P4PORT
              value: "1666"
        - name: perforce-storage
            claimName: juicefs-pvc


apiVersion: v1
kind: Service
  name: perforce-service
  namespace: default
  type: NodePort
    - port: 1666
      targetPort: 1666
    app: perforce-server

Apply them

kubectl apply -f deployment.yaml
kubectl apply -f nodeport.yaml

Check port k8s assigned for perforce-server by

kubectl get svc

In my case the port is 30222. Point your domain to the public IP of node. Your Perforce address is your-domain:30222. Remember to adjust your firewall or other related security policies.

Set Password

Although you can do this step using init containers with some tricks and let k8s do this for you, it is tedious so I just get into the pod and do it manually and only once because the setup will be persistent as the pod is provided with PVC.

Get pod name

kubectl get pods -l app=perforce-server

Then get into it

kubectl exec pod-name-you-just-got -it -- /bin/bash

Enable authorization

p4 protect -o > protections.p4s

In googled results, the usernames of admin are supers but in my protection.p4s I only see a root. Never mind, just set password for root

p4 -u root passwd

Now you can connect to Perforce server using your-domain:30222 with root and password.

You can connect to it with root using p4admin GUI client and create users with normal permission for daily development.


@2024-05-18 16:20