Building the Ultimate Home Server – Part Five - Fixing my Docker Compose Situation
In my last post, I discussed how I was using Docker to deploy web apps on my home server. In the past month since then, I've continued to tinker with my process, and I've learned a little bit more about making it a little easier for myself.
Portainer Stacks are Dumb
I really didn't have a clear reason why I was using Portainer stacks to handle my docker-compose files. I liked having one single place to handle my entire server. However, using one docker-compose.yml as the authoritative source of app information does not necessitate pasting it into a web interface to gain the benefits of having Portainer stacks.
One of the few advantages of having a Portainer Stack rather than a traditional .yml compose file is the ability to pull the whole stack down using a single click. If you have several stacks, it might make sense. For my server, I have one stack that controls all apps. If one app was being troublesome, I would go directly to that container and restart it from the Portainer GUI - I wouldn't take my entire server down to fix one small issue. I can still view information at a glance with Portainer significantly easier than querying through the command line - Portainer itself still has value, but not as the source for my compose files.
As the number of containers in my docker compose neared 50 separate services, Portainer would have more errors deploying my giant stack. There was no explanation for why the deployment failed. The message would simply say Failure to deploy stack with no additional information. Oftentimes simply trying again seconds later would fix the issue, but I shouldn't have to do the same thing over and over - that's the definition of insanity.
Docker Compose CLI Gives Me the Control
After some troubleshooting, I found that having such a large stack meant that the health check that confirms that apps are up after 60 seconds would fail because docker was working on installing other apps. With Portainer, there was no way to change the length of the health check, so docker was assuming that it had failed when it just needed patience. With the docker-compose command, I was able to change the health check as an environmental variable. So then, I would navigate to where my docker-compose.yml file was located and run this command:
If I was really smart, I would set up a bash alias so I could run something like server-up
and have this variable included by default. It's on the list of things to happen in the future…
Git Makes Docker Compose Simple
Back when I was using Portainer, I started out with a stack that was linked to a git repo. In my quest to eliminate variables to try to get the Failure to deploy stack message to stop showing up, I started manually copying and pasting. This made my life slightly more annoying. However, now that I wasn't using stacks any more and was just using a .yml file, it was back to using a Git repo once again.
I host my docker-compose file in my own home-hosted Gitlab instance. GitLab gives me a web text editor that I can use to edit my compose file from anywhere. I could then ssh into my server, go a quick git pull
, then docker-compose up -d
and it's off to the races.
Deploying a Customer Link Shortener
Twitter has their own custom link shortener - t.co - that enables Twitter users to share links while simultaneously giving Twitter another opportunity to gobble user's data. I've also personally used Bit.ly for personal link sharing. But I have a home server… why not host something similar to bit.ly myself?
The open-source project Polr allows you to do just that - home-hosted link shortening made easier.
I already own the domain name grantmclravy.com, using that for personal projects, including this blog, so I slapped together a quick Polr container using this Docker container. I added it to my Docker compose file like so:
polr:
image: ajanvier/polr
container_name: polr
ports:
- "24632:8080"
environment:
DB_HOST: db
DB_DATABASE: polr
DB_USERNAME: polr
DB_PASSWORD: polr-db-pw
APP_NAME: "Granto Link Shortener"
APP_ADDRESS: links.grantmclravy.com
ADMIN_USERNAME: AdminUser
ADMIN_PASSWORD: polr-admin-pw
ADMIN_EMAIL: [email protected]
SETTING_SHORTEN_PERMISSION: "true"
MAIL_HOST: smtp.mailgun.org
MAIL_PORT: 465
MAIL_USERNAME: [email protected]
MAIL_PASSWORD: polr-email-pw
MAIL_FROM_ADDRESS: [email protected]
MAIL_FROM_NAME: Polr Link Shortener
I added a new host in Nginx Proxy Manager to redirect links.grantmclravy.com to port 24632 on my server, adding my previously created SSL certificate, and I had a custom link shortener. I tried it out with friends: sending them a link to https://links.grantmclravy.com/not-a-rickroll.
If you're a goober and have been on the internet for a baby bit, you'll probably recognize that link is definitely a rickroll.
But… links.grantmclravy.com is lame
bit.ly
is nice and short. t.co
is even better. To have a good link shortener, it should be… well… short, right?
Enter the Polynesian island of Tonga
Tonga is a Polynesian island nation with a rich history. The island of Tonga was the capital of the Tongan empire, a powerful empire that reached its peak in about AD 1250. Scholars believe the Tongan empire was formed around AD 950 and lasted all the way until 1865. My western-centric brain assumed that the empire would have fallen when Britain annexed them into the British empire, but Tonga was never part of the British Empire. Tonga remained independent, having a “Treaty of Friendship” with the British government. The Tongan Monarch remained in control of the island nation until 2008, when Tonga became a constitutional monarchy with much of the power being placed in the prime minister. Pretty cool, right? This is the type of stuff I never heard in my World History class that is absolutely fascinating.
Tonga also happens to have a really cool TLD (Top Level Domain) of .to
. I was able to buy gran.to
for $40. I changed my Docker compose to:
polr:
image: ajanvier/polr
container_name: polr
ports:
- "24632:8080"
environment:
DB_HOST: db
DB_DATABASE: polr
DB_USERNAME: polr
DB_PASSWORD: polr-db-pw
APP_NAME: "Gran.to Link Shortener"
APP_ADDRESS: gran.to
ADMIN_USERNAME: AdminUser
ADMIN_PASSWORD: polr-admin-pw
ADMIN_EMAIL: [email protected]
SETTING_SHORTEN_PERMISSION: "true"
MAIL_HOST: smtp.mailgun.org
MAIL_PORT: 465
MAIL_USERNAME: [email protected]
MAIL_PASSWORD: polr-email-pw
MAIL_FROM_ADDRESS: [email protected]
MAIL_FROM_NAME: Polr Link Shortener
and set up Cloudflare DNS, https certs, and Nginx Proxy manager as explained in my last post.
Try this on for size:
https://gran.to/rickroll
What you see is what you get. It says rickroll; you get rickrolled. No tomfoolery here. Plus it's just a bop.
I also set up a redirect for this site at https://gran.to/blog - pretty fancy, eh?
In conclusion
Playing with a home server is an awesome hobby that has taught me so much. When I started this project, I was an accounting student playing with technology in-between classes. Now, I'm a full-time IT professional that gets paid to play with computers all day. God truly has been good to me these past few months.