domain-management
Configure domain routing and Cloudflare DNS for sgcarstrends.com and subdomains. Use when adding new services, updating domain patterns, or debugging DNS issues.
- Category: discovered
- Tags: github, community
- Version: 1.0.0
- Author: walid
- Downloads: 0
- GitHub stars: 12
- Updated: 2025-12-22
Download the latest version (v1.0.0) from this page.
SKILL.md
---
name: domain-management
description: Configure domain routing and Cloudflare DNS for sgcarstrends.com and subdomains. Use when adding new services, updating domain patterns, or debugging DNS issues.
allowed-tools: Read, Edit, Grep, Glob
---
# Domain Management Skill
This skill helps you manage domains and DNS configuration for the SG Cars Trends platform.
## When to Use This Skill
- Adding new subdomains
- Configuring SSL certificates
- Updating DNS records
- Debugging domain resolution issues
- Setting up custom domains for services
- Managing Cloudflare settings
- Troubleshooting SSL/TLS errors
## Domain Architecture
### Domain Structure
```
sgcarstrends.com # Production web app
staging.sgcarstrends.com # Staging web app
dev.sgcarstrends.com # Development web app
api.sgcarstrends.com # Production API
api.staging.sgcarstrends.com # Staging API
api.dev.sgcarstrends.com # Development API
admin.sgcarstrends.com # Admin app (future)
docs.sgcarstrends.com # Documentation (future)
```
### Naming Convention
**Web Apps:**
- Production: Apex domain (`sgcarstrends.com`)
- Other envs: `{stage}.sgcarstrends.com`
**Backend Services:**
- Pattern: `{service}.{stage}.sgcarstrends.com`
- Production service: `{service}.sgcarstrends.com` (no stage prefix)
Examples:
```
api.sgcarstrends.com # Production API
api.staging.sgcarstrends.com # Staging API
websocket.sgcarstrends.com # Production WebSocket service
websocket.dev.sgcarstrends.com # Dev WebSocket service
```
## DNS Provider: Cloudflare
### Why Cloudflare?
- Free SSL certificates
- DDoS protection
- CDN capabilities
- Fast DNS propagation
- Analytics and logs
- Page Rules for optimization
### DNS Management
Cloudflare manages DNS records, AWS Route53 is for SSL certificate validation only.
## SST Domain Configuration
### DNS Stack
```typescript
// infra/dns.ts
import { StackContext } from "sst/constructs";
import * as route53 from "aws-cdk-lib/aws-route53";
export function DNS({ stack }: StackContext) {
// Import existing hosted zone (created in Route53)
const hostedZone = route53.HostedZone.fromLookup(stack, "HostedZone", {
domainName: "sgcarstrends.com",
});
stack.addOutputs({
HostedZoneId: hostedZone.hostedZoneId,
HostedZoneName: hostedZone.zoneName,
});
return { hostedZone };
}
```
### Web App Domain
```typescript
// infra/web.ts
import { StackContext, NextjsSite, use } from "sst/constructs";
import { DNS } from "./dns";
export function Web({ stack, app }: StackContext) {
const { hostedZone } = use(DNS);
const web = new NextjsSite(stack, "web", {
path: "apps/web",
customDomain: {
domainName: app.stage === "production"
? "sgcarstrends.com" // Apex domain for prod
: `${app.stage}.sgcarstrends.com`, // Subdomain for others
hostedZone: hostedZone.zoneName,
},
});
stack.addOutputs({
WebUrl: web.url,
WebDomain: web.customDomainUrl,
});
return { web };
}
```
### API Domain
```typescript
// infra/api.ts
import { StackContext, Function, use } from "sst/constructs";
import { DNS } from "./dns";
export function API({ stack, app }: StackContext) {
const { hostedZone } = use(DNS);
const api = new Function(stack, "api", {
handler: "apps/api/src/index.handler",
url: {
domain: {
domainName: app.stage === "production"
? "api.sgcarstrends.com"
: `api.${app.stage}.sgcarstrends.com`,
hostedZone: hostedZone.zoneName,
},
},
});
stack.addOutputs({
ApiUrl: api.url,
ApiDomain: api.url,
});
return { api };
}
```
## Cloudflare Configuration
### DNS Records
Cloudflare DNS records point to AWS CloudFront or Lambda Function URLs:
```
Type Name Value Proxy
CNAME sgcarstrends.com d111111abcdef8.cloudfront.net ✓ Proxied
CNAME staging d222222abcdef8.cloudfront.net ✓ Proxied
CNAME dev d333333abcdef8.cloudfront.net ✓ Proxied
CNAME api abc123.lambda-url.ap-southeast-1.on.aws ✓ Proxied
CNAME api.staging def456.lambda-url.ap-southeast-1.on.aws ✓ Proxied
```
### SSL/TLS Settings
**Encryption Mode**: Full (strict)
- Encrypts traffic from browser to Cloudflare
- Encrypts traffic from Cloudflare to origin (AWS)
- Validates origin certificate
**Edge Certificates**:
- Automatically provisioned by Cloudflare
- Covers `*.sgcarstrends.com` and `sgcarstrends.com`
- Auto-renewed
### Page Rules
```
Rule 1: Cache API responses
URL: api.sgcarstrends.com/*
Settings:
- Cache Level: Standard
- Edge Cache TTL: 1 hour
Rule 2: Always use HTTPS
URL: *sgcarstrends.com/*
Settings:
- Always Use HTTPS: On
Rule 3: Security headers
URL: sgcarstrends.com/*
Settings:
- Security Headers: On
- HSTS: Enabled
```
## SSL Certificate Management
### AWS Certificate Manager
SST automatically requests certificates from ACM:
```typescript
// Automatic when using customDomain
const web = new NextjsSite(stack, "web", {
customDomain: {
domainName: "sgcarstrends.com",
hostedZone: hostedZone.zoneName,
},
});
// SST will:
// 1. Request certificate from ACM
// 2. Add DNS validation records to Route53
// 3. Wait for validation
// 4. Attach certificate to CloudFront/Lambda
```
### Manual Certificate Request
If needed:
```bash
# Request certificate
aws acm request-certificate \
--domain-name sgcarstrends.com \
--subject-alternative-names *.sgcarstrends.com \
--validation-method DNS \
--region us-east-1 # CloudFront requires us-east-1
# Get validation records
aws acm describe-certificate \
--certificate-arn arn:aws:acm:... \
--region us-east-1
```
Add validation CNAME records to Cloudflare DNS.
## Adding New Subdomains
### 1. Define in SST
```typescript
// infra/new-service.ts
import { StackContext, Function, use } from "sst/constructs";
import { DNS } from "./dns";
export function NewService({ stack, app }: StackContext) {
const { hostedZone } = use(DNS);
const service = new Function(stack, "new-service", {
handler: "apps/new-service/src/index.handler",
url: {
domain: {
domainName: app.stage === "production"
? "newservice.sgcarstrends.com"
: `newservice.${app.stage}.sgcarstrends.com`,
hostedZone: hostedZone.zoneName,
},
},
});
return { service };
}
```
### 2. Deploy
```bash
npx sst deploy --stage production
```
SST will:
1. Request ACM certificate
2. Create Route53 records for validation
3. Wait for validation
4. Create Lambda Function URL or CloudFront distribution
5. Output the AWS resource URL
### 3. Add Cloudflare DNS
Get the AWS URL from SST outputs, then:
1. Go to Cloudflare dashboard
2. Select `sgcarstrends.com` domain
3. Click "DNS" → "Add record"
4. Type: CNAME
5. Name: `newservice` (or `newservice.staging`)
6. Target: The AWS URL (CloudFront or Lambda)
7. Proxy status: Proxied (orange cloud)
8. TTL: Auto
9. Save
### 4. Verify
```bash
# Check DNS resolution
dig newservice.sgcarstrends.com
# Test HTTPS
curl -I https://newservice.sgcarstrends.com
```
## Debugging DNS Issues
### Check DNS Propagation
```bash
# Check Cloudflare DNS
dig @1.1.1.1 sgcarstrends.com
dig @1.1.1.1 api.sgcarstrends.com
# Check global propagation
dig sgcarstrends.com @8.8.8.8 # Google DNS
dig sgcarstrends.com @1.1.1.1 # Cloudflare DNS
# Or use online tools
# https://www.whatsmydns.net/#CNAME/api.sgcarstrends.com
```
### Check SSL Certificate
```bash
# Check certificate details
openssl s_client -connect sgcarstrends.com:443 -servername sgcarstrends.com
# Check certificate expiry
echo | openssl s_client -connect sgcarstrends.com:443 -servername sgcarstrends.com 2>/dev/null | openssl x509 -noout -dates
```
### Test Domain Resolution
```bash
# Test HTTP → HTTPS redirect
curl -I http://sgcarstrends.com
# Test HTTPS
curl -I https://sgcarstrends.com
# Test API endpoint
curl -I https://api.sgcarstrends.com/health
```
### Common Issues
**Issue**: DNS not resolving
**Solutions**:
1. Check Cloudflare DNS record exists
2. Verify record type (CNAME vs A)
3. Check proxy status (should be Proxied)
4. Wait for propagation (usually < 5 minutes)
**Issue**: SSL certificate error
**Solutions**:
1. Check Cloudflare SSL mode is "Full (strict)"
2. Verify ACM certificate is issued
3. Check certificate covers the subdomain
4. Verify Route53 has validation records
**Issue**: 522 error (Connection timed out)
**Solutions**:
1. Check Lambda/CloudFront is running
2. Verify security groups allow HTTPS
3. Check origin server is responding
4. Review Cloudflare → Origin connection
**Issue**: Redirecting to wrong domain
**Solutions**:
1. Check SST `customDomain` configuration
2. Verify Cloudflare page rules
3. Check application redirect logic
## CORS Configuration
When API and Web are on different domains:
```typescript
// apps/api/src/index.ts
import { Hono } from "hono";
import { cors } from "hono/cors";
const app = new Hono();
app.use("/*", cors({
origin: [
"https://sgcarstrends.com",
"https://staging.sgcarstrends.com",
"https://dev.sgcarstrends.com",
"http://localhost:3001", // Local development
],
credentials: true,
}));
```
## Monitoring
### Cloudflare Analytics
1. Go to Cloudflare dashboard
2. Select domain
3. Click "Analytics & Logs"
View:
- Traffic stats
- Performance metrics
- Security events
- Cache analytics
### AWS Route53 Health Checks
```typescript
// infra/monitoring.ts
import { StackContext } from "sst/constructs";
import * as route53 from "aws-cdk-lib/aws-route53";
export function Monitoring({ stack }: StackContext) {
new route53.CfnHealthCheck(stack, "ApiHealthCheck", {
healthCheckConfig: {
type: "HTTPS",
fullyQualifiedDomainName: "api.sgcarstrends.com",
port: 443,
resourcePath: "/health",
requestInterval: 30,
failureThreshold: 3,
},
});
}
```
## Domain Migration
### Migrating to New Domain
1. **Set up new domain in Cloudflare**
2. **Deploy to new domain**:
```typescript
customDomain: {
domainName: "new-domain.com",
hostedZone: newHostedZone.zoneName,
}
```
3. **Test new domain thoroughly**
4. **Set up redirects from old to new**:
```typescript
// Cloudflare page rule
URL: old-domain.com/*
Forwarding URL: 301 - https://new-domain.com/$1
```
5. **Update all references**
6. **Monitor traffic**
7. **Keep old domain for 6-12 months**
## Apex Domain Considerations
### Using Apex Domain
The project uses apex domain (`sgcarstrends.com`) for production:
**Advantages**:
- Shorter, cleaner URL
- Better for branding
- SEO benefits
**Challenges**:
- CNAME at apex not allowed by DNS spec
- Solution: Cloudflare CNAME flattening
### Cloudflare CNAME Flattening
Cloudflare automatically flattens CNAMEs at apex:
```
# This works with Cloudflare:
CNAME sgcarstrends.com → d111111abcdef8.cloudfront.net
# Cloudflare resolves it to:
A sgcarstrends.com → 104.21.x.x
A sgcarstrends.com → 172.67.x.x
```
## Subdomain Strategy
### Current Subdomains
```
Web apps:
sgcarstrends.com # Production
staging.sgcarstrends.com # Staging
dev.sgcarstrends.com # Development
API:
api.sgcarstrends.com # Production
api.staging... # Staging
api.dev... # Development
Future:
admin.sgcarstrends.com # Admin panel
docs.sgcarstrends.com # Documentation
status.sgcarstrends.com # Status page
```
### Adding Future Services
Follow the pattern:
- **Production**: `{service}.sgcarstrends.com`
- **Non-production**: `{service}.{stage}.sgcarstrends.com`
## Security Headers
Configure in Cloudflare or application:
```typescript
// apps/web/next.config.js
const securityHeaders = [
{
key: "X-DNS-Prefetch-Control",
value: "on",
},
{
key: "Strict-Transport-Security",
value: "max-age=63072000; includeSubDomains; preload",
},
{
key: "X-Frame-Options",
value: "SAMEORIGIN",
},
{
key: "X-Content-Type-Options",
value: "nosniff",
},
{
key: "Referrer-Policy",
value: "origin-when-cross-origin",
},
];
const nextConfig = {
async headers() {
return [
{
source: "/:path*",
headers: securityHeaders,
},
];
},
};
```
## References
- Cloudflare Docs: https://developers.cloudflare.com
- AWS Route53: https://docs.aws.amazon.com/route53
- SST Custom Domains: https://docs.sst.dev/custom-domains
- Related files:
- `infra/dns.ts` - DNS configuration
- `infra/CLAUDE.md` - Infrastructure documentation
## Best Practices
1. **Use Cloudflare Proxy**: Enable orange cloud for DDoS protection
2. **Full (Strict) SSL**: Always use strict SSL mode
3. **HTTPS Only**: Enforce HTTPS with page rules
4. **Consistent Naming**: Follow `{service}.{stage}.domain` pattern
5. **Certificate Management**: Let SST handle ACM certificates
6. **DNS TTL**: Use Auto for active development, higher for stable
7. **Monitoring**: Set up health checks for critical domains
8. **Documentation**: Document all subdomains and their purpose