How to Install Nginx with Docker Compose (Step by Step)

If you are using Docker then you can build and run one container at a time. Then, you will have to manually connect each container together. Also, you must be careful with dependencies and startup order. This is where Docker Compose comes into the picture.

Docker Compose is a tool used for running multi-container Docker applications. It uses a YAML file to define all services in a single file to build one or more containers. It uses service definitions to build fully customizable environments with multiple containers that can share networks and data volumes. You can deploy your entire app by just running a single command. Docker Compose works in all environments like production, staging, development, and testing.

install nginx with docker compose

Features of Docker Compose

  • Preserve volume data when containers are created
  • Single host deployment
  • Quick and easy configuration
  • Only recreate containers that have changed
  • High productivity
  • Security

In this post, we will show you how to install Nginx with Docker Compose

Step 1 - Getting Started

First, it is a good idea to update your systems package cache to the latest version. You can update them using the following command:

				
					apt-get update -y
				
			

After updating the system package cache, install other required dependencies using the following command:

				
					apt-get install apt-transport-https software-properties-common ca-certificates curl gnupg lsb-release -y
				
			

Step 2 - Install Docker

Before starting, Docker CE must be installed on your server.

For Debian and Ubuntu operating systems, follow the below steps to install Docker CE:

First, you will need to add the Docker CE repository to APT. You can add it using the following command:

				
					curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
				
			

Once the repository is added, update the repository cache and install Docker CE with the following command:

				
					apt-get update -y
apt-get install docker-ce docker-ce-cli -y
				
			

Once the installation has been finished, verify the Docker version using the following command:

				
					docker version
				
			

You should see the following output:

				
					Client: Docker Engine - Community
Version: 20.10.8
API version: 1.41
Go version: go1.16.6
Git commit: 3967b7d
Built: Fri Jul 30 19:54:27 2021
OS/Arch: linux/amd64
Context: default
Experimental: true

Server: Docker Engine - Community
Engine:
Version: 20.10.8
API version: 1.41 (minimum version 1.12)
Go version: go1.16.6
Git commit: 75249d8
Built: Fri Jul 30 19:52:33 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.9
GitCommit: e25210fe30a0a703442421b0f60afac609f950a3
runc:
Version: 1.0.1
GitCommit: v1.0.1-0-g4144b63
docker-init:
Version: 0.19.0
GitCommit: de40ad0
				
			

For CentOS, RHEL, and Fedora operating systems, follow the below steps to install Docker CE:

First, add the Docker CE repo with the following command:

				
					dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
				
			

Next, install the Docker CE using the following command:

				
					dnf install docker-ce --nobest -y
				
			

Once the installation is completed, start the Docker service and enable it to start at system reboot:

				
					systemctl start docker
systemctl enable docker
				
			

Step 3 - Install Docker Compose

By default, Docker Compose is not included in any of the Linux distributions. So you will need to download its binary from the GitHub page:

First, download the Docker Compose binary with the following command:

				
					curl -s https://api.github.com/repos/docker/compose/releases/latest | grep browser_download_url | grep docker-compose-Linux-x86_64 | cut -d '"' -f 4 | wget -qi -
				
			

Once the download is completed, set the execution permission to the downloaded binary:

				
					chmod +x docker-compose-Linux-x86_64
				
			

Next, move the downloaded binary to the system path:

				
					mv docker-compose-Linux-x86_64 /usr/bin/docker-compose
				
			

Now, verify the Docker Compose installation using the following command:

				
					docker-compose --version
				
			

You should see the following output:

				
					docker-compose version 1.29.2, build 5becea4c
				
			

Step 4 - Create a Web Page to Serve on Nginx Container

In this section, we will create a sample index.html page for the Nginx website. Let’s create a new directory to hold the website content using the following command:

				
					mkdir -p project/src
				
			

Next, create an index.html page inside the src directory:

				
					nano project/src/index.html
				
			

Add the following contents:

				
					<!doctype html>
<html lang="en">
<head>

<p>Nginx with Docker Compose</p>


</head>
<body>

<h2>Install Nginx using Docker Compose.</h2>
<p>This content is being served by an Nginx Docker container.</p>

