Deploying Supabase with Portainer and Keeping Your Sanity
Thinking of running Supabase with Portainer? Many try, few survive without falling into a maze of unhealthy containers and cryptic errors. Here’s how to keep your sanity and actually get it running.
There’s a special place in developer hell reserved for Docker Compose path errors. You know the one. Everything looks fine. You copy a docker-compose.yml from the docs, slap it into Portainer’s Stacks editor, hit “Deploy”… and suddenly your screen lights up like Las Vegas on New Year’s Eve. One container says it’s unhealthy. Another refuses to start. A third just keeps respawning itself like an immortal phoenix with bad syntax.
You dig in, chase down error logs, tweak configs, redeploy… and three hours later you’re staring at a log file that says something like:
dependency failed to start: container supabase-vector is unhealthy
That’s the moment you realize you’ve fallen down a rabbit hole deeper than Alice’s. And spoiler: the rabbit hole has layers. Every single container you poke at throws a different error.
So let’s back up. Here’s how you can actually get Supabase running under Portainer without tearing your hair out.
Step 1: Follow the Official Guide First
Head over to the official Supabase docs. Follow the “Self-Hosting with Docker” setup guide like a good citizen. This does a couple of important things:
- It generates all the environment variables you’ll need.
- It creates the directory structure where your volumes will live.
- It gives you a working baseline where everything actually comes up healthy the first time.
Do not skip this. Don’t think you’re cleverer than the docs. You’re not. I tried. I failed. Trust me: run the commands, get it working locally, then move on.
Step 2: Know Where You Put the Supabase Project
The setup will create a folder, usually called supabase-project
. Inside it you’ll see a bunch of subdirectories:
supabase-project/
├── docker-compose.yml
├── volumes/
│ ├── api/
│ ├── db/
│ └── ...
This folder is the beating heart of your self-hosted Supabase. Treat it like the One Ring. Don’t lose it. Don’t move it. Write down the path, tattoo it on your arm if you have to. You’re going to need it.
Step 3: The Portainer Stack Trap
Now comes the part where most people (myself included) go wrong. You copy the docker-compose.yml and .env into Portainer’s Stack editor, hit “Deploy”, and boom — the wheels come off. Why?
Because all the volume mounts in the docker-compose.yml look like this:
volumes:
- ./volumes/db:/var/lib/postgresql/data
That ./volumes
path works fine when you run docker compose up
in the same directory as the file. But inside Portainer? Portainer doesn’t have a clue what ./
means.
So you need to replace every ./volumes/...
with the absolute path to your supabase-project folder. For example, if your project lives at /home/user/supabase-project
, then you’d update it like so:
volumes:
- /home/user/supabase-project/volumes/db:/var/lib/postgresql/data
Do this for every service in the compose file. Yes, it’s tedious. Yes, you’ll hate it. But it’s the only way Portainer will stop throwing tantrums.
Spoiler alert: Hit CTRL+F in the Stack Editor and use Replace All.

You can thank me later...
Step 4: Deploy and Breathe
Once you’ve swapped out the volume paths, redeploy the stack in Portainer. Now, instead of seeing a wall of cryptic errors, you’ll see… containers turning green. One by one. Like traffic lights on your way home after a long day. It’s beautiful.
Lessons Learned
- Always follow the official guide first. It sets up the magic sauce.
- Don’t lose track of your supabase-project folder.
- In Portainer,
./volumes
means nothing. Always use full paths. - Don’t get distracted by “supabase-vector is unhealthy.” That’s a symptom, not the disease.
Self-hosting Supabase with Portainer is totally doable. Just remember: the logs will lie to you, the errors will mislead you, but the path — the path — is everything. Get the paths right, and suddenly the rabbit hole turns into a nice straight tunnel.
And on the other side? A shiny, self-hosted Supabase instance, running happily under Portainer, and — most importantly — you still have your hair.