towerops/.gitlab-ci.yml
Graham McIntire 9194ebdd72
ci: migrate GitLab CI to Nix-based Docker builds
Replace Docker-based builds with Nix flakes for reproducible builds.

Changes:
- Use nixos/nix:latest image with `nix` tag requirement
- Build Docker image with `nix build .#dockerImage`
- Add optional Cachix integration for binary caching
- Load image with `docker load < result`
- Keep existing deploy stage unchanged

Benefits:
- Reproducible builds across all environments
- Binary caching via Cachix (faster subsequent builds)
- All dependencies pinned in flake.lock
- Image size similar to Docker builds (~507 MB compressed)

Requirements:
- GitLab Runner with Nix installed and `nix` tag
- Docker socket mounted for loading/pushing images
- Optional: CACHIX_AUTH_TOKEN for binary caching

See docs/gitlab-runner-nix-setup.md for runner setup instructions.

The old Docker-based config is available in git history if rollback needed.
2026-02-07 14:17:20 -06:00

87 lines
2.7 KiB
YAML

stages:
- build
- deploy
variables:
# Nix configuration
NIX_CONFIG: |
experimental-features = nix-command flakes
substituters = https://cache.nixos.org https://towerops.cachix.org
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= towerops.cachix.org-1:YOUR_PUBLIC_KEY_HERE
CACHIX_CACHE: "towerops"
workflow:
auto_cancel:
on_new_commit: interruptible
build:
stage: build
interruptible: true
tags:
- nix # Requires GitLab Runner with Nix installed
image: nixos/nix:latest
before_script:
# Install Docker for loading and pushing images
- nix-env -iA nixpkgs.docker
# Install Cachix if auth token is available
- |
if [ -n "$CACHIX_AUTH_TOKEN" ]; then
nix-env -iA cachix -f https://cachix.org/api/v1/install
echo "$CACHIX_AUTH_TOKEN" | cachix authtoken
fi
script:
# Build Docker image with Nix
- echo "Building Docker image with Nix..."
- nix build .#dockerImage --print-build-logs
# Push build artifacts to Cachix for faster future builds
- |
if [ -n "$CACHIX_AUTH_TOKEN" ]; then
echo "Pushing build artifacts to Cachix..."
nix path-info --json .#dockerImage | jq -r '.[].path' | cachix push $CACHIX_CACHE
fi
# Load image into Docker
- echo "Loading Docker image..."
- docker load < result
# Tag image with commit SHA and latest
- docker tag $(docker images -q | head -1) $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker tag $(docker images -q | head -1) $CI_REGISTRY_IMAGE:latest
# Login to GitLab Container Registry
- echo "$CI_REGISTRY_PASSWORD" | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
# Push to registry
- echo "Pushing to GitLab Container Registry..."
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker push $CI_REGISTRY_IMAGE:latest
rules:
- if: $CI_COMMIT_BRANCH == "main"
deploy:
stage: deploy
needs:
- job: build
artifacts: false
tags:
- home
image:
name: bitnami/kubectl:latest
entrypoint: [""]
script:
- kubectl config get-contexts
- kubectl config use-context towerops/towerops:home-cluster-agent
# Set deployment timestamp (ISO 8601 format in UTC)
- DEPLOY_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
- echo "Deploying at $DEPLOY_TIMESTAMP"
# Deploy new version (migrations run on app start)
- kubectl set image deployment/towerops towerops=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n towerops
- kubectl set env deployment/towerops DEPLOY_TIMESTAMP=$DEPLOY_TIMESTAMP -n towerops
# Don't wait for rollout completion - let Kubernetes handle it asynchronously
environment:
name: production
kubernetes:
namespace: towerops
rules:
- if: $CI_COMMIT_BRANCH == "main"