Skip to content

Fix: acme.json Being Reset to Empty File

Problem

The acme.json file is being reset to an empty file (0 bytes) with wrong permissions (644 instead of 600), causing Traefik to use self-signed certificates instead of Let's Encrypt certificates.

Root Cause

When Docker Compose mounts a file that doesn't exist or has incorrect permissions: 1. Docker creates an empty file with default permissions (644) 2. Traefik can't write to the file (needs 600 permissions) 3. Traefik resets the file or fails to initialize ACME storage 4. Certificates are lost and Traefik falls back to self-signed certificates

Solution

Updated the shared and qual Makefile targets to ensure acme.json is properly initialized before Traefik starts:

  1. Create file if missing: Creates infrastructure/config/traefik/acme.json if it doesn't exist
  2. Initialize with valid JSON: Sets content to {} if file is empty
  3. Set correct permissions: Sets file permissions to 600 (read/write for owner only)
  4. Validate JSON: Ensures file contains valid JSON before Traefik starts

Implementation

make shared Target

The shared target now includes:

@echo "Ensuring acme.json is properly initialized..."
@ACME_FILE="infrastructure/config/traefik/acme.json"; \
if [ ! -f "$$ACME_FILE" ]; then \
    echo "Creating $$ACME_FILE..."; \
    echo '{}' > "$$ACME_FILE"; \
fi; \
chmod 600 "$$ACME_FILE"; \
if [ ! -s "$$ACME_FILE" ]; then \
    echo "Initializing empty $$ACME_FILE..."; \
    echo '{}' > "$$ACME_FILE"; \
    chmod 600 "$$ACME_FILE"; \
fi; \
if ! python3 -m json.tool "$$ACME_FILE" > /dev/null 2>&1; then \
    echo "Resetting invalid $$ACME_FILE..."; \
    echo '{}' > "$$ACME_FILE"; \
    chmod 600 "$$ACME_FILE"; \
fi; \
echo "✅ acme.json ready"

make qual Target

The qual target also ensures acme.json is ready before starting shared infrastructure.

Verification

After running make shared or make qual, verify:

# Check file exists and has correct permissions
ls -l infrastructure/config/traefik/acme.json
# Should show: -rw------- (600 permissions)

# Check file content
cat infrastructure/config/traefik/acme.json
# Should show: {}

# Check file size
stat infrastructure/config/traefik/acme.json
# Should show: 2 bytes (not 0)

Manual Fix

If the file is already corrupted, run:

# Fix acme.json manually
infrastructure/scripts/fix-traefik-certificates.sh

# Or manually:
echo '{}' > infrastructure/config/traefik/acme.json
chmod 600 infrastructure/config/traefik/acme.json

# Restart Traefik
docker compose -f infrastructure/compose/shared.yml --env-file infrastructure/compose/.env.shared restart traefik

Prevention

The fix ensures: - ✅ File is initialized before Traefik starts - ✅ Permissions are correct (600) - ✅ File contains valid JSON - ✅ Traefik can read and write certificates

  • Makefile - shared and qual targets
  • infrastructure/compose/shared.yml - Traefik service definition
  • infrastructure/scripts/fix-traefik-certificates.sh - Manual fix script
  • infrastructure/config/traefik/acme.json - Certificate storage file