<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joseph_oluwaseun</title>
    <description>The latest articles on DEV Community by Joseph_oluwaseun (@passolateam).</description>
    <link>https://dev.to/passolateam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3776826%2F8f7990fc-023b-4bff-ab12-4bef6ff41974.jpeg</url>
      <title>DEV Community: Joseph_oluwaseun</title>
      <link>https://dev.to/passolateam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/passolateam"/>
    <language>en</language>
    <item>
      <title>🏫 EDEN HIGH - Parent Registration Portal</title>
      <dc:creator>Joseph_oluwaseun</dc:creator>
      <pubDate>Tue, 17 Feb 2026 05:27:58 +0000</pubDate>
      <link>https://dev.to/passolateam/parent-registration-portal-2f0i</link>
      <guid>https://dev.to/passolateam/parent-registration-portal-2f0i</guid>
      <description>&lt;p&gt;A production-ready, multi-service web application demonstrating containerization, service isolation, internal networking, and persistent storage using Docker.&lt;/p&gt;

&lt;p&gt;📌 Executive Summary&lt;/p&gt;

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

&lt;p&gt;The application demonstrates:&lt;/p&gt;

&lt;p&gt;Multi-container architecture&lt;/p&gt;

&lt;p&gt;Service isolation&lt;/p&gt;

&lt;p&gt;Docker networking&lt;/p&gt;

&lt;p&gt;Persistent database storage&lt;/p&gt;

&lt;p&gt;Environment-based configuration&lt;/p&gt;

&lt;p&gt;Secure service communication&lt;/p&gt;

&lt;p&gt;The entire system is orchestrated using Docker Compose, making deployment reproducible and environment-agnostic.&lt;/p&gt;

&lt;p&gt;🏗️ Architecture Overview&lt;/p&gt;

&lt;p&gt;The application follows a three-tier architecture model:&lt;/p&gt;

&lt;p&gt;Presentation Layer – Nginx (Frontend)&lt;/p&gt;

&lt;p&gt;Application Layer – Node.js/Express (Backend API)&lt;/p&gt;

&lt;p&gt;Data Layer – PostgreSQL (Database)&lt;/p&gt;

&lt;p&gt;Each component runs in an isolated container and communicates via a custom Docker bridge network.&lt;/p&gt;

&lt;p&gt;🖥️ Architecture Diagram&lt;br&gt;
                        ┌──────────────────────┐&lt;br&gt;
                        │        User          │&lt;br&gt;
                        │  Browser Client      │&lt;br&gt;
                        └──────────┬───────────┘&lt;br&gt;
                                   │&lt;br&gt;
                                   ▼&lt;br&gt;
                        ┌──────────────────────┐&lt;br&gt;
                        │     Frontend         │&lt;br&gt;
                        │   Nginx Container    │&lt;br&gt;
                        │   Port: 3103 → 80    │&lt;br&gt;
                        └──────────┬───────────┘&lt;br&gt;
                                   │  HTTP API Calls&lt;br&gt;
                                   ▼&lt;br&gt;
                        ┌──────────────────────┐&lt;br&gt;
                        │      Backend         │&lt;br&gt;
                        │ Node.js + Express    │&lt;br&gt;
                        │   Port: 3100         │&lt;br&gt;
                        └──────────┬───────────┘&lt;br&gt;
                                   │  Internal Docker Network&lt;br&gt;
                                   ▼&lt;br&gt;
                        ┌──────────────────────┐&lt;br&gt;
                        │      Database        │&lt;br&gt;
                        │    PostgreSQL 13     │&lt;br&gt;
                        │  Port: 5432 (internal)&lt;br&gt;
                        └──────────┬───────────┘&lt;br&gt;
                                   │&lt;br&gt;
                                   ▼&lt;br&gt;
                        ┌──────────────────────┐&lt;br&gt;
                        │  Docker Volume       │&lt;br&gt;
                        │ postgres_data        │&lt;br&gt;
                        │ Persistent Storage   │&lt;br&gt;
                        └──────────────────────┘&lt;/p&gt;

&lt;p&gt;🔄 Request Lifecycle Flow&lt;/p&gt;

&lt;p&gt;User submits registration form.&lt;/p&gt;

&lt;p&gt;Frontend sends POST request to backend API.&lt;/p&gt;

&lt;p&gt;Backend validates request and connects to PostgreSQL.&lt;/p&gt;

