2026-02-03 20:17:24 -08:00
---
2026-02-07 21:44:57 -08:00
title: Deploy K8s Service
Doc review: connect-to-postgres, create-release-artifact-workflow, deploy-k8s-service (#191)
## Summary
Review session covering 3 docs, plus a codebase-wide cleanup:
### Docs reviewed
- **connect-to-postgres** — verified end-to-end (psql connection tested), stamped
- **create-release-artifact-workflow** — clarified that `build-blumeops.yaml` is only a version bump example (not a packages API example)
- **deploy-k8s-service** — fixed stale repoURL (`indri:2200` → `forge.ops.eblu.me:2222`), wrong Caddy config keys (`upstream` → `backend`, added missing `host`), updated Homepage group to "Services", added Tailscale tag documentation
### Codebase cleanup
- Migrated all remaining `op item get --fields` calls to `op read` URI syntax across 7 files (docs, READMEs, YAML comments)
- Simplified the `op read` vs `op item get` guidance in CLAUDE.md
## Side findings (not addressed)
- New `immich-pg` CNPG cluster not yet documented in the postgresql reference card
## Test plan
- [x] `psql` connection to `pg.ops.eblu.me` verified
- [x] All pre-commit hooks pass
- [x] `docs-check-links`, `docs-check-index`, `docs-check-frontmatter` pass
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/191
2026-02-15 07:42:01 -08:00
modified: 2026-02-15
last-reviewed: 2026-02-15
2026-02-03 20:17:24 -08:00
tags:
- how-to
- kubernetes
- argocd
---
# Deploy a Kubernetes Service
Quick reference for deploying a new service to BlumeOps Kubernetes via ArgoCD. See [[adding-a-service|the tutorial]] for detailed explanations.
## Create Manifests
```
argocd/manifests/<service>/
├── deployment.yaml
├── service.yaml
└── ingress-tailscale.yaml
```
Namespace should match service name. Use `registry.ops.eblu.me` for images.
## Create ArgoCD Application
```yaml
# argocd/apps/<service>.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: <service>
namespace: argocd
spec:
project: default
source:
Doc review: connect-to-postgres, create-release-artifact-workflow, deploy-k8s-service (#191)
## Summary
Review session covering 3 docs, plus a codebase-wide cleanup:
### Docs reviewed
- **connect-to-postgres** — verified end-to-end (psql connection tested), stamped
- **create-release-artifact-workflow** — clarified that `build-blumeops.yaml` is only a version bump example (not a packages API example)
- **deploy-k8s-service** — fixed stale repoURL (`indri:2200` → `forge.ops.eblu.me:2222`), wrong Caddy config keys (`upstream` → `backend`, added missing `host`), updated Homepage group to "Services", added Tailscale tag documentation
### Codebase cleanup
- Migrated all remaining `op item get --fields` calls to `op read` URI syntax across 7 files (docs, READMEs, YAML comments)
- Simplified the `op read` vs `op item get` guidance in CLAUDE.md
## Side findings (not addressed)
- New `immich-pg` CNPG cluster not yet documented in the postgresql reference card
## Test plan
- [x] `psql` connection to `pg.ops.eblu.me` verified
- [x] All pre-commit hooks pass
- [x] `docs-check-links`, `docs-check-index`, `docs-check-frontmatter` pass
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/191
2026-02-15 07:42:01 -08:00
repoURL: ssh://forgejo@forge .ops.eblu.me:2222/eblume/blumeops.git
2026-02-03 20:17:24 -08:00
targetRevision: main
path: argocd/manifests/<service>
destination:
server: https://kubernetes.default.svc
namespace: <service>
syncPolicy:
syncOptions:
- CreateNamespace=true
```
## Configure Ingress
2026-02-11 21:10:42 -08:00
Add a [[tailscale-operator|Tailscale Ingress]] routed through the ProxyGroup with Homepage annotations:
2026-02-03 20:17:24 -08:00
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
2026-02-11 21:10:42 -08:00
name: <service>-tailscale
2026-02-03 20:17:24 -08:00
namespace: <service>
annotations:
2026-02-11 21:10:42 -08:00
tailscale.com/proxy-class: "default"
tailscale.com/proxy-group: "ingress"
2026-02-03 20:17:24 -08:00
gethomepage.dev/enabled: "true"
gethomepage.dev/name: "Service Name"
Doc review: connect-to-postgres, create-release-artifact-workflow, deploy-k8s-service (#191)
## Summary
Review session covering 3 docs, plus a codebase-wide cleanup:
### Docs reviewed
- **connect-to-postgres** — verified end-to-end (psql connection tested), stamped
- **create-release-artifact-workflow** — clarified that `build-blumeops.yaml` is only a version bump example (not a packages API example)
- **deploy-k8s-service** — fixed stale repoURL (`indri:2200` → `forge.ops.eblu.me:2222`), wrong Caddy config keys (`upstream` → `backend`, added missing `host`), updated Homepage group to "Services", added Tailscale tag documentation
### Codebase cleanup
- Migrated all remaining `op item get --fields` calls to `op read` URI syntax across 7 files (docs, READMEs, YAML comments)
- Simplified the `op read` vs `op item get` guidance in CLAUDE.md
## Side findings (not addressed)
- New `immich-pg` CNPG cluster not yet documented in the postgresql reference card
## Test plan
- [x] `psql` connection to `pg.ops.eblu.me` verified
- [x] All pre-commit hooks pass
- [x] `docs-check-links`, `docs-check-index`, `docs-check-frontmatter` pass
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/191
2026-02-15 07:42:01 -08:00
gethomepage.dev/group: "Services"
2026-02-03 20:17:24 -08:00
gethomepage.dev/icon: "<service>.png"
gethomepage.dev/href: "https://<service>.ops.eblu.me"
gethomepage.dev/pod-selector: "app=<service>"
spec:
ingressClassName: tailscale
2026-02-11 21:10:42 -08:00
defaultBackend:
service:
name: <service>
port:
number: 80
tls:
- hosts:
- <service>
2026-02-03 20:17:24 -08:00
```
2026-02-11 21:10:42 -08:00
Key points:
- **`proxy-group: "ingress"` ** routes through the shared ProxyGroup instead of spawning a per-ingress proxy
- **Do not use `rules:` with `host:` ** — the ProxyGroup proxy receives the FQDN as Host header (e.g. `<service>.tail8d86e.ts.net` ), so a short `host: <service>` won't match. Use `defaultBackend` instead.
- **`tls.hosts` ** sets the MagicDNS hostname (becomes `<service>.tail8d86e.ts.net` )
Doc review: connect-to-postgres, create-release-artifact-workflow, deploy-k8s-service (#191)
## Summary
Review session covering 3 docs, plus a codebase-wide cleanup:
### Docs reviewed
- **connect-to-postgres** — verified end-to-end (psql connection tested), stamped
- **create-release-artifact-workflow** — clarified that `build-blumeops.yaml` is only a version bump example (not a packages API example)
- **deploy-k8s-service** — fixed stale repoURL (`indri:2200` → `forge.ops.eblu.me:2222`), wrong Caddy config keys (`upstream` → `backend`, added missing `host`), updated Homepage group to "Services", added Tailscale tag documentation
### Codebase cleanup
- Migrated all remaining `op item get --fields` calls to `op read` URI syntax across 7 files (docs, READMEs, YAML comments)
- Simplified the `op read` vs `op item get` guidance in CLAUDE.md
## Side findings (not addressed)
- New `immich-pg` CNPG cluster not yet documented in the postgresql reference card
## Test plan
- [x] `psql` connection to `pg.ops.eblu.me` verified
- [x] All pre-commit hooks pass
- [x] `docs-check-links`, `docs-check-index`, `docs-check-frontmatter` pass
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/191
2026-02-15 07:42:01 -08:00
- **`gethomepage.dev/group` ** — use one of the existing groups: "Services", "Content", or "Infrastructure"
- **`tailscale.com/tags` ** is not needed in the default case — the ProxyGroup already applies `tag:k8s` . Only add this annotation when the service needs public internet access via the [[flyio-proxy]]. When you do, you must include both tags (setting tags overrides the ProxyGroup default):
```yaml
tailscale.com/tags: "tag:k8s,tag:flyio-target"
```
Then add a Caddy route and Fly.io proxy config per [[expose-service-publicly]].
2026-02-11 21:10:42 -08:00
2026-02-03 20:17:24 -08:00
## Add Caddy Route (if needed)
If other pods need to access the service, add to `ansible/roles/caddy/defaults/main.yml` :
```yaml
caddy_services:
- name: <service>
Doc review: connect-to-postgres, create-release-artifact-workflow, deploy-k8s-service (#191)
## Summary
Review session covering 3 docs, plus a codebase-wide cleanup:
### Docs reviewed
- **connect-to-postgres** — verified end-to-end (psql connection tested), stamped
- **create-release-artifact-workflow** — clarified that `build-blumeops.yaml` is only a version bump example (not a packages API example)
- **deploy-k8s-service** — fixed stale repoURL (`indri:2200` → `forge.ops.eblu.me:2222`), wrong Caddy config keys (`upstream` → `backend`, added missing `host`), updated Homepage group to "Services", added Tailscale tag documentation
### Codebase cleanup
- Migrated all remaining `op item get --fields` calls to `op read` URI syntax across 7 files (docs, READMEs, YAML comments)
- Simplified the `op read` vs `op item get` guidance in CLAUDE.md
## Side findings (not addressed)
- New `immich-pg` CNPG cluster not yet documented in the postgresql reference card
## Test plan
- [x] `psql` connection to `pg.ops.eblu.me` verified
- [x] All pre-commit hooks pass
- [x] `docs-check-links`, `docs-check-index`, `docs-check-frontmatter` pass
Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/191
2026-02-15 07:42:01 -08:00
host: "<service>.{{ caddy_domain }}"
backend: "https://<service>.tail8d86e.ts.net"
2026-02-03 20:17:24 -08:00
```
Then: `mise run provision-indri -- --tags caddy`
See [[routing]] for when Caddy is needed.
## Deploy
```bash
# Sync apps to pick up new Application
argocd app sync apps
# Test on feature branch first
argocd app set <service> --revision <branch>
argocd app sync <service>
# Verify
kubectl --context=minikube-indri -n <service> get pods
kubectl --context=minikube-indri -n <service> logs -f deployment/<service>
# After PR merge, reset to main
argocd app set <service> --revision main
argocd app sync <service>
```
## Checklist
- [ ] Manifests in `argocd/manifests/<service>/`
- [ ] Application in `argocd/apps/<service>.yaml`
2026-02-11 21:10:42 -08:00
- [ ] Tailscale Ingress via ProxyGroup with Homepage annotations
2026-02-03 20:17:24 -08:00
- [ ] Caddy route (if pod-to-service access needed)
- [ ] Tested on feature branch
- [ ] PR reviewed and merged
- [ ] Reset to main branch
2026-02-16 17:02:56 -08:00
- [ ] Service added to `service-versions.yaml` for version tracking
2026-02-03 20:17:24 -08:00
## Related
- [[adding-a-service]] - Full tutorial with explanations
- [[apps]] - ArgoCD application registry
- [[routing]] - Service routing options