How to write a Dockerfile

How to write your first Dockerfile in order to deploy your application with Qovery

With Qovery, there are two ways to build and deploy your application:

  1. Without a Dockerfile in your repository: your application is built with Buildpacks
  2. With a Dockerfile: sometimes Buildpacks won't fit your specific setup, and you'll have to write your Dockerfile.

In this article, we'll see, step by step, how to quickly write a proper Dockerfile for any application you would like to deploy.

My Sweet Dockerfile

If you read this, you probably don't know why Docker is used and what is the purpose of a Dockerfile.

Docker is a container engine, building and using images to deploy applications in containers. It looks like virtualization, and each container could be compared to a virtual machine with the minimal setup to run an application.

The Dockerfile is your image builder recipe. When Docker uses it, it will follow all instructions to build your application and run it.

The first step is to create a file named Dockerfile at your project root level so Qovery would be able to find and use it.

Also, to avoid unwanted files from your repository (images, .idea, DS_Store etc.), you need to add a .dockerignore. It will prevent heavy copy tasks of useless files, mostly your project dependencies and libraries you'll get back to with your package manager.

The .dockerignore file works like the .gitignore, so add all the path of the useless files and folders in it.


The first line you'll add in your Dockerfile is FROM.

It will pull an already existing image from Docker Hub. You should most of the time use an image that fits your application language (Node, Python, Java, etc.), but you can go a step backward and begin with a simple Linux image.

Your Dockerfile's first line should look like this:

FROM <image_name>:<image_version>

For example, with python:

FROM python:3


Since most of the images are Linux-based, a good practice is to set up a directory you'll work in. That's the purpose of the WORKDIR line. It defines a directory and moves you in:

FROM <image_name>:<image_version>

If you now work with a relative path (./), it will be in the app directory.


Now you have defined your base image and your working directory, it's time to add your code in. COPY works like cp linux command. First argument is the source and second one is the destination.

It's time to copy your source code in the image.

FROM <image_name>:<image_version>
COPY . .

Here, the elements of your root folder from your current directory will be added inside the /app folder.


One does not simply get source code to run an application.

Most of the time, you have some stuff to do before an application execution like downloading/installing peer dependencies and build your application.

That's the purpose of RUN lines; it will execute a command and wait to finish the task to go forward.

FROM <image_name>:<image_version>
COPY . .
RUN echo "Installing or doing stuff."
RUN <my_command>

You can set as many RUN lines as you need.


If your app needs to be reached from outside the container, you have to open its listening port. EXPOSE is made for this.

FROM <image_name>:<image_version>
COPY . .
RUN echo "Installing or doing stuff"
RUN <my_command>
EXPOSE <app_port>


Your application is now ready to run.

The last thing to do is to specify how to execute it. Add the CMD line with the same command with all the arguments you use locally to launch your application.

FROM <image_name>:<image_version>
COPY . .
RUN echo "Installing or doing stuff"
RUN <my_command>
EXPOSE <app_port>
CMD [ "<command>", "<argument_1>", "<argument_2>" ]

Like a local usage, you can set as many arguments as needed.

Build your image

When Qovery uses your Dockerfile, it first builds it before running it.

If the build fails, Qovery won't be able to launch our application. To simplify debugging, you can build your image locally if you have Docker installed on your computer.

Open a terminal and set the path at the Dockerfile location, and use the command:

cd ~/my/folder/where/my/code/is
docker build .

It will build your image based on your Dockerfile. You'll see all the logs related to all lines you've added in the Dockerfile.

If something goes wrong, it will be printed onto the terminal, and you'll be able to debug it.

Test your image

If your image builds properly, you can now check how it will be handle by Qovery with the command:

qovery run

What's next?

If you follow this tutorial and everything works perfectly, it's time to deploy your app on Qovery. You will find all the things you need to know here.