DEV Community

Clarisse X. K.
Clarisse X. K.

Posted on Edited on

Building the "Little Dino Sanctuary": A Multi-Tier Web Application with Node.js, PostgreSQL, and Docker

A cozy multi-tier web sanctuary for dinosaur cataloging, built with containerized architecture and modern DevOps practices.


1. Introduction & The Problem

When building modern web applications, ensuring consistency across development and production environments is one of the biggest hurdles developers face. For the Little Dino Sanctuary project, the core challenge was to design a reliable, scalable, and secure system for cataloging dinosaur resident records while ensuring seamless deployment.

We chose this project because it perfectly mirrors real-world enterprise architectures separating concerns between a robust backend API, a persistent database layer, and a clean user interface all while strictly adhering to modern security standards like secret management.


2. System Architecture

The application follows a classic multi-tier client-server architecture containerized via Docker:

  • Presentation Tier: Static frontend interface serving resident records (public/index.html).
  • Application Tier: Node.js & Express REST API handling business logic (server.js).
  • Data Tier: PostgreSQL database container managing persistent storage with isolated data volumes.
  • Orchestration: Docker Compose coordinates the networking and startup sequence between the backend and database services.

3. Key Docker Configuration & Explanation

Containerization ensures that the application runs identically on any machine. Below are the essential snippets from our configuration files.

The Dockerfile

Our multi-stage setup optimizes the Node.js runtime environment:

FROM node:18-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Enter fullscreen mode Exit fullscreen mode
  • Explanation: We use a lightweight Alpine Linux base image to keep the container size minimal. It installs production dependencies, copies the source code, and exposes port 3000 to handle incoming HTTP requests.

The docker-compose.yml

version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DB_HOST=db
    depends_on:
      - db
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: dino_sanctuary
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: secretpassword
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:
Enter fullscreen mode Exit fullscreen mode
  • Explanation: This configuration defines two interconnected services (app and db). It establishes internal networking so the Node.js application can communicate securely with the PostgreSQL database container using Docker volumes for persistent data storage.

4. Security Best Practices: Managing .env Secrets

A critical learning point of this project was enforcing strict security policies. To prevent credential leaks, sensitive environment variables (such as database passwords) are stored locally in a .env file which is explicitly excluded from version control via .gitignore. Teammates and evaluators can use .env.example as a safe template.


5. How to Run Locally

Getting the sanctuary up and running on your local machine takes less than a minute with Docker:

  1. Clone the repository:
   git clone https://github.com/Clarisse-X/little-dino-sanctuary.git
   cd little-dino-sanctuary
Enter fullscreen mode Exit fullscreen mode
  1. Configure environment variables: Copy the example file and adjust values if needed:
   cp .env.example .env
Enter fullscreen mode Exit fullscreen mode
  1. Build and launch with Docker Compose:
   docker-compose up --build
Enter fullscreen mode Exit fullscreen mode
  1. Open your browser and navigate to http://localhost:3000.

6. Lessons Learned

  • Containerization Mastery: Gained hands-on experience writing robust Dockerfiles and orchestrating multi-container environments using Docker Compose.
  • Git Workflow Discipline: Learned the importance of structured, incremental commits and rigorous secret management (keeping .env out of public repositories).
  • CI/CD Readiness: Successfully pushed version-tagged images (1.0.0 and latest) to Docker Hub, bridging the gap between local development and cloud distribution.

Project Links & Resources

Top comments (0)