#!/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()