Running a Docker Container in an EC2 Instance

Prerequisites

> Creating and connecting to an AWS EC2 instace

Docker is an open-source platform that allows you to automate the deployment and management of applications within lightweight, isolated containers. Containers are standalone environments that encapsulate an application along with its dependencies, enabling consistent and reliable software delivery across different computing environments.

For the purpose of this tutorial, we're going to deploy Nginx web server within our EC2 instance which is running Amazon Linux. All commands should work for any other linux distro, but installation will only work only for Red Hat based distros or distros with yum as package manager. For other faamilies you might need to install using other managers like apt in debian based distributions.

Installing Docker

We'll be running all of the following commands as root, so first step will be to switch from ex2-user to root. Then, we're gonna update the yum repository. It is generally a good practice to update the package repository before installing any new applications to ensure you have the latest versions of the packages and any necessary security updates. Finally we can run the yum install command.

[] $ sudo su -
[] $ yum update
[] $ yum install docker -y

Once installation gets finished, you can check the docker version in order to verify that it got installed properly as long as it shows some version number like this:

[] $ docker --version
Docker version 20.10.17, build 100c701

Running Docker Service and Container

Docker is composed of two main components: a command line interface client (cli) and a daemon service. Wvery time we run a docker command, the cli amkes a request to the background service which takes care of fetching images, running containers, check containers that are running, etc.

Having that said, now we need to start the docker background service in our machine. For this we will use the standard service management commands to start and check that docker service is running:

[] $ service docker start
Redirecting to /bin/systemctl start docker.service
[] $ service docker status
Redirecting to /bin/systemctl status docker.service ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; preset: disabled) Active: active (running) since Tue 2023-05-16 21:29:32 UTC; 2s ago ...

If you see an output similiar like above (Active: active (running) ), that means that the docker service is already available on your instance.

At this point, we are able to start executing the docker commands. First of all, we need to fetch an image. Docker images are the building blocks of containers in Docker. They are self-contained, portable, and lightweight packages that contain everything needed to run an application. So we can download the nginx image for our tutorial.

[] $ docker pull nginx
[] $ docker images

As you can see, the first command will download the nginx image, then the second one will show the following information related to all images that are already available:

  • REPOSITORY: The docker image name
  • TAG: version of the image. Docker will download the latest image version if we don´t specify from pull command
  • IMAGE ID: This id can be used as reference to work with this image on upcoming commands. However we can use the name displayed on REPOSITORY column as well
  • CREATED: Elapsed time since the image was fetched
  • SIZE: size of image on disk

As containers are created from images, now we can start our container from the image we already pulled by executing the following command:

[] $ docker run -d --name webserver -p 80:80 -v $(pwd):/usr/share/nginx/html nginx

This long command will start our container with an already configured and running Nginx server. The meaning of the command and parameters used in the above command are:

  • run: This is the docker command used to create and run a new container
  • -d: this flag is used to indicate that the container will run in dettached mode (background thread)
  • --name: Used to specify a name to the container. If we don´t provide this parameter, docker will assign a default name which is not recomended in order to have an easier way to interact with our container in future. In this example I´m assigning "webserver" as name
  • -p: This parameter is used to map a port from the container to the actual machine. In this case we are mapping the container port 80 to the port 80 of our EC2 instance. Otherwise, web clients wouldn´t be able can access the service exposed by nginx within docker
  • -v: It defines a Volume mapping. Here we are mapping the current directory where the command is executed with directory whitin container which is configured to be used as static files folder exposed by nginx. This is pretty useful in order to upload and edit our web page without the need of get into the container, making the development process far faster.
  • Last parameter used as you can see is the image id or name, so that docker knows which image the container will be created from

Note that before running this command you have to create and/or move to the directory where you want to store the web page files you want to expose due to the Volume being configured with -v parameter.