refactor: replace generate-job.py with nomad-job.nix, add flake-output input
Use nix eval --raw --impure + builtins.getEnv instead of Python for Nomad job JSON generation. Add flake-output input (default: default) so projects can build non-default outputs like docs. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
95bf5517f7
commit
4af132296e
3 changed files with 96 additions and 110 deletions
|
|
@ -11,6 +11,11 @@ inputs:
|
||||||
description: 'Domain the site is served at (e.g. toph.so)'
|
description: 'Domain the site is served at (e.g. toph.so)'
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
flake-output:
|
||||||
|
description: 'Flake output to build (e.g. default, docs)'
|
||||||
|
required: false
|
||||||
|
default: 'default'
|
||||||
|
|
||||||
nomad-addr:
|
nomad-addr:
|
||||||
description: 'Nomad API address'
|
description: 'Nomad API address'
|
||||||
required: false
|
required: false
|
||||||
|
|
@ -50,7 +55,7 @@ runs:
|
||||||
|
|
||||||
- name: Build site
|
- name: Build site
|
||||||
shell: bash
|
shell: bash
|
||||||
run: nix build .#default --out-link result-site
|
run: nix build ".#${{ inputs.flake-output }}" --out-link result-site
|
||||||
|
|
||||||
- name: Sign and push Nix closure to S3 cache
|
- name: Sign and push Nix closure to S3 cache
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
@ -76,10 +81,13 @@ runs:
|
||||||
- name: Deploy Nomad job
|
- name: Deploy Nomad job
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
python3 "${{ github.action_path }}/generate-job.py" | nomad job run -json -
|
nix eval --raw --impure \
|
||||||
|
--expr "import ${{ github.action_path }}/nomad-job.nix" \
|
||||||
|
| nomad job run -json -
|
||||||
env:
|
env:
|
||||||
NOMAD_ADDR: ${{ inputs.nomad-addr }}
|
NOMAD_ADDR: ${{ inputs.nomad-addr }}
|
||||||
DOMAIN: ${{ inputs.domain }}
|
DOMAIN: ${{ inputs.domain }}
|
||||||
|
SITE_HASH: ${{ env.SITE_HASH }}
|
||||||
SERVER_IMAGE: ${{ inputs.server-image }}
|
SERVER_IMAGE: ${{ inputs.server-image }}
|
||||||
DATACENTER: ${{ inputs.datacenter }}
|
DATACENTER: ${{ inputs.datacenter }}
|
||||||
S3_BUCKET: ${{ inputs.s3-bucket }}
|
S3_BUCKET: ${{ inputs.s3-bucket }}
|
||||||
|
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Generate a Nomad job JSON for a static site deployment.
|
|
||||||
Reads from environment variables, prints JSON to stdout.
|
|
||||||
Pipe to: nomad job run -json -
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
domain = os.environ["DOMAIN"]
|
|
||||||
site_hash = os.environ["SITE_HASH"]
|
|
||||||
server_image = os.environ.get("SERVER_IMAGE", "registry.toph.so/static-server:latest")
|
|
||||||
datacenter = os.environ.get("DATACENTER", "contabo")
|
|
||||||
s3_bucket = os.environ["S3_BUCKET"]
|
|
||||||
|
|
||||||
job_id = "site-" + domain.replace(".", "-")
|
|
||||||
|
|
||||||
startup_cmd = (
|
|
||||||
f"mkdir -p /var/www && "
|
|
||||||
f"aws s3 cp s3://{s3_bucket}/sites/{domain}/{site_hash}.tar.gz - "
|
|
||||||
f"| tar xz -C /var/www/ && "
|
|
||||||
f"exec static-web-server --port 8080 --root /var/www"
|
|
||||||
)
|
|
||||||
|
|
||||||
nomad_template_data = (
|
|
||||||
'{{ with nomadVar "static-sites/s3" }}'
|
|
||||||
"AWS_ACCESS_KEY_ID={{ .access_key }}\n"
|
|
||||||
"AWS_SECRET_ACCESS_KEY={{ .secret_key }}\n"
|
|
||||||
"AWS_ENDPOINT_URL={{ .endpoint }}\n"
|
|
||||||
"{{ end }}"
|
|
||||||
)
|
|
||||||
|
|
||||||
job = {
|
|
||||||
"Job": {
|
|
||||||
"ID": job_id,
|
|
||||||
"Name": job_id,
|
|
||||||
"Namespace": "static-sites",
|
|
||||||
"Type": "service",
|
|
||||||
"Datacenters": [datacenter],
|
|
||||||
"Update": {
|
|
||||||
"MinHealthyTime": 5000000000, # 5s in nanoseconds
|
|
||||||
"HealthyDeadline": 60000000000, # 60s in nanoseconds
|
|
||||||
"MaxParallel": 1,
|
|
||||||
},
|
|
||||||
"TaskGroups": [
|
|
||||||
{
|
|
||||||
"Name": "site",
|
|
||||||
"Count": 1,
|
|
||||||
"Networks": [
|
|
||||||
{
|
|
||||||
"DynamicPorts": [
|
|
||||||
{"Label": "http", "To": 8080}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Services": [
|
|
||||||
{
|
|
||||||
"Name": job_id,
|
|
||||||
"Provider": "nomad",
|
|
||||||
"PortLabel": "http",
|
|
||||||
"Tags": [
|
|
||||||
"traefik.enable=true",
|
|
||||||
f"traefik.http.routers.{job_id}.rule=Host(`{domain}`)",
|
|
||||||
f"traefik.http.routers.{job_id}.entrypoints=websecure",
|
|
||||||
f"traefik.http.routers.{job_id}.tls.certresolver=letsencrypt",
|
|
||||||
],
|
|
||||||
"Checks": [
|
|
||||||
{
|
|
||||||
"Type": "http",
|
|
||||||
"Path": "/",
|
|
||||||
"Interval": 30000000000, # 30s
|
|
||||||
"Timeout": 5000000000, # 5s
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Tasks": [
|
|
||||||
{
|
|
||||||
"Name": "server",
|
|
||||||
"Driver": "docker",
|
|
||||||
"Config": {
|
|
||||||
"image": server_image,
|
|
||||||
"command": "/bin/bash",
|
|
||||||
"args": ["-c", startup_cmd],
|
|
||||||
"ports": ["http"],
|
|
||||||
},
|
|
||||||
"Templates": [
|
|
||||||
{
|
|
||||||
"EmbeddedTmpl": nomad_template_data,
|
|
||||||
"DestPath": "secrets/s3.env",
|
|
||||||
"Envvars": True,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"Resources": {
|
|
||||||
"CPU": 100,
|
|
||||||
"MemoryMB": 128,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
json.dump(job, sys.stdout, indent=2)
|
|
||||||
print()
|
|
||||||
86
deploy-static-site/nomad-job.nix
Normal file
86
deploy-static-site/nomad-job.nix
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
let
|
||||||
|
domain = builtins.getEnv "DOMAIN";
|
||||||
|
siteHash = builtins.getEnv "SITE_HASH";
|
||||||
|
serverImage = builtins.getEnv "SERVER_IMAGE";
|
||||||
|
datacenter = builtins.getEnv "DATACENTER";
|
||||||
|
s3Bucket = builtins.getEnv "S3_BUCKET";
|
||||||
|
|
||||||
|
jobId = "site-" + builtins.replaceStrings [ "." ] [ "-" ] domain;
|
||||||
|
|
||||||
|
startupCmd =
|
||||||
|
"mkdir -p /var/www && " +
|
||||||
|
"aws s3 cp s3://${s3Bucket}/sites/${domain}/${siteHash}.tar.gz - " +
|
||||||
|
"| tar xz -C /var/www/ && " +
|
||||||
|
"exec static-web-server --port 8080 --root /var/www";
|
||||||
|
|
||||||
|
templateData =
|
||||||
|
"{{ with nomadVar \"static-sites/s3\" }}" +
|
||||||
|
"AWS_ACCESS_KEY_ID={{ .access_key }}\n" +
|
||||||
|
"AWS_SECRET_ACCESS_KEY={{ .secret_key }}\n" +
|
||||||
|
"AWS_ENDPOINT_URL={{ .endpoint }}\n" +
|
||||||
|
"{{ end }}";
|
||||||
|
|
||||||
|
job = {
|
||||||
|
Job = {
|
||||||
|
ID = jobId;
|
||||||
|
Name = jobId;
|
||||||
|
Namespace = "static-sites";
|
||||||
|
Type = "service";
|
||||||
|
Datacenters = [ datacenter ];
|
||||||
|
Update = {
|
||||||
|
MinHealthyTime = 5000000000;
|
||||||
|
HealthyDeadline = 60000000000;
|
||||||
|
MaxParallel = 1;
|
||||||
|
};
|
||||||
|
TaskGroups = [
|
||||||
|
{
|
||||||
|
Name = "site";
|
||||||
|
Count = 1;
|
||||||
|
Networks = [
|
||||||
|
{ DynamicPorts = [ { Label = "http"; To = 8080; } ]; }
|
||||||
|
];
|
||||||
|
Services = [
|
||||||
|
{
|
||||||
|
Name = jobId;
|
||||||
|
Provider = "nomad";
|
||||||
|
PortLabel = "http";
|
||||||
|
Tags = [
|
||||||
|
"traefik.enable=true"
|
||||||
|
"traefik.http.routers.${jobId}.rule=Host(`${domain}`)"
|
||||||
|
"traefik.http.routers.${jobId}.entrypoints=websecure"
|
||||||
|
"traefik.http.routers.${jobId}.tls.certresolver=letsencrypt"
|
||||||
|
];
|
||||||
|
Checks = [
|
||||||
|
{ Type = "http"; Path = "/"; Interval = 30000000000; Timeout = 5000000000; }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
Tasks = [
|
||||||
|
{
|
||||||
|
Name = "server";
|
||||||
|
Driver = "docker";
|
||||||
|
Config = {
|
||||||
|
image = serverImage;
|
||||||
|
command = "/bin/bash";
|
||||||
|
args = [ "-c" startupCmd ];
|
||||||
|
ports = [ "http" ];
|
||||||
|
};
|
||||||
|
Templates = [
|
||||||
|
{
|
||||||
|
EmbeddedTmpl = templateData;
|
||||||
|
DestPath = "secrets/s3.env";
|
||||||
|
Envvars = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
Resources = {
|
||||||
|
CPU = 100;
|
||||||
|
MemoryMB = 128;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
builtins.toJSON job
|
||||||
Loading…
Add table
Reference in a new issue