Building a Fully Dockerized User Feedback Application with Flask and PostgreSQL

Published: (February 12, 2026 at 08:20 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Introduction

In this project, I built a full‑stack web application using Docker to demonstrate containerization concepts including Dockerfiles, Docker Compose, volumes, networking, and environment variables. The application allows users to submit feedback through a web interface, which is stored in a PostgreSQL database running in a Docker container.

Project Architecture

The system consists of three services:

  • Frontend – static HTML/CSS/JS served via Nginx
  • Backend – Flask REST API
  • PostgreSQL Database

All services run in isolated containers connected through a custom Docker network.

Dockerfile Explanation

Backend Dockerfile

# syntax=docker/dockerfile:1
FROM python:3.11-slim

# Install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY . /app
WORKDIR /app

# Expose Flask port
EXPOSE 5000

# Run Flask app
CMD ["python", "app.py"]

Frontend Dockerfile (Nginx)

FROM nginx:alpine

# Copy static files into Nginx web directory
COPY ./static /usr/share/nginx/html

# Expose HTTP port
EXPOSE 80

Docker Compose Orchestration

Docker Compose orchestrates the multiple containers:

  • PostgreSQL database
  • Flask backend API
  • Nginx frontend server

Service dependencies are defined using depends_on, and a custom Docker network enables inter‑container communication.

version: "3.9"

services:
  db:
    image: postgres:15
    env_file: .env
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - feedback-net

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    env_file: .env
    depends_on:
      - db
    ports:
      - "5000:5000"
    networks:
      - feedback-net

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    depends_on:
      - backend
    ports:
      - "8080:80"
    networks:
      - feedback-net

networks:
  feedback-net:

volumes:
  pgdata:

Volumes and Networking

  • Volume pgdata persists PostgreSQL data across container restarts.
  • Network feedback-net allows containers to communicate using service names (e.g., db, backend) instead of IP addresses.

Environment Variables

Sensitive data such as database credentials are stored in a .env file and injected into containers via Docker Compose. This avoids hard‑coding secrets in the source code.

POSTGRES_USER=feedback_user
POSTGRES_PASSWORD=secure_password
POSTGRES_DB=feedback_db

Challenges and Lessons Learned

  • Networking: Understanding the difference between Docker’s internal networking (service names) and browser networking (localhost) was essential. Containers communicate via service names, while the host accesses exposed ports through localhost.
  • Persistence: Ensuring database persistence required correctly configuring Docker volumes.

Conclusion

This project demonstrates real‑world Docker usage, including multi‑container orchestration, persistent storage, environment configuration, and networking. It highlights how Docker simplifies deploying full‑stack applications.

+--------------------+
|      Browser       |
+---------+----------+
          |
          v
+--------------------+
|  Frontend (Nginx)   |
|  Container :8080    |
+---------+----------+
          |
          v
+--------------------+
|  Backend (Flask)    |
|  Container :5000    |
+---------+----------+
          |
          v
+--------------------+
| PostgreSQL Database |
| Docker Volume pgdata|
+--------------------+
0 views
Back to Blog

Related posts

Read more »

Cast Your Bread Upon the Waters

!Cover image for Cast Your Bread Upon the Watershttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-t...