Files
grapho/modules/server/forgejo.nix
Brandon Lucas b40ac99524 Initial commit: Ultimate Notetaking, Sync & Backup System
A NixOS-based system for managing personal data across three tiers:
- Tier 1: Configuration (shareable via git)
- Tier 2: Syncable data (nb + Syncthing)
- Tier 3: Large data (self-hosted services + backup)

Includes:
- NixOS modules for nb, Syncthing, backup (restic)
- Server modules for Forgejo, Immich, Jellyfin
- Helper scripts (usync, ustatus)
- Comprehensive documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-13 01:44:00 -05:00

146 lines
3.4 KiB
Nix

# Forgejo Module
#
# Self-hosted Git forge (GitHub/Gitea alternative).
# Used for hosting private nb notebook repositories.
#
# Usage:
# services.forgejo-managed.enable = true;
# services.forgejo-managed.domain = "git.yourdomain.com";
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.forgejo-managed;
in {
options.services.forgejo-managed = {
enable = mkEnableOption "managed Forgejo git forge";
domain = mkOption {
type = types.str;
description = "Domain name for Forgejo.";
example = "git.example.com";
};
httpPort = mkOption {
type = types.port;
default = 3000;
description = "HTTP port for Forgejo (behind reverse proxy).";
};
sshPort = mkOption {
type = types.port;
default = 2222;
description = "SSH port for git operations.";
};
stateDir = mkOption {
type = types.str;
default = "/var/lib/forgejo";
description = "State directory for Forgejo data.";
};
enableLFS = mkOption {
type = types.bool;
default = true;
description = "Enable Git LFS support.";
};
disableRegistration = mkOption {
type = types.bool;
default = true;
description = "Disable open user registration.";
};
adminEmail = mkOption {
type = types.nullOr types.str;
default = null;
description = "Admin email address.";
};
appName = mkOption {
type = types.str;
default = "Forgejo";
description = "Application name shown in UI.";
};
};
config = mkIf cfg.enable {
services.forgejo = {
enable = true;
stateDir = cfg.stateDir;
settings = {
DEFAULT = {
APP_NAME = cfg.appName;
};
server = {
DOMAIN = cfg.domain;
HTTP_PORT = cfg.httpPort;
ROOT_URL = "https://${cfg.domain}/";
SSH_PORT = cfg.sshPort;
SSH_DOMAIN = cfg.domain;
START_SSH_SERVER = true; # Built-in SSH server
LFS_START_SERVER = cfg.enableLFS;
};
service = {
DISABLE_REGISTRATION = cfg.disableRegistration;
REQUIRE_SIGNIN_VIEW = false; # Allow viewing public repos
};
repository = {
DEFAULT_PRIVATE = "private"; # New repos are private by default
ENABLE_PUSH_CREATE_USER = true; # Allow creating repos via push
};
"repository.upload" = {
ENABLED = true;
FILE_MAX_SIZE = 100; # MB
MAX_FILES = 10;
};
session = {
PROVIDER = "file";
COOKIE_SECURE = true; # Require HTTPS
};
log = {
LEVEL = "Info";
};
# Security
security = {
INSTALL_LOCK = true; # Prevent web-based install
MIN_PASSWORD_LENGTH = 12;
};
mailer = mkIf (cfg.adminEmail != null) {
ENABLED = true;
FROM = cfg.adminEmail;
};
};
};
# Open SSH port
networking.firewall.allowedTCPPorts = [ cfg.sshPort ];
# Create backup for Forgejo data
services.backup.paths = mkIf config.services.backup.enable [
cfg.stateDir
];
# Reverse proxy with Caddy (optional, can use nginx)
# Uncomment if using Caddy:
#
# services.caddy = {
# enable = true;
# virtualHosts."${cfg.domain}".extraConfig = ''
# reverse_proxy localhost:${toString cfg.httpPort}
# '';
# };
};
}