Skip to main content

Overview

Private Connect’s DNS integration enables you to access services using friendly .connect domains instead of localhost:port URLs.

Quick Start

Installation

connect dns install
This configures your system to resolve *.connect domains to 127.0.0.1:
🌐 Installing Private Connect DNS...

  Setting up macOS resolver...

  Created: /etc/resolver/connect
  [ok] DNS server started (PID: 12345)

[ok] DNS installed successfully!

  You can now access services via:
    curl http://my-service.connect
    psql -h prod-db.connect

  Commands:
    Status:    connect dns status
    Test:      connect dns test prod-db
    Uninstall: connect dns uninstall

Usage

Once installed, access services by name:
# Database connection
psql -h staging-db.connect -U postgres

# HTTP requests
curl http://api.connect/health

# Application config
DATABASE_URL=postgresql://staging-db.connect/mydb
REDIS_URL=redis://redis.connect:6379

Platform Support

macOS

1

Resolver Configuration

Creates /etc/resolver/connect:
# Private Connect DNS resolver
# Resolves *.connect to local DNS server
nameserver 127.0.0.1
port 15353
2

DNS Server

Starts background DNS server on port 15353:
[ok] DNS server started (PID: 12345)
3

Automatic Startup

DNS server starts automatically with daemon:
connect daemon install

Linux (systemd-resolved)

1

systemd-resolved Detection

# Automatically detects systemd-resolved
systemctl is-active systemd-resolved
2

Drop-in Configuration

Creates /etc/systemd/resolved.conf.d/pconnect.conf:
# Private Connect DNS configuration
[Resolve]
DNS=127.0.0.1:15353
Domains=~connect
3

Service Restart

sudo systemctl restart systemd-resolved

Linux (dnsmasq)

For systems without systemd-resolved:
# Install dnsmasq
sudo apt install dnsmasq

# Configure
echo "address=/.connect/127.0.0.1" | sudo tee /etc/dnsmasq.d/pconnect.conf

# Restart
sudo systemctl restart dnsmasq

Linux (manual /etc/hosts)

Fallback option:
# Add entries manually
sudo tee -a /etc/hosts << EOF
127.0.0.1 staging-db.connect
127.0.0.1 redis.connect
127.0.0.1 api.connect
EOF

DNS Server

How It Works

server.on('message', async (msg, rinfo) => {
  const queryName = parseDnsQueryName(msg);
  
  if (!queryName || !queryName.endsWith('.connect')) {
    sendDnsResponse(server, rinfo, msg, null);
    return;
  }
  
  // Extract service name: "staging-db.connect" → "staging-db"
  const serviceName = queryName.slice(0, -('.connect'.length + 1));
  
  // Always resolve to 127.0.0.1
  const ip = '127.0.0.1';
  sendDnsResponse(server, rinfo, msg, ip);
});
All .connect domains resolve to 127.0.0.1:
dig staging-db.connect

# ;; ANSWER SECTION:
# staging-db.connect.  60  IN  A  127.0.0.1
The proxy/reach handles routing to the actual service.
Implements minimal DNS server:
  • Listens on UDP port 15353 (non-privileged)
  • Responds with A records (IPv4)
  • TTL: 60 seconds
  • NXDOMAIN for non-.connect queries

Server Management

# Start DNS server
connect dns start

# Stop DNS server
connect dns stop

# Check status
connect dns status

# View logs
tail -f ~/.connect/dns.log

Background Process

DNS server runs as a detached process:
const child = spawn(process.execPath, [
  process.argv[1],
  'dns',
  'serve',
  '--port', dnsPort.toString(),
  '--domain', domain,
  '--hub', hubUrl,
], {
  detached: true,
  stdio: ['ignore', logStream, logStream],
  env: { ...process.env, CONNECT_DNS_SERVER: '1' },
});

child.unref();
fs.writeFileSync(pidPath, child.pid?.toString() || '');

Custom Domains

