Deploy Next.js Supabase to a VPS

This guide will help you deploy the Next.js SaaS boilerplate to a VPS.

If you want to self-host your application, you can deploy the Next.js SaaS boilerplate to a VPS. In this specific guide, we will use Digital Ocean, a popular cloud provider in the VPS space.

Much of the setup in this guide is going to similarly apply to other platforms, such as Hetzner, Linode, Vultr, etc.

Generate the Dockerfile image in your project

In your own project, run the following command to generate the Dockerfile.

pnpm run turbo gen docker

This will create a Dockerfile in the root of your project. In addition, it will install some dependencies that may be required to build the project.

0. Create a Digital Ocean Droplet (or other platform)

From Digital Ocean (or any other platform), create a new Droplet. Use the specifications and settings you prefer.

1. Install Docker

To Install Docker, please follow the official Docker installation guide in the Digital Ocean Community.

2. Add Firewall Rules

Add a firewall rule to allow inbound traffic on port 3000.

Please refer to the Digital Ocean documentation for more information.

3. Building the Docker image

We can build the Docker image on the Droplet or build the image locally and push it to a container registry.

If you don't have a powerful VPS, it's recommended to build the image locally and push it to a container registry (such as DockerHub, Github Container Registry, etc.).

Ideally, you can set up a Github Actions workflow to build the image and push it to a container registry automatically when you push a new commit to the repository.

In the next steps, we will build the image on the Digital Ocean Droplet. Only follow this section if you have a powerful VPS, otherwise the build will fail due to lack of memory/CPU.

3.1. Connect with Github repository

3.1.1. Create a Personal Access Token

First, you need to create a Personal Access Token in Github to allow access to the repository. We will reference this token below as <PAT>.

3.1.2. Pull the repository

Next, you need to pull the repository to the Digital Ocean Droplet.

git clone https://<PAT>@github.com/username/repo.git

NB: Replace <PAT> with the Personal Access Token you created in step 3.1.

3.1.3. Install Node.js and dependencies

Navigate to the repository and install the dependencies.

First, set up Node.js and pnpm.

Download and install nvm:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash

Then run:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion

You can now install Node.js:

nvm install 20

Next, install PNPM globally:

npm install -g pnpm

Now, we can install the dependencies:

cd repo # Replace repo with the name of the repository
pnpm install

4. Create the Dockerfile

pnpm run turbo gen docker

5. Build the Docker Image on the Digital Ocean Droplet

Navigate to the repository and build the Docker image.

docker build -t next-supabase-turbo .

If the build fails, it's possible it's out of memory. You can try to add more memory to the Digital Ocean Droplet.

docker build -t --memory 2g -e next-supabase-turbo .

If the Droplet size allows it, you can try to add more memory to the build.

6. Environment Variables

Using the Dev Tools, generate the environment variables for the production environment. Copy the environment variables and paste them in the apps/web/.env.production.local file within the repository. This file gets never committed to the repository since it's ignored by the .gitignore file.

7. Run the Docker Container

First, ensure that the .env.production.local file is present in the apps/web directory.

Then, run the following command to run the Docker container:

docker run -d -p 3000:3000 next-supabase-turbo --env-file apps/web/.env.production.local

8. Access the Application

You can now access the application at http://<your-docker-host>:3000.

9. Next Steps

Now that your application is running, you can start to configure the production environment. You will want to do the following:

  • Configure Nginx to reverse proxy requests to the Docker container
  • Add a custom domain name to Digital Ocean
  • Set up a Firewall in Digital Ocean to allow inbound traffic on port 3000
  • Set up a SSL certificate for your custom domain name with Let's Encrypt

After doing this, you will have a production-ready application that is fully self-hosted!