Self-hosted deployment of Patchworks Core via Helm.
The deployment is available as a legacy all-in-one chart and as two split charts:
charts/patchworks-infra: baseline infrastructure, including MySQL, Redis, RabbitMQ, Elasticsearch, S3/MinIO, Soketi, KubeFaaS, and generated infra credentials.charts/patchworks-app: Patchworks application resources, migrations, seeders, workers, S3 Manager, and ingress.
For GitOps/Argo installs, use the split charts with one shared values file.
For an existing Kubernetes cluster, see the standalone self-hosted getting started guide.
Stand up a complete local environment with kind (Kubernetes in Docker). Everything runs in-cluster — MySQL, Redis, RabbitMQ, Elasticsearch, MinIO, S3 Manager, and the Patchworks application itself.
Total time: ~10 minutes.
| Tool | Install |
|---|---|
| Docker | Desktop or Engine 20+ |
| kind | brew install kind |
| kubectl | brew install kubectl |
| Helm | brew install helm |
kind create cluster --config docs/kind/cluster.yamlThe cluster config maps host ports 80 and 443 to the node (used if you later add an ingress controller) and labels the node ingress-ready.
Confirm it's up:
kubectl cluster-info --context kind-patchworks
kubectl get nodeshelm dependency update charts/patchworks-infraDownloads optional chart dependencies, including the upstream Soketi sub-chart
used only when soketi.subchart.enabled=true. Only needed once (or after
updating Chart.yaml).
The infra chart creates the baseline services. By default, empty in-cluster
credentials are generated once by a pre-install hook and stored in Secrets such
as patchworks-mysql-auth, patchworks-rabbitmq-auth,
patchworks-elasticsearch-auth, and patchworks-s3-auth.
helm install patchworks-infra ./charts/patchworks-infra \
-f docs/kind/values.yaml \
--timeout 10m \
--waithelm install patchworks-app ./charts/patchworks-app \
--set app.url="http://localhost:8080" \
-f docs/kind/values.yaml \
--timeout 10m \
--waitUse the same values file for both charts. The app chart resolves empty
in-cluster credentials to the Secrets generated by the infra chart. Migrations
run as pre-install,pre-upgrade hooks; seeders run as pre-install hooks.
Fabric seeders run before Core migrations, and Core seeders run after Core
migrations. If app.key is empty, the app chart generates a stable APP_KEY
Secret automatically.
kubectl get pods --watchStartup takes 3–7 minutes on a typical laptop — Elasticsearch is usually the slowest. When complete:
NAME READY STATUS RESTARTS
patchworks-elasticsearch-xxxx 1/1 Running 0
patchworks-fabric-seeds-xxxx 0/1 Completed 0
patchworks-core-migrations-xxxx 0/1 Completed 0
patchworks-core-seeds-xxxx 0/1 Completed 0
patchworks-mysql-xxxx 1/1 Running 0
patchworks-rabbitmq-xxxx 1/1 Running 0
patchworks-redis-xxxx 1/1 Running 0
patchworks-s3-xxxx 1/1 Running 0
patchworks-s3-manager-xxxx 1/1 Running 0
patchworks-gateway-xxxx 1/1 Running 0
patchworks-start-xxxx 1/1 Running 0
patchworks-workers-xxxx 1/1 Running 0
patchworks-processor-start-xxxx 1/1 Running 0
patchworks-processor-gateway-xxxx 1/1 Running 0
patchworks-processor-short-processor-xxxx 1/1 Running 0
patchworks-processor-medium-processor-xxxx 1/1 Running 0
patchworks-processor-long-processor-xxxx 1/1 Running 0
kubectl port-forward svc/patchworks-gateway 8080:80Open http://localhost:8080.
# Tail application logs
kubectl logs -l app.kubernetes.io/component=gateway -f
kubectl logs -l app.kubernetes.io/component=workers -f
# Run an artisan command
kubectl exec -it deploy/patchworks-gateway -- php artisan <command>
# Open a MySQL shell
kubectl exec -it deploy/patchworks-mysql -- mysql -upatchworks -p core
# MinIO console. The password is generated in patchworks-s3-auth by default.
kubectl port-forward svc/patchworks-s3 9001:9001
# Open http://localhost:9001
# Upgrade after a values change
helm upgrade patchworks-infra ./charts/patchworks-infra \
-f docs/kind/values.yaml \
--timeout 10m \
--wait
helm upgrade patchworks-app ./charts/patchworks-app \
--set app.url="http://localhost:8080" \
-f docs/kind/values.yaml \
--timeout 10m \
--waitIf you prefer hostnames to port-forward, install Contour and enable ingress:
./docs/kind/setup-contour.shAdd the hostnames to /etc/hosts:
echo "127.0.0.1 patchworks.local core.local start.local webhooks.local callbacks.local fabric.local" | sudo tee -a /etc/hostsThen upgrade the release with ingress enabled:
helm upgrade patchworks-app ./charts/patchworks-app \
-f docs/kind/values.yaml \
--set ingress.enabled=true \
--set ingress.className=contour \
--set ingress.hosts.gateway=core.local \
--set ingress.hosts.start=start.local \
--set ingress.hosts.webhook=webhooks.local \
--set ingress.hosts.callback=callbacks.local \
--set ingress.hosts.fabric=fabric.local \
--set ingress.hosts.dashboard=patchworks.local \
--namespace patchworks \
--timeout 5m \
--waitThe dashboard is then available at http://patchworks.local.
kind delete cluster --name patchworksRemoves all containers and volumes. Nothing persists to the host.
Pods stuck in Pending
Usually resource pressure. Docker Desktop on macOS defaults to 2 CPUs and 2 GB RAM — increase to at least 4 CPUs and 6 GB in Docker Desktop → Settings → Resources.
kubectl describe node patchworks-control-plane
kubectl describe pod <stuck-pod>Elasticsearch stuck in Init:0/1
The init container sets vm.max_map_count on the node via a privileged sysctl. If it fails, set it directly:
docker exec patchworks-control-plane sysctl -w vm.max_map_count=262144
kubectl delete pod -l app.kubernetes.io/component=elasticsearchMigrations Job failed
The Job waits for all infrastructure before running. Check which dependency isn't ready:
kubectl logs job/patchworks-migrations -c wait-for-deps
kubectl logs job/patchworks-migrationsA helm upgrade triggers a fresh Job run.
Full configuration references are in the infra chart README, the app chart README, and the legacy all-in-one chart README.
| Infra chart configuration reference | Infrastructure values and generated credentials |
| App chart configuration reference | Application values, migrations, seeders, workers, and ingress |
| Legacy chart configuration reference | All-in-one chart values |
| Chart overview diagram | Every managed component and how they connect |
| Worker modes diagram | Standalone, microservice, and mono worker types |