Recently, we needed to update the dependencies of a small web application. These dependencies included Docker and the web server itself. Thus, during the update the web app would have been down and the users would see “unable to connect” in their browsers. That’s unprofessional and annoying for the users.
We could have setup a proxy-server and reconfigure DNS so all traffic routes through the proxy. Then during the update, we would deliver a maintenance page from said proxy. This is nice, but also cumbersome to setup – especially, since all DNS changes had to go through a third party.
As an alternative, we could shut the web app down and spin up a separate server – on the server itself.
The temporary server could serve a simple maintenance page.
This does the trick nicely. The only problem is that the TCP port for the web app is now blocked by the maintenance server.
However, since our web app uses Docker Compose, the port can easily be changed in the docker-compose.yml
.
Now, we can test the web app under a different port and users receive a “we will be back” page.
After successful testing, we can kill the maintenance server and revert the changes in docker-compose.yml
.
Here some commands to setup and start such a simple web server:
# on the server, we create a simple maintenance html page
mkdir maintenance
cd maintenance
vim index.html # input contents below
# and now we can start a server
python3 -m http.server 80
The simple html for the website:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Maintenance</title>
</head>
<body>
<h1 style="text-align: center; margin-top: 10rem;">Sorry, we are currently performing some maintenance. We should be back shortly.</h1>
</body>
</html>
This approach works like a charm, but it does have security risks. To be honest, I personally do not trust the toy Python web server.
It is not made for production use – it even says so in the docs.
Therefore, we should keep the the use of this server to a minimum. Once the Docker-related updates ran, we can replace the python3
command with something like this:
docker run -v $(pwd):/usr/share/nginx/html:ro -p 80:80 nginx
Now our maintenance server hums securely in a sandbox and we can go on to do our work behind the curtains.
Happy maintaining!
P.S.: I am aware that one could still secure the nginx container more. However, this technique should really just be used for updates that take a few minutes.