DEV Community

Joseph_oluwaseun
Joseph_oluwaseun

Posted on

🏫 EDEN HIGH - Parent Registration Portal

A production-ready, multi-service web application demonstrating containerization, service isolation, internal networking, and persistent storage using Docker.

📌 Executive Summary

The Parent Registration Portal is a containerized full-stack web application that enables parents to register themselves and their children via a web interface.

The application demonstrates:

Multi-container architecture

Service isolation

Docker networking

Persistent database storage

Environment-based configuration

Secure service communication

The entire system is orchestrated using Docker Compose, making deployment reproducible and environment-agnostic.

🏗️ Architecture Overview

The application follows a three-tier architecture model:

Presentation Layer – Nginx (Frontend)

Application Layer – Node.js/Express (Backend API)

Data Layer – PostgreSQL (Database)

Each component runs in an isolated container and communicates via a custom Docker bridge network.

🖥️ Architecture Diagram
┌──────────────────────┐
│ User │
│ Browser Client │
└──────────┬───────────┘


┌──────────────────────┐
│ Frontend │
│ Nginx Container │
│ Port: 3103 → 80 │
└──────────┬───────────┘
│ HTTP API Calls

┌──────────────────────┐
│ Backend │
│ Node.js + Express │
│ Port: 3100 │
└──────────┬───────────┘
│ Internal Docker Network

┌──────────────────────┐
│ Database │
│ PostgreSQL 13 │
│ Port: 5432 (internal)
└──────────┬───────────┘


┌──────────────────────┐
│ Docker Volume │
│ postgres_data │
│ Persistent Storage │
└──────────────────────┘

🔄 Request Lifecycle Flow

User submits registration form.

Frontend sends POST request to backend API.

Backend validates request and connects to PostgreSQL.

Data is inserted into database.

Backend returns success response.

Frontend updates UI accordingly.

🐳 Containerization Strategy
Backend Dockerfile (Node.js Service)
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install --production

COPY . .

EXPOSE 3100

CMD ["node", "server.js"]

Design Considerations

Uses lightweight Alpine image for smaller footprint.

Dependency caching optimization via layered build.

Exposes only required port.

No hardcoded credentials.

Runtime configuration via environment variables.

Frontend Dockerfile (Nginx Service)
FROM nginx:alpine

COPY . /usr/share/nginx/html

Design Considerations

Static file serving via Nginx.

Minimal attack surface.

No application runtime dependencies.

🧩 Docker Compose Orchestration
services:

db:
image: postgres:13-alpine
restart: always
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- app-network

backend:
build: ./backend
restart: always
ports:
- "3100:3100"
environment:
DB_HOST: db
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ${DB_NAME}
depends_on:
- db
networks:
- app-network

frontend:
build: ./frontend
restart: always
ports:
- "3103:80"
depends_on:
- backend
networks:
- app-network

volumes:
postgres_data:

networks:
app-network:
driver: bridge

🔐 Networking Design

Custom Docker bridge network (app-network)

Internal DNS resolution via service names (db, backend)

Database not exposed to public network

Only required services expose host ports

Reduced attack surface

💾 Persistent Storage Strategy

The PostgreSQL container uses a named Docker volume:

postgres_data:/var/lib/postgresql/data

Benefits:

Data persistence across container restarts

Separation of state from compute

Safe container rebuilds without data loss

⚙️ Configuration Management

Database credentials injected via .env

No hardcoded secrets

Environment-based configuration pattern

Improved portability across environments

🚀 Deployment Process
Prerequisites

Docker

Docker Compose

Setup
git clone https://github.com/passolateam/eden_reg_portal.git
cd eden_reg_portal

docker compose up --build

Access application:

http://localhost:3103

⚠️ Challenges & Engineering Lessons
1️⃣ CORS & Cross-Origin Security

Problem:
Frontend could not communicate with backend due to browser security restrictions.

Resolution:

Implemented proper CORS middleware.

Understood difference between host, container, and browser network contexts.

2️⃣ Localhost Misconfiguration

Problem:
Using localhost inside containerized environments caused communication failures.

Lesson:

localhost refers to the container itself.

Service names must be used within Docker networks.

Public IP required when accessed externally.

3️⃣ Internal vs External Networking

Learned to distinguish between:

Internal container ports

Host-exposed ports

Docker bridge networking

This significantly improved understanding of microservice communication patterns.

4️⃣ Environment Variable Scope

Attempted to use process.env in static frontend JavaScript.

Lesson:

Environment variables are injected at build/runtime.

Static frontend must use proper configuration strategy.

📈 DevOps Principles Demonstrated

Infrastructure as Code (Docker Compose)

Immutable Infrastructure

Service Isolation

Persistent Data Management

Secure Configuration

Network Segmentation

Reproducible Deployments

Log-based Debugging

Container Lifecycle Management

🔮 Future Improvements

Reverse proxy (Nginx API gateway pattern)

HTTPS via Let's Encrypt

Multi-stage Docker builds

Health checks

CI/CD integration

Container registry deployment

Kubernetes migration readiness

🎯 Conclusion

The Parent Registration Portal is more than a simple web form application — it is a demonstration of practical DevOps engineering principles applied to a real-world containerized architecture.

This project strengthened expertise in:

Containerization strategy

Network debugging

Cross-service communication

Secure configuration

Deployment reproducibility

It reflects readiness to design, containerize, and deploy production-grade applications using Docker-based workflows.

Top comments (0)