2026-02-19 19:25:51 +02:00
2026-02-19 19:25:51 +02:00
2026-02-19 19:25:51 +02:00
2026-02-19 19:25:51 +02:00
2026-02-19 19:25:51 +02:00

wafrn-nix

example:

{
  inputs.wafrn-nix.url = "git+https://git.ocbwoy3.dev/kris/wafrn-nix";

  outputs = { self, nixpkgs, wafrn-nix, ... }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        wafrn-nix.nixosModules.default
        ({ ... }: {
          virtualisation.docker.enable = true;

          services.wafrn = {
            enable = true;
            source = "/srv/wafrn";
            stateDir = "/var/lib/wafrn";
            secretsFile = "/run/secrets/wafrn.env";

            # cloudflared doesnt need https:
            # httpPort = 8080;
            # httpsPort = null;

            bun2nix = {
              enable = true;
              outputFile = "bun.nix";
            };

            environment = {
              DOMAIN_NAME = "wafrn.example.com";
              CACHE_DOMAIN = "cache.wafrn.example.com";
              MEDIA_DOMAIN = "media.wafrn.example.com";
              FRONTEND_MEDIA_URL = "https://media.wafrn.example.com";
              FRONTEND_CACHE_URL = "https://cache.wafrn.example.com/api/cache?media=";
              FRONTEND_FQDN_URL = "https://wafrn.example.com";
              ACME_EMAIL = "admin@example.com";
            };
          };
        })
      ];
    };
  };
}

External PDS mode

To use a separate PDS (not the bundled Wafrn PDS container):

services.wafrn = {
  enable = true;
  source = "/srv/wafrn";

  bluesky = {
    enable = true;
    useBundledPds = false;
    pdsDomain = "pds.example.com";
  };

  environment = {
    PDS_DOMAIN_NAME = "pds.example.com";
  };
};

Persistence

All important data is persisted in stateDir:

  • postgres/ - PostgreSQL data
  • redis/ - Redis data
  • uploads/ - user uploads
  • cache/ - backend cache
  • caddy/ - Caddy data and cert state
  • frontend/ - built frontend shared volume
  • pds/ - bundled PDS data (only when enabled)

Secrets

Put secrets in services.wafrn.secretsFile (dotenv format), for example:

ADMIN_PASSWORD=super-secret
JWT_SECRET=another-secret
SMTP_PASSWORD=smtp-secret
PDS_JWT_SECRET=pds-jwt-secret
PDS_ADMIN_PASSWORD=pds-admin-secret
WEBPUSH_PRIVATE=...
WEBPUSH_PUBLIC=...

This file is appended at runtime to the generated .env, so secret values override defaults.

bun2nix integration

By default, services.wafrn.bun2nix.enable = true, which runs bun2nix against the lock file in the Wafrn source checkout before starting containers.

  • Input lock file: services.wafrn.source + "/" + services.wafrn.bun2nix.lockFile (default bun.lock)
  • Output expression: services.wafrn.stateDir + "/" + services.wafrn.bun2nix.outputFile (default bun.nix)
  • Copy prefix: services.wafrn.bun2nix.copyPrefix (default ./)

You can disable this behavior with:

services.wafrn.bun2nix.enable = false;

Minimal Cloudflared exposure

If Cloudflared is your only public entrypoint, you can publish only one local HTTP port:

services.wafrn = {
  enable = true;
  source = "/srv/wafrn";

  httpPort = 8080;
  httpsPort = null;
  openFirewall = false;
};

Then point Cloudflared ingress to http://127.0.0.1:8080.

Description
No description provided
Readme 116 KiB
Languages
Nix 100%