Make Supabase Production-Ready with the Traefik API Gateway

API gateways have rapidly evolved to become a crucial component of most modern cloud infrastructure — particularly within microservices architectures. More so than other cloud components, API gateways need to be secure, robust, resilient, and easy to manage, and the Traefik API gateway is definitely up to this challenge.

In this guide, I want to give you a tour of the Traefik API gateway and explore how to configure it to enable a production-ready, self-hosted deployment of the Supabase Platform on Kubernetes.

Supabase describes itself as “an open source Firebase alternative”. The platform provides a collection of application backend features such as Authentication, Database (Postgres) and Storage (S3) and is quickly growing in popularity amongst many application development communities.

Why choose Traefik Proxy for this guide? Well, because the current Supabase Helm Chart utilizes a rather bare-bones deployment of Kong and Nginx. And although functional, both these configurations fall short of a production-ready environment, namely, a lack of authentication for the GUI and rate limiting of the API.

Substituting Kong and Nginx for Traefik Proxy makes up for the above shortcomings and provides a host of additional benefits:

  • Built-in Let's Encrypt integration
  • Simpler to configure
  • Several Middlewares available
  • Management of a single API Gateway instead of two
  • An upgrade path to Traefik Enterprise

Prerequisites

  • A Kubernetes Cluster (with cert-manager installed)
  • Knowledge of Kubernetes and Helm

Note: Many of the Traefik configurations and concepts used here also apply to other application platforms with similar API gateway requirements.

Architecture

The above architecture represents a high-level overview of the end goal. A production-ready deployment of Supabase on Kubernetes with Traefik API gateway securing the Supabase API and GUI (Studio).

Deploy Supabase on Kubernetes

Note: If you already have a Supabase deployment on Kubernetes, you can skip to the next section to install and configure Traefik Proxy. Since Traefik will be configured to expose the Supabase endpoints it’s important to disable any related Supabase endpoint ingress configurations in your existing deployment.

  1. Use the Supabase Helm chart provided by the supabase-community repo to deploy Supabase on a Kubernetes cluster. The chart’s values.yaml options should be configured to meet the requirements of a production environment (and with Traefik Proxy in mind). So, configure:
    • An externally managed or cluster replicated PostgreSQL database
    • An external transactional mail service, e.g. SendGrid, Mailgun or Sparkpost
    • An external (or internal HA) S3 compatible storage provider, e.g. AWS or Cloudflare
  2. The chart’s default values.yaml enables an nginx ingress for both the Supabase Studio and API services (studio.ingress.enabled and kong.ingress.enabled). Since we’ll be configuring Traefik ingress routes for these services later on, both should be set to false.
  3. Generate the JWT keys and secret values required to create the JWT secret inside the cluster.
  4. Create a database secret containing the username and password of your PostgreSQL database and another secret with your SMTP provider credentials.
  5. Deploy the Supabase helm chart inside your cluster. helm -n default install supabase -f my-custom-values.yaml.

Use the kubectl port-forward command to check the Supabase API endpoints and GUI have successfully deployed in your cluster.

To check Supabase Studio, run the following command:

> kubectl port-forward service/supabase-supabase-studio -n default 3000:3000

Navigate to http://localhost:3000/projects and you should be presented with the Supabase Studio frontend:

Once you’ve confirmed Supabase Studio is working, go ahead and test the API endpoint next.

Navigate to http://localhost:3000/project/default/api?page=auth. This API Docs page features API commands with your previously configured access credentials substituted in. Click to copy the generated curl command used to authenticate with the /rest/v1/ endpoint.

Use the kubectl port-forward command once again, this time to proxy the Supabase API:

> kubectl port-forward service/supabase-supabase-kong -n default 8000:8000

Next, execute the curl command you copied from the API Docs in Studio:

curl 'https://api.supabase.local/rest/v1/' \
-H "apikey: SUPABASE_SERVICE_KEY" \
-H "Authorization: Bearer SUPABASE_SERVICE_KEY" | jq

