# See https://github.com/sunmeplz/xray-3x-ui { config, lib, pkgs, ... }: with lib; let cfg = config.machine.xray-3x-ui; # Minimum Go version required for building minGoVersion = "1.26.0"; xray-3x-ui = assert assertMsg (versionAtLeast pkgs.go.version minGoVersion) "3x-ui requires Go >= ${minGoVersion}, but ${pkgs.go.version} is available"; pkgs.buildGoModule rec { pname = "3x-ui"; version = "2.8.11"; src = pkgs.fetchFromGitHub { owner = "MHSanaei"; repo = "3x-ui"; rev = "v${version}"; hash = "sha256-2I6t3caf2t7nKSFwxI/dVIobpBzuptrgauuXfFw8ltg="; }; vendorHash = "sha256-M8YQTMfF/xZut4hxUcAfF2xGK625vwJNp4JS/zoXUCQ="; ldflags = [ "-s" "-w" ]; meta = with lib; { description = "Xray panel supporting multi-protocol multi-user"; homepage = "https://github.com/MHSanaei/3x-ui"; license = licenses.gpl3Only; platforms = platforms.linux; maintainers = [ ]; }; }; in { # Service implementation config = mkIf cfg.enable { # User and group configuration users.users.xray-3x-ui = { isSystemUser = true; group = "xray-3x-ui"; description = "3x-ui service user"; }; users.groups.xray-3x-ui = { }; # Directory structure systemd.tmpfiles.rules = [ "d ${cfg.dataDir} 0755 xray-3x-ui xray-3x-ui -" "d ${cfg.dataDir}/bin 0755 xray-3x-ui xray-3x-ui -" "d ${cfg.dataDir}/logs 0755 xray-3x-ui xray-3x-ui -" ]; # Systemd service systemd.services.xray-3x-ui = { description = "3x-ui Xray Panel"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; environment = { XUI_DB_FOLDER = cfg.dataDir; XUI_BIN_FOLDER = "${cfg.dataDir}/bin"; XUI_LOG_FOLDER = "${cfg.dataDir}/logs"; }; preStart = '' # Symlink xray-core binary to expected location ln -sf ${pkgs.xray}/bin/xray ${cfg.dataDir}/bin/xray-linux-amd64 ''; serviceConfig = { Type = "simple"; ExecStart = "${xray-3x-ui}/bin/3x-ui"; WorkingDirectory = cfg.dataDir; Restart = "on-failure"; RestartSec = "10s"; User = "xray-3x-ui"; Group = "xray-3x-ui"; StateDirectory = "3x-ui 3x-ui/bin 3x-ui/logs"; StateDirectoryMode = "0755"; AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" "CAP_NET_ADMIN" ]; CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" "CAP_NET_ADMIN" ]; }; }; # Add to system packages for CLI access environment.systemPackages = [ xray-3x-ui ]; }; }