<script>class RocketElementorAnimation{constructor(){this.deviceMode=document.createElement("span"),this.deviceMode.id="elementor-device-mode-wpr",this.deviceMode.setAttribute("class","elementor-screen-only"),document.body.appendChild(this.deviceMode)}_detectAnimations(){let t=getComputedStyle(this.deviceMode,":after").content.replace(/"/g,"");this.animationSettingKeys=this._listAnimationSettingsKeys(t),document.querySelectorAll(".elementor-invisible[data-settings]").forEach(t=>{const e=t.getBoundingClientRect();if(e.bottom>=0&&e.top<=window.innerHeight)try{this._animateElement(t)}catch(t){}})}_animateElement(t){const e=JSON.parse(t.dataset.settings),i=e._animation_delay||e.animation_delay||0,n=e[this.animationSettingKeys.find(t=>e[t])];if("none"===n)return void t.classList.remove("elementor-invisible");t.classList.remove(n),this.currentAnimation&&t.classList.remove(this.currentAnimation),this.currentAnimation=n;let s=setTimeout(()=>{t.classList.remove("elementor-invisible"),t.classList.add("animated",n),this._removeAnimationSettings(t,e)},i);window.addEventListener("rocket-startLoading",function(){clearTimeout(s)})}_listAnimationSettingsKeys(t="mobile"){const e=[""];switch(t){case"mobile":e.unshift("_mobile");case"tablet":e.unshift("_tablet");case"desktop":e.unshift("_desktop")}const i=[];return["animation","_animation"].forEach(t=>{e.forEach(e=>{i.push(t+e)})}),i}_removeAnimationSettings(t,e){this._listAnimationSettingsKeys().forEach(t=>delete e[t]),t.dataset.settings=JSON.stringify(e)}static run(){const t=new RocketElementorAnimation;requestAnimationFrame(t._detectAnimations.bind(t))}}document.addEventListener("DOMContentLoaded",RocketElementorAnimation.run);</script></body>
</html>
				
			

Save and close the file when you are finished.

We will use this sample page to replace the default Nginx landing page in the Nginx container.

Step 5 -Setup docker-compose.yaml File

To demonstrate how to work with Docker Compose, you will need to create a docker-compose.yaml file. Let’s create a docker-compose.yaml file inside the project directory:

				
					nano project/docker-compose.yaml
				
			

Add the following contents:

				
					version: '3'
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./src:/usr/share/nginx/html
links:
- php
php:
image: php:7-fpm
				
			

Save and close the file when you are finished.

A brief explanation of each service in the above file is shown below:

  • version – It defines the configuration version.
  • services – It holds all service definitions.
  • web – It downloads Nginx’s latest image from the Docker Hub and sets up a port redirection with the ports directive. It will redirect all requests on port 8080 on the host machine to the web container on port 80.
  • volumes – It will mount the local src folder to the /usr/share/nginx/html folder inside the container.
  • php – It will download php-fpm image, create a container and link it with the Nginx container.

Step 6 - Run Docker Compose

At this, point the docker-compose.yaml file is ready to host an Nginx server. You can now use docker-compose up command to bring your environment up.

Navigate to the project directory and run Docker Compose with the following command:

				
					cd project
docker-compose up -d
				
			

You should get the following output:

				
					Creating network "project_default" with the default driver
Pulling php (php:7-fpm)...
7-fpm: Pulling from library/php
f8416d8bac72: Pull complete
2259392b425a: Pull complete
cfb39fc3daf5: Pull complete
5c501de24ca4: Pull complete
e8930b753eab: Pull complete
0e3476f1c018: Pull complete
93bffa7fd21b: Pull complete
aed0342a8936: Pull complete
70c98c90e58c: Pull complete
71099d83f07c: Pull complete
Digest: sha256:799979e1e6404f71fc6f80e0f37b4da3eb2acc669210797e99c7f7a71c79305d
Status: Downloaded newer image for php:7-fpm
Pulling web (nginx:latest)...
latest: Pulling from library/nginx
a330b6cecb98: Pull complete
e0ad2c0621bc: Pull complete
9e56c3e0e6b7: Pull complete
09f31c94adc6: Pull complete
32b26e9cdb83: Pull complete
20ab512bbb07: Pull complete
Digest: sha256:853b221d3341add7aaadf5f81dd088ea943ab9c918766e295321294b035f3f3e
Status: Downloaded newer image for nginx:latest
Creating project_php_1 ... done
Creating project_web_1 ... done
				
			

You can verify all images downloaded by Docker Compose using the following command:

				
					docker-compose images
				
			

Sample output:

				
					Container Repository Tag Image Id Size
-------------------------------------------------------------
project_php_1 php 7-fpm a879f4b3639f 462.4 MB
project_web_1 nginx latest ad4c705f24d3 133.3 MB
				
			

To check all running containers, run the following command:

				
					docker-compose ps
				
			

Sample output:

				
					Name Command State Ports
---------------------------------------------------------------------------------------------
project_php_1 docker-php-entrypoint php-fpm Up 9000/tcp
project_web_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:8080->80/tcp,:::8080->80/tcp
				
			

You can also check the logs of running container using the following command:

				
					docker-compose logs
				
			

Sample output:

				
					Attaching to project_web_1, project_php_1
php_1 | [10-Sep-2021 10:38:30] NOTICE: fpm is running, pid 1
php_1 | [10-Sep-2021 10:38:30] NOTICE: ready to handle connections
web_1 | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
web_1 | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
web_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
web_1 | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
web_1 | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
web_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
web_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
web_1 | /docker-entrypoint.sh: Configuration complete; ready for start up
web_1 | 2021/09/10 10:38:31 [notice] 1#1: using the "epoll" event method
web_1 | 2021/09/10 10:38:31 [notice] 1#1: nginx/1.21.3
web_1 | 2021/09/10 10:38:31 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6)
web_1 | 2021/09/10 10:38:31 [notice] 1#1: OS: Linux 5.4.0-29-generic
web_1 | 2021/09/10 10:38:31 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
web_1 | 2021/09/10 10:38:31 [notice] 1#1: start worker processes
web_1 | 2021/09/10 10:38:31 [notice] 1#1: start worker process 31
				
			

You can now access your application by visiting the URL http://your-server-ip:8080 in your web browser. You should see your sample index.html page on the following screen:

nginx sample page

Conclusion

That’s it for now. You have successfully installed Nginx with Docker Compose on Linux. I hope You can now easily create a docker-compose.yaml file to host a multi-container applications. For more information about Docker Compose, check the official documentation page.

Avatar for Hitesh Jethva
Hitesh Jethva

I am a fan of open source technology and have more than 10 years of experience working with Linux and Open Source technologies. I am one of the Linux technical writers for Cloud Infrastructure Services.

1 5 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x