> For the complete documentation index, see [llms.txt](https://docs.k9.io/key9-identity/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.k9.io/key9-identity/maxmind-api-proxy/deployment/service.md).

# Running as a Service

For production use, run `maxmind-api-proxy` as a managed system service so that it starts automatically on boot and restarts on failure.

***

## Linux — systemd

### 1. Place the binary and config

```bash
# Copy the binary
sudo cp maxmind-api-proxy /usr/local/bin/maxmind-api-proxy
sudo chmod 755 /usr/local/bin/maxmind-api-proxy

# Create a config directory and copy the config
sudo mkdir -p /etc/maxmind-api-proxy
sudo cp my-config.json /etc/maxmind-api-proxy/config.json

# Restrict config permissions (contains credentials)
sudo chmod 600 /etc/maxmind-api-proxy/config.json
```

### 2. Create a dedicated service user

Running the proxy as a non-root user limits the blast radius if it is ever compromised.

```bash
sudo useradd --system --no-create-home --shell /usr/sbin/nologin maxmind-proxy
sudo chown root:maxmind-proxy /etc/maxmind-api-proxy/config.json
```

> If using TLS with Let's Encrypt, the service user also needs read access to the certificate files:
>
> ```bash
> sudo setfacl -m u:maxmind-proxy:rx /etc/letsencrypt/live/ /etc/letsencrypt/archive/
> ```

### 3. Create the unit file

Create `/etc/systemd/system/maxmind-api-proxy.service`:

```ini
[Unit]
Description=MaxMind API Proxy
After=network.target redis.service
Wants=redis.service

[Service]
Type=simple
User=maxmind-proxy
Group=maxmind-proxy
ExecStart=/usr/local/bin/maxmind-api-proxy /etc/maxmind-api-proxy/config.json
Restart=on-failure
RestartSec=5s

# Harden the service
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
```

### 4. Enable and start

```bash
sudo systemctl daemon-reload
sudo systemctl enable maxmind-api-proxy
sudo systemctl start maxmind-api-proxy

# Check status
sudo systemctl status maxmind-api-proxy

# Follow logs
sudo journalctl -u maxmind-api-proxy -f
```

### 5. Reload after config changes

The proxy reads its config only at startup. After editing the config file, restart the service:

```bash
sudo systemctl restart maxmind-api-proxy
```

***

## macOS — launchd

### 1. Place the binary and config

```bash
sudo cp maxmind-api-proxy /usr/local/bin/maxmind-api-proxy
sudo chmod 755 /usr/local/bin/maxmind-api-proxy

sudo mkdir -p /etc/maxmind-api-proxy
sudo cp my-config.json /etc/maxmind-api-proxy/config.json
sudo chmod 600 /etc/maxmind-api-proxy/config.json
```

### 2. Create the plist

Create `/Library/LaunchDaemons/io.k9.maxmind-api-proxy.plist`:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>io.k9.maxmind-api-proxy</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/maxmind-api-proxy</string>
        <string>/etc/maxmind-api-proxy/config.json</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/var/log/maxmind-api-proxy.log</string>
    <key>StandardErrorPath</key>
    <string>/var/log/maxmind-api-proxy.log</string>
</dict>
</plist>
```

### 3. Load the service

```bash
sudo launchctl load /Library/LaunchDaemons/io.k9.maxmind-api-proxy.plist

# Check it is running
sudo launchctl list | grep maxmind
```

***

## Docker

A minimal `Dockerfile` for containerised deployments:

```dockerfile
FROM scratch
COPY maxmind-api-proxy /maxmind-api-proxy
COPY config.json /etc/maxmind-api-proxy/config.json
ENTRYPOINT ["/maxmind-api-proxy", "/etc/maxmind-api-proxy/config.json"]
```

Build and run:

```bash
# Cross-compile a static Linux binary
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o maxmind-api-proxy

docker build -t maxmind-api-proxy:latest .

docker run -d \
  --name maxmind-api-proxy \
  --restart unless-stopped \
  -p 8443:8443 \
  maxmind-api-proxy:latest
```

For configuration management in Docker, mount the config file as a volume rather than baking it into the image:

```bash
docker run -d \
  --name maxmind-api-proxy \
  --restart unless-stopped \
  -p 8443:8443 \
  -v /etc/maxmind-api-proxy/config.json:/etc/maxmind-api-proxy/config.json:ro \
  maxmind-api-proxy:latest
```