&lt;p&gt;Data is inserted into database.&lt;/p&gt;

&lt;p&gt;Backend returns success response.&lt;/p&gt;

&lt;p&gt;Frontend updates UI accordingly.&lt;/p&gt;

&lt;p&gt;🐳 Containerization Strategy&lt;br&gt;
Backend Dockerfile (Node.js Service)&lt;br&gt;
FROM node:18-alpine&lt;/p&gt;

&lt;p&gt;WORKDIR /app&lt;/p&gt;

&lt;p&gt;COPY package*.json ./&lt;br&gt;
RUN npm install --production&lt;/p&gt;

&lt;p&gt;COPY . .&lt;/p&gt;

&lt;p&gt;EXPOSE 3100&lt;/p&gt;

&lt;p&gt;CMD ["node", "server.js"]&lt;/p&gt;

&lt;p&gt;Design Considerations&lt;/p&gt;

&lt;p&gt;Uses lightweight Alpine image for smaller footprint.&lt;/p&gt;

&lt;p&gt;Dependency caching optimization via layered build.&lt;/p&gt;

&lt;p&gt;Exposes only required port.&lt;/p&gt;

&lt;p&gt;No hardcoded credentials.&lt;/p&gt;

&lt;p&gt;Runtime configuration via environment variables.&lt;/p&gt;

&lt;p&gt;Frontend Dockerfile (Nginx Service)&lt;br&gt;
FROM nginx:alpine&lt;/p&gt;

&lt;p&gt;COPY . /usr/share/nginx/html&lt;/p&gt;

&lt;p&gt;Design Considerations&lt;/p&gt;

&lt;p&gt;Static file serving via Nginx.&lt;/p&gt;

&lt;p&gt;Minimal attack surface.&lt;/p&gt;

&lt;p&gt;No application runtime dependencies.&lt;/p&gt;

&lt;p&gt;🧩 Docker Compose Orchestration&lt;br&gt;
services:&lt;/p&gt;

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

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

&lt;p&gt;frontend:&lt;br&gt;
    build: ./frontend&lt;br&gt;
    restart: always&lt;br&gt;
    ports:&lt;br&gt;
      - "3103:80"&lt;br&gt;
    depends_on:&lt;br&gt;
      - backend&lt;br&gt;
    networks:&lt;br&gt;
      - app-network&lt;/p&gt;

&lt;p&gt;volumes:&lt;br&gt;
  postgres_data:&lt;/p&gt;

&lt;p&gt;networks:&lt;br&gt;
  app-network:&lt;br&gt;
    driver: bridge&lt;/p&gt;

&lt;p&gt;🔐 Networking Design&lt;/p&gt;

&lt;p&gt;Custom Docker bridge network (app-network)&lt;/p&gt;

&lt;p&gt;Internal DNS resolution via service names (db, backend)&lt;/p&gt;

&lt;p&gt;Database not exposed to public network&lt;/p&gt;

&lt;p&gt;Only required services expose host ports&lt;/p&gt;

&lt;p&gt;Reduced attack surface&lt;/p&gt;

&lt;p&gt;💾 Persistent Storage Strategy&lt;/p&gt;

&lt;p&gt;The PostgreSQL container uses a named Docker volume:&lt;/p&gt;

&lt;p&gt;postgres_data:/var/lib/postgresql/data&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;p&gt;Data persistence across container restarts&lt;/p&gt;

&lt;p&gt;Separation of state from compute&lt;/p&gt;

&lt;p&gt;Safe container rebuilds without data loss&lt;/p&gt;

&lt;p&gt;⚙️ Configuration Management&lt;/p&gt;

&lt;p&gt;Database credentials injected via .env&lt;/p&gt;

&lt;p&gt;No hardcoded secrets&lt;/p&gt;

&lt;p&gt;Environment-based configuration pattern&lt;/p&gt;

&lt;p&gt;Improved portability across environments&lt;/p&gt;

&lt;p&gt;🚀 Deployment Process&lt;br&gt;
Prerequisites&lt;/p&gt;

&lt;p&gt;Docker&lt;/p&gt;

&lt;p&gt;Docker Compose&lt;/p&gt;

&lt;p&gt;Setup&lt;br&gt;
git clone &lt;a href="https://github.com/passolateam/eden_reg_portal.git" rel="noopener noreferrer"&gt;https://github.com/passolateam/eden_reg_portal.git&lt;/a&gt;&lt;br&gt;
cd eden_reg_portal&lt;/p&gt;

