Hosting multiple web applications in Docker
Tags: docker, nginx, ssl
Published: 2020-07-08 12:13:49

---
title: Hosting multiple web applications in Docker
published: true
date: 2020-07-07 13:00:00 UTC
tags: Docker,NGINX,SSL
canonical_url: https://SimonReynolds.ie/hosting-multiple-web-applications-in-docker/
---

 ![Hosting multiple web applications in Docker](https://images.unsplash.com/photo-1511578194003-00c80e42dc9b?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=2000&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ)

I've written before about [developing software in Docker containers](https://simontaite.com/hosting-multiple-web-applications-in-docker/developing-in-a-docker-container) and while that has been a step forward for development and being able to isolate development environments, the strength of Docker has always been in running applications without having to worry about requirements or dependencies.

![Hosting multiple web applications in Docker](https://SimonReynolds.ie/content/images/2020/07/Docker.jpg)<figcaption>How it all began...</figcaption>

For managing clusters of applications we have plenty of options, Kubernetes, Docker Swarm, OpenStack and of course Docker Compose.

Options like Kubernetes are indispensable when operating at scale, with dozens, hundreds or even thousands of instances of multiple microservices all working together to provide a full application.

But when it comes to something like hosting a personal blog like this one then it can be overkill. Something simpler like Docker Compose will do just fine.

<!--kg-card-begin: markdown-->
```yml
version: '3.1'

services:
  ghost:
    container_name: ghost
    image: ghost:alpine
    restart: always
    ports:
      - 127.0.0.1:2368:2368
    volumes:
      - ./content:/var/lib/ghost/content
      - ./config.production.json:/var/lib/ghost/config.production.json
```
<!--kg-card-end: markdown-->

This is a relatively simple example of a docker-compose.yml file but it shows the important details, we specify our image, it's set to restart automatically in case of a crash or failure and mounts some files from the native file system and forwards to a port on the server itself.

This is where we can set up a reverse proxy in nginx, but why install it when nginx is available as a docker image?

Particularly when we have the chance to use this amazing piece of work?

{% github evertramos/docker-compose-letsencrypt-nginx-proxy-companion no-readme %}

It sits between one or more docker containers and the outside world, forwarding requests and also taking care of SSL certificates using LetsEncrypt.

![Hosting multiple web applications in Docker](https://simontaite.com/content/images/2020/07/webproxy-1-.jpg)

To host our ghost blog behind it all we need to do is expand our docker-compose file and restart that container. The nginx proxy will detect it based on the extra environment variables and handle all proxy reversing and add your new SSL certificates.

<!--kg-card-begin: markdown-->
```yml
version: '3.1'

services:
  ghost:
    container_name: ghost
    image: ghost:alpine
    restart: always
    ports:
      - 127.0.0.1:2368:2368
    volumes:
      - ./content:/var/lib/ghost/content
      - ./config.production.json:/var/lib/ghost/config.production.json
    environment:
      # Note how VIRTUAL_HOST and LETSENCRYPT_HOST allow for multiple domains
      - VIRTUAL_HOST=simonreynolds.ie,www.simonreynolds.ie
      - LETSENCRYPT_HOST=simonreynolds.ie,www.simonreynolds.ie
      - LETSENCRYPT_EMAIL=REDACTED@example.com
      - MAIN_DOMAIN=simonreynolds.ie
      - VIRTUAL_PORT=2368

networks:
  default:
      external:
        name: webproxy
```
<!--kg-card-end: markdown-->

I took the extra step of creating the `webproxy` network myself so I can host multiple sites across different domains from just one server.

This makes spinning up small sites for testing ideas incredibly easy and fully automates SSL certificates so I never have to worry about expired certificates again!