From 1e183aca120abe3af272173e3ee63c554cfbb0b3 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 12 May 2025 16:55:34 -0400 Subject: [PATCH 1/3] feat: a nix package, comfig and devShell for supabase-auth --- .gitignore | 1 + flake.lock | 61 ++++++++++++++++ flake.nix | 170 +++++++++++++++++++++++++++++++++++++++++++ nix/auth-module.nix | 51 +++++++++++++ nix/steps-module.nix | 26 +++++++ 5 files changed, 309 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 nix/auth-module.nix create mode 100644 nix/steps-module.nix diff --git a/.gitignore b/.gitignore index acab1be45..5f19b5380 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ www/.DS_Store www/node_modules npm-debug.log .data +result diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..123b37c33 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1746576598, + "narHash": "sha256-FshoQvr6Aor5SnORVvh/ZdJ1Sa2U4ZrIMwKBX5k2wu0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b3582c75c7f21ce0b429898980eddbbf05c68e55", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..a46a7654d --- /dev/null +++ b/flake.nix @@ -0,0 +1,170 @@ +{ + description = "Supabase Auth Service with Nix modules and steps"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + let + systems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + + forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system); + + mkAuthConfig = system: + let + pkgs = nixpkgs.legacyPackages.${system}; + lib = pkgs.lib; + + # Go package + auth-service = pkgs.buildGoModule { + pname = "supabase-auth"; + version = "0.1.0"; + src = ./.; + + vendorHash = "sha256-QBQUUFWT3H3L7ajFV8cgi0QREXnm0ReIisD+4ACfLZQ="; + + buildFlags = [ "-tags" "netgo" ]; + doCheck = false; + + # Specify the main package + subPackages = [ "." ]; + + # Specify the output binary name + postInstall = '' + mv $out/bin/auth $out/bin/supabase-auth + ''; + }; + + # Evaluate both the auth and steps modules + config = lib.evalModules { + modules = [ + ./nix/auth-module.nix + ./nix/steps-module.nix + { + _module.args.pkgs = pkgs; + auth = { + enable = true; + package = auth-service; + port = 9999; + settings = { + GOTRUE_DB_DRIVER = "postgres"; + GOTRUE_SITE_URL = "http://localhost:3000"; + SITE_URL = "http://localhost:3000"; + GOTRUE_API_EXTERNAL_URL = "http://localhost:9999"; + API_EXTERNAL_URL = "http://localhost:9999"; + GOTRUE_DB_HOST = "localhost"; + GOTRUE_DB_PORT = "5432"; + GOTRUE_DB_NAME = "postgres"; + GOTRUE_DB_USER = "postgres"; + GOTRUE_DB_PASSWORD = "postgres"; + DATABASE_URL = "postgres://postgres:postgres@localhost:5432/postgres"; + GOTRUE_JWT_SECRET = "your-super-secret-jwt-token-with-at-least-32-characters-long"; + GOTRUE_JWT_EXP = "3600"; + GOTRUE_JWT_DEFAULT_GROUP_NAME = "authenticated"; + GOTRUE_DISABLE_SIGNUP = "false"; + GOTRUE_MAILER_AUTOCONFIRM = "true"; + GOTRUE_SMTP_ADMIN_EMAIL = "admin@example.com"; + GOTRUE_SMTP_HOST = "localhost"; + GOTRUE_SMTP_PORT = "2500"; + GOTRUE_SMTP_USER = ""; + GOTRUE_SMTP_PASS = ""; + GOTRUE_SMTP_SENDER_NAME = "Supabase"; + }; + }; + steps = { + enable = true; + }; + } + ]; + }; + + authConfigOutput = pkgs.stdenv.mkDerivation { + name = "auth-config"; + src = ./.; + buildInputs = [ pkgs.bash auth-service ]; + + buildPhase = '' + mkdir -p $out/etc $out/bin + + # Write the auth configuration + cat > $out/etc/auth.env < $out/bin/manage-auth < /dev/null; then + echo "Auth service is running" + else + echo "Auth service is not running" + fi + ;; + *) + echo "Usage: \$0 {start|stop|restart|status}" + exit 1 + ;; + esac + EOF + chmod +x $out/bin/manage-auth + ''; + + installPhase = "true"; + }; + + in + { + packages.default = authConfigOutput; + devShells.default = pkgs.mkShell { + buildInputs = [ + pkgs.bash + auth-service + pkgs.go + pkgs.gopls + pkgs.gotools + pkgs.go-outline + pkgs.gocode + pkgs.gopkgs + pkgs.godef + pkgs.golint + pkgs.delve + ]; + shellHook = '' + echo "Build with: nix build ." + echo "Result will be in ./result" + echo "Auth service version: ${auth-service.version}" + ''; + }; + }; + in + { + packages = forAllSystems (system: (mkAuthConfig system).packages); + devShells = forAllSystems (system: (mkAuthConfig system).devShells); + }; +} \ No newline at end of file diff --git a/nix/auth-module.nix b/nix/auth-module.nix new file mode 100644 index 000000000..ddf3382d7 --- /dev/null +++ b/nix/auth-module.nix @@ -0,0 +1,51 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.auth; +in { + options.auth = { + enable = mkEnableOption "Supabase Auth Service"; + + package = mkOption { + type = types.package; + description = "The Supabase Auth package to use."; + }; + + port = mkOption { + type = types.port; + default = 9999; + description = "Port to run the auth service on."; + }; + + settings = mkOption { + type = types.attrs; + default = { + SITE_URL = "http://localhost:3000"; + API_EXTERNAL_URL = "http://localhost:9999"; + DB_HOST = "localhost"; + DB_PORT = "5432"; + DB_NAME = "postgres"; + DB_USER = "postgres"; + DB_PASSWORD = "postgres"; + JWT_SECRET = "your-super-secret-jwt-token-with-at-least-32-characters-long"; + JWT_EXP = "3600"; + JWT_DEFAULT_GROUP_NAME = "authenticated"; + DISABLE_SIGNUP = "false"; + MAILER_AUTOCONFIRM = "true"; + SMTP_ADMIN_EMAIL = "admin@example.com"; + SMTP_HOST = "localhost"; + SMTP_PORT = "2500"; + SMTP_USER = ""; + SMTP_PASS = ""; + SMTP_SENDER_NAME = "Supabase"; + }; + description = "Configuration settings for the auth service."; + }; + }; + + config = mkIf cfg.enable { + # No NixOS-specific options here + }; +} \ No newline at end of file diff --git a/nix/steps-module.nix b/nix/steps-module.nix new file mode 100644 index 000000000..d31ee2778 --- /dev/null +++ b/nix/steps-module.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.steps; +in { + options.steps = { + enable = mkEnableOption "Auth service initialization steps"; + + commands = mkOption { + type = types.listOf types.str; + default = []; + description = "Commands to run during service initialization."; + }; + }; + + config = mkIf cfg.enable { + steps.commands = [ + # Wait for database to be ready + #"until pg_isready -h ${config.auth.settings.DB_HOST} -p ${config.auth.settings.DB_PORT} -U ${config.auth.settings.DB_USER}; do sleep 1; done" + # Run migrations if they exist + #"if [ -d migrations ]; then go run main.go migrate up; fi" + ]; + }; +} \ No newline at end of file From 82701a9704ba14ac44bccabb4c1213c225d50ea4 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Sat, 17 May 2025 18:00:36 -0400 Subject: [PATCH 2/3] feat: create an activation script and systemd service --- flake.nix | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index a46a7654d..cfdbfdb2a 100644 --- a/flake.nix +++ b/flake.nix @@ -91,7 +91,7 @@ buildInputs = [ pkgs.bash auth-service ]; buildPhase = '' - mkdir -p $out/etc $out/bin + mkdir -p $out/etc $out/bin $out/lib/systemd/system # Write the auth configuration cat > $out/etc/auth.env < $out/lib/systemd/system/gotrue.service < $out/bin/manage-auth < $out/bin/activate </dev/null; then + useradd -r -s /bin/false gotrue + fi + + # Set proper ownership + chown -R gotrue:gotrue /opt/gotrue + chown -R gotrue:gotrue /etc/auth.d + chown -R gotrue:gotrue /etc/gotrue + + # Set proper permissions + chmod 775 /opt/gotrue + chmod 775 /etc/auth.d + chmod 775 /etc/gotrue + + # Copy the binary + cp ${auth-service}/bin/supabase-auth /opt/gotrue/gotrue + chown gotrue:gotrue /opt/gotrue/gotrue + chmod 755 /opt/gotrue/gotrue + + # Copy the systemd unit file + cp $out/lib/systemd/system/gotrue.service /etc/systemd/system/ + chmod 644 /etc/systemd/system/gotrue.service + + # Copy the environment file + cp $out/etc/auth.env /etc/gotrue.generated.env + chown gotrue:gotrue /etc/gotrue.generated.env + chmod 600 /etc/gotrue.generated.env + + # Create symlinks for easy access + ln -sf $out/bin/manage-auth /usr/local/bin/gotrue-manage + ln -sf $out/share/gotrue/gotrue.service /usr/local/share/gotrue/gotrue.service + ln -sf $out/bin/activate /usr/local/bin/auth-activate + + # Reload systemd + systemctl daemon-reload + + # Enable and start the service + systemctl enable gotrue.service + systemctl restart gotrue.service + + echo "Gotrue service has been activated and started" + echo "You can manage the service using: gotrue-manage {start|stop|restart|status}" + EOF + chmod +x $out/bin/activate + + # Create symlinks to the systemd unit files for easy access + mkdir -p $out/share/gotrue + ln -s $out/lib/systemd/system/gotrue.service $out/share/gotrue/gotrue.service ''; installPhase = "true"; @@ -140,7 +226,9 @@ in { - packages.default = authConfigOutput; + packages = { + default = authConfigOutput; + }; devShells.default = pkgs.mkShell { buildInputs = [ pkgs.bash From 19bbc3a33b582a772d1f84c43c41d59c1b317824 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Sat, 17 May 2025 18:26:03 -0400 Subject: [PATCH 3/3] feat: package and activation --- flake.nix | 44 +++++++++++++++-------- nix/README.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 nix/README.md diff --git a/flake.nix b/flake.nix index cfdbfdb2a..ea5b08139 100644 --- a/flake.nix +++ b/flake.nix @@ -170,11 +170,6 @@ mkdir -p /etc/auth.d mkdir -p /etc/gotrue - # Create gotrue user if it doesn't exist - if ! id "gotrue" &>/dev/null; then - useradd -r -s /bin/false gotrue - fi - # Set proper ownership chown -R gotrue:gotrue /opt/gotrue chown -R gotrue:gotrue /etc/auth.d @@ -185,7 +180,7 @@ chmod 775 /etc/auth.d chmod 775 /etc/gotrue - # Copy the binary + # Copy the binary to the correct location cp ${auth-service}/bin/supabase-auth /opt/gotrue/gotrue chown gotrue:gotrue /opt/gotrue/gotrue chmod 755 /opt/gotrue/gotrue @@ -194,15 +189,26 @@ cp $out/lib/systemd/system/gotrue.service /etc/systemd/system/ chmod 644 /etc/systemd/system/gotrue.service - # Copy the environment file - cp $out/etc/auth.env /etc/gotrue.generated.env - chown gotrue:gotrue /etc/gotrue.generated.env - chmod 600 /etc/gotrue.generated.env - - # Create symlinks for easy access - ln -sf $out/bin/manage-auth /usr/local/bin/gotrue-manage - ln -sf $out/share/gotrue/gotrue.service /usr/local/share/gotrue/gotrue.service - ln -sf $out/bin/activate /usr/local/bin/auth-activate + # Copy the environment file to the correct location + cp $out/etc/auth.env /etc/auth.d/20_generated.env + chown gotrue:gotrue /etc/auth.d/20_generated.env + chmod 600 /etc/auth.d/20_generated.env + + # Create symlinks for easy access from nix profile + mkdir -p /usr/local/bin + mkdir -p /usr/local/share/gotrue + + # Create symlinks to the nix profile locations + ln -sf "\$NIX_PROFILE/bin/manage-auth" /usr/local/bin/gotrue-manage + ln -sf "\$NIX_PROFILE/share/gotrue/gotrue.service" /usr/local/share/gotrue/gotrue.service + ln -sf "\$NIX_PROFILE/bin/activate" /usr/local/bin/auth-activate + ln -sf "\$NIX_PROFILE/bin/gotrue" /usr/local/bin/gotrue + + # Allow UFW connections to GoTrue metrics exporter if UFW is installed + if command -v ufw >/dev/null 2>&1; then + ufw allow 9122/tcp comment "GoTrue metrics exporter" + echo "Added UFW rule for GoTrue metrics exporter" + fi # Reload systemd systemctl daemon-reload @@ -213,12 +219,20 @@ echo "Gotrue service has been activated and started" echo "You can manage the service using: gotrue-manage {start|stop|restart|status}" + echo "The following commands are available:" + echo " gotrue-manage - Manage the Gotrue service" + echo " auth-activate - Run this activation script again" + echo " gotrue - The auth service binary" EOF chmod +x $out/bin/activate # Create symlinks to the systemd unit files for easy access mkdir -p $out/share/gotrue ln -s $out/lib/systemd/system/gotrue.service $out/share/gotrue/gotrue.service + + # Copy the auth binary to the package's bin directory + cp ${auth-service}/bin/supabase-auth $out/bin/gotrue + chmod +x $out/bin/gotrue ''; installPhase = "true"; diff --git a/nix/README.md b/nix/README.md new file mode 100644 index 000000000..8d9e38e02 --- /dev/null +++ b/nix/README.md @@ -0,0 +1,97 @@ +# Nix Configuration for Auth Service + +This directory contains Nix modules and configurations for the Auth service. The setup allows for building and installing the Auth service using Nix, with proper systemd integration and configuration management. + +## Files + +- `auth-module.nix`: Defines the Nix module for the Auth service configuration +- `steps-module.nix`: Defines the Nix module for service startup steps and commands + +## Building and Installation + +### Prerequisites + +- Nix package manager installed +- System with systemd (for service management) + +### Installation + +1. Install the package: +```bash +nix profile install . +``` + +2. Activate the service: +```bash +sudo auth-activate +``` + +### Available Commands + +After installation, the following commands are available: + +- `gotrue`: The auth service binary +- `gotrue-manage`: Manage the service (start/stop/restart/status) +- `auth-activate`: Run the activation script again + +## Configuration + +The service configuration is managed through environment variables, which are set in the Nix configuration. The main configuration file is generated at `/etc/auth.d/20_generated.env` during activation. + +### Service Structure + +- Binary: `/opt/gotrue/gotrue` +- Config directory: `/etc/auth.d` +- Systemd service: `gotrue.service` +- Metrics port: 9122 (automatically configured in UFW if available) + +## Development + +### Updating the Service + +1. Modify the relevant Nix files: + - `flake.nix` for package definition and build process + - `auth-module.nix` for service configuration + - `steps-module.nix` for startup steps + +2. Rebuild and reinstall: +```bash +nix profile install . +sudo auth-activate +``` + +### Testing Changes + +1. Build the package: +```bash +nix build . +``` + +2. The result will be in `./result/` with the following structure: + - `bin/`: Contains the binary and management scripts + - `share/gotrue/`: Contains the systemd service file + - `etc/`: Contains the environment configuration + +## System Requirements + +- Linux system with systemd +- UFW (optional, for metrics port configuration) +- Proper permissions for the `gotrue` user (created by system image) + +## Troubleshooting + +1. If the service fails to start: + - Check logs: `journalctl -u gotrue.service` + - Verify permissions: `ls -l /opt/gotrue /etc/auth.d` + - Check config: `cat /etc/auth.d/20_generated.env` + +2. If commands are not found: + - Verify installation: `nix profile list` + - Check symlinks: `ls -l /usr/local/bin/gotrue*` + +## Notes + +- The activation script assumes the `gotrue` user exists (created by system image) +- The service runs as the `gotrue` user +- Configuration is managed through environment variables +- The service is automatically started and enabled on activation \ No newline at end of file