Swiftorial Logo
Home
Swift Lessons
Tutorials
Learn More
Career
Resources

Building Docker Images

Building Docker images allows you to package your application and its dependencies into a portable container. This guide covers key concepts, steps to create and manage Docker images, examples, and best practices for building Docker images with Express.js applications.

Key Concepts of Building Docker Images

  • Dockerfile: A text document that contains all the commands to assemble an image.
  • Image: A read-only template with instructions for creating a Docker container.
  • Layer: Each instruction in a Dockerfile creates a layer in the image.
  • Build Context: The files and directories accessible to the Docker engine during the build process.

Setting Up the Project

Initialize a new Express.js project and create a Dockerfile:

// Initialize a new project
// npm init -y

// Install Express
// npm install express

// Create the project structure
// mkdir src
// touch src/index.js Dockerfile .dockerignore .gitignore

// .gitignore
node_modules
.env

// .dockerignore
node_modules
npm-debug.log

Creating an Express Application

Create a simple Express application:

Example: index.js

// src/index.js
const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
    res.send('Hello, Docker Images!');
});

app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}/`);
});

Creating a Dockerfile

Create a Dockerfile to containerize your Express application:

Example: Dockerfile

// Dockerfile
# Use the official Node.js 14 image as the base image
FROM node:14

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

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install the app dependencies
RUN npm install

# Copy the app source code to the working directory
COPY . .

# Expose port 3000 to the outside world
EXPOSE 3000

# Run the app
CMD ["node", "src/index.js"]

Building the Docker Image

Build the Docker image for your Express application:

// Build the Docker image
docker build -t my-express-app .

// List Docker images to verify the build
docker images

Running the Docker Container

Run the Docker container from the built image:

// Run the Docker container
docker run -p 3000:3000 my-express-app

// Open http://localhost:3000 in your browser to see the application running

Managing Docker Images

Use Docker commands to manage your images:

Tagging an Image

// Tag the Docker image
docker tag my-express-app myusername/my-express-app:latest

Pushing an Image to Docker Hub

// Log in to Docker Hub
docker login

// Push the Docker image to Docker Hub
docker push myusername/my-express-app:latest

Pulling an Image from Docker Hub

// Pull the Docker image from Docker Hub
docker pull myusername/my-express-app:latest

Using Docker Compose with Built Images

Set up Docker Compose to manage multi-container applications with built images:

Example: docker-compose.yml

// docker-compose.yml
version: '3.8'
services:
  web:
    image: myusername/my-express-app:latest
    ports:
      - "3000:3000"
// Run Docker Compose
docker-compose up

// Open http://localhost:3000 in your browser to see the application running

Best Practices for Building Docker Images

  • Use Official Base Images: Use official base images from Docker Hub to ensure security and stability.
  • Minimize Image Size: Use multi-stage builds and remove unnecessary files to minimize image size.
  • Leverage Caching: Order Dockerfile instructions to leverage Docker's layer caching for faster builds.
  • Use .dockerignore: Use a .dockerignore file to exclude unnecessary files from the build context.
  • Keep Layers Small: Combine related instructions into a single RUN instruction to reduce the number of layers.
  • Scan for Vulnerabilities: Regularly scan your images for known vulnerabilities using tools like Clair or Trivy.

Testing Docker Image Integration

Test your Docker image to ensure it works correctly:

Example: Testing with Mocha and Chai

// Install Mocha and Chai
// npm install --save-dev mocha chai

// test/app.test.js
const chai = require('chai');
const expect = chai.expect;
const axios = require('axios');

describe('Express App', () => {
    it('should return Hello, Docker Images!', async () => {
        const response = await axios.get('http://localhost:3000');
        expect(response.data).to.equal('Hello, Docker Images!');
    });
});

// Add test script to package.json
// "scripts": {
//   "test": "mocha"
// }

// Run tests
// docker build -t my-express-app .
// docker run -p 3000:3000 my-express-app
// npm test

Key Points

  • Dockerfile: A text document that contains all the commands to assemble an image.
  • Image: A read-only template with instructions for creating a Docker container.
  • Layer: Each instruction in a Dockerfile creates a layer in the image.
  • Build Context: The files and directories accessible to the Docker engine during the build process.
  • Follow best practices for building Docker images, such as using official base images, minimizing image size, leveraging caching, using .dockerignore files, keeping layers small, and scanning for vulnerabilities.

Conclusion

Building Docker images allows you to package your application and its dependencies into a portable container. By understanding and implementing the key concepts, steps, examples, and best practices covered in this guide, you can effectively build Docker images for your Express.js applications. Happy coding!