Docker app hosting

Like a ton of other people I was recently inspired by listening to Lex Fridman interview Peter Levels. Hearing him speak about the current state of development made me want to simplify.

I was trying out fly.io for an app that I was working on but it was yet another platform to learn, will probably fall out of fashion, and was kinda pricey for what I wanted to use it for. I have already messed around with:

  • heroku
  • netlify
  • vercel
  • others

And those are great for high availability and horizontal scaling but....I don't have those problems and those platforms can get expensive quick compared to having your own VPS and running your apps on it. Granted, I'm familiar with servers and docker. If you're not then by all means use those services. They're great for that. However, since I have that experience, use a wide range of technologies for different apps, then docker with my VPS makes a lot of sense to me. It also helps that it's relatively easy to find Dockerfiles for various frameworks.

Why Docker?

I prefer to not mess around with server packages and updates if I don't have to. It scares me doing that stuff in production. Using docker means I can easily run apps that need varying versions of php, node, python, etc and I don't have to worry about getting all those pieces in place directly on my server. If I just used php and no framework like Peter then I probably wouldn't bother with docker.

Let's go

I just had to figure out how to come up with a github action workflow to deploy to my server. Here's what I came up with. This does require some server set up(below).

The workflow deletes all but the last three images stored on github and on my server so I'm not paying for those on github and not chewing through disk space on my server.

Server setup

First, create a github user account with docker permissions on your server:

sudo useradd -m github
sudo usermod -aG docker github

And created a ssh key/pair for the github user:

# change to github user
sudo su - github

# generate ssh key/pair
ssh-keygen -t rsa -b 4096 -C "[email protected]"

Next, copy the contents of /home/github/.ssh/id_rsa.pub into /home/github/.ssh/authorized_keys and fix the permissions if necessary:

chmod 600 /home/github/.ssh/authorized_keys

Next create the required repository secrets here:

https://github.com/<your-username>/<repository-name>/settings/secrets/actions

The following secrets should be created:

SERVER_HOST=<your servers hostname or ip>
SERVER_SSH_KEY=<the contents of the private key: /home/github/.ssh/id_rsa>
SERVER_USERNAME=github

The deploy script also assumes your container needs env vars set and those should be created in a /home/github/yourappsname.env file. It also assumes the container uses port 3000 and should forward to the same port on the host.

You can then add nginx in front of it if you've configured a domain's DNS to point to your server. Create an A record if using an ip as the value and the domain as the name. Ex: yourappsname.com.

# /etc/nginx/conf.d/yourappsname.conf
server {
    listen 80;
    server_name yourappsname.com www.yourappsname.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Reload nginx:

nginx -s reload

And then use certbot to add an ssl certificate:

certbot --nginx -d yourappsname.com -d www.yourappsname.com

Result

Now I have a pretty good template to follow to deploy whatever apps I decide to build and not be charged a crazy amount by hosting providers. The only hosting I'm using is a fixed price Hetzner VPS I can resize if/when I need to.

Next steps

Postgres has been my database of choice but I think I want to simplify to just using sqlite and see how far that gets me. A lot of the things I want to build are hobby projects with potential to make money. I don't want to pay for fancy db hosting for these apps. There are some database providers that have free plans but I haven't come across any that offer free backups and that's something I do want. I plan to use docker volumes to store the sqlite database on my VPS host and then start with cron-based backups and then use litestream if I ever feel the need to go down that path.

Categories: Servers