Using a Different TLD

# Install with custom domain
connect dns install --domain local

# Now use .local domains
curl http://api.local
psql -h db.local

Multiple Domain Support

Install separate resolvers:
# Development
connect dns install --domain dev

# Staging
connect dns install --domain staging

# Production
connect dns install --domain prod
Access:
curl http://api.dev
curl http://api.staging  
curl http://api.prod

Testing

DNS Resolution Test

connect dns test staging-db
Output:
🔍 Testing DNS resolution for staging-db.connect...

  [ok] Resolved: staging-db.connect -> 127.0.0.1

Manual Testing

dig staging-db.connect

# ;; ANSWER SECTION:
# staging-db.connect.  60  IN  A  127.0.0.1

Application Testing

# PostgreSQL
psql -h staging-db.connect -U postgres -c "SELECT version();"

# Redis
redis-cli -h redis.connect PING

# HTTP
curl -v http://api.connect/health

# MySQL
mysql -h mysql.connect -u root -p

Integration with Proxy

Combined Setup

DNS + Proxy for seamless subdomain routing:
# 1. Install DNS
connect dns install

# 2. Start proxy
connect proxy start

# 3. Reach services
connect reach staging-db 5432
connect reach redis 6379

# 4. Access via .connect domains through proxy
psql -h staging-db.connect -p 9999
redis-cli -h redis.connect -p 9999

HTTP(S) Access

With HTTPS proxy:
connect proxy start --https
Access:
curl https://api.connect:9999/health
curl https://frontend.connect:9999/

Caching

Service Cache

DNS server caches service metadata:
let serviceCache: Map<string, number> = new Map();
let lastFetch = 0;
const CACHE_TTL = 5000; // 5 seconds

async function refreshServiceCache() {
  const now = Date.now();
  if (now - lastFetch < CACHE_TTL) return;
  
  const response = await fetch(`${hubUrl}/v1/services`, {
    headers: { 'x-api-key': apiKey },
  });
  
  if (response.ok) {
    const services = await response.json();
    serviceCache.clear();
    for (const service of services) {
      if (service.tunnelPort) {
        serviceCache.set(service.name.toLowerCase(), service.tunnelPort);
      }
    }
    lastFetch = now;
  }
}

DNS Cache Flushing

# Flush DNS cache
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

Uninstallation

connect dns uninstall
This:
  1. Stops the DNS server
  2. Removes resolver configuration
  3. Cleans up background processes
🌐 Uninstalling Private Connect DNS...

  [ok] DNS server stopped
  Removed: /etc/resolver/connect

[ok] DNS uninstalled

Troubleshooting

DNS Not Resolving

1

Check DNS Server

connect dns status
Should show:
 DNS Server: running (PID: 12345)
2

Verify Resolver Config

# macOS
cat /etc/resolver/connect

# Linux
cat /etc/systemd/resolved.conf.d/pconnect.conf
3

Test Resolution

connect dns test my-service
4

Flush DNS Cache

# macOS
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

# Linux
sudo systemd-resolve --flush-caches

Service Not Found

# Check if service is exposed/reached
connect whoami

# Check active routes
cat ~/.connect/active-routes.json

# Verify service in hub
curl -H "x-api-key: $API_KEY" https://hub.privateconnect.io/v1/services

Permission Issues

# macOS - creating /etc/resolver requires sudo
[x] Failed to create resolver directory.
  Run: sudo mkdir -p /etc/resolver
Solution:
sudo connect dns install

Best Practices

Use Descriptive Names

# Good
staging-db.connect
prod-api.connect

# Avoid
db.connect
api.connect

Daemon Mode

Install daemon for automatic startup:
connect daemon install
DNS server starts with daemon.

Environment Variables

Use .connect in configs:
DATABASE_URL=postgresql://staging-db.connect
REDIS_URL=redis://cache.connect

Testing

Always test DNS after installation:
connect dns test my-service

Build docs developers (and LLMs) love