feat: web-arm install atticd
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
./modules/victoriametrics.nix
|
./modules/victoriametrics.nix
|
||||||
./modules/blackbox-exporter.nix
|
./modules/blackbox-exporter.nix
|
||||||
./modules/updns.nix
|
./modules/updns.nix
|
||||||
|
./modules/atticd.nix
|
||||||
|
|
||||||
./utils/modules/autoupgrade.nix
|
./utils/modules/autoupgrade.nix
|
||||||
./utils/modules/promtail
|
./utils/modules/promtail
|
||||||
|
|||||||
207
hosts/web-arm/modules/atticd.nix
Normal file
207
hosts/web-arm/modules/atticd.nix
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
atticHost = "attic.cloonar.com";
|
||||||
|
atticPort = 8080; # Internal port for atticd
|
||||||
|
in {
|
||||||
|
# Declare required secrets
|
||||||
|
sops.secrets.atticd = {
|
||||||
|
# This should contain environment variables for atticd
|
||||||
|
# Format: KEY=value per line
|
||||||
|
# Required:
|
||||||
|
# ATTIC_SERVER_TOKEN_HS256_SECRET=<random-256-bit-secret>
|
||||||
|
# Optional:
|
||||||
|
# ATTIC_SERVER_DATABASE_URL=postgresql://user:pass@localhost/attic
|
||||||
|
};
|
||||||
|
|
||||||
|
# Attic server service
|
||||||
|
services.atticd = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# Credentials file from sops
|
||||||
|
environmentFile = config.sops.secrets.atticd.path;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
listen = "127.0.0.1:${toString atticPort}";
|
||||||
|
|
||||||
|
# API endpoint configuration
|
||||||
|
api-endpoint = "https://${atticHost}/";
|
||||||
|
|
||||||
|
# Allow automatic registration (set to false for production if you want to control access)
|
||||||
|
allow-registration = false;
|
||||||
|
|
||||||
|
# Require tokens for all operations
|
||||||
|
require-proof-of-possession = true;
|
||||||
|
|
||||||
|
# Chunking settings for large uploads
|
||||||
|
chunking = {
|
||||||
|
# Minimum chunk size: 16 MiB
|
||||||
|
min-size = 16 * 1024 * 1024;
|
||||||
|
# Average chunk size: 64 MiB
|
||||||
|
avg-size = 64 * 1024 * 1024;
|
||||||
|
# Maximum chunk size: 256 MiB
|
||||||
|
max-size = 256 * 1024 * 1024;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Garbage collection
|
||||||
|
garbage-collection = {
|
||||||
|
# GC interval in seconds (12 hours)
|
||||||
|
interval = 12 * 60 * 60;
|
||||||
|
|
||||||
|
# Delete unreferenced chunks after 7 days
|
||||||
|
default-retention-period = 7 * 24 * 60 * 60;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Storage configuration
|
||||||
|
storage = {
|
||||||
|
# Use local filesystem storage
|
||||||
|
type = "local";
|
||||||
|
# Store in /var/lib/atticd
|
||||||
|
path = "/var/lib/atticd/storage";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Optional: S3-compatible storage (commented out)
|
||||||
|
# storage = {
|
||||||
|
# type = "s3";
|
||||||
|
# region = "eu-central-1";
|
||||||
|
# bucket = "attic-cache";
|
||||||
|
# endpoint = "https://s3.eu-central-1.amazonaws.com";
|
||||||
|
# };
|
||||||
|
|
||||||
|
# Database configuration
|
||||||
|
database = {
|
||||||
|
url = "postgresql://atticd@/atticd?host=/run/postgresql";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Compression
|
||||||
|
compression = {
|
||||||
|
# Use zstd compression
|
||||||
|
type = "zstd";
|
||||||
|
level = 3; # Balance between speed and compression
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Create state directory with proper permissions
|
||||||
|
systemd.services.atticd = {
|
||||||
|
serviceConfig = {
|
||||||
|
StateDirectory = "atticd";
|
||||||
|
StateDirectoryMode = "0750";
|
||||||
|
# Security hardening
|
||||||
|
PrivateTmp = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = true;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
LockPersonality = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
SystemCallFilter = "@system-service";
|
||||||
|
SystemCallErrorNumber = "EPERM";
|
||||||
|
# Resource limits
|
||||||
|
LimitNOFILE = 65536;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Nginx reverse proxy configuration
|
||||||
|
services.nginx.virtualHosts."${atticHost}" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
acmeRoot = null;
|
||||||
|
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString atticPort}";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
# Increase timeouts for large uploads
|
||||||
|
proxy_connect_timeout 300;
|
||||||
|
proxy_send_timeout 300;
|
||||||
|
proxy_read_timeout 300;
|
||||||
|
send_timeout 300;
|
||||||
|
|
||||||
|
# Increase body size limit for large NAR uploads (500MB)
|
||||||
|
client_max_body_size 500M;
|
||||||
|
client_body_buffer_size 128k;
|
||||||
|
|
||||||
|
# Proxy headers
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# Buffering settings for better performance
|
||||||
|
proxy_buffering on;
|
||||||
|
proxy_buffer_size 4k;
|
||||||
|
proxy_buffers 8 4k;
|
||||||
|
proxy_busy_buffers_size 8k;
|
||||||
|
proxy_temp_file_write_size 8k;
|
||||||
|
|
||||||
|
# Cache settings for static content
|
||||||
|
proxy_cache_valid 200 302 10m;
|
||||||
|
proxy_cache_valid 404 1m;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
locations."/health" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString atticPort}/health";
|
||||||
|
};
|
||||||
|
|
||||||
|
# API endpoint with stricter rate limiting
|
||||||
|
locations."~ ^/api/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:${toString atticPort}";
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
# Rate limiting for API endpoints
|
||||||
|
limit_req zone=attic_api burst=10 nodelay;
|
||||||
|
|
||||||
|
# Same proxy settings as above
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
client_max_body_size 500M;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure Nginx rate limiting zones
|
||||||
|
services.nginx.appendHttpConfig = ''
|
||||||
|
# Rate limiting zones for Attic
|
||||||
|
limit_req_zone $binary_remote_addr zone=attic_api:10m rate=10r/s;
|
||||||
|
limit_req_zone $binary_remote_addr zone=attic_upload:10m rate=5r/s;
|
||||||
|
|
||||||
|
# Connection limiting
|
||||||
|
limit_conn_zone $binary_remote_addr zone=attic_conn:10m;
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.postgresql.ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "atticd";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
services.postgresql.ensureDatabases = [ "atticd" ];
|
||||||
|
services.postgresqlBackup.databases = [ "atticd" ];
|
||||||
|
|
||||||
|
services.borgbackup.jobs.default.exclude = [
|
||||||
|
"/var/lib/atticd"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Monitoring with Prometheus (if you have it set up)
|
||||||
|
# services.prometheus.scrapeConfigs = [{
|
||||||
|
# job_name = "atticd";
|
||||||
|
# static_configs = [{
|
||||||
|
# targets = [ "127.0.0.1:${toString atticPort}" ];
|
||||||
|
# }];
|
||||||
|
# }];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user