Containerized URL Shortener

Multi-Container Docker Application

A URL shortening service built as a multi-container Docker deployment. Three separate containers -- nginx, Flask, and PostgreSQL -- communicate over a Docker network to accept a URL, shorten it, store the mapping, and redirect visitors who follow the shortened link. The entire stack is defined in a single docker-compose.yml and launches with one command.

Why Containers

The point of this project is containerization itself. Each service runs in its own isolated Docker container with its own filesystem, dependencies, and process space. The nginx container does not have Python installed. The Flask container does not have PostgreSQL installed. They only interact over the internal Docker network, the same way separate machines would communicate over a real network. Docker Compose orchestrates all three containers as a single unit: one command builds all images, creates the network, attaches the volume, and starts every service.

Architecture

Three containerized services, each with a distinct role:

  • nginx -- Reverse proxy and static file server. Serves the HTML form directly to the browser and forwards all API requests to the Flask container. The browser never communicates with Flask or PostgreSQL directly.
  • Flask -- Python backend that handles the URL shortening logic. Receives proxied requests from nginx, generates a shortened slug, writes the original-to-short mapping into PostgreSQL, and handles redirect lookups when someone visits a short URL.
  • PostgreSQL -- Relational database that stores every URL mapping. Data persists across container restarts through a Docker named volume, meaning docker-compose down and docker-compose up will not lose any previously shortened URLs.

Request Flow

Step by step, here is what happens when a user shortens a URL:

  • The user opens http://localhost:80 in a browser. nginx serves the static HTML form.
  • The user submits a URL. The browser sends a POST request to nginx.
  • nginx proxies the POST to the Flask container on the internal Docker network.
  • Flask generates a shortened slug, sends an INSERT query to PostgreSQL, and returns the shortened URL to nginx, which passes it back to the browser.
  • When someone clicks the shortened URL, the same chain runs in reverse: nginx proxies to Flask, Flask queries PostgreSQL for the original URL, and returns a redirect response.

Tech Stack

  • Docker and Docker Compose (container orchestration)
  • nginx (reverse proxy, static file serving)
  • Flask / Python (backend application logic)
  • PostgreSQL (persistent data storage)
  • Docker named volumes (data persistence across restarts)

View on GitHub