That Docker web server

I have a Digital Ocean droplet running a Docker Nginx web server, where I can serve different websites under different subdomains.

Things used to be easier when PHP + MySQL stack hosting that used cPanel and stuff were more dominant a decade ago. Everything was point-and-click, and voila you get a blog running on its own subdomain. The process is more complicated today if I want to retain the same level of control with my web content, but it’s for the best. cPanel was never freeware anyway.

Without further ado, I got subdomains running with these steps:

  1. On Digital Ocean, start a Docker droplet.
  2. Install Nginx in the droplet so that Docker and Nginx run side by side. (Don’t install an Nginx docker container)
apt update
apt install nginx
  1. Configure Nginx firewall:
ufw app list
ufw allow 'Nginx HTTP'
ufw status
  1. Check that Nginx is doing fine:
systemctl status nginx
  1. Make website containers (examples below are PHP containers):
docker run -d --name web1  -p 8081:80 eboraas/apache-php
docker run -d --name web2  -p 8082:80 eboraas/apache-php
  1. Now we start putting these PHP containers into subdomains. In your DNS, make the following records:
  • ‘A’ record from root domain to droplet IP
  • ‘CNAME’ record from each subdomain name to root domain
  1. In the droplet, go to /etc/nginx/sites-available
  2. Create in this folder with the content below:
server {

    listen          80;
  location / {

  1. Do the same for web2 container.
  2. Go to /etc/nginx/sites-enabled and run the following:
ln -s ../sites-available/ .

ln -s ../sites-available/ .
  1. Make sure there’s no error running the sites.
nginx -t
  1. Restart nginx
systemctl restart nginx
  1. Both and web2 should work after restart.

I have not figured out how to add HTTPS and Let’s Encrypt to this process yet. For now if you’re using this method, ensure you’re not hosting anything sensitive or gives room or contains functions that can be exploited by the outsiders. I’ll make another post for HTTPS and Let’s Encrypt once I get it working.