An Interest In:
Web News this Week
- April 20, 2024
- April 19, 2024
- April 18, 2024
- April 17, 2024
- April 16, 2024
- April 15, 2024
- April 14, 2024
Self-hosting with Supabase
Please note that this article is a work in progress. Please leave any suggestions or questions in the comments.
Relevant materials:
What is Supabase?
Supabase is an open-source database solution based on Postgres. It includes all the standard features of Postgres with some killer additions such as realtime streams and a REST API. These are all backed up by incredibly powerful libraries.
Pros and cons of self-hosting
There are many reasons you might want to self-host Supabase:
More database space - by using your own VPS, you could have a database that is many times bigger than what is (currently) available via Supabase managed platform
Full infrastructure control - you're in control of everything so if you need to make a change, you have that option
There are also some reasons you may want to let Supabase host your database instead of self-hosting:
It's already setup - You don't have to have a significant level of technical knowledge to setup a Supabase instance on their platform
Costs - They offer a free plan which may be enough for your needs
Who is this article for?
This article was written for people who want to self-host Supabase but have perhaps gotten lost with the self-hosting guides out there. Please be aware that at this time, the self-hosted options don't include the dashboard. If that's a deal breaker for you, this guide isn't for you.
To get the most out of this article, it is strongly advised that you have some basic experience with the following:
- Nginx - Configuring endpoints / proxies
- Docker - Deploying, configuring Dockerfiles
Even if you're lacking those skills, I've done my best to explain the key parts, as well as the files you need to change.
We will be using Portainer to manage our Docker containers. We'll also be using our service behind Cloudflare. For this, we'll use db.example.com
as our domain name. This will be mentioned later in the Nginx configuration section.
Getting setup
The first thing you should do is setup somewhere to host. I personally recommend DigitalOcean as almost everything can be done from the web dashboard. For the purpose of this article, if you see the word 'Droplet', this simply refers to a VPS which will host our Supabase instance.
Supabase provide some one-click deploys for several platforms, but we won't be using those as they don't contain the full Supabase experience.
Instead, we'll be installing Docker. Several VPS providers already have 'ready to deploy' Docker instances. I'd recommend using one as this can save you a significant amount of time compared to setting Docker up manually.
Assuming you have setup a Droplet / VPS with Docker running, the first thing to do is install Portainer. To do this, follow the guide at https://documentation.portainer.io/v2.0/deploy/ceinstalldocker/ . As of writing, there are only 3 steps needed to get Portainer installed:
- SSH into your VPS
- Run
docker volume create portainer_data
- Run
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
Next, you need to perform some basic configuration for Portainer. In your web browser, go to http://<ip-of-your-vps>:9000
and follow the on-screen instructions.
Next, we need to setup Nginx. Fortunately, this is very easy with Portainer.
Optional tip before continuing: Setup 2 volumes, nginx-config
and nginx-data
, and then use those from the volumes
tab when setting up Nginx.
From the left-menu of the Portainer dashboard, select 'App Templates' and from the list, select 'Nginx', and then follow the instructions.
Setting up the Docker images
Now that you've got Portainer running, you'll need to get the Supabase repo.
First, for the Supabase repo from https://github.com/supabase/supabase, and then git clone
your forked version into a directory of your choice.
The next step is to remove everything we don't need. For this, delete all folders except the /docker
folder.
If you're intending to use Nginx (as we will be in this article) Within the /docker
folder, you should remove the /supabase-traefik
folder as this will interfere with Nginx.
You should then move the /docker
and /dockerfiles
folder to the root of the repo. Your directory structure should look something like this:
- /docker- /dockerfiles--|-- /kong--|--|-- Dockerfile--|--|-- kong.yml--|-- /postgres--|--|-- 00-initial-schema.sql--|--|-- auth-schema.sql--|--|-- Dockerfile- .env- .gitignore- docker-compose.yml
Inside your .gitignore
file, add .env
. You'll be adding the contents of the .env
file to the deployment configuration via Portainer, so it's nice to have something you can copy and paste.
As per the docs, make sure you change the values of the .env
files.
Next, you may want to change some of the settings in /dockerfiles/kong/kong.yml
. In particular, changing the keyauth_credentials
sections at the bottom of the file. Using the JWT secret you created in .env
, encode some new tokens at https://jwt.io
(More details: https://supabase.io/docs/guides/self-hosting#running-supabase)
The final step is to commit + push the repo.
Deploying via Portainer
Going back to the Portainer web dashboard, select 'Stacks' from the left menu, and then click on 'Add Stack'.
Give your stack a name, and select 'Git repository'. For the repository URL, enter the full URL to your Supabase fork.
Under 'Environment variables' click on 'Advanced mode', and then copy and paste the contents of your .env
file.
Finally, click 'Deploy the stack' at the bottom. This process might take a few minutes to finish. Once it is completed, click 'Containers' from the Portainer menu. You may notice that 1 of the containers isn't running. Simply select it, and then click 'Start'. It should then run without any issues.
If your containers keep stopping, check the logs for them.
The final step for this section is configuring the hostname for each Supabase service. From the containers menu item in the Portainers dashboard, select each Supabase container. Click on 'Duplicate/edit' near the top of the page. Then, scroll to the bottom of the page, select the 'Network' tab under 'Advanced container settings'. In the 'Hostname' field, enter the name of the service. For example, for the supabase-rest
container, set the hostname to rest
. You can set this to anything you like, but I recommend keeping it relevant to the container. Finally, click 'Deploy this container'. It will warn you that a container with the same name already exists - click 'OK'. After a short while, the container will be redeployed with the new hostname. Repeat these steps for each Supabase container.
By doing this, it will help Nginx connect to the container and make it easier to identify in other parts of the infrastructure.
Configuring Nginx
In order to setup Nginx to support the various services needed for Supabase, we need to modify our Nginx config.
To do this, you need to SSH into your server, and then cd
your way to the volume where your Nginx config is stored. If you set up a nginx-config
volume as mentioned above, this will (usually) be located at /var/lib/docker/volumes/nginx-config/_data
.
From here, we need to modify 2 files. The first is nginx.conf
.
Inside the http
section, add the following:
map $http_upgrade $connection_upgrade { default upgrade; '' close;}upstream websocket { server realtime:4000;}
The other file we need to modify is conf.d/default.conf
. There's many ways you can configure Nginx, but for the sake of simplicity, we're going to keep this to a single file.
In conf.d/default.conf
, replace the entire contents with the following:
server { listen 443 ssl; server_name db.example.com; # REST location ~ ^/rest/v1/(.*)$ { proxy_set_header Host $host; rewrite ^/rest/v1/(.*) /$1 break; proxy_pass http://rest:3000; proxy_redirect off; } # AUTH location ~ ^/auth/v1/(.*)$ { proxy_set_header Host $host; rewrite ^/auth/v1/(.*) /$1 break; proxy_pass http://auth:9999; proxy_redirect off; } # REALTIME location ~ ^/realtime/v1/(.*)$ { proxy_redirect off; proxy_pass http://kong:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; }}
Let me explain what's going on here.
Firstly, our REST handler is listening to all requests sent to /rest/v1
path, as well as anything added after that part of the path. It is then routing it to the Supabase REST server, which by default will be accessible internally at http://rest:3000
.
Likewise, our auth handler is listening for requests to /auth/v1
, and routing them to the Supabase auth server, which is hosted at http://auth:9999
.
Finally, the realtime subscriptions are handled by the /realtime/v1
route. This routes those requests to Kong (which is utilized in Postgres to provide internal routing between services). By default, this is hosted at http://kong:8000
.
Note that realtime does NOT use the rewrite
directive while the other proxies do.
The reason we perform this proxying is that it allows us to ensure that requests from the Supabase libraries (e.g. @supabase/supabase-js
) are able to correctly route to the different services in the stack.
You may be able to route all services to Kong instead - I haven't tried this personally, and that's probably a better option. In that situation, you may not need to use the rewrite
directive. If you try this, leave a comment with your findings!
After you've made the changes, save the file, and restart the Nginx container from the Portainer dashboard. To make sure everything is working as expected, select the Nginx container and then 'View logs'. It should indicate that everything is running as expected.
Finally, from the Nginx container (in the Portainer dashboard), connect it to the supabase_default
network - the option to do this is found at the bottom of that page in the dashboard.
Final checks
At this point, everything should be running as expected.
You should be able to connect to your Postgres server using your VPS IP address, port 5432, and using the username postgres
and the postgres password you setup inside the environmental variables.
Closing notes
As stated previously, this article is a work in progress. I am still working through some of the finer details of configuring the Supabase stack for self-hosting. There might be some things missing from the article - leave a comment to let me know, and I'll look into adding it.
Setting up Supabase for self-hosting is by no means a quick task, and there's still room for improvement. Hopefully, this article will help speed up the process for you and set you off on the journey.
Original Link: https://dev.to/chronsyn/self-hosting-with-supabase-1aii
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To