Docker Compose Apache Web Server

Posted on  by 



  1. Apache Server Docker
  2. Docker Compose Tutorial
  3. Docker Compose Httpd
  4. Docker Compose Execute Command

This is my second post for this blog series on Docker. If you haven’t already read my previous post, I highly recommend you to read that article first. Here, I’m going to dive a little deeper into container management by working on a further complicated application and advanced features of docker.

Until now, I’ve already covered the introduction, basic container usage and default networking in docker. So, let’s now get into more advanced concepts in container virtualization. For this post, my goal is to build and run a container serving web server. And as usual, there are going to be some challenges to achieve this goal, which we’ll tackle during this article. With that said, let’s get into action.


Building a Docker Image

I’m using a CentOS’s latest image as before. If you’re planning to test this in some other platforms, the procedures might vary a little. Similar to previous post, let’s first create a Dockerfile to build an image with the required packages and configuration. My initial Dockerfile looks something like this:

Docker Compose - Hashicorp's Vault and Consul Part B (EaaS, dynamic secrets, leases, and revocation) Docker Compose - Hashicorp's Vault and Consul Part C (Consul) Docker Compose with two containers - Flask REST API service container and an Apache server container Docker compose: Nginx reverse proxy with multiple containers. Starting with Docker Compose We will be using Docker Compose to set up an environment with two docker containers: a webserver with Apache and PHP and a database server with MySQL. This is a frequent recurring scenario and opens the door for experimenting with Wordpress, PHP frameworks. Apache Web Server is the #1 web server in the world and powers most of the web servers on the internet. With Docker, we can deploy Apache without needing to configure it on our host machine.

Docker Compose Apache Web Server

Then, I tried to build an image using this file. Note, I’m using Ubuntu as my host operating system. Here are the results I obtained:

Upon failing to build an image, I researched about the error that I received. Actually, it’s a well-known issue with AUFS. It occurs when trying to install high-privilege requiring packages (e.g. httpd) in CentOS like containers (e.g. Fedora, RHEL, Oracle, etc.) within non-CentOS like hosts (e.g. Ubuntu). There are some kernel patches for this issue. However, I couldn’t find a solid method to do it successfully. So, I used a work-around solution. First, I installed a CentOS machine, installed docker engine in it and then, built my httpd image there. After building it, I saved it as a tar file, copied it to my main Ubuntu system, and loaded it. And it worked without encountering above issue.

Encouraged by this small success, I continued my setup, just to face another immediately. Upon trying to run my image, it didn’t work as expected. Although I started it as a daemon, it exited prematurely instead of serving a website. Upon referring to working Dockerfiles online, httpd tends to confuse itself when closed incompletely during container restart. So, we need to specify remove statements in our Dockerfile to delete existing httpd data. Or better, we can create a Bash script defining the configuration and required actions, and then call it in the Dockerfile. Doing this is very useful when we need to deploy advanced level containers. Accordingly, my new Dockerfile and its corresponding script look like these:

Note: I built this image in CentOS host as mentioned above. After building this image and copying it to my Ubuntu system, I loaded and ran it. Here, I’m running this container in Daemon mode and I mapped host’s port 8080 to container’s 80 port. That means, I can access the web site served by this container via port 8080 of host machine.

Apache Server Docker

Upon running this HTTPD container, I am able to access its page as shown in the below screenshot:

Let’s also quickly mount our website’s source code to this container so that it’ll serve our web page instead of Apache’s test page. To do that, let’s stop the container. You may remove it altogether from the process list also. Then, let’s re-run the httpd image in a way that it’ll serve the page defined by us.

Now that I’ve got my web server running in default mode, I would like to configure it and make it serve my own web application, right? However, there is a hurdle in doing that. Traditionally, docker containers run only one process or service, unlike physical or virtual machines which can run any number of services. So, when I ran my above container, the Apache server got started in foreground. That means if I try to attach to its TTY or console, I attach to that httpd process instead of the container’s shell. Thus, I cannot manage my container as I’d have done with traditional servers.

Well, at this point, it’s common to think that containers aren’t that beneficial and useful as they’re said to be. Once I thought it too. However, the problem doesn’t exist with the container virtualization or Docker. Rather, the problem is in our perception and inability to embrace change. We tend to view and use technologies the way we always have been doing. Therefore, until we unlearn what we already know and try to learn new technologies from new perspective, this problem cannot be solved.

Back to the topic, Docker by default allows only one foreground service to run inside a container, and I believe they’ve good reason for it as well. But there are methods like Supervisor and Runit to run multiple services in the container. About running single service or multiple services in a container, it all depends on our requirements and preference. Based on this information, I’d like to have sshd running in parallel with the httpd service in my container. This way, I can login to my container and perform my preferred configurations and administration tasks. Note: it’s not necessary that we must always have SSH access to the containers. In fact, I’d like to have my container as light as possible. So, once I’ve got my container fully configured, I won’t be using supervisor or sshd along with my web server.

Then, let’s build an image out of it. Note that I’m building and saving this image in a CentOS host machine.

Next, let’s fetch that tar ball file to our Ubuntu docker host and start using it as follows:

Docker Compose Tutorial

Upon successfully running this container, I saw the same web page as before. The main difference in this container in comparison to the above one is that it runs its services (SSH and Apache) in supervised mode. Here’s a video tutorial implementing the whole setup procedure:

Well, this is it for now. Today, I’ve covered about running services like Apache and SSH inside the container in both standalone and supervised modes. I hope this has been informative and useful for you. Please let me know of your opinion in the Comments sections below. And as always, thanks for reading!

Docker Compose Httpd


Docker Compose Execute Command

Related Posts





Coments are closed