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.
87 lines
2.7 KiB
YAML
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"
|