Containerizing a Simple Web Application with Docker: Step-by-Step Guide

Ā·

5 min read

Containerizing a Simple Web Application with Docker: Step-by-Step Guide

Hey everyone! šŸ™Œ Welcome back to another exciting post in my DevOps journey as part of the #90DaysOfDevOps challenge! Today, we'll be working with Docker to build and deploy two web applicationsā€”one using Node.js and another using Python (Flask). šŸš€

If you're new to Docker, don't worry! I'll guide you through each step, showing you how to containerize and run these apps separately, without using Docker Compose. Letā€™s dive in!

What is Docker? šŸ³

Docker is a tool that makes it easy to package applications and their dependencies into containers. Containers provide a consistent environment for running apps, so you donā€™t have to worry about platform differences. Today, weā€™ll containerize two simple web appsā€”one written in Node.js and the other in Pythonā€”using individual Dockerfiles for each.

What is a Dockerfile? šŸ“œ

A Dockerfile is a text file that contains a set of instructions to create a Docker image. It acts as a blueprint for Docker to automate the building of images, defining everything needed to run your application.

Hereā€™s a quick breakdown of what a Dockerfile can include:

  • Base Image: The starting point for your application, usually a lightweight operating system or a pre-built image (like Node.js or Python).

  • Instructions: Commands that specify how to set up your application, such as installing dependencies, copying files, and exposing ports.

  • Environment Variables: Configuration options that can be set inside the container to customize behavior.

  • Commands to Run: The command that will be executed when a container is started from the image, usually the command to run your application.

Using a Dockerfile simplifies the process of deploying applications, making it easier to replicate environments across different machines.

Letā€™s Get Started!

Step 1: Setting Up the Node.js and Python Apps

Weā€™ll first create two separate web applications, one with Node.js and another with Python (Flask).

Node.js App

  1. Create a directory for the project and the Node.js app.
mkdir docker-project
cd docker-project
mkdir node-app
  1. Inside the node-app folder, create a file called app.js:
// node-app/app.js
const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello from Node.js!');
});

app.listen(port, () => {
  console.log(`Node.js app is running on http://localhost:${port}`);
});
  1. Create a package.json file to manage dependencies:
{
  "name": "node-app",
  "version": "1.0.0",
  "main": "app.js",
  "dependencies": {
    "express": "^4.17.1"
  },
  "scripts": {
    "start": "node app.js"
  }
}
  1. Install the dependencies:
cd node-app
npm install
cd ..

Python App

  1. Now, set up the Python Flask app in a separate folder.
mkdir python-app
  1. Inside the python-app folder, create a file called app.py:
# python-app/app.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello from Python!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
  1. Create a requirements.txt file to specify the Flask dependency:
vim# python-app/requirements.txt
Flask==2.0.1
Werkzeug==2.0.3

Step 2: Writing the Dockerfiles

We will now create individual Dockerfiles for each application, so each app can be containerized and run independently.

Dockerfile for Node.js App

In the node-app directory, create a Dockerfile:

# node-app/Dockerfile
# Use the official Node.js 20 image as the base
FROM node:20-alpine

# Set the working directory inside the container
WORKDIR /usr/src/app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install the dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Expose port 3000
EXPOSE 3000

# Command to run the application
CMD ["npm", "start"]

Dockerfile for Python App

In the python-app directory, create another Dockerfile:

# python-app/Dockerfile
# Use the official Python 3.9 image as the base
FROM python:3.9-slim

# Set the working directory inside the container
WORKDIR /app

# Copy requirements.txt and install dependencies
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

# Copy the rest of the application code
COPY . .

# Expose port 5000
EXPOSE 5000

# Command to run the application
CMD ["python", "app.py"]

Each app now has its own Dockerfile, allowing us to build and run them separately.

Step 3: Building and Running the Docker Containers

Now, letā€™s build and run each app individually using Docker commands.

Node.js App

  1. Navigate to the node-app folder and build the Docker image:
cd node-app
docker build -t node-app .
  1. After building the image, run the container:
docker run -d -p 3000:3000 node-app

This will start the Node.js app, and you can access it at localhost:3000.

Python App

  1. Navigate to the python-app folder and build the Docker image:
cd python-app
docker build -t python-app .
  1. After building the image, run the container:
docker run -d -p 5000:5000 python-app

The Python app will be available at localhost:5000.

Step 4: Pushing the Docker Images to Docker Hub

To share your work with others, you can push the Docker images to Docker Hub.

  1. First, log in to Docker Hub:

     docker login
    

  • Tag each image with your Docker Hub username:

      docker tag node-app yourusername/node-app:latest
      docker tag python-app yourusername/python-app:latest
    
  1. Push the images to Docker Hub:
docker push yourusername/node-app:latest
docker push yourusername/python-app:latest

Conclusion

Congrats! šŸŽ‰ You've successfully built and deployed two separate web applicationsā€”one in Node.js and the other in Pythonā€”using Docker. We created individual Dockerfiles for each app and ran them in isolated containers.

This project helps you understand how to containerize applications and manage them separately without needing Docker Compose. Feel free to experiment by adding more features or services to the containers.

Until next time, happy learning and keep building! šŸ’»āœØ

Ā