ci-actions/deploy-nix-site/action.yaml
Christopher Mühl 33c8946041
Add Nix-based deploy action for isolated builds
- New deploy-nix-site action using Nix flakes
- Runs in nixos/nix:latest container for proper isolation
- Builds using flake.nix, uploads to S3, deploys to Nomad
- Update deploy-site action to install Nomad CLI
- Document both actions in README

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-16 14:39:25 +01:00

150 lines
4.5 KiB
YAML

name: Deploy Nix Site
description: Deploy static site built with Nix flake to S3 and Nomad
inputs:
site-name:
description: 'Site identifier (used as service name in Nomad)'
required: true
traefik-rule:
description: 'Traefik routing rule (e.g., Host(`example.com`) or Host(`example.com`) || Host(`www.example.com`))'
required: true
flake-output:
description: 'Nix flake output to build (e.g., .#packages.x86_64-linux.default or .#)'
required: false
default: '.#'
s3-endpoint:
description: 'S3 endpoint'
required: false
default: 'https://s3.toph.so'
runs:
using: composite
steps:
- name: Install tools
shell: bash
run: |
# Install AWS CLI
nix profile install nixpkgs#awscli2
# Install Nomad
nix profile install nixpkgs#nomad
# Make available in PATH
export PATH="$HOME/.nix-profile/bin:$PATH"
echo "$HOME/.nix-profile/bin" >> $GITHUB_PATH
# Set Nomad address
echo "NOMAD_ADDR=http://alvin:4646" >> $GITHUB_ENV
- name: Build site with Nix
shell: bash
run: |
nix build ${{ inputs.flake-output }} --print-build-logs
# Find the result
if [ -L result ]; then
BUILD_OUTPUT="result"
else
echo "Error: No result symlink found after nix build"
exit 1
fi
echo "BUILD_OUTPUT=$BUILD_OUTPUT" >> $GITHUB_ENV
- name: Package and upload to S3
shell: bash
run: |
ARTIFACT_NAME="${{ github.sha }}.tar.gz"
# Package the built output
tar czf "/tmp/${ARTIFACT_NAME}" -C "$BUILD_OUTPUT" .
# Configure AWS CLI for S3
export AWS_ACCESS_KEY_ID="${{ env.S3_ACCESS_KEY }}"
export AWS_SECRET_ACCESS_KEY="${{ env.S3_SECRET_KEY }}"
export AWS_ENDPOINT_URL="${{ inputs.s3-endpoint }}"
export AWS_EC2_METADATA_DISABLED=true
# Upload to S3
aws s3 cp "/tmp/${ARTIFACT_NAME}" "s3://artifacts/${ARTIFACT_NAME}"
# Make publicly readable
aws s3api put-object-acl \
--bucket artifacts \
--key "${ARTIFACT_NAME}" \
--acl public-read
echo "📦 Artifact uploaded: ${{ inputs.s3-endpoint }}/artifacts/${ARTIFACT_NAME}"
- name: Deploy via Nomad
shell: bash
run: |
cat > /tmp/deploy-${{ inputs.site-name }}.nomad.json <<'NOMAD_EOF'
{
"Job": {
"ID": "${{ inputs.site-name }}",
"Name": "${{ inputs.site-name }}",
"Type": "service",
"Datacenters": ["contabo"],
"Constraints": [{
"LTarget": "${node.unique.name}",
"RTarget": "alvin",
"Operand": "="
}],
"TaskGroups": [{
"Name": "web",
"Count": 1,
"Networks": [{
"Mode": "bridge",
"DynamicPorts": [{
"Label": "http",
"To": 8080
}]
}],
"Services": [{
"Name": "${{ inputs.site-name }}",
"PortLabel": "http",
"Provider": "nomad",
"Tags": [
"traefik.enable=true",
"traefik.http.routers.${{ inputs.site-name }}.rule=${{ inputs.traefik-rule }}",
"traefik.http.routers.${{ inputs.site-name }}.entrypoints=websecure",
"traefik.http.routers.${{ inputs.site-name }}.tls.certresolver=letsencrypt"
]
}],
"Tasks": [{
"Name": "server",
"Driver": "docker",
"Config": {
"image": "joseluisq/static-web-server:2",
"ports": ["http"]
},
"Env": {
"SERVER_ROOT": "/local/public",
"SERVER_LOG_LEVEL": "info"
},
"Artifacts": [{
"GetterSource": "${{ inputs.s3-endpoint }}/artifacts/${{ github.sha }}.tar.gz",
"RelativeDest": "local/public",
"GetterMode": "dir"
}],
"Resources": {
"CPU": 100,
"MemoryMB": 64
}
}]
}]
}
}
NOMAD_EOF
nomad job run /tmp/deploy-${{ inputs.site-name }}.nomad.json
- name: Deployment summary
shell: bash
run: |
echo "✅ Deployed ${{ inputs.site-name }}"
echo "📋 Traefik rule: ${{ inputs.traefik-rule }}"