How To Run Nginx Using Docker

How To Run Nginx Using Docker

NGINX is a popular open-source software used for web serving, reverse proxying, caching, load balancing, media streaming, and more. It can also function as a proxy server for email (IMAP, POP3, and SMTP) and a reverse proxy and load balancer for HTTP, TCP, and UDP servers. Nginx is quite popular and used on many high traffic websites today. In this tutorial, we’ll learn how to run Nginx in a container using Docker. We’ll tackle how to download and run the image, create several containers from that image, learn about foreground vs background tasks, and see how to inspect the logs.


Image Vs Container

  • An Image is an application you want to run
  • A Container is an instance of the image running as a process
  • There can be many containers running via the same image
  • Docker Hub is the main registry for images at hub.docker.com

Launch A Container

We can launch a new container using the following command.

docker container run --publish 80:80 nginx

You may see some output in the terminal similar to this.

$ docker container run --publish 80:80 nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up

Docker Dashboard will also show the container running.

nginx docker container running

Open a browser to visit http://localhost and we should see an Nginx web server happily offering the default web page.

nginx web page via docker

In the terminal, we will also see some logging of the browser making requests from the webserver.

172.17.0.1 - - [28/Sep/2020:15:10:03 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36" "-"

How It Works

docker container run –publish 80:80 nginx

When the command above is triggered, the Docker engine takes a series of steps.

  1. Download the Nginx image from Docker Hub, if not already in local cache
  2. Started a new Container from the Nginx image
  3. Opened port 80 on the host IP
  4. Routes host traffic port 80 to Container IP port 80

Running In Detached Mode

The reason why we were able to see the log output of the container straight away, is because the container is running in the foreground. Many times you just want the container to run in the background. This is what is known as Detached Mode. First, we need to stop the running container. We can do this by first finding the container id or name with docker ps, then using the docker stop command to stop it.

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
902affce585b        nginx               "/docker-entrypoint.…"   2 hours ago         Up 2 hours          0.0.0.0:80->80/tcp   sharp_hoover

Based on the above output, we can stop the container with either of the following two:

  • docker stop sharp_hoover
  • docker stop 902affce585b
  • Now let’s run the image again, creating a brand new container that runs in detached mode. Note the use of the –detach flag.

    $ docker container run --publish 80:80 --detach nginx

    Detach tells Docker to run the container in the background, and the only output to the terminal, in this case, is the unique container id. Every time you run a new container, you get a new unique id. Let’s look at the containers running again using docker container ls.

    $ docker container ls
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
    d62595efbb6c        nginx               "/docker-entrypoint.…"   4 minutes ago       Up 4 minutes        0.0.0.0:80->80/tcp   quizzical_hermann

    Our new Nginx container running in the background has the name quizzical_hermann.

    We can stop the container with docker container stop passing in just the first couple of characters of the container id.

    $ docker container stop d62
    d62

    Listing Containers

    In the past, you might use docker ps to display containers. The more appropriate way to list containers now is using docker container ls. When listing our containers we don’t see any.

    $ docker container ls
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

    This is because if a container is not running, it will not be displayed. To see all containers, even those that are not running, you need to add the -a flag.

    $ docker container ls -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
    d62595efbb6c        nginx               "/docker-entrypoint.…"   14 minutes ago      Exited (0) 4 minutes ago                        quizzical_hermann
    902affce585b        nginx               "/docker-entrypoint.…"   2 hours ago         Exited (0) 16 minutes ago                       sharp_hoover
    

    Now we see both containers. Those funny names are created automatically if you don’t specify a name for the container during creation. Just like every ID is unique for containers, the name is also required to be unique. Docker randomly generates the name from an open-source list of adjectives and notable hackers of scientists. So how can we give our own name to a container? We can do this by specifying the –name flag.

    $ docker container run --publish 80:80 --detach --name my_nginx_server nginx
    4402b968a91567195e690ca4c5c7d79525c5823f640ff0d2cceb6ee045d2a8d6
    
    $ docker container ls -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                NAMES
    4402b968a915        nginx               "/docker-entrypoint.…"   8 seconds ago       Up 7 seconds                0.0.0.0:80->80/tcp   my_nginx_server
    d62595efbb6c        nginx               "/docker-entrypoint.…"   19 minutes ago      Exited (0) 10 minutes ago                        quizzical_hermann
    902affce585b        nginx               "/docker-entrypoint.…"   2 hours ago         Exited (0) 21 minutes ago                        sharp_hoover
    

    Viewing Container Logs In Detached Mode

    If a container is running in the background, we don’t see any output from the logs at the terminal. If we want to see those logs, we can do that with the docker container logs command.

    $ docker container logs my_nginx_server
    /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
    /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
    10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
    10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
    /docker-entrypoint.sh: Configuration complete; ready for start up
    172.17.0.1 - - [28/Sep/2020:17:18:38 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36" "-"
    172.17.0.1 - - [28/Sep/2020:17:18:39 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36" "-"

    Working With Containers

    Here are the commands you’ll want to be familiar with when working with your containers.

    $ docker container
    
    Usage:  docker container COMMAND
    
    Manage containers
    
    Commands:
      attach      Attach local standard input, output, and error streams to a running container
      commit      Create a new image from a container's changes
      cp          Copy files/folders between a container and the local filesystem
      create      Create a new container
      diff        Inspect changes to files or directories on a container's filesystem
      exec        Run a command in a running container
      export      Export a container's filesystem as a tar archive
      inspect     Display detailed information on one or more containers
      kill        Kill one or more running containers
      logs        Fetch the logs of a container
      ls          List containers
      pause       Pause all processes within one or more containers
      port        List port mappings or a specific mapping for the container
      prune       Remove all stopped containers
      rename      Rename a container
      restart     Restart one or more containers
      rm          Remove one or more containers
      run         Run a command in a new container
      start       Start one or more stopped containers
      stats       Display a live stream of container(s) resource usage statistics
      stop        Stop one or more running containers
      top         Display the running processes of a container
      unpause     Unpause all processes within one or more containers
      update      Update configuration of one or more containers
      wait        Block until one or more containers stop, then print their exit codes
    
    Run 'docker container COMMAND --help' for more information on a command.
    

    Removing Containers

    At this point, we have 3 containers in total. One is running and the other two are idle. Let’s try to remove them all in one shot.

    $ docker container rm 440 d62 902
    d62
    902
    Error response from daemon: You cannot remove a running container 4402b968a91567195e690ca4c5c7d79525c5823f640ff0d2cceb6ee045d2a8d6. Stop the container before attempting removal or force remove

    Two of the containers were removed, however, we can see by the error message that a running container can not be removed without stopping it first or forcing the remove. Here we use the -f flag to force the running container to be removed.

    $ docker container rm 440 -f
    440

    Finally, we list all containers one more time, and we can see that our docker playground is clean.

    $ docker container ls -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

    Learn More About Docker And Nginx

    Summary

    We learned about some basic commands to work with Nginx and Docker. The commands we want to be familiar with after this tutorial are listed here.

    docker container run Run a command in a new container
    docker container ls List containers
    docker container stop Stop one or more running containers
    docker container start Start one or more stopped containers
    docker container logs Fetch the logs of a container
    docker container top Display the running processes of a container
    docker container rm Remove one or more containers