Muhammad SharjeelSenior Software Engineer

Islamabad · --:--:--


Hosting Multiple Domains on One Server with Docker, NGINX & SSL (DevOps for Developers)

As a full-stack developer, I recently had to deploy multiple backend services on one server, each with its own domain and SSL certificate. Here's how I combined Docker, NGINX, and Certbot to build a scalable, production-grade setup — without needing a dedicated DevOps engineer.

As a full-stack developer, I usually focus on building features — not server orchestration. But recently, I needed to deploy three independent services (Alara, PolyX, Langflow) on a single cloud server. Each had its own domain name, microservices, databases, and required HTTPS.

This felt like a DevOps task. But instead of offloading it, I decided to learn it. Here's exactly how I pulled it off with Docker, NGINX, and Certbot.

Problem Statement

  • One server (GCP VM)
  • Three services: Alara, PolyX, Langflow
  • Each must be accessible from its own domain:
    • https://alara-agents.com
    • https://poly-x.com
    • https://langflow.app
  • Each service uses microservices (Node.js, Redis, MongoDB)
  • Each service is containerized with Docker
  • All domains must have valid SSL certificates (Let's Encrypt)

Solution Architecture

I used a centralized NGINX reverse proxy pattern:

  1. One main NGINX container exposed on ports 80 and 443
  2. Each app stack runs its own Docker services (on custom ports)
  3. Domains are routed via NGINX server_name blocks
  4. SSL certificates are handled via Certbot and mounted into NGINX

Folder Structure

/projects
  ├── nginx-proxy/
  │   ├── docker-compose.yml
  │   └── conf.d/
  │       ├── alara.conf
  │       ├── polyx.conf
  │       └── langflow.conf
  ├── alara/
  │   └── docker-compose.yml
  ├── polyx/
  │   └── docker-compose.yml
  └── langflow/
      └── docker-compose.yml

Docker Networking Strategy

I created a shared Docker network:

docker network create shared

Each app and the NGINX container are connected to this shared network. This allows NGINX to proxy to containers by name (e.g., alara-api:3000).

Central NGINX Setup

Here’s a snippet from my main NGINX container’s compose file:

services:
    nginx:
      image: nginx:latest
      ports:
        - "80:80"
        - "443:443"
      volumes:
        - ./conf.d:/etc/nginx/conf.d
        - /etc/letsencrypt:/etc/letsencrypt
        - /var/www/certbot:/var/www/certbot
      networks:
        - shared

NGINX Domain Config (alara.conf)

server {
    listen 80;
    server_name alara-agents.com;
  
    location /.well-known/acme-challenge/ {
      root /var/www/certbot;
    }
  
    location / {
      return 301 https://$host$request_uri;
    }
  }
  
  server {
    listen 443 ssl;
    server_name alara-agents.com;
  
    ssl_certificate /etc/letsencrypt/live/alara-agents.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/alara-agents.com/privkey.pem;
  
    location / {
      proxy_pass http://alara-api:3000;
      include proxy_params;
    }
  }

I repeated this setup for poly-x.com and langflow.app as well.

App Port Mapping (Avoiding Conflicts)

Each service stack maps its internal ports to unique external ones. For example:

Alara:
    3100:3000 (API)
    3101:3001 (Auth)
    3102:5000 (Alerts)
  
  PolyX:
    3200:3000
    3201:4000
    3202:5000
  
  Langflow:
    3300:3000
    3301:5000

MongoDB and Redis also get isolated ports per service. This eliminates any conflicts.

SSL via Certbot

I used Certbot in webroot mode (so it works behind NGINX):

docker run --rm -it \
    -v /etc/letsencrypt:/etc/letsencrypt \
    -v /var/www/certbot:/var/www/certbot \
    certbot/certbot certonly \
    --webroot --webroot-path=/var/www/certbot \
    -d alara-agents.com -d poly-x.com -d langflow.app

Certificates are automatically mounted into the NGINX container.

Auto-Renewal

I set up a cron job to renew certificates and reload NGINX monthly:

0 3 * * * docker run --rm \
    -v /etc/letsencrypt:/etc/letsencrypt \
    -v /var/www/certbot:/var/www/certbot \
    certbot/certbot renew --webroot --webroot-path=/var/www/certbot \
    && docker exec nginx-proxy nginx -s reload

Result: 3 Domains, 1 Server, Full HTTPS

  • https://alara-agents.com → Alara stack
  • https://poly-x.com → PolyX stack
  • https://langflow.app → Langflow stack

All isolated, independently scalable, and SSL-secure — running on a single server.

Key Takeaways

  • Use one NGINX reverse proxy to handle all domain routing
  • Keep Docker networks shared but services isolated
  • Use Certbot in webroot mode and mount volumes into NGINX
  • Map ports uniquely per app to prevent service collisions

Final Thoughts

This experience taught me that as a full-stack dev, understanding DevOps makes you 10× more effective — especially when working solo or deploying to production. This setup is now part of my go-to deployment playbook.

Hope it helps you as much as it helped me!

esc
HomeThe hero, the system map and selected workPageWorkAll 6 projects, each with a glimpse of its interfacePageAboutExperience, how I work and the stack I usePageWriting12 posts on engineering, AI and designPageGet in touchContact me by email or hire me on UpworkSection
Alara CodeTurns a client brief into a complete, human-approved software delivery pack.ProjectPolyXIdentity, tenancy and access platform shared by every product in the company.ProjectPolyX SDKTypeScript auth SDK on npm that puts the platform behind one typed client.ProjectAlara SpaceMulti-tenant team wiki that AI agents can read and write through MCP.ProjectAlara PlanProject tracker with AI meeting minutes, support intake and an MCP server.ProjectODINOmni-channel customer engagement platform on a microservices backend.Project
A portfolio that builds itself while you scrollThis site starts as a blank canvas and a swarm of cursors draws it in front of you. Here is why I wanted that, what it is made of, and everything that went wrong on the way.8 min readUnslopping AI output with nothing but a skillYou do not need a better model to get rid of the purple gradients. You need your taste written down as a skill the agent loads before it touches the screen.2 min readAI Assistant Coding vs Vibe CodingAs AI becomes ubiquitous in software development, a dangerous pattern is emerging: developers blindly accepting AI suggestions without understanding the code. This 'vibe coding' approach undermines the fundamentals of being a developer. Here's why understanding code matters more than shipping it, and how to use AI as a proper assistant.8 min readHosting Multiple Domains on One Server with Docker, NGINX & SSL (DevOps for Developers)As a full-stack developer, I recently had to deploy multiple backend services on one server, each with its own domain and SSL certificate. Here's how I combined Docker, NGINX, and Certbot to build a scalable, production-grade setup — without needing a dedicated DevOps engineer.3 min readTaming CORS in a Microservices Monorepo: From Async Validation to a Unified ConfigCORS errors can be frustrating, especially in a microservices monorepo setup. This blog dives into what CORS really is, why it matters, and how I solved the CORS challenge using a shared JSON config file — establishing a single source of truth for all services.4 min readDebugging Tips for Frontend Developers (React + Next.js)Effective debugging is one of the most valuable skills for frontend developers. Here's a practical guide to debugging with logs, using the debugger keyword, troubleshooting APIs, and improving performance — with a special focus on React and Next.js.3 min readIs the ‘AI Developer’ a Threat to Jobs – or a Marketing Stunt?AI dev tools are booming — but are they replacing developers or just reshaping workflows? Here's the balanced view.3 min readUsing Docker & NGINX to Build a Suite of MicroservicesExplore how to use Docker and NGINX to containerize and orchestrate a scalable microservices suite. Includes setup tips, architecture advice, and real-world tradeoffs.3 min readGetting Started with Next.js: Structure, Tips & DeploymentA developer-friendly introduction to Next.js — learn how to scaffold projects, understand folder structure, configure features, and deploy to Vercel seamlessly.3 min readGrid Systems: The Foundation of Great UI DesignWant cleaner, more balanced layouts? A grid system brings structure, rhythm, and clarity to your UI — and Tailwind makes it easier than ever to implement.2 min readUsing Generative AI to Speed Up Creative and Dev WorkflowsFrom ChatGPT to v0.dev — here's how generative AI helps streamline UI design, prototyping, coding, and problem-solving in modern workflows.3 min readWhat Is Accessible Design and Why It MattersAccessibility isn’t a nice-to-have. It’s a necessity. Here's why accessible design matters — and how to get it right in your UI and frontend code.3 min read
GitHubgithub.com/isharjeelddNew tabLinkedInlinkedin.com/in/muhammad-sharjeel-254a48108New tabUpworkHire me for freelance workNew tab