&lt;p&gt;docker compose up --build&lt;/p&gt;

&lt;p&gt;Access application:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:3103" rel="noopener noreferrer"&gt;http://localhost:3103&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⚠️ Challenges &amp;amp; Engineering Lessons&lt;br&gt;
1️⃣ CORS &amp;amp; Cross-Origin Security&lt;/p&gt;

&lt;p&gt;Problem:&lt;br&gt;
Frontend could not communicate with backend due to browser security restrictions.&lt;/p&gt;

&lt;p&gt;Resolution:&lt;/p&gt;

&lt;p&gt;Implemented proper CORS middleware.&lt;/p&gt;

&lt;p&gt;Understood difference between host, container, and browser network contexts.&lt;/p&gt;

&lt;p&gt;2️⃣ Localhost Misconfiguration&lt;/p&gt;

&lt;p&gt;Problem:&lt;br&gt;
Using localhost inside containerized environments caused communication failures.&lt;/p&gt;

&lt;p&gt;Lesson:&lt;/p&gt;

&lt;p&gt;localhost refers to the container itself.&lt;/p&gt;

&lt;p&gt;Service names must be used within Docker networks.&lt;/p&gt;

&lt;p&gt;Public IP required when accessed externally.&lt;/p&gt;

&lt;p&gt;3️⃣ Internal vs External Networking&lt;/p&gt;

&lt;p&gt;Learned to distinguish between:&lt;/p&gt;

&lt;p&gt;Internal container ports&lt;/p&gt;

&lt;p&gt;Host-exposed ports&lt;/p&gt;

&lt;p&gt;Docker bridge networking&lt;/p&gt;

&lt;p&gt;This significantly improved understanding of microservice communication patterns.&lt;/p&gt;

&lt;p&gt;4️⃣ Environment Variable Scope&lt;/p&gt;

&lt;p&gt;Attempted to use process.env in static frontend JavaScript.&lt;/p&gt;

&lt;p&gt;Lesson:&lt;/p&gt;

&lt;p&gt;Environment variables are injected at build/runtime.&lt;/p&gt;

&lt;p&gt;Static frontend must use proper configuration strategy.&lt;/p&gt;

&lt;p&gt;📈 DevOps Principles Demonstrated&lt;/p&gt;

&lt;p&gt;Infrastructure as Code (Docker Compose)&lt;/p&gt;

&lt;p&gt;Immutable Infrastructure&lt;/p&gt;

&lt;p&gt;Service Isolation&lt;/p&gt;

&lt;p&gt;Persistent Data Management&lt;/p&gt;

&lt;p&gt;Secure Configuration&lt;/p&gt;

&lt;p&gt;Network Segmentation&lt;/p&gt;

&lt;p&gt;Reproducible Deployments&lt;/p&gt;

&lt;p&gt;Log-based Debugging&lt;/p&gt;

&lt;p&gt;Container Lifecycle Management&lt;/p&gt;

&lt;p&gt;🔮 Future Improvements&lt;/p&gt;

&lt;p&gt;Reverse proxy (Nginx API gateway pattern)&lt;/p&gt;

&lt;p&gt;HTTPS via Let's Encrypt&lt;/p&gt;

&lt;p&gt;Multi-stage Docker builds&lt;/p&gt;

&lt;p&gt;Health checks&lt;/p&gt;

&lt;p&gt;CI/CD integration&lt;/p&gt;

&lt;p&gt;Container registry deployment&lt;/p&gt;

&lt;p&gt;Kubernetes migration readiness&lt;/p&gt;

&lt;p&gt;🎯 Conclusion&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;This project strengthened expertise in:&lt;/p&gt;

&lt;p&gt;Containerization strategy&lt;/p&gt;

&lt;p&gt;Network debugging&lt;/p&gt;

&lt;p&gt;Cross-service communication&lt;/p&gt;

&lt;p&gt;Secure configuration&lt;/p&gt;

&lt;p&gt;Deployment reproducibility&lt;/p&gt;

&lt;p&gt;It reflects readiness to design, containerize, and deploy production-grade applications using Docker-based workflows.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devsecops</category>
      <category>devops</category>
      <category>html</category>
    </item>
  </channel>
</rss>
