{ description = "A basic Go web server setup"; inputs = { nixpkgs.url = "nixpkgs/nixos-unstable"; utils.url = "github:numtide/flake-utils"; portable-svc.url = "git+https://tulpa.dev/cadey/portable-svc.git?ref=main"; }; outputs = { self, nixpkgs, utils, portable-svc }: utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ] (system: let pkgs = import nixpkgs { overlays = [ portable-svc.overlay ]; inherit system; }; version = builtins.substring 0 8 self.lastModifiedDate; in { packages = { default = pkgs.buildGoModule { pname = "web-server"; inherit version; src = ./.; # This hash locks the dependencies of this package. It is # necessary because of how Go requires network access to resolve # VCS. See https://www.tweag.io/blog/2021-03-04-gomod2nix/ for # details. Normally one can build with a fake sha256 and rely on native Go # mechanisms to tell you what the hash should be or determine what # it should be "out-of-band" with other tooling (eg. gomod2nix). # To begin with it is recommended to set this, but one must # remeber to bump this hash when your dependencies change. #vendorSha256 = pkgs.lib.fakeSha256; vendorSha256 = "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo="; }; docker = let web = self.packages.${system}.default; in pkgs.dockerTools.buildLayeredImage { name = web.pname; tag = web.version; contents = [ web ]; config = { Cmd = [ "/bin/web-server" ]; WorkingDir = "/"; }; }; web-service = pkgs.substituteAll { name = "web-server.service"; src = ./systemd/web-server.service.in; web = self.packages.${system}.default; }; portable = let web = self.packages.${system}.default; in pkgs.portableService { inherit (web) version; name = web.pname; description = "A web server"; units = [ self.packages.${system}.web-service ]; }; }; defaultApp = utils.lib.mkApp { drv = self.packages.${system}.default; }; devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ go gopls gotools go-tools ]; }; }) // { nixosModule = { config, lib, pkgs, ... }: with lib; let cfg = config.xeserv.services.gohello; in { options.xeserv.services.gohello = { enable = mkEnableOption "Enables the gohello HTTP service"; domain = mkOption rec { type = types.str; default = "gohello.local.cetacean.club"; example = default; description = "The domain name for gohello"; }; }; config = mkIf cfg.enable { systemd.services."xeserv.gohello" = { wantedBy = [ "multi-user.target" ]; serviceConfig = let pkg = self.packages.${pkgs.system}.default; in { Restart = "on-failure"; ExecStart = "${pkg}/bin/web-server"; DynamicUser = "yes"; RuntimeDirectory = "xeserv.gohello"; RuntimeDirectoryMode = "0755"; StateDirectory = "xeserv.gohello"; StateDirectoryMode = "0700"; CacheDirectory = "xeserv.gohello"; CacheDirectoryMode = "0750"; }; }; services.nginx.virtualHosts.${cfg.domain} = { locations."/" = { proxyPass = "http://127.0.0.1:3031"; }; }; }; }; nixosConfigurations.container = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ self.nixosModule ({ pkgs, ... }: { # Only allow this to boot as a container boot.isContainer = true; # Allow nginx through the firewall networking.firewall.allowedTCPPorts = [ 80 ]; services.nginx.enable = true; xeserv.services.gohello.enable = true; }) ]; }; }; }