The result should start similar to the partial snippet below:

  {
  "swagger": "2.0",
  "info": {
    "description": "",
    "title": "standard public schema",
    "version": "10.2.0.20230209 (pre-release)"
  },
……

Supabase is now successfully deployed and primed to be made production-ready with the help of the Traefik API gateway 🎉.

Deploy and configure the Traefik API gateway

As mentioned earlier, the default deployment of the supabase-kubernetes helm chart requires some important additional steps before it’s production-ready.

Install Traefik (Helm)

Before installing Traefik, make a minor addition to the values.yaml file so Traefik redirects all HTTP requests to HTTPS:

ports:
  web:
    redirectTo: websecure

Next, install Traefik via the traefik-helm-chart:

helm install -f myvalues.yaml traefik traefik/traefik

Configure the Traefik API gateway for Supabase’s APIs & GUI

Now it’s time to create the necessary Traefik configurations.

If you followed the Supabase chart deployment instructions above, you’ll recall the ingress configurations for both the Studio and API services were disabled (set to false).

Both ingress routes require a valid SSL certificate for their respective domains. e.g.

  • api.supabase.example.com for the Supabase API ingress route
  • studio.example.com for the Supabase Studio ingress route

Ensure these certificate secrets exist before creating the ingress routes that reference them.

Now, create the ingress routes that will publicly expose both the API endpoints and Studio services, this will also enable SSL/TLS termination for both routes:

api.supabase.example.com.yaml

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: api.supabase.example.com
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - kind: Rule
      match: Host(`api.supabase.example.com`)
      services:        
        - name: supabase-supabase-kong
          port: 8000
  tls:
    secretName: api.supabase.example.com

studio.example.com.yaml

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: studio.example.com
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - kind: Rule
      match: Host(`studio.example.com`)
      services:        
        - name: supabase-supabase-studio
          port: 3000
  tls:
    secretName: studio.example.com

Create two corresponding DNS records for your domain with your DNS provider, api.supabase.example.com and studio.example.com, both pointing to the IP address of the load balancer associated with your Traefik instance.

Protect the Supabase Studio dashboard with Traefik middleware

Navigate to https://studio.example.com, and you should (again) be presented with the Supabase Studio web interface. You’ll notice the Studio dashboard is currently unprotected — i.e., there’s no authentication step before access.

The Supabase dashboard can be secured using a Traefik *Auth middleware such as BasicAuth. Traefik's ForwardAuth middleware with an external authentication server like Authelia is another option.

However, I highly recommend taking access control to another level with Traefik Enterprise. Its built-in middleware OpenID Connect Authentication integrates with existing authentication deployments. See 'Going further with Traefik Enterprise' below for more details.

Rate limiting the Supabase API

At this point, Traefik is configured so both the Supabase Studio and API endpoints are secured against unauthorized or unauthenticated access.

So, can this deployment be considered production-ready? Not quite yet. The Supabase API has no protection against bursts of incoming traffic, be it from unexpected high traffic or malicious abuse, such as Denial-of-Service (DoS) attacks, it's a concern that cannot be left unaddressed.

Traefik has this covered with yet again another middleware option, the RateLimit middleware.

Define a rate limit to suit your needs using a middleware object:

# Here, an average of 200 requests per second is allowed.
# In addition, a burst of 100 requests is allowed.
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: ratelimit-supabase-api
  namespace: default
spec:
  rateLimit:
    average: 200
    burst: 100

This will set an overall rate limit across all Supabase API endpoints. This is a good starting point, plus the RateLimit middleware is capable of more granular rate limiting via options such as sourceCriterion.ipStrategy and sourceCriterion.requestHeaderName which sets rate limits based on incoming IP and request header groups respectively.

Apply the new middleware to the api.supabase.example.com ingress route:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: api.supabase.example.com
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - kind: Rule
      match: Host(`api.supabase.example.com`)
      services:        
        - name: supabase-supabase-kong
          port: 8000
      middlewares:
            - name: ratelimit-supabase-api
  tls:
    secretName: api.supabase.example.com

Once applied, your Supabase API route now has a safeguard against high volumes of traffic. You can also set a rate limit on the Studio service if required.

Production ready?

The Traefik API gateway is now handling:

  • TLS/Termination for the Supabase Studio and API routes
  • Secure authentication and authorization to Supabase Studio
  • Rate limiting of the Supabase API route

Your Supabase deployment is now production-ready!

Going further with Traefik Enterprise

Although this guide demonstrates a production-ready deployment of Supabase using the open source version of Traefik, it’s not without its limitations. Upgrading to Traefik Enterprise offers a path to overcoming these limitations. Let’s take a look at some ways in which Traefik Enterprise achieves this.

Authentication and authorization

As mentioned, Traefik Enterprise offers much more robust authentication solutions over middleware like BasicAuth and ForwardAuth. For example, the built-in OpenID Connect Authentication middleware means Traefik Enterprise can easily accommodate your existing authentication and authorization infrastructure to provide access control to Supabase.

The above is a simplified illustration of how the OIDC Authentication middleware functions. For a more detailed look at how to configure the OIDC middleware, check out Matt Elgin's article, 3 OIDC Configurations with Traefik Enterprise, from Basic to Advanced.

High availability

The very start of this guide mentions the importance of API gateways in modern microservices architectures. In contrast to Traefik’s open source edition, Traefik Enterprise is deployed by default as a cluster of proxy nodes. Substituting the default Supabase API gateway (a potential single point of failure) for Traefik Enterprise enables the Supabase endpoints to be served in a highly available and scalable fashion by a cluster of proxies. Not to mention the reduced complexity from now only managing a single API gateway installation, Traefik Enterprise.

Migrating to Traefik Enterprise also introduces a wealth of authentication protocols (beyond JWT) for authenticating with the Supabase API (including LDAP, OAuth2, OpenID, and HMAC). This opens the door for many other applications to interact with your API.

Distributed rate limiting

The rate limit middleware configurations applied to Supabase endpoints in this guide limit requests per an individual Traefik proxy. Traefik Enterprise’s distributed rate limiting ensures that requests are limited over time throughout your cluster and not just on an individual proxy.

Configuring this in Traefik Enterprise is as simple as adding a single line to your existing open source RateLimit middleware config:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: ratelimit-supabase-api
  namespace: default
spec:
  plugin: # <- just add this line to enable distributed rate limiting
	  rateLimit:
		average: 200
		burst: 100

Support

Last but not least — support. Traefik Enterprise comes with built-in support. A team of engineers is at your disposal should you encounter any issues or need any assistance with the installation, setup, or management of Traefik Enterprise. Quality support (in my opinion) is an important part of what makes a deployment “production-ready.”

Conclusion

This Supabase deployment has demonstrated how the Traefik API gateway can help build a production-ready application through the implementation of some of its key features.

Bear in mind authentication, rate limiting, TLS termination, and high availability are just the tip of the iceberg when it comes to the capabilities of the Traefik API gateway. If your application architecture requires a more complicated feature set, such as service mesh, security compliance, or disaster recovery, Traefik Enterprise can accommodate these needs.

To learn more about how the Traefik and Traefik Enterprise API gateways can enable production-ready applications and platforms, check out Traefik’s excellent glossary and the documentation for both Traefik Proxy and Traefik Enterprise. If you’d like to try out Traefik Enterprise for yourself, you can sign up for a 30-day free trial.

See the API Gateway Cloud Natives Trust Want to simplify the discovery, security, and deployment of APIs and microservices? Explore Traefik Enterprise today.Learn More

This is a companion discussion topic for the original entry at https://traefik.io/blog/production-ready-kubernetes-deployments-traefik-api-gateway-supabase/