CodeGym /Courses /Docker SELF /Dockerfile: creation and file structure

Dockerfile: creation and file structure

Docker SELF
Level 13 , Lesson 1
Available

2.1 Key Concepts of Dockerfile

Dockerfile is a text file that contains a sequence of commands Docker uses to create an image. It acts like a "recipe," describing how the image should be built—from the base layer to the final state. Understanding the structure and process of creating a Dockerfile is important for effectively using Docker.

Main Concepts of Dockerfile:

  1. Idempotency: commands in Dockerfile should be idempotent—their repeated execution gives the same result.
  2. Order: commands are executed sequentially from top to bottom. The order matters since each command creates a new layer for the image.
  3. Layered Structure: practically every instruction adds a new layer to the image. These layers are cached, which helps optimize the build process.

Structure of a Dockerfile:

A Dockerfile consists of instructions, each performing a specific function. Here are the main ones:

  1. FROM: sets the base image that will be used to create a new image.
  2. MAINTAINER: defines the author of the Dockerfile (deprecated, but useful for information).
  3. RUN: executes commands in the container and creates a new layer.
  4. COPY: copies files and directories from the build context to the container’s file system.
  5. ADD: copies files and directories, supports extracting archives and downloading files from URLs.
  6. WORKDIR: sets a working directory for the subsequent commands.
  7. ENV: sets environment variables.
  8. CMD: defines the default command to run when the container starts.
  9. ENTRYPOINT: defines the command that gets executed when the container starts, with support for passing arguments.
  10. EXPOSE: declares the ports the container uses.
  11. VOLUME: creates a mount point for external volumes.

2.2 Creating a Dockerfile

Example of creating a Dockerfile

Let's look at a simple example of creating a Dockerfile for a Node.js web app.

Step 1: Creating a base Dockerfile

Create a file named Dockerfile in the root of your project and add the following lines:

dockerfile

# Use the Node.js base image
FROM node:14

# Set the working directory
WORKDIR /app

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

# Install dependencies
RUN npm install

# Copy all project files
COPY . .

# Specify the port the app will use
EXPOSE 3000

# Define the command to run the app
CMD ["node", "app.js"]

This Dockerfile does the following:

  1. FROM node:14: uses the official Node.js image version 14 as the base.
  2. WORKDIR /app: sets the working directory for subsequent commands.
  3. COPY package*.json ./: copies the package.json and package-lock.json files to the working directory.
  4. RUN npm install: installs dependencies from package.json.
  5. COPY . .: copies all project files into the container's working directory.
  6. EXPOSE 3000: specifies that the app will use port 3000.
  7. CMD ["node", "app.js"]: defines the command to run the app.

Step 2: Building the Image

After creating the Dockerfile, build the image using the docker build command:

Terminal

docker build -t my-node-app .

This command will create an image named my-node-app using the Dockerfile from the current directory.

Step 3: Running the Container

Run a container based on the created image using the docker run command:

Terminal

docker run -d -p 3000:3000 my-node-app

This example runs the container in detached mode, mapping the container's port 3000 to port 3000 on your host machine. Now you can access the app at http://localhost:3000.

2.3 Additional Dockerfile Instructions

1. Setting up environment variables

You can set environment variables that will be available in the container using the ENV instruction.

dockerfile

ENV NODE_ENV=production

2. Using multiple RUN commands

Sometimes it's worth combining several commands into one RUN instruction to reduce the number of layers, shrink the image size, and speed up the build process.

dockerfile

RUN apt-get update && apt-get install -y \
  curl \
  git \
  && rm -rf /var/lib/apt/lists/*

Helpful! If the command doesn't fit on one line, you can use the \ symbol to continue on the next line. This will be interpreted as one command.

Helpful! To write multiple commands on one line, you can use &&: command1 && command2 && command3. This allows you to execute several commands sequentially.

Optimizing command order

For efficient use of Docker cache, first copy files that rarely change (like package.json) and install dependencies before adding the rest of the project files.

Example of an advanced Dockerfile

In more complex projects, an advanced Dockerfile with additional settings might be required.

dockerfile

# Using a minimal base Node.js image
FROM node:14-alpine

# Setting the working directory
WORKDIR /usr/src/app

# Copying package.json and installing dependencies
COPY package*.json ./
RUN npm install --only=production

# Copying the source code
COPY . .

# Specifying the port to work on
EXPOSE 8080

# Setting environment variables
ENV NODE_ENV=production

# Running the application
CMD ["node", "server.js"]
3
Task
Docker SELF, level 13, lesson 1
Locked
Creating a simple Dockerfile for a Node.js application
Creating a simple Dockerfile for a Node.js application
3
Task
Docker SELF, level 13, lesson 1
Locked
Optimizing Dockerfile with Dependency Installation
Optimizing Dockerfile with Dependency Installation
3
Task
Docker SELF, level 13, lesson 1
Locked
Using Multiple RUN Commands
Using Multiple RUN Commands
3
Task
Docker SELF, level 13, lesson 1
Locked
Using a minimal base image
Using a minimal base image
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION