{"id":43831329,"url":"https://github.com/haiku/infrastructure","last_synced_at":"2026-02-06T03:15:43.774Z","repository":{"id":25991368,"uuid":"100975785","full_name":"haiku/infrastructure","owner":"haiku","description":"Haiku infrastructure as code","archived":false,"fork":false,"pushed_at":"2026-01-30T16:03:27.000Z","size":9640,"stargazers_count":23,"open_issues_count":19,"forks_count":18,"subscribers_count":10,"default_branch":"main","last_synced_at":"2026-01-30T18:56:33.024Z","etag":null,"topics":["docker","haiku","infrastructure"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/haiku","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/haiku.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-08-21T17:19:21.000Z","updated_at":"2026-01-30T16:03:31.000Z","dependencies_parsed_at":"2023-10-01T16:33:38.693Z","dependency_job_id":"3b41d53c-b979-4ece-bec3-6135325f2985","html_url":"https://github.com/haiku/infrastructure","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/haiku/infrastructure","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haiku%2Finfrastructure","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haiku%2Finfrastructure/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haiku%2Finfrastructure/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haiku%2Finfrastructure/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haiku","download_url":"https://codeload.github.com/haiku/infrastructure/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haiku%2Finfrastructure/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29147521,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T02:39:25.012Z","status":"ssl_error","status_checked_at":"2026-02-06T02:37:22.784Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","haiku","infrastructure"],"created_at":"2026-02-06T03:15:43.702Z","updated_at":"2026-02-06T03:15:43.765Z","avatar_url":"https://github.com/haiku.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Infrastructure as code\n\nTreating Haiku's infrastructure as cattle instead of kittens since 2017.\n\n## Directories\n\n  * docs - Full documentation on Haiku's infrastructure\n  * containers - Manifests to build and deploy containers\n  * deployments - Kubernetes manifests for Haiku infrastructure\n  * playground - Things that we're experimenting with. Not used in production.\n\n# Architecture\n\n![Architecture](docs/architecture.png)\n\n# Quickstart\n\nThese are the path of least resistance for new admins to do \"things\"\n\n| :boom: DANGER                                                        |\n|:---------------------------------------------------------------------|\n|*Never* run ```kubectl delete``` on persistent volume claims you need! Running ```kubectl delete``` / ```kubectl delete -f ``` on things describing volume claims will result in Kubernetes dropping (deleting) persistant volumes. (AKA massive + rapid data loss)|\n\nRunning through the [Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) class is recommended!\n\n## Pre-requirements\n\n* Install kubectl\n* Export the Kubernetes configuration from Digital Ocean, import locally\n  * If this is your first kubernetes cluster, just put it at ```~/.kube/config```\n\n## Quick Commands\n\n\u003e aka, i'm a sysadmin and a dog in a lab-coat\n\n### Check your configured cluster\n\n*List the known Kubernetes Clusters (contexts) of my client:*\n```\nkubectl config get-contexts\n```\n\n*Change the Kubernetes Cluster my local client focuses on:*\n```\nkubectl config use-context (NAME)\n```\n\n### List Deployments\n\n\u003e Deployments are \"how many desired sets of pods\" within the cluster.\n\n```\nkubectl get deployments\n```\n\n### Scaling Deployments\n\nIf you want something to \"stop running for a while\", this is the easiest\nand safest way.  NEVER run ```kubectl delete``` if you don't know what\nyou're doing.\n\n```\nkubectl scale --replicas=0 deployments/(NAME)\n```\n\n### List Pods\n\n\u003e Pods are one or more tightly related containers running in Kubernetes\n\u003e Deleting a Pod will result in the related deployment recreating it.\n\n### Entering a container\n\naka, equavient to ```docker exec -it (NAME) /bin/bash -l...```\n\nIf the pod has one container:\n\n```\nkubectl exec -it pod/(NAME) -- /bin/bash -l\n```\n\nIf the pod has multiple containers:\n\n```\nkubectl exec -it pod/(NAME) -c containername -- /bin/bash -l\n```\n\n### Examining Stuff\n\n```\nkubectl describe pod/(NAME)\nkubectl describe deployment/(NAME)\n```\n\n## Initial Installation\n\n* Deploy ingress controller via instructions in deployments/ingress-controller/traefik\n* Deploy manifests in deployments for various services\n* Scale each deployment to 0 replicas\n  * ```kubectl scale --replicas=0 deployments/(BLAH)```\n* Populate persistent volumes for each application\n  * see tools/migration_tools for some scripts to do this en-masse via rsync\n* Once ready for switchover, adjust DNS to new load balancer\n* Scale up applications\n* ```kubectl scale --replicas=1 deployments/(BLAH)```\n\n## Rolling Restarts\n\n*To perform a rolling restart of each deployment replica:*\n```\nkubectl rollout restart deployment/(NAME)\n```\n\n### Example\n\n\u003e -n kube-system is the namespace. We run Traefik in a seperate namespace since it's important.\n\n*Rolling restart of Traefik:*\n```\nkubectl -n kube-system rollout restart daemonset/traefik-ingress-controller\n```\n\n## Rolling Upgrade\n\nHere we upgrade a container image from the command line.  You can also update the matching yml document\nand run ```kubectl apply -f (thing).yml```\n\n### Example\n\n\u003e -n kube-system is the namespace. We run Traefik in a seperate namespace since it's important.\n\n*Rolling upgrade of Traefik:*\n```\nkubectl -n kube-system set image daemonset/traefik-ingress-controller traefik-ingress-lb=docker.io/traefik:v2.6\n```\n\n## Accessing Services / Pods\n\nYou can port-forward / tunnel from various points within the Kubernetes cluster to your local desktop. This is really\nuseful for troubleshooting or understanding issues better.\n\n*Listen on localhost port 8888, to port 9999 within the pod*\n```\nkubectl port-forward pod/(NAME) 8888:9999\n```\n\n*Listen on localhost port 8080, to named port web of the service*\n```\nkubectl port-forward service/(NAME) 8080:web\n```\n\nPressing ctl+c will terminate the port-forwarding proxy\n\n## Importing data\n\n*Restoring volume / database backups:*\n**See deployments/other/restore*.yml**\n\n*Manual database import:*\n```cat coolstuff.sql | kubectl exec -i deployment/postgres -- psql -U postgres```\n\n## Forcing CronJobs\n\nWe leverage multiple jobs to perform various automatic activities within kubernetes. Some example\njobs include postgresql backups to s3, persistent volume backups to s3, and syncing various git\nrepositories.\n\nOnce and a while, you may want to force these jobs to run before performing maintenance, or for\ntesting purposes.\n\n* pgbackup - PostgreSQL backup jobs\n* pvbackup - Persistent volume backup jobs\n\n\u003e There are several example restore jobs in deployments/other.  These can be manually edited\n\u003e and applied to restore data.  It's highly recommended to review these CAREFULLY before use\n\u003e as a mistake could result in unattended data loss.\n\u003e\n\u003e These restore jobs should be used on empty databases / persistent volumes only!\n\n1. Listing CronJobs\n    ```\n    $ kubectl get cronjobs\n    NAME                        SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE\n    discourse-pgbackup          0 0 * * 1,4   False     0        2d14h           6d13h\n    discourse-pvbackup          0 3 * * 3     False     0        11h             6d17h\n    gerrit-github-sync          0 * * * *     False     0        38m             13d\n    gerrit-pvbackup             0 1 * * 1,4   False     0        2d13h           8d\n    haikudepotserver-pgbackup   0 0 * * 1,4   False     0        2d14h           3d21h\n    .\n    ```\n2. Forcing a CronJob to run\n    This is a great thing to do before any maintenance :-)\n    ```\n    $ kubectl create job --from=cronjob/discourse-pgbackup discourse-pgbackup-manual-220316\n    ```\n3. Monitoring manual CronJob\n    ```\n    $ kubectl get jobs\n    NAME                                 COMPLETIONS   DURATION   AGE\n    discourse-pgbackup-manual-220316     1/1           1m         1m\n\n    $ kubectl logs jobs/discourse-pgbackup-manual-220316\n    Backup discourse...\n    Backup complete!\n    Encryption complete!\n    Added `s3remote` successfully.\n    `/tmp/discourse_2022-03-14.sql.xz.gpg` -\u003e `s3remote/haiku-backups/pg-discourse/discourse_2022-03-14.sql.xz.gpg`\n    Total: 0 B, Transferred: 136.45 MiB, Speed: 77.32 MiB/s\n    Snapshot of discourse completed successfully! (haiku-backups/pg-discourse/discourse_2022-03-14.sql.xz.gpg)\n    ```\n\n# Secrets\n\nFor obvious reasons, :key: secrets are omitted from this repository.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaiku%2Finfrastructure","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhaiku%2Finfrastructure","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaiku%2Finfrastructure/lists"}