@@ -125,13 +125,13 @@ DNS_TOKEN="$HETZNER_DNS_API_TOKEN"
125125echo " DNS token length: ${# DNS_TOKEN} characters"
126126# Should show: DNS token length: 32 characters
127127
128- # Test Cloud API access
129- curl -H " Authorization: Bearer $CLOUD_TOKEN " \
128+ # Test Cloud API access (silent mode for clean JSON output)
129+ curl -s - H " Authorization: Bearer $CLOUD_TOKEN " \
130130 " https://api.hetzner.cloud/v1/servers" | jq
131131# Expected output: {"servers": []}
132132
133- # Test DNS API access
134- curl -H " Auth-API-Token: $DNS_TOKEN " \
133+ # Test DNS API access (silent mode for clean JSON output)
134+ curl -s - H " Auth-API-Token: $DNS_TOKEN " \
135135 " https://dns.hetzner.com/api/v1/zones" | jq
136136# Expected output: {"zones": [...]}
137137```
@@ -221,8 +221,8 @@ GRAFANA_DOMAIN=grafana.torrust-demo.dev
221221222222
223223# Floating IP Configuration (your actual IPs)
224- FLOATING_IP_V4 =78.47.140.132
225- FLOATING_IP_V6 =2a01:4f8:1c17:a01d::/64
224+ FLOATING_IPV4 =78.47.140.132
225+ FLOATING_IPV6 =2a01:4f8:1c17:a01d::/64
226226
227227# Generate secure passwords
228228MYSQL_ROOT_PASSWORD=$( openssl rand -base64 32)
@@ -257,8 +257,8 @@ GRAFANA_DOMAIN=grafana.torrust-demo.com
257257258258
259259# Floating IP Configuration (your actual IPs)
260- FLOATING_IP_V4 =78.47.140.132
261- FLOATING_IP_V6 =2a01:4f8:1c17:a01d::/64
260+ FLOATING_IPV4 =78.47.140.132
261+ FLOATING_IPV6 =2a01:4f8:1c17:a01d::/64
262262
263263# Generate secure passwords
264264MYSQL_ROOT_PASSWORD=$( openssl rand -base64 32)
@@ -307,13 +307,136 @@ make app-deploy ENVIRONMENT_TYPE=production ENVIRONMENT_FILE=production-hetzner
307307## Step 7: Configure DNS
308308
309309After deployment, you need to configure DNS to point your domain to the floating
310- IP. See the [ Deployment Guide - Part 3: DNS Configuration] ( ../../deployment-guide.md#-part-3-dns-configuration )
311- for detailed instructions on:
310+ IP. This section provides complete working examples for Hetzner DNS API configuration.
312311
313- - Creating DNS zones via Hetzner DNS API
314- - Setting up A/AAAA records for your subdomains
315- - Configuring automatic DNS management
316- - Testing DNS propagation
312+ ### 7.1 Create DNS Zone
313+
314+ First, create a DNS zone for your domain:
315+
316+ ``` bash
317+ # Source your environment configuration with DNS API token
318+ source infrastructure/config/providers/hetzner.env
319+
320+ # Create DNS zone for your domain
321+ curl -s -H " Auth-API-Token: $HETZNER_DNS_API_TOKEN " \
322+ -H " Content-Type: application/json" \
323+ -X POST \
324+ -d ' {"name": "torrust-demo.dev", "ttl": 86400}' \
325+ https://dns.hetzner.com/api/v1/zones | jq
326+ ```
327+
328+ ** Expected Response:**
329+
330+ ``` json
331+ {
332+ "zone" : {
333+ "id" : " Vpew4Pb3YoDjBVHMvV9AHB" ,
334+ "name" : " torrust-demo.dev" ,
335+ "ttl" : 86400 ,
336+ "registrar" : " " ,
337+ "legacy_dns_host" : " " ,
338+ "legacy_ns" : [],
339+ "ns" : [
340+ " hydrogen.ns.hetzner.com" ,
341+ " oxygen.ns.hetzner.com" ,
342+ " helium.ns.hetzner.de"
343+ ],
344+ "created" : " 2025-01-13T19:17:12Z" ,
345+ "verified" : " 0001-01-01T00:00:00Z" ,
346+ "modified" : " 2025-01-13T19:17:12Z" ,
347+ "project" : " " ,
348+ "owner" : " " ,
349+ "permission" : " " ,
350+ "zone_type" : " PRIMARY" ,
351+ "status" : " verified" ,
352+ "paused" : false ,
353+ "is_secondary_dns" : false ,
354+ "txt_verification" : {
355+ "name" : " " ,
356+ "token" : " "
357+ },
358+ "records_count" : 2
359+ }
360+ }
361+ ```
362+
363+ ### 7.2 Create DNS A Records
364+
365+ Create A records for your tracker and monitoring subdomains:
366+
367+ ``` bash
368+ # Create tracker subdomain A record
369+ curl -s -H " Auth-API-Token: $HETZNER_DNS_API_TOKEN " \
370+ -H " Content-Type: application/json" \
371+ -X POST \
372+ -d ' {
373+ "value": "78.47.140.132",
374+ "ttl": 86400,
375+ "type": "A",
376+ "name": "tracker",
377+ "zone_id": "Vpew4Pb3YoDjBVHMvV9AHB"
378+ }' \
379+ https://dns.hetzner.com/api/v1/records | jq
380+
381+ # Create grafana subdomain A record
382+ curl -s -H " Auth-API-Token: $HETZNER_DNS_API_TOKEN " \
383+ -H " Content-Type: application/json" \
384+ -X POST \
385+ -d ' {
386+ "value": "78.47.140.132",
387+ "ttl": 86400,
388+ "type": "A",
389+ "name": "grafana",
390+ "zone_id": "Vpew4Pb3YoDjBVHMvV9AHB"
391+ }' \
392+ https://dns.hetzner.com/api/v1/records | jq
393+ ```
394+
395+ ** Expected Response for each record:**
396+
397+ ``` json
398+ {
399+ "record" : {
400+ "id" : " 0de308260c254fa933b2c89312d6eb08" ,
401+ "type" : " A" ,
402+ "name" : " tracker" ,
403+ "value" : " 78.47.140.132" ,
404+ "zone_id" : " Vpew4Pb3YoDjBVHMvV9AHB" ,
405+ "ttl" : 86400 ,
406+ "created" : " 2025-01-13T19:48:51Z" ,
407+ "modified" : " 2025-01-13T19:48:51Z"
408+ }
409+ }
410+ ```
411+
412+ ### 7.3 Verify DNS Configuration
413+
414+ Verify your DNS records are created correctly:
415+
416+ ``` bash
417+ # List all records in your zone
418+ curl -s -H " Auth-API-Token: $HETZNER_DNS_API_TOKEN " \
419+ " https://dns.hetzner.com/api/v1/records?zone_id=Vpew4Pb3YoDjBVHMvV9AHB" | jq
420+
421+ # Test DNS resolution
422+ dig tracker.torrust-demo.dev
423+ dig grafana.torrust-demo.dev
424+ ```
425+
426+ ### 7.4 Configure Nameservers at Domain Registrar
427+
428+ Finally, configure your domain registrar to use Hetzner's nameservers:
429+
430+ ``` text
431+ hydrogen.ns.hetzner.com
432+ oxygen.ns.hetzner.com
433+ helium.ns.hetzner.de
434+ ```
435+
436+ ** Important** : Replace ` torrust-demo.dev ` with your actual domain, ` 78.47.140.132 `
437+ with your floating IP, and ` Vpew4Pb3YoDjBVHMvV9AHB ` with your actual zone ID.
438+
439+ For additional DNS configuration options, see the [ Deployment Guide - Part 3: DNS Configuration] ( ../../deployment-guide.md#-part-3-dns-configuration ) .
317440
318441## Step 5.5: Optional - Configure Persistent Volume for Data Persistence
319442
0 commit comments