Files
nixos-config/hosts/m3-atlas/services/containers/AGENTS.md
2026-01-02 15:12:26 +01:00

2.7 KiB

CONTAINER SERVICES (m3-atlas)

Container orchestration with Podman + Traefik reverse proxy

OVERVIEW

11 containerized services on dedicated web network (10.89.0.0/24) with Traefik SSL termination.

STRUCTURE

containers/
├── default.nix          # Network setup + service imports
├── baserow.nix          # 10.89.0.10 - No-code database
├── ghost.nix            # 10.89.0.11 - Blog platform
├── kestra.nix           # 10.89.0.12 - Workflow orchestration
├── littlelink.nix       # 10.89.0.13 - Link aggregator
├── matomo.nix           # 10.89.0.14 - Analytics
├── restreamer.nix       # 10.89.0.15 - Video streaming
├── slash.nix            # 10.89.0.16 - Link shortener
└── slash-nemoti.nix     # 10.89.0.17 - Personal link shortener

WHERE TO LOOK

Task Action Notes
Add container Copy existing .nix, increment IP Must update default.nix imports
Fix networking Check IP conflicts in 10.89.0.0/24 Gateway always 10.89.0.1
Debug Traefik Check router rules in service file Domain must match DNS
Access database Use --add-host=mysql:10.89.0.1 Gateway IP for host services

CONVENTIONS

Container Definition Template

virtualisation.oci-containers.containers.<name> = {
  image = "registry/image:tag";
  ports = ["127.0.0.1:<external>:<internal>"];
  volumes = ["/var/lib/<service>:/data"];
  environmentFiles = [config.age.secrets.<name>-env.path];
  extraOptions = [
    "--network=web"
    "--ip=10.89.0.<sequential>"
    "--add-host=mysql:10.89.0.1"  # If DB needed
  ];
};

Traefik Integration

services.traefik.dynamicConfigOptions.http = {
  services.<name>.loadBalancer.servers = [{ 
    url = "http://127.0.0.1:<port>"; 
  }];
  routers.<name> = {
    rule = "Host(`<subdomain>.m3ta.dev`)";
    service = "<name>";
    tls.certResolver = "godaddy";
  };
  # Legacy redirect (if needed)
  routers.<name>-old = {
    rule = "Host(`<subdomain>.m3tam3re.com`)";
    service = "<name>";
    middlewares = ["redirect-m3ta"];
  };
};

IP Allocation

  • 10.89.0.1: Gateway (host)
  • 10.89.0.10-17: Assigned containers
  • 10.89.0.18+: Available for new services

ANTI-PATTERNS

  • DON'T expose ports publicly - bind to 127.0.0.1 only
  • DON'T skip static IP assignment - routing breaks without it
  • DON'T hardcode secrets - use age-encrypted env files
  • DON'T forget to add imports to default.nix

NOTES

  • Network created via activation script in default.nix
  • All services behind Traefik - no direct external access
  • MySQL/PostgreSQL run on host, accessed via gateway IP
  • Secrets pattern: <service>-env.age with environment variables