detached dae054c

refactor: use ~/.gordon for data, ~/.config/gordon for config

- Default data directory changed from /var/lib/gordon to ~/.gordon
- Config file now searched in ~/.config/gordon (XDG compliant)
- Add shared helpers in internal/app/paths.go for path logic
- Update README with clearer setup guide and consistent paths
- Remove version from goreleaser archive names for stable download URLs

Directory structure:
- Config: ~/.config/gordon/gordon.toml
- Data: ~/.gordon/ (registry, env, logs, secrets)
commit
dae054ca7a77723aa13523b0234c1c4123a12fbb
author
brice · · 2026-01-12 17:30 UTC
committer
brice · · 2026-01-12 17:48 UTC
parent
9a2dd31
signature
unsigned
5 files · +97 -51
M .goreleaser.yaml +1 -1
@@ -26,7 +26,7 @@ builds:
2626 # docker_manifests:
2727
2828 archives:
29- - name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
29+ - name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
3030
3131 changelog:
3232 sort: asc
@@ -26,7 +26,7 @@ builds:
26 # docker_manifests:26 # docker_manifests:
27 27
28 archives:28 archives:
29- - name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"29+ - name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
30 30
31 changelog:31 changelog:
32 sort: asc32 sort: asc
M README.md +53 -25
@@ -40,20 +40,19 @@ Build on your machine, push to deploy. Works from your laptop or CI.
4040 ### Installation
4141
4242 ```bash
43-# Download Gordon from the releases page
44-# https://github.com/bnema/gordon/releases/latest
45-# Example: wget https://github.com/bnema/gordon/releases/download/v2.0.0/gordon_2.0.0_linux_amd64.tar.gz
46-# Then extract:
47-tar -xzf gordon_*.tar.gz
43+# Download from releases
44+wget https://github.com/bnema/gordon/releases/latest/download/gordon_linux_amd64.tar.gz
45+tar -xzf gordon_linux_amd64.tar.gz
4846 chmod +x gordon
4947 sudo mv gordon /usr/local/bin/
5048
51-# Create initial config
52-gordon start
53-# Press Ctrl+C after config is created
49+# Create config
50+mkdir -p ~/.config/gordon
51+cp examples/minimal.toml ~/.config/gordon/gordon.toml
52+# Edit gordon.toml with your domain
5453 ```
5554
56-**Important:** This is just the binary installation. For a complete working setup including networking, firewall, and systemd service, follow the [detailed setup guide](#detailed-setup-guide-podman-rootless-mode) below.
55+**Important:** For a complete working setup including networking, firewall, and systemd service, follow the [detailed setup guide](#detailed-setup-guide-podman-rootless-mode) below.
5756
5857 ## Core Concepts
5958
@@ -86,7 +85,7 @@ VOLUME ["/app/uploads", "/app/data"] # Multiple volumes supported
8685 ### Environment Configuration
8786 Gordon automatically creates and loads env files based on domain names:
8887 ```bash
89-# Auto-created on first run: ~/.local/share/gordon/env/app_mydomain_com.env
88+# Auto-created on first run: ~/.gordon/env/app_mydomain_com.env
9089 # Just add your variables:
9190 DATABASE_URL=postgresql://localhost:5432/myapp
9291 API_KEY=sk-1234567890
@@ -107,7 +106,7 @@ Gordon also supports network groups, see [examples/](examples/) for advanced usa
107106 - **Volumes**: Automatically created from Dockerfile VOLUME directives, persist across updates
108107
109108 ### Production ready logging
110-- **Logs**: All container output saved to `~/.local/share/gordon/logs/containers/`
109+- **Logs**: All container output saved to `~/.gordon/logs/containers/`
111110 - **Rotation**: Logs rotate at 100MB, keeping 3 backups for 28 days
112111
113112 ## Configuration
@@ -204,9 +203,9 @@ See [examples/github-workflow.yml](examples/github-workflow.yml) and [.github/ac
204203
205204 ## Detailed Setup Guide (Podman Rootless Mode)
206205
207-> **Note:** This guide uses Podman in rootless mode for enhanced security. Docker users can follow similar steps - Gordon works with any OCI-compatible runtime. Refer to Quick Start for the binary installation.
206+> **Note:** This guide uses Podman in rootless mode for enhanced security. Docker users can follow similar steps. Gordon works with any OCI-compatible runtime.
208207
209-### 1. VPS Preparation
208+### 1. System Preparation
210209 ```bash
211210 # Update system
212211 sudo apt update && sudo apt upgrade -y
@@ -216,11 +215,11 @@ sudo apt install -y podman ufw
216215
217216 # Configure firewall
218217 sudo ufw allow 22/tcp 80/tcp 443/tcp
219-sudo default deny
218+sudo ufw default deny incoming
220219 sudo ufw --force enable
221220 ```
222221
223-### 2. Enable Port Forwarding
222+### 2. Port Forwarding (rootless requires this)
224223 ```bash
225224 # Forward 80/443 to unprivileged port 8080
226225 sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
@@ -231,21 +230,19 @@ sudo apt install -y iptables-persistent
231230 sudo netfilter-persistent save
232231 ```
233232
234-### 3. Configure Rootless Containers
233+### 3. Rootless Container Setup
235234 ```bash
236235 # Enable user namespaces
237236 echo 'user.max_user_namespaces=28633' | sudo tee -a /etc/sysctl.conf
238237 sudo sysctl -p
239238
240-# Setup subuid/subgid
239+# Setup subuid/subgid for your user
241240 sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
242241
243242 # Enable podman socket
244243 systemctl --user enable --now podman.socket
245-```
246244
247-### 4. Registry Configuration
248-```bash
245+# Allow localhost registry (podman config)
249246 mkdir -p ~/.config/containers
250247 cat > ~/.config/containers/registries.conf <<EOF
251248 [registries.insecure]
@@ -253,9 +250,40 @@ registries = ['localhost:5000']
253250 EOF
254251 ```
255252
256-### 5. Create Systemd Service
253+### 4. Install Gordon
254+```bash
255+# Download from releases
256+wget https://github.com/bnema/gordon/releases/latest/download/gordon_linux_amd64.tar.gz
257+tar -xzf gordon_linux_amd64.tar.gz
258+chmod +x gordon
259+sudo mv gordon /usr/local/bin/
260+```
261+
262+### 5. Configure Gordon
263+```bash
264+# Create config directory and file
265+mkdir -p ~/.config/gordon
266+cat > ~/.config/gordon/gordon.toml <<EOF
267+[server]
268+port = 8080
269+registry_port = 5000
270+registry_domain = "registry.yourdomain.com"
271+
272+[secrets]
273+backend = "unsafe" # Use "pass" or "sops" for production
274+
275+[registry_auth]
276+enabled = false # Enable after testing
277+
278+[routes]
279+"app.yourdomain.com" = "myapp:latest"
280+EOF
281+```
282+
283+Data is stored in `~/.gordon/` (registry, env files, logs, secrets).
284+
285+### 6. Create Systemd Service
257286 ```bash
258-# Create user service
259287 mkdir -p ~/.config/systemd/user
260288 cat > ~/.config/systemd/user/gordon.service <<EOF
261289 [Unit]
@@ -267,19 +295,19 @@ Type=simple
267295 Restart=always
268296 RestartSec=5
269297 ExecStart=/usr/local/bin/gordon start
270-WorkingDirectory=%h
271298
272299 [Install]
273300 WantedBy=default.target
274301 EOF
275302
276-# Enable and start service
303+# Enable and start
277304 systemctl --user daemon-reload
278305 systemctl --user enable --now gordon
279306 sudo loginctl enable-linger $USER
280307
281-# Verify it's running
308+# Verify
282309 systemctl --user status gordon
310+journalctl --user -u gordon -f # Watch logs
283311 ```
284312
285313 ## Deployment Strategies
@@ -40,20 +40,19 @@ Build on your machine, push to deploy. Works from your laptop or CI.
40 ### Installation40 ### Installation
41 41
42 ```bash42 ```bash
43-# Download Gordon from the releases page43+# Download from releases
44-# https://github.com/bnema/gordon/releases/latest44+wget https://github.com/bnema/gordon/releases/latest/download/gordon_linux_amd64.tar.gz
45-# Example: wget https://github.com/bnema/gordon/releases/download/v2.0.0/gordon_2.0.0_linux_amd64.tar.gz45+tar -xzf gordon_linux_amd64.tar.gz
46-# Then extract:
47-tar -xzf gordon_*.tar.gz
48 chmod +x gordon46 chmod +x gordon
49 sudo mv gordon /usr/local/bin/47 sudo mv gordon /usr/local/bin/
50 48
51-# Create initial config49+# Create config
52-gordon start50+mkdir -p ~/.config/gordon
53-# Press Ctrl+C after config is created51+cp examples/minimal.toml ~/.config/gordon/gordon.toml
52+# Edit gordon.toml with your domain
54 ```53 ```
55 54
56-**Important:** This is just the binary installation. For a complete working setup including networking, firewall, and systemd service, follow the [detailed setup guide](#detailed-setup-guide-podman-rootless-mode) below.55+**Important:** For a complete working setup including networking, firewall, and systemd service, follow the [detailed setup guide](#detailed-setup-guide-podman-rootless-mode) below.
57 56
58 ## Core Concepts57 ## Core Concepts
59 58
@@ -86,7 +85,7 @@ VOLUME ["/app/uploads", "/app/data"] # Multiple volumes supported
86 ### Environment Configuration85 ### Environment Configuration
87 Gordon automatically creates and loads env files based on domain names:86 Gordon automatically creates and loads env files based on domain names:
88 ```bash87 ```bash
89-# Auto-created on first run: ~/.local/share/gordon/env/app_mydomain_com.env88+# Auto-created on first run: ~/.gordon/env/app_mydomain_com.env
90 # Just add your variables:89 # Just add your variables:
91 DATABASE_URL=postgresql://localhost:5432/myapp90 DATABASE_URL=postgresql://localhost:5432/myapp
92 API_KEY=sk-123456789091 API_KEY=sk-1234567890
@@ -107,7 +106,7 @@ Gordon also supports network groups, see [examples/](examples/) for advanced usa
107 - **Volumes**: Automatically created from Dockerfile VOLUME directives, persist across updates106 - **Volumes**: Automatically created from Dockerfile VOLUME directives, persist across updates
108 107
109 ### Production ready logging108 ### Production ready logging
110-- **Logs**: All container output saved to `~/.local/share/gordon/logs/containers/`109+- **Logs**: All container output saved to `~/.gordon/logs/containers/`
111 - **Rotation**: Logs rotate at 100MB, keeping 3 backups for 28 days110 - **Rotation**: Logs rotate at 100MB, keeping 3 backups for 28 days
112 111
113 ## Configuration112 ## Configuration
@@ -204,9 +203,9 @@ See [examples/github-workflow.yml](examples/github-workflow.yml) and [.github/ac
204 203
205 ## Detailed Setup Guide (Podman Rootless Mode)204 ## Detailed Setup Guide (Podman Rootless Mode)
206 205
207-> **Note:** This guide uses Podman in rootless mode for enhanced security. Docker users can follow similar steps - Gordon works with any OCI-compatible runtime. Refer to Quick Start for the binary installation.206+> **Note:** This guide uses Podman in rootless mode for enhanced security. Docker users can follow similar steps. Gordon works with any OCI-compatible runtime.
208 207
209-### 1. VPS Preparation208+### 1. System Preparation
210 ```bash209 ```bash
211 # Update system210 # Update system
212 sudo apt update && sudo apt upgrade -y211 sudo apt update && sudo apt upgrade -y
@@ -216,11 +215,11 @@ sudo apt install -y podman ufw
216 215
217 # Configure firewall216 # Configure firewall
218 sudo ufw allow 22/tcp 80/tcp 443/tcp217 sudo ufw allow 22/tcp 80/tcp 443/tcp
219-sudo default deny218+sudo ufw default deny incoming
220 sudo ufw --force enable219 sudo ufw --force enable
221 ```220 ```
222 221
223-### 2. Enable Port Forwarding222+### 2. Port Forwarding (rootless requires this)
224 ```bash223 ```bash
225 # Forward 80/443 to unprivileged port 8080224 # Forward 80/443 to unprivileged port 8080
226 sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080225 sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
@@ -231,21 +230,19 @@ sudo apt install -y iptables-persistent
231 sudo netfilter-persistent save230 sudo netfilter-persistent save
232 ```231 ```
233 232
234-### 3. Configure Rootless Containers233+### 3. Rootless Container Setup
235 ```bash234 ```bash
236 # Enable user namespaces235 # Enable user namespaces
237 echo 'user.max_user_namespaces=28633' | sudo tee -a /etc/sysctl.conf236 echo 'user.max_user_namespaces=28633' | sudo tee -a /etc/sysctl.conf
238 sudo sysctl -p237 sudo sysctl -p
239 238
240-# Setup subuid/subgid239+# Setup subuid/subgid for your user
241 sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER240 sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
242 241
243 # Enable podman socket242 # Enable podman socket
244 systemctl --user enable --now podman.socket243 systemctl --user enable --now podman.socket
245-```
246 244
247-### 4. Registry Configuration245+# Allow localhost registry (podman config)
248-```bash
249 mkdir -p ~/.config/containers246 mkdir -p ~/.config/containers
250 cat > ~/.config/containers/registries.conf <<EOF247 cat > ~/.config/containers/registries.conf <<EOF
251 [registries.insecure]248 [registries.insecure]
@@ -253,9 +250,40 @@ registries = ['localhost:5000']
253 EOF250 EOF
254 ```251 ```
255 252
256-### 5. Create Systemd Service253+### 4. Install Gordon
254+```bash
255+# Download from releases
256+wget https://github.com/bnema/gordon/releases/latest/download/gordon_linux_amd64.tar.gz
257+tar -xzf gordon_linux_amd64.tar.gz
258+chmod +x gordon
259+sudo mv gordon /usr/local/bin/
260+```
261+
262+### 5. Configure Gordon
263+```bash
264+# Create config directory and file
265+mkdir -p ~/.config/gordon
266+cat > ~/.config/gordon/gordon.toml <<EOF
267+[server]
268+port = 8080
269+registry_port = 5000
270+registry_domain = "registry.yourdomain.com"
271+
272+[secrets]
273+backend = "unsafe" # Use "pass" or "sops" for production
274+
275+[registry_auth]
276+enabled = false # Enable after testing
277+
278+[routes]
279+"app.yourdomain.com" = "myapp:latest"
280+EOF
281+```
282+
283+Data is stored in `~/.gordon/` (registry, env files, logs, secrets).
284+
285+### 6. Create Systemd Service
257 ```bash286 ```bash
258-# Create user service
259 mkdir -p ~/.config/systemd/user287 mkdir -p ~/.config/systemd/user
260 cat > ~/.config/systemd/user/gordon.service <<EOF288 cat > ~/.config/systemd/user/gordon.service <<EOF
261 [Unit]289 [Unit]
@@ -267,19 +295,19 @@ Type=simple
267 Restart=always295 Restart=always
268 RestartSec=5296 RestartSec=5
269 ExecStart=/usr/local/bin/gordon start297 ExecStart=/usr/local/bin/gordon start
270-WorkingDirectory=%h
271 298
272 [Install]299 [Install]
273 WantedBy=default.target300 WantedBy=default.target
274 EOF301 EOF
275 302
276-# Enable and start service303+# Enable and start
277 systemctl --user daemon-reload304 systemctl --user daemon-reload
278 systemctl --user enable --now gordon305 systemctl --user enable --now gordon
279 sudo loginctl enable-linger $USER306 sudo loginctl enable-linger $USER
280 307
281-# Verify it's running308+# Verify
282 systemctl --user status gordon309 systemctl --user status gordon
310+journalctl --user -u gordon -f # Watch logs
283 ```311 ```
284 312
285 ## Deployment Strategies313 ## Deployment Strategies
M internal/adapters/in/cli/auth.go +3 -10
@@ -15,6 +15,7 @@ import (
1515 "golang.org/x/term"
1616
1717 "gordon/internal/adapters/out/tokenstore"
18+ "gordon/internal/app"
1819 "gordon/internal/domain"
1920 "gordon/internal/usecase/auth"
2021 )
@@ -318,18 +319,10 @@ func loadAuthConfig(configPath string) (*cliConfig, error) {
318319 v := viper.New()
319320
320321 // Set defaults
321- v.SetDefault("server.data_dir", "/var/lib/gordon")
322+ v.SetDefault("server.data_dir", app.DefaultDataDir())
322323 v.SetDefault("secrets.backend", "unsafe")
323324
324- if configPath != "" {
325- v.SetConfigFile(configPath)
326- } else {
327- v.SetConfigName("gordon")
328- v.SetConfigType("yaml")
329- v.AddConfigPath("/etc/gordon")
330- v.AddConfigPath("$HOME/.gordon")
331- v.AddConfigPath(".")
332- }
325+ app.ConfigureViper(v, configPath)
333326
334327 if err := v.ReadInConfig(); err != nil {
335328 if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
@@ -15,6 +15,7 @@ import (
15 "golang.org/x/term"15 "golang.org/x/term"
16 16
17 "gordon/internal/adapters/out/tokenstore"17 "gordon/internal/adapters/out/tokenstore"
18+ "gordon/internal/app"
18 "gordon/internal/domain"19 "gordon/internal/domain"
19 "gordon/internal/usecase/auth"20 "gordon/internal/usecase/auth"
20 )21 )
@@ -318,18 +319,10 @@ func loadAuthConfig(configPath string) (*cliConfig, error) {
318 v := viper.New()319 v := viper.New()
319 320
320 // Set defaults321 // Set defaults
321- v.SetDefault("server.data_dir", "/var/lib/gordon")322+ v.SetDefault("server.data_dir", app.DefaultDataDir())
322 v.SetDefault("secrets.backend", "unsafe")323 v.SetDefault("secrets.backend", "unsafe")
323 324
324- if configPath != "" {325+ app.ConfigureViper(v, configPath)
325- v.SetConfigFile(configPath)
326- } else {
327- v.SetConfigName("gordon")
328- v.SetConfigType("yaml")
329- v.AddConfigPath("/etc/gordon")
330- v.AddConfigPath("$HOME/.gordon")
331- v.AddConfigPath(".")
332- }
333 326
334 if err := v.ReadInConfig(); err != nil {327 if err := v.ReadInConfig(); err != nil {
335 if _, ok := err.(viper.ConfigFileNotFoundError); !ok {328 if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
A internal/app/paths.go +33 -0
@@ -0,0 +1,33 @@
1+// Package app provides the application initialization and wiring.
2+package app
3+
4+import (
5+ "os"
6+ "path/filepath"
7+
8+ "github.com/spf13/viper"
9+)
10+
11+// DefaultDataDir returns the default data directory path.
12+// Uses ~/.gordon for user installations, /var/lib/gordon as fallback.
13+func DefaultDataDir() string {
14+ if homeDir, err := os.UserHomeDir(); err == nil {
15+ return filepath.Join(homeDir, ".gordon")
16+ }
17+ return "/var/lib/gordon"
18+}
19+
20+// ConfigureViper sets up viper with standard config file search paths.
21+// Config file: gordon.toml
22+// Search paths (in order): /etc/gordon, ~/.config/gordon, current directory
23+func ConfigureViper(v *viper.Viper, configPath string) {
24+ if configPath != "" {
25+ v.SetConfigFile(configPath)
26+ } else {
27+ v.SetConfigName("gordon")
28+ v.SetConfigType("toml")
29+ v.AddConfigPath("/etc/gordon")
30+ v.AddConfigPath("$HOME/.config/gordon")
31+ v.AddConfigPath(".")
32+ }
33+}
@@ -0,0 +1,33 @@
1+// Package app provides the application initialization and wiring.
2+package app
3+
4+import (
5+ "os"
6+ "path/filepath"
7+
8+ "github.com/spf13/viper"
9+)
10+
11+// DefaultDataDir returns the default data directory path.
12+// Uses ~/.gordon for user installations, /var/lib/gordon as fallback.
13+func DefaultDataDir() string {
14+ if homeDir, err := os.UserHomeDir(); err == nil {
15+ return filepath.Join(homeDir, ".gordon")
16+ }
17+ return "/var/lib/gordon"
18+}
19+
20+// ConfigureViper sets up viper with standard config file search paths.
21+// Config file: gordon.toml
22+// Search paths (in order): /etc/gordon, ~/.config/gordon, current directory
23+func ConfigureViper(v *viper.Viper, configPath string) {
24+ if configPath != "" {
25+ v.SetConfigFile(configPath)
26+ } else {
27+ v.SetConfigName("gordon")
28+ v.SetConfigType("toml")
29+ v.AddConfigPath("/etc/gordon")
30+ v.AddConfigPath("$HOME/.config/gordon")
31+ v.AddConfigPath(".")
32+ }
33+}
M internal/app/run.go +7 -15
@@ -276,7 +276,7 @@ func createOutputAdapters(ctx context.Context, log zerowrap.Logger) (*docker.Run
276276 func createStorage(cfg Config, log zerowrap.Logger) (*filesystem.BlobStorage, *filesystem.ManifestStorage, error) {
277277 dataDir := cfg.Server.DataDir
278278 if dataDir == "" {
279- dataDir = "/var/lib/gordon"
279+ dataDir = DefaultDataDir()
280280 }
281281
282282 registryDir := filepath.Join(dataDir, "registry")
@@ -298,7 +298,7 @@ func createStorage(cfg Config, log zerowrap.Logger) (*filesystem.BlobStorage, *f
298298 func createEnvLoader(cfg Config, log zerowrap.Logger) (*envloader.FileLoader, error) {
299299 dataDir := cfg.Server.DataDir
300300 if dataDir == "" {
301- dataDir = "/var/lib/gordon"
301+ dataDir = DefaultDataDir()
302302 }
303303
304304 envDir := cfg.Env.Dir
@@ -339,7 +339,7 @@ func createLogWriter(cfg Config, log zerowrap.Logger) (*logwriter.LogWriter, err
339339 if logDir == "" {
340340 dataDir := cfg.Server.DataDir
341341 if dataDir == "" {
342- dataDir = "/var/lib/gordon"
342+ dataDir = DefaultDataDir()
343343 }
344344 logDir = filepath.Join(dataDir, "logs", "containers")
345345 }
@@ -384,7 +384,7 @@ func createAuthService(ctx context.Context, cfg Config, log zerowrap.Logger) (ou
384384 // Get data directory
385385 dataDir := cfg.Server.DataDir
386386 if dataDir == "" {
387- dataDir = "/var/lib/gordon"
387+ dataDir = DefaultDataDir()
388388 }
389389
390390 // Create token store (needed for token auth or to store revocations)
@@ -723,7 +723,7 @@ func findPidFile() string {
723723 func loadConfig(v *viper.Viper, configPath string) error {
724724 v.SetDefault("server.port", 80)
725725 v.SetDefault("server.registry_port", 5000)
726- v.SetDefault("server.data_dir", "/var/lib/gordon")
726+ v.SetDefault("server.data_dir", DefaultDataDir())
727727 v.SetDefault("logging.level", "info")
728728 v.SetDefault("logging.format", "console")
729729 v.SetDefault("logging.file.enabled", false)
@@ -735,21 +735,13 @@ func loadConfig(v *viper.Viper, configPath string) error {
735735 v.SetDefault("logging.container_logs.max_size", 100)
736736 v.SetDefault("logging.container_logs.max_backups", 3)
737737 v.SetDefault("logging.container_logs.max_age", 28)
738- v.SetDefault("env.dir", "/var/lib/gordon/env")
738+ v.SetDefault("env.dir", "") // defaults to {data_dir}/env when empty
739739 v.SetDefault("secrets.backend", "unsafe")
740740 v.SetDefault("registry_auth.enabled", false)
741741 v.SetDefault("registry_auth.type", "password")
742742 v.SetDefault("registry_auth.token_expiry", "720h")
743743
744- if configPath != "" {
745- v.SetConfigFile(configPath)
746- } else {
747- v.SetConfigName("gordon")
748- v.SetConfigType("yaml")
749- v.AddConfigPath("/etc/gordon")
750- v.AddConfigPath("$HOME/.gordon")
751- v.AddConfigPath(".")
752- }
744+ ConfigureViper(v, configPath)
753745
754746 if err := v.ReadInConfig(); err != nil {
755747 if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
@@ -276,7 +276,7 @@ func createOutputAdapters(ctx context.Context, log zerowrap.Logger) (*docker.Run
276 func createStorage(cfg Config, log zerowrap.Logger) (*filesystem.BlobStorage, *filesystem.ManifestStorage, error) {276 func createStorage(cfg Config, log zerowrap.Logger) (*filesystem.BlobStorage, *filesystem.ManifestStorage, error) {
277 dataDir := cfg.Server.DataDir277 dataDir := cfg.Server.DataDir
278 if dataDir == "" {278 if dataDir == "" {
279- dataDir = "/var/lib/gordon"279+ dataDir = DefaultDataDir()
280 }280 }
281 281
282 registryDir := filepath.Join(dataDir, "registry")282 registryDir := filepath.Join(dataDir, "registry")
@@ -298,7 +298,7 @@ func createStorage(cfg Config, log zerowrap.Logger) (*filesystem.BlobStorage, *f
298 func createEnvLoader(cfg Config, log zerowrap.Logger) (*envloader.FileLoader, error) {298 func createEnvLoader(cfg Config, log zerowrap.Logger) (*envloader.FileLoader, error) {
299 dataDir := cfg.Server.DataDir299 dataDir := cfg.Server.DataDir
300 if dataDir == "" {300 if dataDir == "" {
301- dataDir = "/var/lib/gordon"301+ dataDir = DefaultDataDir()
302 }302 }
303 303
304 envDir := cfg.Env.Dir304 envDir := cfg.Env.Dir
@@ -339,7 +339,7 @@ func createLogWriter(cfg Config, log zerowrap.Logger) (*logwriter.LogWriter, err
339 if logDir == "" {339 if logDir == "" {
340 dataDir := cfg.Server.DataDir340 dataDir := cfg.Server.DataDir
341 if dataDir == "" {341 if dataDir == "" {
342- dataDir = "/var/lib/gordon"342+ dataDir = DefaultDataDir()
343 }343 }
344 logDir = filepath.Join(dataDir, "logs", "containers")344 logDir = filepath.Join(dataDir, "logs", "containers")
345 }345 }
@@ -384,7 +384,7 @@ func createAuthService(ctx context.Context, cfg Config, log zerowrap.Logger) (ou
384 // Get data directory384 // Get data directory
385 dataDir := cfg.Server.DataDir385 dataDir := cfg.Server.DataDir
386 if dataDir == "" {386 if dataDir == "" {
387- dataDir = "/var/lib/gordon"387+ dataDir = DefaultDataDir()
388 }388 }
389 389
390 // Create token store (needed for token auth or to store revocations)390 // Create token store (needed for token auth or to store revocations)
@@ -723,7 +723,7 @@ func findPidFile() string {
723 func loadConfig(v *viper.Viper, configPath string) error {723 func loadConfig(v *viper.Viper, configPath string) error {
724 v.SetDefault("server.port", 80)724 v.SetDefault("server.port", 80)
725 v.SetDefault("server.registry_port", 5000)725 v.SetDefault("server.registry_port", 5000)
726- v.SetDefault("server.data_dir", "/var/lib/gordon")726+ v.SetDefault("server.data_dir", DefaultDataDir())
727 v.SetDefault("logging.level", "info")727 v.SetDefault("logging.level", "info")
728 v.SetDefault("logging.format", "console")728 v.SetDefault("logging.format", "console")
729 v.SetDefault("logging.file.enabled", false)729 v.SetDefault("logging.file.enabled", false)
@@ -735,21 +735,13 @@ func loadConfig(v *viper.Viper, configPath string) error {
735 v.SetDefault("logging.container_logs.max_size", 100)735 v.SetDefault("logging.container_logs.max_size", 100)
736 v.SetDefault("logging.container_logs.max_backups", 3)736 v.SetDefault("logging.container_logs.max_backups", 3)
737 v.SetDefault("logging.container_logs.max_age", 28)737 v.SetDefault("logging.container_logs.max_age", 28)
738- v.SetDefault("env.dir", "/var/lib/gordon/env")738+ v.SetDefault("env.dir", "") // defaults to {data_dir}/env when empty
739 v.SetDefault("secrets.backend", "unsafe")739 v.SetDefault("secrets.backend", "unsafe")
740 v.SetDefault("registry_auth.enabled", false)740 v.SetDefault("registry_auth.enabled", false)
741 v.SetDefault("registry_auth.type", "password")741 v.SetDefault("registry_auth.type", "password")
742 v.SetDefault("registry_auth.token_expiry", "720h")742 v.SetDefault("registry_auth.token_expiry", "720h")
743 743
744- if configPath != "" {744+ ConfigureViper(v, configPath)
745- v.SetConfigFile(configPath)
746- } else {
747- v.SetConfigName("gordon")
748- v.SetConfigType("yaml")
749- v.AddConfigPath("/etc/gordon")
750- v.AddConfigPath("$HOME/.gordon")
751- v.AddConfigPath(".")
752- }
753 745
754 if err := v.ReadInConfig(); err != nil {746 if err := v.ReadInConfig(); err != nil {
755 if _, ok := err.(viper.ConfigFileNotFoundError); !ok {747 if _, ok := err.(viper.ConfigFileNotFoundError); !ok {

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close