Files
turbovault-app/docs/GITHUB_SECRETS.md
Ryan Kazokas 69993a3bf5 Deploy to production: GitHub Actions + ghcr.io + Kubernetes
- Switch from Gitea to GitHub Container Registry (ghcr.io)
- Add GitHub Actions workflow with Tailscale connectivity
- Update k8s manifests for cloud nodes and Traefik ingress
- Configure for turbo.kazcloud.dev domain
- Test deployment with home page text change
2026-03-29 08:46:27 -04:00

6.3 KiB

GitHub Secrets Configuration

This document explains what secrets you need to configure in GitHub for automatic builds and deployments.

Required Secrets

Go to: https://github.com/ryan/turbovault-app/settings/secrets/actions

1. GITHUB_TOKEN (Built-in)

Purpose: Authenticate to GitHub Container Registry (ghcr.io)

Value: This is automatically provided by GitHub Actions - no setup needed!

How to add:

  1. Go to GitHub repo → Settings → Secrets and variables → Actions
  2. Click "New repository secret"
  3. Name: GITEA_USERNAME
  4. Secret: ryan
  5. Click "Add secret"

2. TAILSCALE_CLIENT_ID

Purpose: Allows GitHub Actions to connect to your Tailscale network (to reach Kubernetes)

How to create:

  1. Go to: https://login.tailscale.com/admin/settings/oauth
  2. Click "Generate OAuth client"
  3. Description: GitHub Actions - TurboVault
  4. Select tags: tag:ci (or create if it doesn't exist)
  5. Copy the Client ID

How to add to GitHub:

  1. Go to GitHub repo → Settings → Secrets and variables → Actions
  2. Click "New repository secret"
  3. Name: TAILSCALE_CLIENT_ID
  4. Secret: Paste the Client ID
  5. Click "Add secret"

3. TAILSCALE_CLIENT_SECRET

Purpose: OAuth secret for Tailscale connection

How to get:

(You got this when creating the OAuth client in step 3 above)

How to add to GitHub:

  1. Go to GitHub repo → Settings → Secrets and variables → Actions
  2. Click "New repository secret"
  3. Name: TAILSCALE_CLIENT_SECRET
  4. Secret: Paste the Client Secret
  5. Click "Add secret"

4. KUBECONFIG

Purpose: Allows kubectl to deploy to your Kubernetes cluster

How to create:

# Encode your kubeconfig as base64
cat ~/.kube/config | base64 -w 0 > kubeconfig-base64.txt

# Copy the contents
cat kubeconfig-base64.txt

How to add to GitHub:

  1. Go to GitHub repo → Settings → Secrets and variables → Actions
  2. Click "New repository secret"
  3. Name: KUBECONFIG
  4. Secret: Paste the base64-encoded kubeconfig
  5. Click "Add secret"

Optional: Scoped Kubeconfig (More Secure)

Instead of using your full kubeconfig, create a limited service account:

# Create service account
kubectl create serviceaccount turbovault-deployer -n turbovault

# Create role with deployment permissions only
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: turbovault-deployer
  namespace: turbovault
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "patch", "update"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]
- apiGroups: ["apps"]
  resources: ["deployments/status"]
  verbs: ["get"]
EOF

# Bind role to service account
kubectl create rolebinding turbovault-deployer \
  --role=turbovault-deployer \
  --serviceaccount=turbovault:turbovault-deployer \
  -n turbovault

# Get service account token (valid for 10 years)
kubectl create token turbovault-deployer -n turbovault --duration=87600h > token.txt

# Create minimal kubeconfig
cat <<EOF > deployer-kubeconfig.yaml
apiVersion: v1
kind: Config
clusters:
- cluster:
    server: https://100.101.31.99:6443
    insecure-skip-tls-verify: true
  name: k3s
contexts:
- context:
    cluster: k3s
    namespace: turbovault
    user: turbovault-deployer
  name: k3s
current-context: k3s
users:
- name: turbovault-deployer
  user:
    token: $(cat token.txt)
EOF

# Encode for GitHub
cat deployer-kubeconfig.yaml | base64 -w 0 > deployer-kubeconfig-base64.txt

# Use this in KUBECONFIG secret
cat deployer-kubeconfig-base64.txt

This limits GitHub Actions to only deploying TurboVault, not full cluster access.


Summary of Required Secrets

Secret Name Purpose How to Get
GITHUB_TOKEN Push to ghcr.io Built-in (no setup needed!)
TAILSCALE_CLIENT_ID Connect to Tailscale Tailscale → OAuth clients
TAILSCALE_CLIENT_SECRET Connect to Tailscale Tailscale → OAuth clients
KUBECONFIG Deploy to Kubernetes cat ~/.kube/config | base64 -w 0

Verifying Secrets

After adding all secrets, you should see 3 secrets in GitHub:

  1. Go to: https://github.com/ryankazokas/turbovault-app/settings/secrets/actions
  2. Verify all 3 are listed:
    • TAILSCALE_CLIENT_ID
    • TAILSCALE_CLIENT_SECRET
    • KUBECONFIG

Note: GITHUB_TOKEN is automatic - you don't need to add it!


Testing the Workflow

After secrets are configured:

# Create a test tag
git tag v0.0.1-test
git push origin v0.0.1-test

Watch the workflow at: https://github.com/ryan/turbovault-app/actions

The workflow should:

  1. Build Docker image
  2. Push to Gitea registry (gitea.kazcloud.dev)
  3. Connect to Tailscale
  4. Deploy to Kubernetes
  5. Wait for rollout to complete

Troubleshooting

"Error: authentication required" (Gitea)

  • Check GITEA_TOKEN is set correctly
  • Verify token has write:package scope
  • Test: docker login gitea.kazcloud.dev with token

"Error: Failed to connect to Tailscale"

  • Check TAILSCALE_CLIENT_ID and TAILSCALE_CLIENT_SECRET are correct
  • Verify OAuth client is active in Tailscale admin
  • Check tags are configured correctly (tag:ci)

"Error: Unable to connect to the server" (Kubernetes)

  • Check KUBECONFIG secret is set correctly
  • Verify base64 encoding (no line breaks with -w 0)
  • Verify Tailscale connected (check logs)
  • Test kubeconfig works: kubectl --kubeconfig=<file> get pods -n turbovault

"Error: deployment not found"

  • Make sure initial deployment is done first: ./scripts/deploy-k8s.sh
  • Workflow only updates existing deployments, doesn't create them

Security Best Practices

DO:

  • Use service account with minimal permissions (recommended)
  • Rotate tokens regularly
  • Use OAuth for Tailscale (not auth keys)
  • Only enable workflows on protected branches

DON'T:

  • Share secrets in code or documentation
  • Use admin kubeconfig if possible
  • Commit secrets to git
  • Use long-lived Tailscale auth keys

Next Steps

After configuring secrets:

  1. Read DEPLOYMENT.md for initial deployment
  2. Test workflow with a tag push
  3. Monitor Actions tab for build status

Questions? Check the GitHub Actions logs for detailed error messages.