{"id":13588597,"url":"https://github.com/shepherdjerred/homelab","last_synced_at":"2025-04-05T03:30:44.430Z","repository":{"id":36980016,"uuid":"456264103","full_name":"shepherdjerred/homelab","owner":"shepherdjerred","description":"Configuration-as-code for my homelab","archived":false,"fork":false,"pushed_at":"2025-03-31T02:55:10.000Z","size":12704,"stargazers_count":20,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-02T10:52:25.156Z","etag":null,"topics":["cdk8s","kubernetes","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shepherdjerred.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}},"created_at":"2022-02-06T20:28:07.000Z","updated_at":"2025-03-31T02:49:10.000Z","dependencies_parsed_at":"2024-03-01T06:32:58.596Z","dependency_job_id":"3f5d6a6a-17a2-46b5-a903-43a9ffb48a6d","html_url":"https://github.com/shepherdjerred/homelab","commit_stats":null,"previous_names":["shepherdjerred/homelab"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shepherdjerred%2Fhomelab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shepherdjerred%2Fhomelab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shepherdjerred%2Fhomelab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shepherdjerred%2Fhomelab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shepherdjerred","download_url":"https://codeload.github.com/shepherdjerred/homelab/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284911,"owners_count":20913691,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cdk8s","kubernetes","typescript"],"created_at":"2024-08-01T15:06:48.685Z","updated_at":"2025-04-05T03:30:44.407Z","avatar_url":"https://github.com/shepherdjerred.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Homelab\n\n[![Renovate enabled](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com/)\n![ArgoCD badge](https://argocd.tailnet-1a49.ts.net/api/badge?name=lamport)\n\nThis repository contains resources related to my homelab, currently called\n`lamport`. I give each of my servers a unique name so that I can keep track of\nthem over time.\n\nCurrently my server is managed with Kubernetes. I've used Docker, Ansible, and\nbash scripts in the past. Kubernetes has been an interesting experiment and I\nthink it's overall worthwhile since the ecosystem is so rich.\n\n## Details\n\nI've spent a _lot_ of time making this project pleasant to work with. Here are\nsome things I'm proud of:\n\n- Close to zero host setup\n  - It's literally just a few commands to deploy my entire cluster\n- Entirely written in TypeScript built with [cdk8s](https://cdk8s.io/) and\n  [Deno](https://deno.com/)\n- Automated backups\n  - The applications I care about are regularly backed up to\n    [BorgBase](https://www.borgbase.com/)\n- HTTPS ingress with [Tailscale](https://tailscale.com/)\n- All secrets managed with [1Password](https://1password.com/)\n- Jenkins CI w/ Earthly used by my open-source projects\n- Entirely automated deployment for updates, upgrades, etc.\n  - Commit-to-deployment takes about 1min\n- Automated dependency updates\n  - For Docker images (w/ pinned SHAs)\n  - For Helm charts\n  - For Kubernetes/k3s\n  - For Jenkins plugins\n  - For Deno dependencies\n  - [My approach](https://github.com/shepherdjerred/homelab/blob/main/cdk8s/src/versions.ts)\n    allows all of my dependencies to be pinned and updated regularly\n\n## Installation\n\nThese instructions are for future me, so that I can re-create my cluster from\nscratch if needed.\n\n### Host Setup\n\nAt some point I should automate these steps, either as a part of a script, my\ndotfiles, ansible, etc.\n\n- Install Tailscale\n- Install Linuxbrew\n- Install fish, vim, helix, rtx, languages (Deno), etc.\n- Set fish as the default shell\n- Configure fish\n- Setup auto-updates with Ubuntu\n\n  - \u003chttps://help.ubuntu.com/community/AutomaticSecurityUpdates\u003e\n\n- Set `KUBE_CONFIG`\n- Update kernel parameters:\n  \u003chttps://docs.k3s.io/security/hardening-guide#set-kernel-parameters\u003e\n- Increase number of file watchers:\n\n  ```\n  sudo sysctl -w fs.inotify.max_user_watches=1990692\n  sudo sysctl -w fs.inotify.max_user_instances=512\n  sudo sysctl -w fs.inotify.max_queued_events=65536\n  ```\n\n### Cluster Setup\n\n1. Copy `k3s` to `/etc/rancher/k3s/`\n\n   ```bash\n   sudo cp -r k3s/. /etc/rancher/k3s/\n   ```\n\n1. Install k3s.\n\n   ```bash\n   curl -sfL https://get.k3s.io | sh -\n   ```\n\n1. Copy the Kubernetes configuration\n\n   ```bash\n   rm -rfv ~/.kube \u0026\u0026 mkdir ~/.kube \u0026\u0026 sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config \u0026\u0026 sudo chown $USER:$USER ~/.kube/config \u0026\u0026 chmod 600 ~/.kube/config\n   ```\n\n1. Install `helm`.\n\n   ```bash\n   brew install helm\n   ```\n\n1. Install Argo CD manually.\n\n   \u003e [!NOTE] This will be imported into Argo CD itself as part of the CDK8s\n   \u003e manifest\n\n   ```bash\n   kubectl create namespace argocd\n   helm repo add argo https://argoproj.github.io/argo-helm\n   helm install argocd argo/argo-cd --namespace argocd\n   ```\n\n1. Set the credentials in the `secrets` directory.\n\n   - Be sure not to commit any changes to these files so that secrets don't\n     leak.\n   - These should be the only credentials that are manually set. Everything else\n     can be retrieved from 1Password.\n   - Annoyingly, the credential in `1password-secret.yaml` _must_ be base64\n     encoded.\n\n     ```bash\n     cat 1password-credentials.json | base64 -w 0\n     ```\n\n     ```bash\n     kubectl create namespace 1password\n     kubectl apply -f secrets/1password-secret.yaml\n     kubectl apply -f secrets/1password-token.yaml\n     ```\n\n1. Build and deploy the manifests in this repo\n\n   ```bash\n   cd cdk8s \u0026\u0026 deno task up\n   ```\n\n1. Get the initial Argo CD `admin` password.\n\n   ```bash\n   kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath=\"{.data.password}\" | base64 -d\n   ```\n\n1. Change Argo CD the `admin` password.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshepherdjerred%2Fhomelab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshepherdjerred%2Fhomelab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshepherdjerred%2Fhomelab/lists"}