header source
my icon
esplo.net
ぷるぷるした直方体
Cover Image for Setting up an HTTPS Proxy on localhost using Docker

Setting up an HTTPS Proxy on localhost using Docker

about9mins to read

When developing applications that involve OAuth, you may occasionally want to access your local application server via https://localhost/. This is necessary for security reasons, as redirect URLs need to be specified, and HTTPS is often the only option.

Setting up a local proxy server can solve this issue, but the setup process can be cumbersome and may pollute your local environment. As someone who values a clean PC environment, I wanted to avoid unnecessary installations.

That's why I created an SSL termination proxy using Docker. Not only does it avoid polluting the environment, but it also allows for fast setup, taking around 30 seconds for the first time and 1 second for subsequent setups. The image is publicly available on GitHub and DockerHub, so feel free to use it if you need it.

https://github.com/esplo/docker-local-ssl-termination-proxy

https://hub.docker.com/r/esplo/docker-local-ssl-termination-proxy/

The usage is simple, but the IP retrieval part depends on the OS. Please adjust according to your environment. The following command creates a proxy for a local application running on port 3000:

Mac OSX

docker run -it \
  -e "HOST_IP=`ipconfig getifaddr en0`" \
  -e "PORT=3000" \
  -p 443:443 \
  --rm \
  esplo/docker-local-ssl-termination-proxy

Linux

docker run -it \
  -e "HOST_IP=`hostname -I | awk '{print $1}'`" \
  -e "PORT=3000" \
  -p 443:443 \
  --rm \
  esplo/docker-local-ssl-termination-proxy

Windows?

We're waiting for your Pull Request.

Below is an explanation of why I created this Docker image and how it works.

Simply put, you can't access HTTPS

To access your local server via HTTPS, you need to create a certificate or configure HTTPS settings. This is a hassle, as most development servers run on HTTP.

Setting up a proxy with Nginx or Apache to access localhost via HTTPS

When you want to access localhost via HTTPS, a common approach is to set up Nginx or Apache on the host machine. While this is possible, it requires installing Nginx or Apache just for this purpose, which can be complicated and unclear.

This issue can be elegantly solved by using Docker to create a black box. Not only is it fast, but it's also easy to understand, which helps maintain your development motivation.

Issues with setting up an Nginx proxy within Docker

The main issue is how to embed the host's IP address in the Nginx configuration file.

One problem is obtaining the IP address. In Docker for Mac, if the network mode is set to host, you cannot access localhost from the host machine. As a result, you need to use the bridge mode and pass the host's IP address as an environment variable. Since the host's IP address cannot be obtained from within the Docker container, it needs to be passed as an environment variable at startup.

Another issue is that Nginx configuration files do not support environment variables. Fortunately, a document explains how to use the envsubst command to replace environment variables.

https://qiita.com/takyam/items/e92e5a6ca1548cbd58db

We use this method to embed environment variables.

Code Explanation

It's very simple, but I'll explain the flow along with the repository files.

https://github.com/esplo/docker-local-ssl-termination-proxy

Ordinary Dockerfile

This is an ordinary SSL termination proxy using Nginx. The Nginx configuration file is still a template within the image. When it's actually started, entrypoint.sh is called to replace the environment variables using envsubst.

nginx.conf uses environment variable names

In nginx.conf, we specify environment variables as follows. This part is replaced by entrypoint.sh.

http {
  ...
  upstream app {
    server ${HOST_IP}:${PORT};

Using envsubst to replace nginx.conf

In entrypoint.sh, we use envsubst to replace the environment variables and create the actual configuration file, which is then used to start Nginx.

envsubst '$$PORT$$HOST_IP' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
nginx

Conclusion

I created a Docker image that allows you to easily access https://localhost/. Use this to reduce your workload and enjoy developing your application.

If you know a command to get the IP address that works across Mac and Linux, please send a Pull Request

Share