Overview:
Puts Docker Containers to sleep and wakes them back up when they're needed.
Written in Node.js, this application acts as a HTTP reverse proxy and stops Docker containers which haven't been accessed recently and starts them again when a new request comes in. ContainerNursery also makes sure there are no more active WebSocket connections before stopping the container.
To improve the user experience a loading page is presented, which automatically reloads when the containers webserver is ready.
The application listens on port 80 by default for HTTP traffic and uses the socket at /var/run/docker.sock to connect to the docker daemon.
GitHub: https://github.com/ItsEcholot/ContainerNursery
GitHub Packages: https://github.com/ItsEcholot/ContainerNursery/pkgs/container/containernursery
Quick Demo:
Setup Guide:
There are multiple ways to setup and use ContainerNursery depending on your use case and network setup.
In this guide I want to give a quick overview which choices have to be made and to present a non exhaustive list of possible solutions for each choice.
More information can be found in the README.md file on the GitHub Repo.
DNS:
Since ContainerNursery is a reverse proxy it will use the host header of the request to decide where the request should be routed to. This means we have to reach CN using a domain name and can't simply use an IP + PORT combination. So you have to find a way to route multiple domain names to the same IP (probably the Unraid IP since CN is running as a Docker Container on that machine).
Hosts File:
Edit the local hosts file on your device. Your OS uses this file to resolve domain names to IPs. This file is located at /etc/hosts on Linux and MacOS and at C:\Windows\System32\drivers\etc on Windows.
Add an entry for each application you want to proxy through ContainerNursery.
Example:
192.168.1.2 my-important-app.unraid
192.168.1.2 handbrake.apps.unraid
192.168.1.2 speedtest.apps.unraid
In this example 192.168.1.2 is your Unraid (and thus ContainerNursery) IP and the names are freely choosable domains.
DNS Server:
You can also use your local DNS server to define new domains and point them to your ContainerNursery IP. While more complicated this approach allows all devices which make use of your local DNS server (if you announce it using DHCP, probably all your network devices) to access your apps using the defined domains.
Your DNS server could be a PF/OPNSense box, your modem (if it allows adding manual DNS entries) or a dedicated DNS server application like PiHole for example.
Since all this sub-methods are configured differently, DuckDuckGo (other search engines are available) is probably the best way to figure this one out by yourself.
Ports:
By default ContainerNurser is setup, like most reverse proxies, to run on port 80 since this is the default port for HTTP requests. This way you don't have to append a port to the domain name when trying to access your applications. Since port 80 is also used by Unraid to serve it's Webinterface you basically have two options:
Change Unraids Webinterface port
This is the preferred method since it allows using all your other applications like you would expect them to, i.e without having to append a port to the domain name. This can be accomplished by navigating to the Settings > Management Access page and changing the HTTP port value to something other than 80. 8080 would be a great candidate, since it's easy to remember.
This means that from now on you would have to access your Unraid WebUI (only if you don't use https) using the following URL: http://<yourunraidip>:8080
This method also means you could deploy CN using host networking instead of bridge, however I don't recommend this, since the useful isolation layer between host and container is then not used.
Change ContainerNurserys port
This can be easily done by editing the CN container and making sure you're using bridge networking and maping the port from 80 to 8080 for example.
If you use this way the Unraid WebUI will still be available like usual, but all your services have to be accessed with this port appended, for example: http://hanbrake.apps.unraid:8080
Networking:
Since you want to use ContainerNursery to proxy your requests to your applications, CN will have to be able to access your other containers. The approach here depends on how your other apps and CNs network is configured.
Custom bridge network
This is the most elegant solution in my eyes. Custom docker bridge networks allow you to specify which containers should be able to access this network and communicate with each other (without having to map any ports) and most importantly allow you to use the name of the container as a hostname. Docker will then automatically resolve the correct container IP address for you. Using this approach dramatically reduces the attack surface, since less ports are open on the Unraid Host itself.
To use this approach open up the Unraid Console using SSH or the WebUI and run the following command, creating a custom bridge network with the name proxy:
docker network create proxy
Now edit all your applications, which you want to access through ContainerNursery and change the following option:
Network Type --> Custom: proxy
You can (and should) now remove all port mappings (hint: make a note of what port the app uses inside the container, since they're not always the same), since you will only be accessing the app through the domain (and CN as a reverse proxy) instead of the raw IP + port combination.
Make sure ContainerNursery itself is also switched to using your newly created docker bridge network but keep the port mapping (change it to your desired value if needed, see the part about ports above) since we need to be able to access ContainerNursery from other machines so that it can route our requests to the desired containers.
Now you can configure ContainerNursery like in this example:
proxyHosts:
- domain: handbrake.apps.unraid
containerName: handbrake
proxyHost: handbrake
proxyPort: 5800
timeoutSeconds: 14400
Since we use a custom bridge network which translates the container name to the correct IP address we can use handbrake as our proxyHost value. The proxyPort value is the internal port (the port the actual application inside of the container listens on) of the target container since containers of the same bridge network can communicate freely with each other without any port mapping taking place.
Default bridge network
If you want to use the default bridge network docker provides you will have to map ports on both ContainerNursery and the container you want to access and then use a configuration like in this example:
proxyHosts:
- domain: handbrake.apps.unraid
containerName: handbrake
proxyHost: 192.168.1.2
proxyPort: 6800
timeoutSeconds: 14400
192.168.1.2 is the IP of the Unraid machine and the port 6800 is the mapped port of the handbrake container.
Host network
The same rules as for the default bridge network hold true but now localhost can be used inside the config, since localhost now refers to the Unraid machine and not the CN docker container.
proxyHosts:
- domain: handbrake.apps.unraid
containerName: handbrake
proxyHost: 127.0.0.1
proxyPort: 6800
timeoutSeconds: 14400