1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
Copyright (C) 2026 Doan Luu Duc Tai <doan@luuduct.ai>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
CENTRAL CONFIGURATION
One root .env holds each installation's deployment settings and secrets.
Public .env.example documents every supported key, public default, private
placeholder, and comment. Hostnames remain public in generated pages, DNS,
certificates, and URLs. Centralization is not secrecy or access control.
cargo stack config, service initialization, and chat initialization preserve
existing settings/secrets and append missing public defaults to the same .env.
No second environment file. The shared Rust configuration library also reads
defaults from .env.example, keeping older exports compatible.
PUBLIC SETTINGS
BASE_DOMAIN
Root web/WKD domain. Derive www aliases from each configured host.
SITE_HOST, GIT_HOST, SEARCH_HOST, WKD_HOST, CHAT_HOST
Fully qualified DNS names; no scheme, path, or port. Set production
HTTPS routes and canonical www redirects. CHAT_HOST also selects the
exact trusted external chat origin.
CHAT_LOCAL_HOST
Development gateway hostname ending in .localhost. Default:
chat.localhost. Browser identity files bind to this origin and local port.
WEB_BIND
Production publish address. Default :: serves IPv4/IPv6. Use 127.0.0.1
for isolated staging. Development always binds loopback.
HTTP_PORT, HTTPS_PORT
Caddy listeners and Podman published ports; defaults 80/443. HTTPS also
publishes UDP for HTTP/3. Generated links include nonstandard HTTPS ports.
Public certificate validation still needs standard external CA validation
ports or alternative certificate/routing arrangements. Port settings do
not configure DNS, firewall rules, or external forwarding.
LOCAL_HTTP_PORT
Local HTTP on 127.0.0.1; host HTTPS port is this value plus one. Caddy
still listens on container ports 80/443. --port overrides one invocation.
var/state.json retains installation/project names and image state.
An explicit .env local port overrides the saved port.
CGIT_UPSTREAM, SEARXNG_UPSTREAM, CHAT_UPSTREAM
Proxy targets, e.g. cgit:8080, searxng:8080, chat:8080. Not bind settings.
Bundled internal 8080 listeners and health checks remain image contracts.
A changed target needs an actual service at that host/port.
CHAT_BIND, CHAT_ORIGIN
Direct development socket and exact browser origin. Defaults:
127.0.0.1:9080 and http://127.0.0.1:9080. Require loopback and an exact
HTTP origin match. --bind overrides CHAT_BIND. Containers bind privately
to 0.0.0.0:8080; trusted origin comes from CHAT_HOST/HTTPS_PORT or
CHAT_LOCAL_HOST/LOCAL_HTTP_PORT. Identity files pin their origin.
Editing these settings neither migrates encrypted identities nor grants
access on another origin.
BACKUP_RECIPIENT, BACKUP_PUBLIC_KEY
Public OpenPGP fingerprint and project-relative public key path for
encrypted exports. --recipient/--key override them. Keep the secret
GnuPG key and revocation certificate outside the project.
PRIVATE SETTINGS
SEARXNG_SECRET
Generated at first stack initialization; existing values preserved.
CHAT_SETUP_TOKEN
Generated by chat initialization or first startup. Authorizes only
first owner registration, including after an explicit backend reset.
Cannot recover a lost owner private key.
RENDER AND APPLY
Edit .env locally; never commit or publish it. See .env.example for exact
keys. Validate hostnames, ports, sockets, fingerprints, and paths before use.
Diagnostics never dump the config map or echo invalid .env contents.
Render public deployment files without starting services:
cargo stack config
cargo stack config --production
Output under var/local/ or var/production/:
Caddyfile
cgitrc
web/
Templates use {{PUBLIC_KEY}} placeholders: infra/Caddyfile,
infra/Caddyfile.local, infra/containers/cgit/cgitrc, first-party website HTML.
Never run Caddy on unrendered templates. Podman mounts generated files.
Public host/origin changes reach routes, www redirects, website links, cgit
clone prefixes, and chat navigation. Local rendering uses /git, /search,
and http://CHAT_LOCAL_HOST:LOCAL_HTTP_PORT for chat.
Apply to existing local services:
cargo stack up --local
Production uses prebuilt management command/images:
./bin/stack up --production
Running file servers can read rendered website updates. Listener, container
environment, and loaded Caddy changes need the service update above.
Restart direct local chat with cargo stack chat for new bind/origin/navigation
settings. Reopen your identity file afterward, as after any chat restart.
PUBLICATION AND LIMITS
stack-config substitutes only explicitly allowlisted public values.
{{CHAT_SETUP_TOKEN}} and other private/unknown placeholders fail instead of
exposing values. Public pages/proxy config never receive a full environment
dump. Chat receives the public allowlist plus CHAT_SETUP_TOKEN; other
containers receive only declared secrets. Caddy needs rendered public config,
not .env or private tokens.
Git ignores .env, runtime files, local renders, exports, and tool caches.
Source templates, commented example, validated defaults, and configuration
implementation remain public. Full encrypted backups include the single
.env; source-only releases exclude it.
Personal content stays in source: copyright, author names, canonical contact,
public keys/WKD hashes, repository metadata, GNU license links. Changing a
hostname creates no new email identity and regenerates no WKD keys.
Image digests, source hashes, fixed crypto/protocol/resource bounds remain
reviewed reproducible code/config, not private deployment knobs.
|