detached 27908bb

docs: streamline README, remove AI-generated fluff

- Remove mascot image and centered header
- New direct tagline focused on value prop
- Remove generic "Key Features" and "Perfect For" sections
- Replace "Philosophy" with concise "Why Gordon?"
- Cut examples/README.md from 438 to 29 lines
- Remove duplicated content, use table format
commit
27908bbe72b76e3ddec8b85c77ed3d39848f2978
author
brice · · 2026-01-12 19:35 UTC
committer
brice · · 2026-01-12 22:36 UTC
parent
086173e
signature
unsigned
2 files · +31 -461
M README.md +12 -33
@@ -1,34 +1,16 @@
11 # Gordon
22
3-> Deploy containers to your VPS in seconds, not hours. One push, zero complexity.
3+Your VPS already runs Docker. Gordon makes it deploy on push.
44
5-<div align="center">
6- <img src="assets/gordon-mascot-hq-trsp.png" alt="Gordon Mascot" width="200">
7- <h3>The Smart Way to Deploy Containers on Your VPS</h3>
8- <p><em>Push image → Auto-deploy → Zero downtime</em></p>
9-</div>
10-
11-## What is Gordon?
12-
13-Gordon is a lightweight deployment system that turns any VPS into a container hosting platform with push-to-deploy capabilities. It combines a private container registry with an intelligent reverse proxy to create a self-hosted alternative to complex orchestration systems.
14-
15-### Key Features
16-
17-- **Built-in Container Registry**: Your VPS becomes a private registry
18-- **Push-to-Deploy**: Pushing an image triggers automatic deployment
19-- **Smart Routing**: Multi-domain support with automatic HTTPS
20-- **Zero-Downtime Updates**: Graceful container swaps on new pushes
21-- **Network Isolation**: Each app gets its own network with attached services
22-- **Auto-Volume Management**: Persistent storage from Dockerfile VOLUME directives
23-- **Environment Merging**: Dockerfile ENV + your custom variables
24-- **Minimal Footprint**: ~15MB RAM usage, single binary
5+```bash
6+docker build -t myapp .
7+docker push registry.your-server.com/myapp:latest
8+# Live at https://app.your-server.com
9+```
2510
26-### Perfect For
11+> docker push → live in production. From your laptop or CI. Your choice.
2712
28-- **Solo developers** running multiple projects on one VPS
29-- **Small teams** wanting simple, reliable deployments
30-- **Agencies** managing client applications across servers
31-- **Anyone** tired of overengineered deployment solutions
13+Gordon combines a private container registry with a reverse proxy. Push an image, it deploys. Handles multiple domains, zero downtime updates, persistent volumes, and environment merging. Single binary, ~15MB RAM.
3214
3315 ## How It Works
3416
@@ -348,14 +330,11 @@ Gordon is open source and welcomes contributions:
348330 - [Suggest features](https://github.com/bnema/gordon/discussions)
349331 - [Submit PRs](https://github.com/bnema/gordon/pulls)
350332
351-## Philosophy
333+## Why Gordon?
352334
353-Traditional deployment pipelines recreate your development environment in CI/CD systems, adding complexity and points of failure. Gordon takes a different approach: **your development machine is already a perfect build environment**.
335+Most deployment tools require a CI/CD pipeline before you can ship anything. Gordon works the other way: push from your laptop on day one, add GitHub Actions when the project grows.
354336
355-```bash
356-# Traditional: Code → CI/CD → Build → Test → Deploy → Hope
357-# Gordon: Code → Build → Test → Push → Done
358-```
337+Your dev machine has 16 cores and 32GB RAM. Your VPS has 2 cores and 2GB. Why rebuild everything on the weak machine? Build locally, push the result.
359338
360339 ## License
361340
@@ -363,4 +342,4 @@ GPL-3.0 - Use freely, contribute back.
363342
364343 ---
365344
366-**Built for developers who ship.** If Gordon helps you deploy faster, [give it a star](https://github.com/bnema/gordon).⏎̸
345+If your deployment process has more YAML than application code, something went wrong.⏎̸
@@ -1,34 +1,16 @@
1 # Gordon1 # Gordon
2 2
3-> Deploy containers to your VPS in seconds, not hours. One push, zero complexity.3+Your VPS already runs Docker. Gordon makes it deploy on push.
4 4
5-<div align="center">5+```bash
6- <img src="assets/gordon-mascot-hq-trsp.png" alt="Gordon Mascot" width="200">6+docker build -t myapp .
7- <h3>The Smart Way to Deploy Containers on Your VPS</h3>7+docker push registry.your-server.com/myapp:latest
8- <p><em>Push image → Auto-deploy → Zero downtime</em></p>8+# Live at https://app.your-server.com
9-</div>9+```
10-
11-## What is Gordon?
12-
13-Gordon is a lightweight deployment system that turns any VPS into a container hosting platform with push-to-deploy capabilities. It combines a private container registry with an intelligent reverse proxy to create a self-hosted alternative to complex orchestration systems.
14-
15-### Key Features
16-
17-- **Built-in Container Registry**: Your VPS becomes a private registry
18-- **Push-to-Deploy**: Pushing an image triggers automatic deployment
19-- **Smart Routing**: Multi-domain support with automatic HTTPS
20-- **Zero-Downtime Updates**: Graceful container swaps on new pushes
21-- **Network Isolation**: Each app gets its own network with attached services
22-- **Auto-Volume Management**: Persistent storage from Dockerfile VOLUME directives
23-- **Environment Merging**: Dockerfile ENV + your custom variables
24-- **Minimal Footprint**: ~15MB RAM usage, single binary
25 10
26-### Perfect For11+> docker push → live in production. From your laptop or CI. Your choice.
27 12
28-- **Solo developers** running multiple projects on one VPS13+Gordon combines a private container registry with a reverse proxy. Push an image, it deploys. Handles multiple domains, zero downtime updates, persistent volumes, and environment merging. Single binary, ~15MB RAM.
29-- **Small teams** wanting simple, reliable deployments
30-- **Agencies** managing client applications across servers
31-- **Anyone** tired of overengineered deployment solutions
32 14
33 ## How It Works15 ## How It Works
34 16
@@ -348,14 +330,11 @@ Gordon is open source and welcomes contributions:
348 - [Suggest features](https://github.com/bnema/gordon/discussions)330 - [Suggest features](https://github.com/bnema/gordon/discussions)
349 - [Submit PRs](https://github.com/bnema/gordon/pulls)331 - [Submit PRs](https://github.com/bnema/gordon/pulls)
350 332
351-## Philosophy333+## Why Gordon?
352 334
353-Traditional deployment pipelines recreate your development environment in CI/CD systems, adding complexity and points of failure. Gordon takes a different approach: **your development machine is already a perfect build environment**.335+Most deployment tools require a CI/CD pipeline before you can ship anything. Gordon works the other way: push from your laptop on day one, add GitHub Actions when the project grows.
354 336
355-```bash337+Your dev machine has 16 cores and 32GB RAM. Your VPS has 2 cores and 2GB. Why rebuild everything on the weak machine? Build locally, push the result.
356-# Traditional: Code → CI/CD → Build → Test → Deploy → Hope
357-# Gordon: Code → Build → Test → Push → Done
358-```
359 338
360 ## License339 ## License
361 340
@@ -363,4 +342,4 @@ GPL-3.0 - Use freely, contribute back.
363 342
364 ---343 ---
365 344
366-**Built for developers who ship.** If Gordon helps you deploy faster, [give it a star](https://github.com/bnema/gordon).⏎̸345+If your deployment process has more YAML than application code, something went wrong.⏎̸
M examples/README.md +19 -428
@@ -1,438 +1,29 @@
1-# Gordon Configuration Examples
1+# Examples
22
3-This directory contains configuration examples for different use cases and environments.
3+Copy an example and edit:
44
5-## Full Configuration Reference
6-
7-Here's the complete Gordon configuration with all default values:
8-
9-```toml
10-# gordon.toml - Complete configuration reference with defaults
11-
12-[server]
13-port = 8080 # HTTP/HTTPS proxy port (default: 8080)
14-registry_port = 5000 # Container registry port (default: 5000)
15-registry_domain = "" # REQUIRED - Your registry domain (no default)
16-runtime = "auto" # Container runtime (default: "auto")
17- # Options: auto, docker, podman, podman-rootless
18-socket_path = "" # Custom socket path (default: "" - auto-detected)
19-data_dir = "~/.local/share/gordon" # Data directory (default: ~/.local/share/gordon)
20- # Root user default: ./data
21-ssl_email = "" # Email for Let's Encrypt (default: "" - uses Cloudflare)
22-
23-[secrets]
24-backend = "pass" # Secrets backend (default: "pass")
25- # Options: pass, sops, unsafe
26- # "unsafe" stores secrets in plain text (dev only)
27-
28-[registry_auth]
29-enabled = true # Enable registry authentication (default: true)
30-type = "password" # Auth type (default: "password")
31- # Options: password, token
32-
33-# Password auth settings (when type = "password")
34-username = "" # REQUIRED - username for docker login
35-password_hash = "" # REQUIRED - path to bcrypt hash in secrets backend
36- # Example: "gordon/registry/password_hash"
37-
38-# Token auth settings (when type = "token")
39-# token_secret = "" # REQUIRED - path to JWT signing secret
40- # Example: "gordon/registry/token_secret"
41-
42-[routes]
43-# Domain to image mappings (default: empty)
44-# "app.example.com" = "myapp:latest"
45-# "api.example.com" = "myapi:v1.0.0"
46-
47-[network_groups]
48-# Group domains for shared networking (default: empty)
49-# "backend" = ["app.example.com", "api.example.com"]
50-# "monitoring" = ["grafana.example.com", "prometheus.example.com"]
51-
52-[attachments]
53-# Attach services to apps or groups (default: empty)
54-# "app.example.com" = ["postgres:latest", "redis:latest"]
55-# "backend" = ["shared-cache:latest", "message-queue:latest"]
56-
57-[auto_route]
58-enabled = false # Auto-create routes from image names (default: false)
59-
60-[volumes]
61-auto_create = true # Auto-create volumes from VOLUME directives (default: true)
62-prefix = "gordon" # Volume name prefix (default: "gordon")
63-preserve = true # Keep volumes when removing containers (default: true)
64-
65-[env]
66-dir = "{data_dir}/env" # Environment files directory (default: {data_dir}/env)
67-# Note: Secret providers are now configured via [secrets].backend
68-
69-[logging]
70-enabled = true # Enable file logging (default: true)
71-level = "info" # Log level (default: "info")
72- # Options: trace, debug, info, warn, error, fatal, panic
73-dir = "{data_dir}/logs" # Log directory (default: {data_dir}/logs)
74-main_log_file = "gordon.log" # Main log file (default: "gordon.log")
75-proxy_log_file = "proxy.log" # Proxy log file (default: "proxy.log")
76-container_log_dir = "containers" # Container logs subdirectory (default: "containers")
77-max_size = 100 # Max log size in MB (default: 100)
78-max_backups = 3 # Number of old logs to keep (default: 3)
79-max_age = 28 # Days to keep old logs (default: 28)
80-compress = true # Compress rotated logs (default: true)
81-```
82-
83-## Available Examples
84-
85-### [`minimal.toml`](minimal.toml)
86-**Perfect for getting started**
87-- Single route configuration
88-- Default settings
89-- No authentication
90-- Ideal for testing and learning
91-
92-### [`development.toml`](development.toml)
93-**Local development setup**
94-- Multiple .local domains
95-- No authentication for ease of use
96-- Third-party development tools
97-- localhost registry
98-
99-### [`staging.toml`](staging.toml)
100-**Staging and preview environments**
101-- Branch-based deployments
102-- Feature branch testing
103-- PR preview environments
104-- Separate staging registry
105-
106-### [`production.toml`](production.toml)
107-**Production-ready configuration**
108-- Pinned image versions
109-- Registry authentication
110-- Multiple production services
111-- Monitoring tools included
112-
113-### [`saas-multi-tenant.toml`](saas-multi-tenant.toml)
114-**Multi-tenant SaaS platform**
115-- Customer subdomains
116-- Custom domains
117-- Shared application architecture
118-- Enterprise features
119-
120-### [`logging.toml`](logging.toml)
121-**Comprehensive logging configuration**
122-- Complete logging setup examples
123-- Different logging levels and configurations
124-- Production and development logging strategies
125-- Log rotation and monitoring examples
126-
127-### [`rollback-workflow-example.md`](rollback-workflow-example.md)
128-**Simple version deployment and rollback workflow**
129-- Manifest annotation-based deployments
130-- Simple version changes for deployments and rollbacks
131-- Version tracking and deployment strategies
132-
133-### [`github-workflow.yml`](github-workflow.yml)
134-**GitHub Actions CI/CD workflow**
135-- Automatic deployment on tag push
136-- Uses official Gordon deploy action
137-- Build arguments and multi-platform support
138-- Monorepo configurations
139-
140-## Quick Start
141-
142-1. **Choose an example** that matches your use case
143-2. **Copy the config file** to your Gordon directory:
144- ```bash
145- cp examples/minimal.toml gordon.toml
146- ```
147-3. **Edit the configuration** with your domains and settings
148-4. **Start Gordon**:
149- ```bash
150- gordon start
151- ```
152-
153-## Customization Tips
154-
155-### Domain Configuration
156-Update the `[routes]` section with your actual domains:
157-```toml
158-[routes]
159-"your-domain.com" = "your-app:latest"
160-"api.your-domain.com" = "your-api:v1.0.0"
161-```
162-
163-### Registry Setup
164-Configure your registry domain and authentication:
165-```toml
166-[server]
167-registry_domain = "registry.your-domain.com"
168-
169-[secrets]
170-backend = "pass" # or "sops", or "unsafe" for development
171-
172-[registry_auth]
173-enabled = true
174-type = "password" # or "token"
175-
176-# For password auth:
177-username = "deploy"
178-password_hash = "gordon/registry/password_hash" # path in secrets backend
179-
180-# For token auth (recommended for CI/CD):
181-# type = "token"
182-# token_secret = "gordon/registry/token_secret"
183-```
184-
185-**Token Management CLI:**
186-```bash
187-# Generate a bcrypt hash for password auth
188-gordon auth password hash
189-
190-# Generate tokens for CI/CD (token auth type)
191-gordon auth token generate --subject ci-bot --scopes push,pull --expiry 0
192-gordon auth token list
193-gordon auth token revoke <token-id>
194-```
195-
196-### Container Runtime Setup
197-Gordon supports Docker and Podman with automatic detection:
198-```toml
199-[server]
200-runtime = "auto" # auto, docker, podman, podman-rootless
201-socket_path = "" # optional custom socket path
202-
203-# Examples:
204-# runtime = "docker" # Force Docker
205-# runtime = "podman" # Force Podman root
206-# runtime = "podman-rootless" # Force Podman rootless
207-# socket_path = "unix:///run/user/1000/podman/podman.sock"
208-```
209-
210-Override with environment variables:
211-```bash
212-# Works for both Docker and Podman
213-export CONTAINER_HOST=unix:///custom/path/container.sock
214-export CONTAINER_HOST=tcp://remote-docker:2376
215-gordon start
216-```
217-
218-### Logging Configuration
219-Enable comprehensive logging to monitor your deployments:
220-```toml
221-[logging]
222-enabled = true # Enable file-based logging
223-level = "info" # Log level: trace, debug, info, warn, error
224-dir = "./logs" # Directory for log files
225-main_log_file = "gordon.log" # Main application logs
226-proxy_log_file = "proxy.log" # HTTP proxy traffic logs
227-container_log_dir = "containers" # Container logs subdirectory
228-
229-# Log rotation settings
230-max_size = 100 # Max log file size in MB
231-max_backups = 5 # Number of old log files to keep
232-max_age = 30 # Max age in days
233-compress = true # Compress old log files
234-```
235-
236-See [`logging.toml`](logging.toml) for comprehensive logging examples.
237-
238-### Environment Variables
239-Gordon intelligently merges environment variables from multiple sources:
240-
241-1. **Dockerfile ENV directives** (automatically detected)
242-2. **Your .env files** (override Dockerfile ENV)
243-3. **Runtime environment** (lowest priority)
244-
245-#### Dockerfile ENV (Automatic Detection)
246-```dockerfile
247-FROM node:18-alpine
248-WORKDIR /app
249-
250-# Gordon automatically reads these ENV directives
251-ENV NODE_ENV=production
252-ENV PORT=3000
253-ENV LOG_LEVEL=info
254-ENV DATABASE_HOST=localhost
255-
256-COPY package*.json ./
257-RUN npm install
258-COPY . .
259-EXPOSE 3000
260-CMD ["npm", "start"]
261-```
262-
263-#### Custom Environment Files
264-Create `.env` files for each route: `./data/env/app_yourdomain_com.env`
2655 ```bash
266-# Your custom overrides (these take precedence over Dockerfile ENV)
267-DATABASE_HOST=db.mydomain.com
268-DATABASE_USER=myapp
269-DATABASE_PASSWORD=${pass:myapp/db-password}
270-API_KEY=${sops:secrets.yaml:api_key}
271-# NODE_ENV, PORT, LOG_LEVEL from Dockerfile are preserved
272-```
273-
274-#### Final Applied Environment
275-```bash
276-NODE_ENV=production # From Dockerfile ENV
277-PORT=3000 # From Dockerfile ENV
278-LOG_LEVEL=info # From Dockerfile ENV
279-DATABASE_HOST=db.mydomain.com # From .env (overridden)
280-DATABASE_USER=myapp # From .env (new)
281-DATABASE_PASSWORD=secret123 # From .env via pass
282-API_KEY=abc123 # From .env via SOPS
283-```
284-
285-#### Production Environment Variables
286-For sensitive production data:
287-```bash
288-export GORDON_REGISTRY_PASSWORD="your-secure-password"
289-export GORDON_SSL_EMAIL="admin@your-domain.com"
290-```
291-
292-### Volume Management
293-Gordon automatically creates persistent volumes from Dockerfile VOLUME directives:
294-
295-#### Dockerfile VOLUME (Automatic Detection)
296-```dockerfile
297-FROM postgres:15
298-# Gordon automatically creates persistent volumes for these paths
299-VOLUME ["/var/lib/postgresql/data"]
300-
301-# Multi-volume example
302-FROM myapp:latest
303-VOLUME ["/app/data", "/app/logs", "/app/uploads"]
304-```
305-
306-#### Volume Features
307-- **Zero Configuration**: Reads VOLUME directives automatically
308-- **Persistent Storage**: Data survives container restarts and updates
309-- **Predictable Naming**: `gordon-{domain}-{path-hash}` format
310-- **Cross-Platform**: Works with Docker and Podman
311-
312-#### Volume Configuration (Optional)
313-```toml
314-[volumes]
315-auto_create = true # Default: true (automatically handle VOLUME directives)
316-prefix = "gordon" # Default: "gordon" (volume name prefix)
317-preserve = true # Default: true (keep volumes when containers are removed)
318-```
319-
320-#### Complete Dockerfile Example
321-```dockerfile
322-FROM node:18-alpine
323-WORKDIR /app
324-
325-# Environment variables (automatically merged with your .env files)
326-ENV NODE_ENV=production
327-ENV PORT=3000
328-ENV LOG_LEVEL=info
329-
330-# Install dependencies
331-COPY package*.json ./
332-RUN npm install
333-
334-# Copy application code
335-COPY . .
336-
337-# Persistent storage (automatically managed by Gordon)
338-VOLUME ["/app/data", "/app/logs"]
339-
340-# Network configuration
341-EXPOSE 3000
342-
343-# Start command
344-CMD ["npm", "start"]
6+cp examples/minimal.toml ~/.config/gordon/gordon.toml
3457 ```
3468
347-When you deploy this image:
348-- Gordon reads ENV directives and merges with your .env files
349-- Gordon creates volumes for `/app/data` and `/app/logs`
350-- Your data persists across deployments and reboots
351-- Environment variables are intelligently managed
9+## Configurations
35210
353-## DNS Configuration
354-
355-### Cloudflare Setup (Recommended)
356-For all examples except development, set up these DNS records:
357-
358-```
359-Type Name Content
360-A app.your-domain.com YOUR_SERVER_IP
361-A api.your-domain.com YOUR_SERVER_IP
362-A registry.your-domain.com YOUR_SERVER_IP
363-```
364-
365-Or use a wildcard:
366-```
367-Type Name Content
368-A *.your-domain.com YOUR_SERVER_IP
369-```
370-
371-### Local Development
372-For the development example, add to `/etc/hosts`:
373-```
374-127.0.0.1 app.local
375-127.0.0.1 api.local
376-127.0.0.1 admin.local
377-```
378-
379-## Workflow Examples
380-
381-### Simple Deployment
382-```bash
383-# Build your app
384-export VERSION=latest
385-docker build --tag myapp:$VERSION --tag registry.your-domain.com/myapp:$VERSION .
386-
387-# Push to deploy
388-docker push registry.your-domain.com/myapp:$VERSION
389-```
390-
391-### Version Management
392-```bash
393-# Build and push specific version
394-export VERSION=v1.2.0
395-docker build --tag myapp:$VERSION --tag registry.your-domain.com/myapp:$VERSION .
396-docker push registry.your-domain.com/myapp:$VERSION
397-
398-# Update config
399-# "app.your-domain.com" = "myapp:v1.2.0"
400-```
401-
402-### Simple Version Deployment with Manifest Annotations
403-```bash
404-# Build and push your versions first
405-export VERSION=v1.1.0
406-podman build --tag myapp:$VERSION --tag registry.your-domain.com/myapp:$VERSION .
407-podman push registry.your-domain.com/myapp:$VERSION
408-
409-export VERSION=v1.2.0
410-podman build --tag myapp:$VERSION --tag registry.your-domain.com/myapp:$VERSION .
411-podman push registry.your-domain.com/myapp:$VERSION
412-
413-# Deploy v1.2.0
414-export VERSION=v1.2.0
415-podman manifest create myapp:latest
416-podman manifest add myapp:latest registry.your-domain.com/myapp:$VERSION
417-podman manifest annotate myapp:latest --annotation version=$VERSION registry.your-domain.com/myapp:$VERSION
418-podman manifest push myapp:latest registry.your-domain.com/myapp:latest
419-
420-# Rollback to v1.1.0 (just change the version)
421-export VERSION=v1.1.0
422-podman manifest create myapp:latest --amend
423-podman manifest add myapp:latest registry.your-domain.com/myapp:$VERSION
424-podman manifest annotate myapp:latest --annotation version=$VERSION registry.your-domain.com/myapp:$VERSION
425-podman manifest push myapp:latest registry.your-domain.com/myapp:latest
426-```
11+| File | Use case |
12+|------|----------|
13+| [`minimal.toml`](minimal.toml) | Single app, no auth. Start here. |
14+| [`development.toml`](development.toml) | Local .local domains, unsafe secrets |
15+| [`staging.toml`](staging.toml) | Branch previews, token auth |
16+| [`production.toml`](production.toml) | Pinned versions, full logging |
17+| [`saas-multi-tenant.toml`](saas-multi-tenant.toml) | Customer subdomains, shared services |
18+| [`logging.toml`](logging.toml) | All logging options explained |
42719
428-See [`rollback-workflow-example.md`](rollback-workflow-example.md) for complete version deployment workflow documentation.
20+## Workflows
42921
430-## Need Help?
22+| File | Purpose |
23+|------|---------|
24+| [`github-workflow.yml`](github-workflow.yml) | Deploy on git tag push |
25+| [`rollback-workflow-example.md`](rollback-workflow-example.md) | Version management with manifests |
43126
432-- **Read the main [README](../README.md)** for detailed documentation
433-- **Check the logs** for deployment issues
434-- **Open an issue** if you find problems with these examples
435-- **Contribute** your own configuration examples!
27+## Config Reference
43628
437----
438-*These examples are starting points - customize them for your specific needs!*⏎̸
29+See comments in each `.toml` file. Full docs: [README](../README.md#configuration)
@@ -1,438 +1,29 @@
1-# Gordon Configuration Examples1+# Examples
2 2
3-This directory contains configuration examples for different use cases and environments.3+Copy an example and edit:
4 4
5-## Full Configuration Reference
6-
7-Here's the complete Gordon configuration with all default values:
8-
9-```toml
10-# gordon.toml - Complete configuration reference with defaults
11-
12-[server]
13-port = 8080 # HTTP/HTTPS proxy port (default: 8080)
14-registry_port = 5000 # Container registry port (default: 5000)
15-registry_domain = "" # REQUIRED - Your registry domain (no default)
16-runtime = "auto" # Container runtime (default: "auto")
17- # Options: auto, docker, podman, podman-rootless
18-socket_path = "" # Custom socket path (default: "" - auto-detected)
19-data_dir = "~/.local/share/gordon" # Data directory (default: ~/.local/share/gordon)
20- # Root user default: ./data
21-ssl_email = "" # Email for Let's Encrypt (default: "" - uses Cloudflare)
22-
23-[secrets]
24-backend = "pass" # Secrets backend (default: "pass")
25- # Options: pass, sops, unsafe
26- # "unsafe" stores secrets in plain text (dev only)
27-
28-[registry_auth]
29-enabled = true # Enable registry authentication (default: true)
30-type = "password" # Auth type (default: "password")
31- # Options: password, token
32-
33-# Password auth settings (when type = "password")
34-username = "" # REQUIRED - username for docker login
35-password_hash = "" # REQUIRED - path to bcrypt hash in secrets backend
36- # Example: "gordon/registry/password_hash"
37-
38-# Token auth settings (when type = "token")
39-# token_secret = "" # REQUIRED - path to JWT signing secret
40- # Example: "gordon/registry/token_secret"
41-
42-[routes]
43-# Domain to image mappings (default: empty)
44-# "app.example.com" = "myapp:latest"
45-# "api.example.com" = "myapi:v1.0.0"
46-
47-[network_groups]
48-# Group domains for shared networking (default: empty)
49-# "backend" = ["app.example.com", "api.example.com"]
50-# "monitoring" = ["grafana.example.com", "prometheus.example.com"]
51-
52-[attachments]
53-# Attach services to apps or groups (default: empty)
54-# "app.example.com" = ["postgres:latest", "redis:latest"]
55-# "backend" = ["shared-cache:latest", "message-queue:latest"]
56-
57-[auto_route]
58-enabled = false # Auto-create routes from image names (default: false)
59-
60-[volumes]
61-auto_create = true # Auto-create volumes from VOLUME directives (default: true)
62-prefix = "gordon" # Volume name prefix (default: "gordon")
63-preserve = true # Keep volumes when removing containers (default: true)
64-
65-[env]
66-dir = "{data_dir}/env" # Environment files directory (default: {data_dir}/env)
67-# Note: Secret providers are now configured via [secrets].backend
68-
69-[logging]
70-enabled = true # Enable file logging (default: true)
71-level = "info" # Log level (default: "info")
72- # Options: trace, debug, info, warn, error, fatal, panic
73-dir = "{data_dir}/logs" # Log directory (default: {data_dir}/logs)
74-main_log_file = "gordon.log" # Main log file (default: "gordon.log")
75-proxy_log_file = "proxy.log" # Proxy log file (default: "proxy.log")
76-container_log_dir = "containers" # Container logs subdirectory (default: "containers")
77-max_size = 100 # Max log size in MB (default: 100)
78-max_backups = 3 # Number of old logs to keep (default: 3)
79-max_age = 28 # Days to keep old logs (default: 28)
80-compress = true # Compress rotated logs (default: true)
81-```
82-
83-## Available Examples
84-
85-### [`minimal.toml`](minimal.toml)
86-**Perfect for getting started**
87-- Single route configuration
88-- Default settings
89-- No authentication
90-- Ideal for testing and learning
91-
92-### [`development.toml`](development.toml)
93-**Local development setup**
94-- Multiple .local domains
95-- No authentication for ease of use
96-- Third-party development tools
97-- localhost registry
98-
99-### [`staging.toml`](staging.toml)
100-**Staging and preview environments**
101-- Branch-based deployments
102-- Feature branch testing
103-- PR preview environments
104-- Separate staging registry
105-
106-### [`production.toml`](production.toml)
107-**Production-ready configuration**
108-- Pinned image versions
109-- Registry authentication
110-- Multiple production services
111-- Monitoring tools included
112-
113-### [`saas-multi-tenant.toml`](saas-multi-tenant.toml)
114-**Multi-tenant SaaS platform**
115-- Customer subdomains
116-- Custom domains
117-- Shared application architecture
118-- Enterprise features
119-
120-### [`logging.toml`](logging.toml)
121-**Comprehensive logging configuration**
122-- Complete logging setup examples
123-- Different logging levels and configurations
124-- Production and development logging strategies
125-- Log rotation and monitoring examples
126-
127-### [`rollback-workflow-example.md`](rollback-workflow-example.md)
128-**Simple version deployment and rollback workflow**
129-- Manifest annotation-based deployments
130-- Simple version changes for deployments and rollbacks
131-- Version tracking and deployment strategies
132-
133-### [`github-workflow.yml`](github-workflow.yml)
134-**GitHub Actions CI/CD workflow**
135-- Automatic deployment on tag push
136-- Uses official Gordon deploy action
137-- Build arguments and multi-platform support
138-- Monorepo configurations
139-
140-## Quick Start
141-
142-1. **Choose an example** that matches your use case
143-2. **Copy the config file** to your Gordon directory:
144- ```bash
145- cp examples/minimal.toml gordon.toml
146- ```
147-3. **Edit the configuration** with your domains and settings
148-4. **Start Gordon**:
149- ```bash
150- gordon start
151- ```
152-
153-## Customization Tips
154-
155-### Domain Configuration
156-Update the `[routes]` section with your actual domains:
157-```toml
158-[routes]
159-"your-domain.com" = "your-app:latest"
160-"api.your-domain.com" = "your-api:v1.0.0"
161-```
162-
163-### Registry Setup
164-Configure your registry domain and authentication:
165-```toml
166-[server]
167-registry_domain = "registry.your-domain.com"
168-
169-[secrets]
170-backend = "pass" # or "sops", or "unsafe" for development
171-
172-[registry_auth]
173-enabled = true
174-type = "password" # or "token"
175-
176-# For password auth:
177-username = "deploy"
178-password_hash = "gordon/registry/password_hash" # path in secrets backend
179-
180-# For token auth (recommended for CI/CD):
181-# type = "token"
182-# token_secret = "gordon/registry/token_secret"
183-```
184-
185-**Token Management CLI:**
186-```bash
187-# Generate a bcrypt hash for password auth
188-gordon auth password hash
189-
190-# Generate tokens for CI/CD (token auth type)
191-gordon auth token generate --subject ci-bot --scopes push,pull --expiry 0
192-gordon auth token list
193-gordon auth token revoke <token-id>
194-```
195-
196-### Container Runtime Setup
197-Gordon supports Docker and Podman with automatic detection:
198-```toml
199-[server]
200-runtime = "auto" # auto, docker, podman, podman-rootless
201-socket_path = "" # optional custom socket path
202-
203-# Examples:
204-# runtime = "docker" # Force Docker
205-# runtime = "podman" # Force Podman root
206-# runtime = "podman-rootless" # Force Podman rootless
207-# socket_path = "unix:///run/user/1000/podman/podman.sock"
208-```
209-
210-Override with environment variables:
211-```bash
212-# Works for both Docker and Podman
213-export CONTAINER_HOST=unix:///custom/path/container.sock
214-export CONTAINER_HOST=tcp://remote-docker:2376
215-gordon start
216-```
217-
218-### Logging Configuration
219-Enable comprehensive logging to monitor your deployments:
220-```toml
221-[logging]
222-enabled = true # Enable file-based logging
223-level = "info" # Log level: trace, debug, info, warn, error
224-dir = "./logs" # Directory for log files
225-main_log_file = "gordon.log" # Main application logs
226-proxy_log_file = "proxy.log" # HTTP proxy traffic logs
227-container_log_dir = "containers" # Container logs subdirectory
228-
229-# Log rotation settings
230-max_size = 100 # Max log file size in MB
231-max_backups = 5 # Number of old log files to keep
232-max_age = 30 # Max age in days
233-compress = true # Compress old log files
234-```
235-
236-See [`logging.toml`](logging.toml) for comprehensive logging examples.
237-
238-### Environment Variables
239-Gordon intelligently merges environment variables from multiple sources:
240-
241-1. **Dockerfile ENV directives** (automatically detected)
242-2. **Your .env files** (override Dockerfile ENV)
243-3. **Runtime environment** (lowest priority)
244-
245-#### Dockerfile ENV (Automatic Detection)
246-```dockerfile
247-FROM node:18-alpine
248-WORKDIR /app
249-
250-# Gordon automatically reads these ENV directives
251-ENV NODE_ENV=production
252-ENV PORT=3000
253-ENV LOG_LEVEL=info
254-ENV DATABASE_HOST=localhost
255-
256-COPY package*.json ./
257-RUN npm install
258-COPY . .
259-EXPOSE 3000
260-CMD ["npm", "start"]
261-```
262-
263-#### Custom Environment Files
264-Create `.env` files for each route: `./data/env/app_yourdomain_com.env`
265 ```bash5 ```bash
266-# Your custom overrides (these take precedence over Dockerfile ENV)6+cp examples/minimal.toml ~/.config/gordon/gordon.toml
267-DATABASE_HOST=db.mydomain.com
268-DATABASE_USER=myapp
269-DATABASE_PASSWORD=${pass:myapp/db-password}
270-API_KEY=${sops:secrets.yaml:api_key}
271-# NODE_ENV, PORT, LOG_LEVEL from Dockerfile are preserved
272-```
273-
274-#### Final Applied Environment
275-```bash
276-NODE_ENV=production # From Dockerfile ENV
277-PORT=3000 # From Dockerfile ENV
278-LOG_LEVEL=info # From Dockerfile ENV
279-DATABASE_HOST=db.mydomain.com # From .env (overridden)
280-DATABASE_USER=myapp # From .env (new)
281-DATABASE_PASSWORD=secret123 # From .env via pass
282-API_KEY=abc123 # From .env via SOPS
283-```
284-
285-#### Production Environment Variables
286-For sensitive production data:
287-```bash
288-export GORDON_REGISTRY_PASSWORD="your-secure-password"
289-export GORDON_SSL_EMAIL="admin@your-domain.com"
290-```
291-
292-### Volume Management
293-Gordon automatically creates persistent volumes from Dockerfile VOLUME directives:
294-
295-#### Dockerfile VOLUME (Automatic Detection)
296-```dockerfile
297-FROM postgres:15
298-# Gordon automatically creates persistent volumes for these paths
299-VOLUME ["/var/lib/postgresql/data"]
300-
301-# Multi-volume example
302-FROM myapp:latest
303-VOLUME ["/app/data", "/app/logs", "/app/uploads"]
304-```
305-
306-#### Volume Features
307-- **Zero Configuration**: Reads VOLUME directives automatically
308-- **Persistent Storage**: Data survives container restarts and updates
309-- **Predictable Naming**: `gordon-{domain}-{path-hash}` format
310-- **Cross-Platform**: Works with Docker and Podman
311-
312-#### Volume Configuration (Optional)
313-```toml
314-[volumes]
315-auto_create = true # Default: true (automatically handle VOLUME directives)
316-prefix = "gordon" # Default: "gordon" (volume name prefix)
317-preserve = true # Default: true (keep volumes when containers are removed)
318-```
319-
320-#### Complete Dockerfile Example
321-```dockerfile
322-FROM node:18-alpine
323-WORKDIR /app
324-
325-# Environment variables (automatically merged with your .env files)
326-ENV NODE_ENV=production
327-ENV PORT=3000
328-ENV LOG_LEVEL=info
329-
330-# Install dependencies
331-COPY package*.json ./
332-RUN npm install
333-
334-# Copy application code
335-COPY . .
336-
337-# Persistent storage (automatically managed by Gordon)
338-VOLUME ["/app/data", "/app/logs"]
339-
340-# Network configuration
341-EXPOSE 3000
342-
343-# Start command
344-CMD ["npm", "start"]
345 ```7 ```
346 8
347-When you deploy this image:9+## Configurations
348-- Gordon reads ENV directives and merges with your .env files
349-- Gordon creates volumes for `/app/data` and `/app/logs`
350-- Your data persists across deployments and reboots
351-- Environment variables are intelligently managed
352 10
353-## DNS Configuration11+| File | Use case |
354-12+|------|----------|
355-### Cloudflare Setup (Recommended)13+| [`minimal.toml`](minimal.toml) | Single app, no auth. Start here. |
356-For all examples except development, set up these DNS records:14+| [`development.toml`](development.toml) | Local .local domains, unsafe secrets |
357-15+| [`staging.toml`](staging.toml) | Branch previews, token auth |
358-```16+| [`production.toml`](production.toml) | Pinned versions, full logging |
359-Type Name Content17+| [`saas-multi-tenant.toml`](saas-multi-tenant.toml) | Customer subdomains, shared services |
360-A app.your-domain.com YOUR_SERVER_IP18+| [`logging.toml`](logging.toml) | All logging options explained |
361-A api.your-domain.com YOUR_SERVER_IP
362-A registry.your-domain.com YOUR_SERVER_IP
363-```
364-
365-Or use a wildcard:
366-```
367-Type Name Content
368-A *.your-domain.com YOUR_SERVER_IP
369-```
370-
371-### Local Development
372-For the development example, add to `/etc/hosts`:
373-```
374-127.0.0.1 app.local
375-127.0.0.1 api.local
376-127.0.0.1 admin.local
377-```
378-
379-## Workflow Examples
380-
381-### Simple Deployment
382-```bash
383-# Build your app
384-export VERSION=latest
385-docker build --tag myapp:$VERSION --tag registry.your-domain.com/myapp:$VERSION .
386-
387-# Push to deploy
388-docker push registry.your-domain.com/myapp:$VERSION
389-```
390-
391-### Version Management
392-```bash
393-# Build and push specific version
394-export VERSION=v1.2.0
395-docker build --tag myapp:$VERSION --tag registry.your-domain.com/myapp:$VERSION .
396-docker push registry.your-domain.com/myapp:$VERSION
397-
398-# Update config
399-# "app.your-domain.com" = "myapp:v1.2.0"
400-```
401-
402-### Simple Version Deployment with Manifest Annotations
403-```bash
404-# Build and push your versions first
405-export VERSION=v1.1.0
406-podman build --tag myapp:$VERSION --tag registry.your-domain.com/myapp:$VERSION .
407-podman push registry.your-domain.com/myapp:$VERSION
408-
409-export VERSION=v1.2.0
410-podman build --tag myapp:$VERSION --tag registry.your-domain.com/myapp:$VERSION .
411-podman push registry.your-domain.com/myapp:$VERSION
412-
413-# Deploy v1.2.0
414-export VERSION=v1.2.0
415-podman manifest create myapp:latest
416-podman manifest add myapp:latest registry.your-domain.com/myapp:$VERSION
417-podman manifest annotate myapp:latest --annotation version=$VERSION registry.your-domain.com/myapp:$VERSION
418-podman manifest push myapp:latest registry.your-domain.com/myapp:latest
419-
420-# Rollback to v1.1.0 (just change the version)
421-export VERSION=v1.1.0
422-podman manifest create myapp:latest --amend
423-podman manifest add myapp:latest registry.your-domain.com/myapp:$VERSION
424-podman manifest annotate myapp:latest --annotation version=$VERSION registry.your-domain.com/myapp:$VERSION
425-podman manifest push myapp:latest registry.your-domain.com/myapp:latest
426-```
427 19
428-See [`rollback-workflow-example.md`](rollback-workflow-example.md) for complete version deployment workflow documentation.20+## Workflows
429 21
430-## Need Help?22+| File | Purpose |
23+|------|---------|
24+| [`github-workflow.yml`](github-workflow.yml) | Deploy on git tag push |
25+| [`rollback-workflow-example.md`](rollback-workflow-example.md) | Version management with manifests |
431 26
432-- **Read the main [README](../README.md)** for detailed documentation27+## Config Reference
433-- **Check the logs** for deployment issues
434-- **Open an issue** if you find problems with these examples
435-- **Contribute** your own configuration examples!
436 28
437----29+See comments in each `.toml` file. Full docs: [README](../README.md#configuration)
438-*These examples are starting points - customize them for your specific needs!*⏎̸

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