I thought it would be fun to try self-hosting Supabase as a technical exercise. This isn’t a comprehensive guide, but rather some notes on what I ran into and learned along the way.

The Supabase website (supabase.com) has a guide on setting up local development with Supabase, which is relatively straightforward. (Local Development | Supabase Docs) This is intended to be used in conjunction with a project on the Supabase Platform, and is probably the best path to get started.

Instead I went with Docker self-hosting using their guide at Self-Hosting with Docker | Supabase Docs . It was a great learning experience!

My Droplet Lacks Space

I immediately bumped into a few difficulties. I wanted to re-use my little 2 Gb RAM / 1 vCPU DigitalOcean droplet which hosts my personal website. The storage was running out, so I added a 50 Gb volume from DigitalOcean. They provide configuration commands to run, which I did. However, the Ext4 mounted volume was much smaller than 50 Gb. I had to use growpart and resize2fs to get it to use the available space. After that I moved a bunch of files over and deleted some other ones on the original partition, including executing a script I found to remove non-current snaps. Finally, I went through the major logs’ configuration files and repointed them to my new volume.

Now that I had room, I followed the guide instructions.

Problems with the Database

The approach is pretty simple in theory – install Docker on your host, clone the repo (supabase/docker at master · supabase/supabase · GitHub), set up a .env file with appropriate secrets, run the docker compose command, and then troubleshoot until everything is working. For me, the initial attempts were pretty dismal. Several of the containers were unhealthy, and I was not sure if it was due to bad settings in my .env file or something else. In the container logs, I was getting an error: ‘supabase_admin@postgres FATAL: password authentication failed’ for at least one of the containers. I spent a while trying to confirm the database admin user was setup properly. Perhaps I changed the database user password in the .env file after the database was created, I am not sure. Ultimately I removed the old container images. Then I had to delete /volumes/db/data which another user reported helped, and that fixed the first problem. (steps here: uninstall and delete database data)

Sequencing Docker Compose

The storage-api container had an error about ‘hashes don’t match for migration’. This error turned out to require a version upgrade, from 0.43 to 1.0.6 in the yaml file. This was a surprise because I thought it should work without upgrading one of the containers against the instructions. I had a bit of trouble getting this to work at first, the version number stayed the same despite changing it in the main yaml file. Eventually I learned that the second yaml file in my compose command was overwriting the version number from the first file. I ended up switching the order of these so my final command was: sudo PWD=${PWD} docker compose -f docker-compose.s3.yml -f docker-compose.yml up -d . Note that I had to add the PWD=${PWD} part because that path variable in the yaml file didn’t work otherwise (error was ‘The “PWD” variable is not set. Defaulting to a blank string.’)

Health Checks Timing and Kluges

The other tricky bit had to do with the health checks. I extended a few of the timeouts and retries, but eventually settled for a hack whereby I run the compose up command, let it reach a stopping point, then run sudo docker compose down. I then do a ‘restart‘ variant of my docker compose up command, which allows everything to start properly. Still not sure why, seems to have something to do with containers running out of time before a service they depend on becomes healthy. I think that can be fixed in the yaml file eventually.

No Dot in the Host

I also ran into another error ‘Can’t set long node name! Please check your configuration’ . This one was tricky, eventually I realized it was because my hostname didn’t have a dot in it. It was expecting something like wyethjones.com but my hosting server had a name assigned from DigitalOcean. So I updated my /etc/hosts file to change it to a hostname with a dot, and that problem went away.

BigQuery Setup

The yaml file had comments instructing which sections to comment out to use Postgres for logging vs. BigQuery. I followed the instructions but still got errors, particularly ‘(MatchError) no match of right hand side value:’. This was because a supposedly optional file was actually required, so I created the gcloud.json file which resolved this error. I went through and uncommented both sections, and the logger is using Postgres by default.

Next Steps

The docker containers were finally healthy and I could access the endpoints locally via forwarded ports set up in VS Code. In my next post I’ll describe setting up DNS and Cloudflare Tunnels and pointing an application at my new Supabase backend. (see Part 2 here: Self-Hosting Supabase – Part 2)

Last modified: August 18, 2024

Author

Comments

Write a Reply or Comment

Your email address will not be published.