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:
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
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}/`);
});
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
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:
- Build Docker image of the app using
docker build testing/docker .
- 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
- Run
qovery init
- Choose application name, e.g.,
node-app
- Choose project name, e.g.,
testing-docker
- 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
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)
How does Qovery know to map port 3000 to 80?
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
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
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.
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!