DEV Community

Patryk Jeziorowski for Qovery

Posted on • Edited on • Originally published at docs.qovery.com

Productive and simple way to deploy Dockerized applications

In recent years, Docker has been becoming more and more popular tool used to deploy web applications. According to Datadog in 2018, the adoption of Docker in large organizations reached about 47 percent and almost 20 percent in small organizations. This report it two years old - no doubt Docker is even more common now.

In my opinion, knowing Docker basics is an essential tool in the toolbox of every software engineer, especially in the web development ecosystem. In this article, I'll demonstrate the easiest way to Dockerize and deploy a simple application. Before we dive deep into practical steps, let's first answer two essential questions - "What is Docker" and "Why should I use it" in the first place.

Docker in a nutshell

Docker is a tool that makes it easy to build and deploy your applications, typically to the cloud environment. It allows you to package your application in a container that contains your app with all of the things it needs, such as libraries and other dependencies. Then, this package can be run on any machine with a Docker engine installed, no matter the underlying configuration or system distribution.

Why should I use Docker?

It works on my machine sentence has become a meme in the software world. You can even get a sticker on your laptop:

It works on my machine

Making applications run consistently in various environments is one of the issues addressed very well by Docker.

Docker makes sure that your containerized applications run in the same way on your machine, on your friend's machine, and on the AWS server (and anywhere else where Docker engine is installed). It is truly a superpower. As a developer, you no longer need to worry about the underlying system. After you Dockerize your app, you can be sure that it behaves in the same manner in your development, testing, and production environments, as well as on your local machine. It makes building and testing applications way more comfortable than it was before.

Another reason why you should be interested in Docker is the popularization of cloud, microservices, and Kubernetes. Docker is the first-class citizen in the cloud-native world, so if you want to take the full advantage of scalable, cloud-native application architectures, Docker is the way to go.

How to deploy Docker containers

Let's move on to the practical application and usage of Docker. We'll now build a very simple web application that responds to HTTP requests, dockerize it and deploy to Qovery - a scalable Container as a Service platform.

Create a simple application

For the sake of simplicity, we'll create a simple Node.js application that returns a Hello, World text in response to HTTP requests. I choose Node.js here because it's simple and popular technology, but you can use Docker with basically any language and framework.

Let's create an empty folder for our new application and initialize an empty Git repository:

mkdir deploying-docker
cd deploying-docker
git init
Enter fullscreen mode Exit fullscreen mode

Now, create app.js file with the source code of our server:

const http = require('http');

const hostname = '0.0.0.0';
const port = 3000;

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hello World');
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});
Enter fullscreen mode Exit fullscreen mode

It is a very simple server that returns "Hello World" text on its root endpoint. After it's done, we want to make this app run in a Docker container. To do so, we need to create a Dockerfile.

What is Dockerfile?

Besides containers, Docker uses the concept of Images. Image is a template used to create and run containers. Dockerfile describes the steps required to build the image. Later on, this image is used as a template to run containers with your application.

You can think about images and containers as a good analogy to classes and objects (instances of a given class) in the Object-Oriented Programming world.

Create a Dockerfile that will allow us to run our Node.js app in a container. Create a file named Dockerfile with the following content:

FROM node:13-alpine

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

COPY . .

EXPOSE 3000

CMD node app.js
Enter fullscreen mode Exit fullscreen mode

Let's discuss all lines of the Dockerfile:

  • FROM node:13-alpine specifies the base of our Docker image. It's a base used to get started with building an image.
  • RUN mkdir -p /usr/src/app creates a new empty folder in /usr/src/app
  • WORKDIR /usr/src/app defines the working directory of our container
  • COPY . . adds the contents of our application to the container
  • EXPOSE 3000 informs Docker that the container listens on the specified network port at runtime
  • and, finally: CMD node app.js is the command that starts our application.

Now we got all basic things we need to run our application in a Docker container! Let's try it out:

  1. Build Docker image of the app using docker build testing/docker .
  2. Run a container with our application by executing docker run -p 3000:3000 testing/docker

the -p 3000:3000 flag makes container port 3000 accessible on your localhost:3000.

Great! The container is up. Run docker ps to see the list of running containers and confirm that it is indeed running.

