Deploying Applications Using Nginx and Docker

Introduction

Deploying web applications can be overwhelming, especially when handling multiple services like a frontend, backend, and database. This guide will walk you through deploying a Next.js frontend, FastAPI backend, and PostgreSQL database using Docker and Nginx as a reverse proxy.

By the end of this tutorial, you’ll understand how to:

  • Use Docker Compose to manage multi-container applications.
  • Configure Nginx as a reverse proxy for your frontend and backend.
  • Secure your application with SSL certificates.

Understanding the Architecture

We’ll deploy the following services:

  • Frontend: A Next.js application running on port 3000.
  • Backend: A FastAPI service running on port 8000.
  • Database: A PostgreSQL instance for data storage.
  • Nginx: A reverse proxy to handle traffic and SSL termination.

Docker Compose will orchestrate these services and ensure they run together in an isolated network.


Step 1: Setting Up Docker Compose

Our docker-compose.yml file defines how all the services run together:

version: '3.8'

services:
  app:
    image: <link_to_image>
    container_name: fastapi_app
    restart: always
    ports:
      - "8000:8000"
    depends_on:
      - db
    environment:
      - DATABASE_URL=postgresql://${DATABASE_USERNAME}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}
    networks:
      - app_network

  db:
    image: postgres:latest
    container_name: postgres_db
    restart: always
    environment:
      POSTGRES_USER: ${DATABASE_USERNAME}
      POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
      POSTGRES_DB: ${DATABASE_NAME}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app_network

  nginx:
    image: nginx:latest
    container_name: nginx_proxy
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - /etc/letsencrypt/<path>/fullchain.pem:/etc/letsencrypt/live/<path>/fullchain.pem
      - /etc/letsencrypt/<path>/privkey.pem:/etc/letsencrypt/live/<path>/privkey.pem
    depends_on:
      - app
    networks:
      - app_network

  frontend:
    image: <link_to_image>
    container_name: nextjs_frontend
    ports:
      - "3000:3000"
    environment:
      - NEXT_PUBLIC_API_URL=<api_url>
    depends_on:
      - app
    networks:
      - app_network

networks:
  app_network:

volumes:
  postgres_data:

Step 2: Configuring Nginx as a Reverse Proxy

The Nginx configuration file (nginx.conf) routes requests to the correct service:

http {
    server {
        listen 80;
        server_name <url>;
        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl;
        server_name <url>;
        
        ssl_certificate /etc/letsencrypt/<path>/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/<path>/privkey.pem;

        location / {
            proxy_pass http://fastapi_app:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

Step 3: Running the Application

Build and Run the Containers

docker-compose up -d

This will start all services in the background.

Verify Everything is Running

docker ps

You should see containers for nginx_proxy, fastapi_app, nextjs_frontend, and postgres_db.

Restarting a Service

If you make changes, restart a specific service:

docker-compose restart nginx

Conclusion

You’ve successfully deployed a Next.js + FastAPI application with PostgreSQL, managed with Docker and Nginx. This setup ensures: ✅ Scalable and isolated services. ✅ Secure deployment with HTTPS. ✅ Easy container management using Docker Compose.

Now, you can focus on developing your application while Docker and Nginx handle the deployment. 🚀




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • From Delhi to Geneva: My Journey to CERN
  • Introduction to Vector Databases
  • Understanding Artificial Neural Networks