CapRover and Processes on the Metal
Why
With Heroku dropping the free tier from their service I decided to
make better use of the “server” I have sitting in my home office. My current
system was to just boot docker containers in the background with --restart
unless-stopped
, setting the ports manually, and updating my nginx configuration
to forward correctly per sub-domain.
Naturally this is a pretty manual process which I have gotten sick of, so I decided to check out the alternatives and settled on CapRover which describes itself as:
CapRover is an extremely easy to use app/database deployment & web server manager for your NodeJS, Python, PHP, ASP.NET, Ruby, MySQL, MongoDB, Postgres, WordPress (and etc…) applications!
It’s blazingly fast and very robust as it uses Docker, nginx, LetsEncrypt and NetData under the hood behind its simple-to-use interface.
For all my toy applications I had it was as simple as caprover deploy
from the
directory since they all had their own Dockerfiles, which meant CapRover could
very easily boot it up and manage the docker service for me.
Problem
This all sounds pretty amazing, so what was the problem I actually had? Well there’s one service I didn’t want to move into CapRover and it was my media service Jellyfin. CapRover doesn’t have a way to just point at the localhost instead of a docker container which makes sense, since there’s zero guarantee that CapRover is running on a single server as it’s designed to handle a swarm.
Solution
To make this less-than-usual setup work we’re required to boot a simple docker image:
FROM tecnativa/tcp-proxy
ENV LISTEN=:8096
ENV TALK=atom:8096
This uses docker-tcp-proxy which describes itself as:
Yes, this is a simply and stupid TCP proxy that listens in one address and talks to another one, with optional forced DNS preresolving.
The port 8096 is just the one used by Jellyfin by default so I kept it to keep
the interface for docker consistent. But if you boot this now you’ll notice that
it actually doesn’t work. We need to let the docker service know how to resolve
atom
which is done with a simple command:
docker service update --host-add atom:192.168.1.128 srv-captain--jellyfin
You’ll notice that I don’t use 127.0.0.1
and that’s because if I ever get a
second server I don’t want it to randomly break if my Jellyfin instance decides
to boot on the other server where it’s not hosted.
And with that done we should now have a functioning pass through on the CapRover application with minimal over head.
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
fe598e5dd266 srv-captain--jellyfin.1.o8mq6v32sky20waib5bnovnyl 0.01% 4.293MiB / 31.06GiB 0.01% 432kB / 72.7kB 13.3MB / 4.1kB 2