Replace low-level S3 operations with native Attic client for better performance, simplicity, and proper Nix binary cache protocol support. Changes: - Replace 'nix copy' + S3 with 'attic push' - Remove S3_ACCESS_KEY, S3_SECRET_KEY, NIX_SIGNING_KEY requirements - Add ATTIC_TOKEN requirement (explicit per-repo security) - Default to 'ci' cache instead of 'toph' - Update Nomad fetch task to pull from Attic instead of S3 - Simplify push-nix-cache to single attic push command - Update documentation with new security model Security: - ATTIC_TOKEN must be explicitly provided as Forgejo secret - Prevents untrusted repos from pushing to cache - Separate ci/toph caches for different trust levels Benefits: - Simpler: Single command instead of sign + copy + sync - Faster: Native Attic protocol vs S3 object storage - Safer: Explicit opt-in prevents unauthorized cache writes - Standards-compliant: Proper Nix binary cache protocol Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
86 lines
2.5 KiB
Nix
86 lines
2.5 KiB
Nix
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 \"nomad/jobs\" }}" +
|
|
"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 = 5000000000; 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
|