Swiftorial Logo
Home
Swift Lessons
Tutorials
Learn More
Career
Resources

Dockerfile

A Dockerfile is a text file that contains a series of instructions on how to build a Docker image. This guide covers key concepts, steps to create and manage Dockerfiles, examples, and best practices for using Dockerfiles with Express.js applications.

Key Concepts of Dockerfile

  • FROM: Specifies the base image to use for the Docker image.
  • WORKDIR: Sets the working directory for any RUN, CMD, ENTRYPOINT, COPY, and ADD instructions that follow it in the Dockerfile.
  • RUN: Executes a command in the container.
  • COPY: Copies new files or directories from the source path and adds them to the filesystem of the container.
  • EXPOSE: Informs Docker that the container listens on the specified network ports at runtime.
  • CMD: Provides defaults for an executing container.

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, Dockerfile!');
});

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 an official Node.js runtime as a parent image
FROM node:14

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

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

# Install any needed packages
RUN npm install

# Bundle app source
COPY . .

# Make port 3000 available to the world outside this container
EXPOSE 3000

# Define environment variable
ENV NODE_ENV=production

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

Building and Running the Docker Container

Build and run the Docker container for your Express application:

Build the Docker Image

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

Run the Docker Container

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

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

Using Docker Commands with Dockerfile

Use Docker commands to manage the Docker container created from the Dockerfile:

List Docker Images

// List Docker images
docker images

List Running Containers

// List running containers
docker ps

Stop a Running Container

// Stop a running container
docker stop 

Remove a Container

// Remove a container
docker rm 

Remove an Image

// Remove an image
docker rmi my-express-app

Run a Command in a Running Container

// Run a command in a running container
docker exec -it  /bin/bash

Fetch Container Logs

// Fetch the logs of a container
docker logs 

Best Practices for Creating Dockerfiles

  • Keep Dockerfiles Simple: Write clear and concise Dockerfiles to make them easy to understand and maintain.
  • Use Official Images: Use official base images to ensure stability and security.
  • Minimize Layers: Combine multiple commands into a single RUN instruction to reduce the number of layers and improve performance.
  • Leverage Caching: Place instructions that are less likely to change at the top of the Dockerfile to leverage Docker's caching mechanism.
  • Use .dockerignore: Exclude unnecessary files and directories from the Docker build context to optimize build times.
  • Use Environment Variables: Use ENV instructions to set environment variables for the container.

Testing Dockerfile Integration

Test your Dockerfile setup 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, Dockerfile!', async () => {
        const response = await axios.get('http://localhost:3000');
        expect(response.data).to.equal('Hello, Dockerfile!');
    });
});

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

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

Key Points

  • FROM: Specifies the base image to use for the Docker image.
  • WORKDIR: Sets the working directory for any RUN, CMD, ENTRYPOINT, COPY, and ADD instructions that follow it in the Dockerfile.
  • RUN: Executes a command in the container.
  • COPY: Copies new files or directories from the source path and adds them to the filesystem of the container.
  • EXPOSE: Informs Docker that the container listens on the specified network ports at runtime.
  • CMD: Provides defaults for an executing container.
  • Follow best practices for creating Dockerfiles, such as keeping Dockerfiles simple, using official images, minimizing layers, leveraging caching, using .dockerignore, and using environment variables.

Conclusion

A Dockerfile is essential for creating Docker images in a consistent and efficient manner. By understanding and implementing the key concepts, steps, examples, and best practices covered in this guide, you can effectively use Dockerfiles to manage your Express.js applications. Happy coding!