feat: branch-based deployment (main → staging, production → prod)
- main branch: auto-deploy to Dokku staging - production branch: build Docker image and deploy to K8s production - Add DEPLOYMENT.md with workflow documentation - Create production branch for manual production deployments Breaking change: pushing to main no longer deploys to production
This commit is contained in:
parent
3a5da6f68c
commit
721c1f2481
2 changed files with 158 additions and 5 deletions
|
|
@ -1,9 +1,10 @@
|
|||
name: Build
|
||||
name: Build and Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- production
|
||||
|
||||
env:
|
||||
DOCKER_BUILDKIT: 1
|
||||
|
|
@ -14,7 +15,30 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
deploy-staging:
|
||||
name: Deploy to Dokku Staging
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Full history needed for Dokku
|
||||
|
||||
- name: Deploy to Dokku
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.DOKKU_SSH_KEY }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
|
||||
chmod 600 ~/.ssh/id_ed25519
|
||||
ssh-keyscan -H 204.110.191.231 >> ~/.ssh/known_hosts
|
||||
git remote add dokku dokku@204.110.191.231:towerops || true
|
||||
git push dokku main:main --force
|
||||
|
||||
build-production:
|
||||
name: Build and Deploy to Production
|
||||
if: github.ref == 'refs/heads/production'
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
|
@ -41,7 +65,7 @@ jobs:
|
|||
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
|
||||
IMAGE=${{ secrets.REGISTRY_URL }}/${{ github.repository }}
|
||||
echo "image=${IMAGE}" >> $GITHUB_OUTPUT
|
||||
echo "tag=${IMAGE}:main-${TIMESTAMP}-${SHORT_SHA}" >> $GITHUB_OUTPUT
|
||||
echo "tag=${IMAGE}:production-${TIMESTAMP}-${SHORT_SHA}" >> $GITHUB_OUTPUT
|
||||
echo "latest_tag=${IMAGE}:latest" >> $GITHUB_OUTPUT
|
||||
echo "cache_tag=${IMAGE}:buildcache" >> $GITHUB_OUTPUT
|
||||
|
||||
|
|
@ -49,6 +73,7 @@ jobs:
|
|||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: k8s/Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
${{ steps.meta.outputs.tag }}
|
||||
|
|
@ -65,6 +90,6 @@ jobs:
|
|||
if ! git diff --cached --quiet; then
|
||||
git commit -m "chore: update towerops-web image to ${{ steps.meta.outputs.tag }} [skip ci]"
|
||||
# Pull with rebase to handle concurrent pushes
|
||||
git pull --rebase origin main
|
||||
git push origin HEAD:main
|
||||
git pull --rebase origin production
|
||||
git push origin HEAD:production
|
||||
fi
|
||||
|
|
|
|||
128
DEPLOYMENT.md
Normal file
128
DEPLOYMENT.md
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
# Deployment Guide
|
||||
|
||||
## Overview
|
||||
|
||||
Towerops uses a branch-based deployment strategy:
|
||||
- **`main` branch** → Dokku staging environment (automatic)
|
||||
- **`production` branch** → Kubernetes production cluster (automatic)
|
||||
|
||||
## Staging Deployment (Dokku)
|
||||
|
||||
### Automatic
|
||||
Push or merge to `main` branch automatically deploys to Dokku staging:
|
||||
|
||||
```bash
|
||||
git push origin main
|
||||
```
|
||||
|
||||
The Forgejo Actions workflow pushes to the Dokku remote: `dokku@204.110.191.231:towerops`
|
||||
|
||||
### Manual
|
||||
You can also deploy manually:
|
||||
|
||||
```bash
|
||||
git push dokku main
|
||||
```
|
||||
|
||||
## Production Deployment (Kubernetes)
|
||||
|
||||
### Process
|
||||
To deploy to production:
|
||||
|
||||
1. **Merge `main` into `production` branch:**
|
||||
```bash
|
||||
git checkout production
|
||||
git merge main
|
||||
git push origin production
|
||||
```
|
||||
|
||||
2. **Forgejo Actions will automatically:**
|
||||
- Build Docker image with tag `production-<timestamp>-<commit>`
|
||||
- Push image to container registry (`git.mcintire.me`)
|
||||
- Update `k8s/deployment.yaml` with new image tag
|
||||
- Commit and push the update back to `production` branch
|
||||
- Kubernetes (via FluxCD) picks up the change and deploys
|
||||
|
||||
3. **Monitor the deployment:**
|
||||
```bash
|
||||
kubectl get pods -n towerops -w
|
||||
```
|
||||
|
||||
### Rollback
|
||||
To rollback to a previous version:
|
||||
|
||||
```bash
|
||||
# Find the commit with the working version
|
||||
git log k8s/deployment.yaml
|
||||
|
||||
# Reset to that commit
|
||||
git checkout production
|
||||
git reset --hard <commit-sha>
|
||||
git push origin production --force
|
||||
```
|
||||
|
||||
Or manually update the image tag in `k8s/deployment.yaml` and push.
|
||||
|
||||
## Required Secrets
|
||||
|
||||
### Forgejo Actions Secrets
|
||||
Configure these in your Forgejo repository settings:
|
||||
|
||||
- `DOKKU_SSH_KEY` - SSH private key for Dokku deployments
|
||||
- `REGISTRY_URL` - Container registry URL (e.g., `git.mcintire.me`)
|
||||
- `REGISTRY_USER` - Registry username
|
||||
- `REGISTRY_PASSWORD` - Registry password/token
|
||||
|
||||
### Kubernetes Secrets
|
||||
These must exist in the `towerops` namespace:
|
||||
|
||||
- `forgejo-registry` - Docker registry credentials
|
||||
- `towerops-secrets` - Application secrets (RELEASE_COOKIE, SECRET_KEY_BASE, CLOAK_KEY)
|
||||
- `towerops-db` - Database connection
|
||||
- `towerops-aws` - AWS credentials
|
||||
- `towerops-billing` - Stripe API keys (optional)
|
||||
- `towerops-redis` - Redis/Valkey connection
|
||||
|
||||
## Branch Protection
|
||||
|
||||
Recommended branch protection rules:
|
||||
|
||||
### `main` branch
|
||||
- Require pull request reviews
|
||||
- Require status checks to pass
|
||||
- Auto-deploys to staging on merge
|
||||
|
||||
### `production` branch
|
||||
- Require pull request reviews
|
||||
- Require status checks to pass
|
||||
- **Only merge from `main`**
|
||||
- Auto-deploys to production on merge
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Staging deployment fails
|
||||
Check Forgejo Actions logs and Dokku logs:
|
||||
```bash
|
||||
ssh dokku@204.110.191.231 logs towerops
|
||||
```
|
||||
|
||||
### Production deployment fails
|
||||
1. Check Forgejo Actions logs for build errors
|
||||
2. Check if image was pushed to registry
|
||||
3. Check Kubernetes pod status:
|
||||
```bash
|
||||
kubectl get pods -n towerops
|
||||
kubectl logs -n towerops deployment/towerops
|
||||
```
|
||||
|
||||
### Image not updating in Kubernetes
|
||||
1. Verify `k8s/deployment.yaml` has the new image tag
|
||||
2. Check FluxCD reconciliation:
|
||||
```bash
|
||||
kubectl get gitrepositories -n flux-system
|
||||
kubectl get kustomizations -n flux-system
|
||||
```
|
||||
3. Manual rollout restart if needed:
|
||||
```bash
|
||||
kubectl rollout restart deployment/towerops -n towerops
|
||||
```
|
||||
Loading…
Add table
Reference in a new issue