1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.forgejo.settings;
9 age = config.age.secrets;
10
11 forgejoSecret = {
12 owner = "forgejo";
13 group = "forgejo";
14 };
15
16 d = lib.py.data.services.git;
17in
18{
19 catppuccin.forgejo.enable = true;
20 py.services.forgejo-runner = {
21 enable = true;
22 tokenFile = age.forgejo-default-runner-token.path;
23 };
24 services.forgejo = {
25 enable = true;
26 package = pkgs.forgejo;
27 lfs.enable = true;
28 database = {
29 type = "postgres";
30 createDatabase = true;
31 passwordFile = age.forgejo-db-pw.path;
32 };
33 secrets = {
34 mailer.PASSWD = age.forgejo-mail-pw.path;
35 security.SECRET_KEY = lib.mkForce age.forgejo-secret-key.path;
36 security.INTERNAL_TOKEN = lib.mkForce age.forgejo-internal-token.path;
37 oauth2.JWT_SECRET = lib.mkForce age.forgejo-oauth2-jwt-secret.path;
38 server.LFS_JWT_SECRET = lib.mkForce age.forgejo-lfs-jwt-secret.path;
39 };
40 settings = {
41 DEFAULT = {
42 APP_NAME = "PyroNet Git";
43 RUN_MODE = "prod";
44 };
45 attachment = {
46 MAX_SIZE = 200;
47 };
48 log."logger.router.MODE" = "";
49 mailer = {
50 ENABLED = true;
51 FROM = "PyroNet Git <git@pyrox.dev>";
52 PROTOCOL = "smtps";
53 SMTP_ADDR = "mail.pyrox.dev";
54 SMTP_PORT = 465;
55 USER = "git@pyrox.dev";
56 };
57 picture = {
58 ENABLE_FEDERATED_AVATAR = true;
59 };
60 ui = {
61 DEFAULT_SHOW_FULL_NAME = true;
62 USE_SERVICE_WORKER = true;
63 SHOW_USER_EMAIL = false;
64 };
65 "ui.meta" = {
66 AUTHOR = "dish";
67 DESCRIPTION = "PyroNet Git Services";
68 };
69 metrics = {
70 ENABLED = true;
71 };
72 server = {
73 DISABLE_SSH = true;
74 DOMAIN = d.extUrl;
75 HTTP_PORT = d.port;
76 ROOT_URL = "https://${cfg.server.DOMAIN}";
77 LFS_START_SERVER = true;
78 };
79 #
80 indexer = {
81 # Enable issue indexing
82 ISSUE_INDEXER_TYPE = "bleve";
83 ISSUE_INDEXER_PATH = "indexers/issues.bleve";
84 # Enable repo indexing
85 REPO_INDEXER_ENABLED = true;
86 REPO_INDEXER_REPO_TYPES = "sources,forks,templates,mirrors";
87 REPO_INDEXER_TYPE = "bleve";
88 REPO_INDEXER_PATH = "indexers/repos.bleve";
89 };
90 session = {
91 PROVIDER = "db";
92 COOKIE_SECURE = true;
93 COOKIE_NAME = "pyrogit-session";
94 DOMAIN = d.extUrl;
95 # Sessions last for 1 week
96 GC_INTERVAL_TIME = 86400 * 7;
97 SESSION_LIFE_TIME = 86400 * 7;
98 };
99 service = {
100 DISABLE_REGISTRATION = true;
101 AUTO_WATCH_NEW_REPOS = false;
102 };
103 security = {
104 INSTALL_LOCK = true;
105 COOKIE_USERNAME = "pyrogit-user";
106 COOKIE_REMEMBER_NAME = "pyrogit-auth";
107 MIN_PASSWORD_LENGTH = 10;
108 PASSWORD_COMPLEXITY = "lower,upper,digit,spec";
109 PASSWORD_HASH_ALGO = "argon2";
110 PASSWORD_CHECK_PWN = true;
111 ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET = true;
112 # Only allow reverse proxies from Tailscale tailnet
113 REVERSE_PROXY_TRUSTED_PROXIES = "10.64.0.0/10";
114 };
115 actions = {
116 ENABLED = true;
117 };
118 };
119 };
120 age.secrets = lib.mkIf config.services.forgejo.enable {
121 forgejo-db-pw = forgejoSecret // {
122 file = ./secrets/forgejo/db-pw.age;
123 };
124 forgejo-mail-pw = forgejoSecret // {
125 file = ./secrets/forgejo/mail-pw.age;
126 };
127 forgejo-aux-docs-runner-token = forgejoSecret // {
128 file = ./secrets/forgejo/aux-docs-runner-token.age;
129 };
130 forgejo-default-runner-token = forgejoSecret // {
131 file = ./secrets/forgejo/default-runner-token.age;
132 };
133 forgejo-gitgay-runner-token = forgejoSecret // {
134 file = ./secrets/forgejo/gitgay-runner-token.age;
135 };
136 forgejo-internal-token = forgejoSecret // {
137 file = ./secrets/forgejo/internal-token.age;
138 };
139 forgejo-oauth2-jwt-secret = forgejoSecret // {
140 file = ./secrets/forgejo/oauth2-jwt-secret.age;
141 };
142 forgejo-lfs-jwt-secret = forgejoSecret // {
143 file = ./secrets/forgejo/lfs-jwt-secret.age;
144 };
145 forgejo-secret-key = forgejoSecret // {
146 file = ./secrets/forgejo/secret-key.age;
147 };
148 };
149 services.anubis.instances.forgejo = lib.mkIf config.services.forgejo.enable {
150 settings = {
151 BIND = ":${toString d.anubis}";
152 POLICY_FNAME = "${pkgs.py.anubis-files}/policies/forgejo.yaml";
153 TARGET = "http://localhost:${toString d.port}";
154 };
155 };
156 services.prometheus.scrapeConfigs = lib.mkIf config.services.forgejo.enable [
157 {
158 job_name = "forgejo";
159 static_configs = [
160 { targets = [ "127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}" ]; }
161 ];
162 }
163 ];
164}