How To Create A Docker Image (step-by-step)

No Comments

Are you interested in learning how to create a docker image? In this guide, we will first look at some of the terminologies and then create a new docker image step-by-step! The image will contain a simple echo server that prints out the values that you provide it.

What is a Docker Image?

A docker image is a snapshot of the current application and includes all the needed dependencies for your application. As a result, new containers can use the image to run the application with all the necessary data.

To create a new image, you need a Dockerfile. Then, it tells Docker how to build the image for your containers by defining it step by step like a recipe. Each step expands on the previous step and thus builds a layered system.

Let’s use a Dockerfile to create a Docker Image!

Now that we know that we need a Dockerfile to create an Image and an Image to create a Container let’s create an example Image. The example Application will be a simple echo server that prints out the values that you provide it. You can find the whole project here(GitHub).

Before starting with the Dockerfile we need the application. So lets first create the project and needed files with the following commands:

mkdir docker-image
cd docker-image
npm init -y
npm i express
touch index.js

Then we add the server code to the index.js file:

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

app.get('/', (req, res) => {

// create a variable GET route that echos the variable
app.get('/:str', (req, res) => {
    const msg = `<p>Write a value behind the / in the URL to see it echoed back. For example, /hello will echo back hello.</p>
    <p>Echo: ${req.params.str}</p>`;


// start the server listening for requests
app.listen(port, () => console.log(`App listening on port ${port}!`));

Now let’s update the package.json with the following content to start the server easily:

  "name": "docker-image",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2"

We can now run the server by executing npm start. You can try it out for yourself. After you started the website, you can visit http://localhost:3000/value to get the following output:

create docker image: application output

Now that we have a working application, let’s turn it into an image by using a dockerfile.

For that, we will create a new file called dockerfile in the same directory. The content of the Dockerfile is as follows (read the comments for an explanation):

# Use node as a base image for the application
FROM node

# Create app directory

# Copy all contents of the directory of the dockerfile into the working directory in the image
COPY . .
# Install app dependencies
RUN npm install

# Start app
CMD [ "npm", "start" ]

You can now build the image by either running docker build -t echo-server . or by using a docker-compose.yml file that looks as follows:

    image: echo-server
    build: ./
      - "3000:3000"

By running docker compose up -d the image will be built, and a container will automatically be created! You can now visit the running application under http://localhost:3000.

Check out the documentation here for a complete overview of all possible Dockerfile commands.

What is a .dockerignore file, and why is it useful?

In addition to the dockerfile itself, we can create a .dockerignore file, and in most cases, it makes sense to do so. The reason is that you can say which elements should not be part of the image. For example, currently, we copied the node_modules folder into the working directory of our image (with the line COPY . . in the dockerfile). In most cases, this is not wanted, so we add it to the .dockerignore file like this:


And now it will not be part of the working directory anymore. However, we get it in there because we run a fresh npm install.


Creating your own docker image is not as hard as it first seems. They always follow the same structure, you first define a base image, add some files and run some commands and then you have your own working image from which you can create infinite containers!

I hope this guide was helpful to you. In case there are any open questions, feel free to send them to me via or in the comments!

If you liked it consider subscribing to my newsletter for monthly updates on new posts!

Discussion (0)

Add Comment

Your email address will not be published. Required fields are marked *