As your application grows, testing new features directly on your live site becomes a recipe for disaster. You need a "sandbox"—a mirror image of your production environment where you can break things safely.
The most professional way to do this is by setting up a dev.mydomain.com subdomain. In this guide, we’ll go from DNS configuration to SSL and Docker deployment.
The Use Case: Why a dev Subdomain?
Imagine you are integrating a new S3 storage backend or a complex authentication flow.
- Production: Your users see a stable, bug-free version.
-
Development: You test your latest
git pushin a live-server environment that perfectly mimics production (same Nginx, same OS, same S3 buckets).
Once the dev site is verified, you simply merge your code to the main branch and deploy to production with 100% confidence.
Step 1: GoDaddy — Creating the "A Record"
Before the world can find your development site, you must point the dev prefix to your server's IP address.
- Log into your GoDaddy Domain Control Center.
- Select your domain and go to Manage DNS.
- Click Add to create a new record:
-
Type:
A -
Name (Host):
dev -
Value (Points to):
[Your_EC2_Elastic_IP] -
TTL:
600(10 minutes for faster propagation).
Step 2: Preparing the EC2 Firewall
AWS blocks traffic by default. Ensure your Security Group allows HTTPS (Port 443) and HTTP (Port 80) for the new traffic.
- Go to AWS Console > EC2 > Security Groups.
- Select the group attached to your instance.
- Verify Inbound Rules include:
-
Port 80 (HTTP) from
0.0.0.0/0 -
Port 443 (HTTPS) from
0.0.0.0/0
Step 3: Generating the SSL Certificate
You cannot share your main domain's SSL certificate with a subdomain. You need a separate certificate for dev.mydomain.com.
- Stop your Docker containers to free up Port 80 for the Let's Encrypt validation:
docker compose down
- Run Certbot in standalone mode:
sudo certbot certonly --standalone -d dev.mydomain.com
- Note the path to your new certificates (usually
/etc/letsencrypt/live/dev.mydomain.com/).
Step 4: Configuring Nginx as a Traffic Cop
Now, update your Nginx configuration to recognize which requests belong to dev versus your main site.
Edit your nginx.conf (or the file in sites-available):
# 1. Main Production Site
server {
listen 443 ssl;
server_name mydomain.com;
ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
location / {
proxy_pass http://web:8000;
# ... standard proxy headers ...
}
}
# 2. New Development Site
server {
listen 443 ssl;
server_name dev.mydomain.com;
ssl_certificate /etc/letsencrypt/live/dev.mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dev.mydomain.com/privkey.pem;
location / {
proxy_pass http://web:8000; # If sharing the same container, or point to a dev container
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Step 5: Updating Application Settings
If you are using a framework like Django, you must explicitly trust the new subdomain.
In your .env file:
ALLOWED_HOSTS=mydomain.com,dev.mydomain.com,[EC2_IP]
CSRF_TRUSTED_ORIGINS=https://mydomain.com,https://dev.mydomain.com
Step 6: The "Clean Start" Restart
With the configurations in place, it’s time to bring the system back online.
# 1. Rebuild the images to pick up the new .env settings
docker compose build
# 2. Start all services
docker compose up -d
# 3. Verify Nginx is happy
docker compose logs nginx
Conclusion
You now have a fully functional development environment. By visiting https://dev.mydomain.com, you can view and test your application without risk to your primary users. This separation is the cornerstone of a professional CI/CD (Continuous Integration/Continuous Deployment) workflow.
Top comments (0)