Setting up an HTTPS Proxy on localhost using Docker
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.
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.
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.
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