Now open a browser at http://localhost:3000 to see that the application in a container responded with Hello, World message.

Did it work? Great. Our app works well in the Docker container. It's adorable, but we want to share our app with the world - running applications only on our own machine won't make us millionaires!

Container as a Service

To deploy our Dockerized application, we'll use Qovery. It's a Container as a Service platform that allows us to deploy Dockerized apps without any efforts. Qovery is free up to three applications (and databases!) in the community version.

Install Qovery CLI

To Sign Up and install the CLI, you can follow the steps described in this link.

After you have access to Qovery, it's time to deploy the application.

Deploy the docker container

  1. Run qovery init
  2. Choose application name, e.g., node-app
  3. Choose project name, e.g., testing-docker
  4. Commit and push your changes to Github: git add . ; git commit -m "Initial commit" ; git push -u origin master" (create an empty repository beforefor your application on Github before if it's not done yet)

Voila! That's all. Your Dockerized application is being deployed as a Docker container. To deploy a Docker container on Qovery, all you need is a Dockerfile that describes containers with your application + running qovery init command to initialize Qovery. From now on, Qovery will build and deploy your Dockerized application after you make any changes in your repository to scalable Kubernetes clusters as a Docker container.

To check that your application is in fact deploying, run qovery status:

BRANCH NAME       | STATUS  | ENDPOINTS                            | APPLICATIONS    | DATABASES
master            | running | https://some.url.qovery.io           | node-app  | 

APPLICATION NAME  | STATUS  | DATABASES
node-app          | running | 

DATABASE NAME     | STATUS  | TYPE       | VERSION | ENDPOINT | PORT     | USERNAME | PASSWORD | APPLICATIONS
Enter fullscreen mode Exit fullscreen mode

Summary

In this guide, you learned the essential basics of Docker. You also learned why you should be interested in using it, and how to deploy your application to the cloud as a Docker container. This is all you need to know to improve your development experience and deploy your application to the cloud with ease! If you have any questions or feedback please do let me know in the comments or join Qovery Discord server and feel free to speak your mind.

Top comments (3)

Collapse
 
angelxmoreno profile image
Angel S. Moreno

How does Qovery know to map port 3000 to 80?

Collapse
 
angelxmoreno profile image
Angel S. Moreno • Edited

Interestingly enough, found this via experimentation:

Using the following docker file when visiting the app url (main-xuser-a-hjiw7xpmxcc2s76x-gtw....), I get
Server running at https://main-xuser-a-hjiw7xpmxcc2s76x-gtw.qovery.io:80

# This stage installs our modules
FROM mhart/alpine-node:14

ARG QOVERY_ROUTER_MAIN_XUSER_API_APP_URL
ENV BASE_HOST=$QOVERY_ROUTER_MAIN_XUSER_API_APP_URL
ENV PORT=80

WORKDIR /app
COPY . .
RUN yarn install
RUN yarn build

EXPOSE 80

CMD ["yarn", "start"]
Enter fullscreen mode Exit fullscreen mode

However, using the below Dockerfile, when i visit the same url I get
Server running at https://main-xuser-a-hjiw7xpmxcc2s76x-gtw.qovery.io:8080

# This stage installs our modules
FROM mhart/alpine-node:14

ARG QOVERY_ROUTER_MAIN_XUSER_API_APP_URL
ENV BASE_HOST=$QOVERY_ROUTER_MAIN_XUSER_API_APP_URL
ENV PORT=8080

WORKDIR /app
COPY . .
RUN yarn install
RUN yarn build

EXPOSE 8080

CMD ["yarn", "start"]
Enter fullscreen mode Exit fullscreen mode

So far, my experience with Qovery has been that of disbelief of how awesome they claim to be mixed with the awesome realization that they sure as hell ain't lying.

Would love to see more complex examples of getting existing projects up and running using their services.

Collapse
 
pjeziorowski profile image
Patryk Jeziorowski

Hey @angelxmoreno , the trick with port mapping - we try to figure it out based on your Dockefile (EXPOSE statements). You could also try completely removing the Dockerfile - then we rely on Buildpacks to do all the dirty job.

We plan to release a major update in mid-May - it will make the service incomparably better than what we have now! :)

Feel free to join our Discord (discord.qovery.com) if you need any help or support. Cheers!