Day 24 of my 90-day DevOps: Advanced Docker Concepts and Project Guide: Building a Multi-Container Application

Abigeal AfolabiAbigeal Afolabi
5 min read

Introduction

Welcome back to Day 24 of my 90-day DevOps journey! Today, we're diving deeper into advanced Docker concepts, focusing on Docker Compose and Docker Networking. These tools are essential for building robust, scalable, and secure containerized applications.

The Journey So Far

As I continue this learning adventure, I've realized that balancing work and this intensive learning experience can be challenging. It's a constant reminder that even experienced professionals face obstacles on their paths to mastery.
However, I believe that sharing my experiences, both the successes and the challenges, can inspire others who are also on their DevOps journeys.

Advanced Docker Concepts

1. Docker Compose

Docker Compose simplifies the management of multi-container applications. It allows you to define services, networks, and volumes in a YAML file, enabling you to spin up your entire application stack with a single command.

2. Docker Networking

Understanding Docker's networking options is crucial for building applications with inter-container communication.

  • Bridge Networking: The default mode, creating a virtual network for containers on the same Docker host.

  • Host Networking: Containers share the host's network stack, allowing direct access to the host's network interfaces.

  • Overlay Networking: Enables communication across multiple Docker hosts, ideal for complex applications.

3. Docker Volumes

Volumes provide persistent storage for containers, ensuring data is retained even after a container is stopped or removed.

4. Docker Swarm

Docker Swarm is Docker's built-in orchestration tool for managing containerized applications across a cluster, offering features like load balancing and service discovery.

5. Docker Security

Security is vital for protecting your containers and applications.

  • Image Scanning: Use tools like Docker Hub's image scanning to identify vulnerabilities.

  • Security Context: Configure contexts to restrict container privileges and network access.

  • Built-in Security Features: Leverage SELinux and AppArmor for enhanced security.

Project Guide: Building a Multi-Container Application with Docker Compose

Project Goal

Create a multi-container application with a web server (Nginx) and a backend application (Node.js) using Docker Compose. The application will dynamically display the current day of your project.

Step-by-Step Guide

  1. Project Setup

    • Create a new project directory (e.g., my-multi-container-app).

    • Create a docker-compose.yml file in the project directory.

    • Set up directories for Nginx (nginx) and Node.js (node-app).

  2. Define Docker Compose Services

docker-compose.yml:

   version: "3.8"
   services:
     nginx:
       image: nginx:latest
       ports:
         - "80:80"
       volumes:
         - ./nginx/conf.d:/etc/nginx/conf.d
         - ./nginx/html:/usr/share/nginx/html
       depends_on:
         - node-app
     node-app:
       build: ./node-app
       ports:
         - "3000:3000"
  1. Nginx Configuration

nginx/conf.d/default.conf:

   server {
     listen 80;

     # Redirect all requests to the Node.js server running on port 3000
     location / {
       proxy_pass http://node-app:3000;
     }
   }

Explanation:

  • server { ... }: Defines a server block, which is a configuration unit for a specific virtual host.

  • listen 80;: Makes Nginx listen for incoming requests on port 80, the standard HTTP port.

  • location / { ... }: Defines a location block, which specifies how to handle requests matching a particular path. In this case, it matches all requests.

  • proxy_pass http://node-app:3000;: Instructs Nginx to forward all incoming requests to the Node.js server running on port 3000 within the Docker network. This is how Nginx acts as a reverse proxy, directing traffic to your backend application.

  1. Node.js Backend Application

    • node-app/package.json: Add your Node.js dependencies (e.g., express).

    • node-app/index.js:

   const express = require('express');
   const app = express();
   const port = 3000;

   app.get('/', (req, res) => {
     const today = new Date();
     const day = today.getDate();
     res.send(`Hello, it's day ${day} of my 90 days DevOps project!`);
   });

   app.listen(port, () => {
     console.log(`Example app listening on port ${port}`);
   });
  • node-app/Dockerfile:
   FROM node:16-alpine
   WORKDIR /app
   COPY package*.json ./
   RUN npm install
   COPY . .
   CMD ["npm", "start"]
  1. Build and Run

    • Build: Run docker-compose build to build images for both services.

    • Run: Execute docker-compose up -d to start services in detached mode.

  2. Testing

    • Access your application at http://localhost. You should see the message dynamically displaying the current day.

Building a Resource for Learners

I plan to document this project on GitHub, creating a resource for anyone who wants to learn about DevOps, including Docker, containerization, cloud security, and related technologies. I've already written a number of courses and will continue to do so throughout my 90-day project. I believe that sharing my knowledge and experiences can be valuable for those starting their own DevOps journeys.

Conclusion

This project guide lays the foundation for building multi-container applications with Docker Compose. By mastering these advanced concepts, you can create sophisticated, scalable, and secure containerized solutions.

Remember, even the most experienced developers have faced challenges on their learning paths. Don't be afraid to embrace the journey and share your experiences with others.

Stay curious and keep learning as you explore the vast possibilities of Docker!

Resources

Docker Documentation

Docker Compose Documentation

Tutorials and Articles

Video Tutorials

Books

Important:

  • Make sure you have the nginx directory created and the nginx/conf.d/default.conf file added.

  • You can create a simple nginx/html directory with an index.html file if you want to serve static content.

Now, when you run docker-compose up -d, you'll have both the Nginx and Node.js containers running, with Nginx acting as a reverse proxy, making your application truly multi-container!

We've built a multi-container application using Docker Compose, where Nginx works with the Node.js backend to make the website work.

0
Subscribe to my newsletter

Read articles from Abigeal Afolabi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abigeal Afolabi
Abigeal Afolabi

๐Ÿš€ Software Engineer by day, SRE magician by night! โœจ Tech enthusiast with an insatiable curiosity for data. ๐Ÿ“ Harvard CS50 Undergrad igniting my passion for code. Currently delving into the MERN stack โ€“ because who doesn't love crafting seamless experiences from front to back? Join me on this exhilarating journey of embracing technology, penning insightful tech chronicles, and unraveling the mysteries of data! ๐Ÿ”๐Ÿ”ง Let's build, let's write, let's explore โ€“ all aboard the tech express! ๐Ÿš‚๐ŸŒŸ #CodeAndCuriosity