You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Swap to caddy and support TLS
* Add logging
* test pass
* check if timing was issue
* Raf style AI review
- Added `os.Remove(d.paths.CaddyPIDFile())` when `waitForAdmin` times out to prevent stale PID files
- Changed `append(redirectRoutes, routes...)` to `slices.Concat(redirectRoutes, routes)` to avoid mutating original slices
- Created `DNSProvider` type with constants `DNSProviderNone`, `DNSProviderCloudflare`, `DNSProviderRoute53`
- Added `ParseDNSProvider()` function that returns an error for unknown providers
- Server now fails to start if an invalid DNS provider is configured
- Updated `tls` field description: "Use with match.port=443 for standard HTTPS"
- Replaced Envoy references with Caddy
- Added `CADDY_STOP_ON_SHUTDOWN` with note to set `false` for production
- Added TLS Ingress section documenting ACME configuration for Cloudflare/Route53
- Added all new environment variables to the table
- Created `waitForProcessExit()` helper that polls every 100ms
- `Stop()` now uses polling instead of `time.Sleep(2 * time.Second)`
- Added debug logging when `Process.Kill()` fails in `Stop()`
- `TestCreateIngress_TLSWithoutACME` verifies error when TLS requested but ACME not configured
- Removed separate `logging` section from Caddy JSON config
- Caddy now writes JSON logs to stderr, captured to `caddy.log` by `daemon.go`
- Log forwarder now tails `CaddyLogFile()` instead of separate `CaddySystemLog()`
- Removed unused `CaddySystemLog()` path method
- `TestGenerateConfig_MixedTLSAndNonTLS` verifies correct behavior with both TLS and non-TLS rules in the same ingress
- Removed unused `ErrCaddyNotRunning`
* More review
Summary of Changes
1. Fixed non-deterministic listenAddrs order (`lib/ingress/config.go`)
- Ports are now collected and sorted before building listen addresses
- Added `TestGenerateConfig_DeterministicOrder` test to verify consistent output
2. Fixed DNS challenge config for Caddy modules (`lib/ingress/config.go`)
- Updated `buildDNSChallengeConfig()` to use correct Caddy DNS module format
- Consolidated propagation settings to apply to all providers:
- `DNS_PROPAGATION_TIMEOUT` - works for both Cloudflare and Route53
- `DNS_RESOLVERS` - custom resolvers for propagation checking
3. Updated Makefile for xcaddy builds
- Changed from downloading pre-built Caddy to building with xcaddy
- Added `build-caddy` and `build-caddy-binaries` targets
- Includes `github.com/caddy-dns/cloudflare` and `github.com/caddy-dns/route53` modules
4. Added test for XDG_DATA_HOME / storage paths (`lib/ingress/config_test.go`)
- `TestGenerateConfig_StoragePath` verifies storage configuration is correct
- Updated `TestGenerateConfig_EmptyIngresses` to check storage section
5. Used slices.Concat for safer append (`lib/ingress/manager.go`)
- Changed `append(existingIngresses, ingress)` to `slices.Concat(existingIngresses, []Ingress{ingress})`
6. Match config path in findCaddyPID (`lib/ingress/daemon.go`)
- Now matches both "caddy run" and the specific config path
- Prevents collision with other Caddy/hypeman instances
7. Reduced admin API timeout to 10s (`lib/ingress/daemon.go`)
- Changed from 30s to 10s for faster failure detection
8. Fixed CaddyStopOnShutdown default (`cmd/api/config/config.go`)
- Default is now `false` (Caddy persists through hypeman restarts)
- Removed "(default: X)" comments from struct fields
9. Updated .env.example
- Added all CADDY_* and ACME_* variables
- Documented all three Route53 auth methods
10. AWS Route53 authentication methods (`lib/ingress/config.go`)
- **Method 1**: Explicit credentials (`AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`)
- **Method 2**: Named profile (`AWS_PROFILE`)
- **Method 3**: IAM role/instance profile (leave credentials empty)
* fix build
* error handle port taken
* 404 hint: didn't match hostname
* version check
* Fix caddy shutdown
* Configurable allowed domains
* Domain allow list
* Match ingress by partial id and name
* Use SNI in test
* Tls integration tests passes locally
* Add a few logs
* Use DNS for discovery and support instance name matching
* Accept using sudo for tests, get caching and parallelism
* Remove route53 for now
* Docker login work when run tests with root
* Fix one more spot with unauth'd docker pull
* Review
Summary of Changes
1. Wildcard & Pattern Matching Logic (`lib/ingress/config.go`)
- Added handling for global wildcard `*` pattern that matches any domain
- Added comprehensive documentation explaining wildcard behavior
- Restructured code for clarity with detailed comments
2. Edge Case Tests (`lib/ingress/config_test.go`)
- Added 12 new test cases covering:
- Global `*` wildcard matching
- Single-char subdomains
- Hyphenated and numeric subdomains
- Empty prefix handling
- Apex domain + wildcard combination
- Empty patterns in lists
3. DNS Provider Constants (`lib/ingress/config.go`)
- Added `caddyProviderCloudflare` constant for Caddy module name
- Added `SupportedDNSProviders()` helper function for future-proof error messages
- Updated `ParseDNSProvider()` to use dynamic error message
- Updated `buildDNSChallengeConfig()` to use constant and log warnings for unknown providers
4. Context Propagation (`lib/dns/server.go`)
- Added `ctx` field to Server struct to store base context
- Store context from `Start()` for use in resolver calls
- Updated `handleAQuery()` to use stored context instead of `context.Background()`
- Improved AAAA comment explaining intentional empty response behavior
5. Duration Validation (`lib/providers/providers.go`)
- Added validation for `DNS_PROPAGATION_TIMEOUT` at startup
- Validates Go duration format (e.g., `2m`, `120s`, `1h`)
- Provides helpful error message with expected format examples
6. Consistency Improvements
- **`lib/ingress/manager.go`**: Replaced slice comparison with `strings.HasPrefix()` for ID prefix matching
- **`lib/ingress/daemon.go`**: Added documented constants for polling intervals (`adminPollInterval`, `processExitPollInterval`)
7. TLS Documentation (`lib/ingress/README.md`)
- Expanded TLS/HTTPS section with:
- TLS requirements section
- Detailed `TLS_ALLOWED_DOMAINS` documentation with pattern matching table
- Wildcard behavior explanation
- Example configurations
- Warning scenarios documentation
- Updated ACME/TLS Settings table with new variables
* Address review comments
1. Removed Route53 Documentation (.env.example)
- Removed the AWS Route53 DNS provider documentation section since it's not actually implemented
- Updated ACME_DNS_PROVIDER comment to only mention cloudflare
2. Changed Default Ports to 0 for Random Assignment
- lib/dns/server.go: Changed DefaultPort from 5353 to 0 with a comment explaining this prevents conflicts on shared dev machines
- cmd/api/config/config.go: Changed CADDY_ADMIN_PORT default from 2019 to 0 with an explanatory comment
- Updated .env.example to reflect the new default
3. Fixed DNS Server Context Handling (lib/dns/server.go)
- Removed the stored ctx field from the Server struct
- Added a new resolverTimeout constant (5 seconds)
- Updated handleAQuery to create a fresh context.Background() with timeout for each DNS query
- This ensures DNS queries don't fail if the parent context is cancelled during shutdown
4. Added Comment in lib/ingress/daemon.go
- Added a comment explaining why context.Background() is intentionally used for the startup wait (to ensure it isn't cancelled if the parent context times out)
5. Simplified Test Code (lib/instances/manager_test.go)
- Removed the confusing if envPath := ...; true construct
- Simplified to just the directory walk loop for loading .env files
6. Added Startup Warning (lib/ingress/manager.go)
- Added a check in Initialize() that warns if any existing TLS ingress has a hostname not in the allowed domains list
- Logs the ingress name, hostname, and allowed domains for easier debugging
Copy file name to clipboardExpand all lines: README.md
+47-7Lines changed: 47 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -60,7 +60,7 @@ getcap ./bin/hypeman
60
60
61
61
**File Descriptor Limits:**
62
62
63
-
Envoy (used for ingress) requires a higher file descriptor limit than the default on some systems (root defaults to 1024 on many systems). If you see "Too many open files" errors, increase the limit:
63
+
Caddy (used for ingress) requires a higher file descriptor limit than the default on some systems. If you see "Too many open files" errors, increase the limit:
|`CADDY_LISTEN_ADDRESS`| Address for Caddy ingress listeners |`0.0.0.0`|
103
+
|`CADDY_ADMIN_ADDRESS`| Address for Caddy admin API |`127.0.0.1`|
104
+
|`CADDY_ADMIN_PORT`| Port for Caddy admin API |`2019`|
105
+
|`CADDY_STOP_ON_SHUTDOWN`| Stop Caddy when hypeman shuts down (set to `true` for dev) |`false`|
106
+
|`ACME_EMAIL`| Email for ACME certificate registration (required for TLS ingresses) |_(empty)_|
107
+
|`ACME_DNS_PROVIDER`| DNS provider for ACME challenges: `cloudflare`|_(empty)_|
108
+
|`ACME_CA`| ACME CA URL (empty = Let's Encrypt production) |_(empty)_|
109
+
|`TLS_ALLOWED_DOMAINS`| Comma-separated allowed domains for TLS (e.g., `*.example.com,api.other.com`) |_(empty)_|
110
+
|`DNS_PROPAGATION_TIMEOUT`| Max time to wait for DNS propagation (e.g., `2m`) |_(empty)_|
111
+
|`DNS_RESOLVERS`| Comma-separated DNS resolvers for propagation checking |_(empty)_|
112
+
|`CLOUDFLARE_API_TOKEN`| Cloudflare API token (when using `cloudflare` provider) |_(empty)_|
106
113
107
114
**Important: Subnet Configuration**
108
115
@@ -111,7 +118,7 @@ The default subnet `10.100.0.0/16` is chosen to avoid common conflicts. Hypeman
111
118
If you need a different subnet, set `SUBNET_CIDR` in your environment. The gateway is automatically derived as the first IP in the subnet (e.g., `10.100.0.0/16` → `10.100.0.1`).
112
119
113
120
**Alternative subnets if needed:**
114
-
-`172.30.0.0/16` - Private range between common Docker (172.17.x.x) and AWS (172.31.x.x) ranges
121
+
-`172.30.0.0/16` - Private range between common Docker (172.17.x.x) and cloud provider (172.31.x.x) ranges
115
122
-`10.200.0.0/16` - Another private range option
116
123
117
124
**Example:**
@@ -144,6 +151,39 @@ ip route show
144
151
```
145
152
Pick the interface used by the default route (usually the line starting with `default`). Avoid using local bridges like `docker0`, `br-...`, `virbr0`, or `vmbr0` as the uplink; those are typically internal virtual networks, not your actual internet-facing interface.
146
153
154
+
**TLS Ingress (HTTPS)**
155
+
156
+
Hypeman uses Caddy with automatic ACME certificates for TLS termination. Certificates are issued via DNS-01 challenges (Cloudflare).
0 commit comments