How-to quickly setup an ephemeral "Self-Hosted" PostHog instance to test API client implementations against
I was writing an application that connected to customer PostHog accounts via the PostHog API and wanted to make sure it still worked for self-hosted PostHog users. But it's pretty hard to find any of those, much less ones where I can ask for an API key with Query permission, so I needed to host it myself.
Now I didn't actually want to go and setup any VPS to run this on. I use serverless platforms like Vercel and Convex for the things I write so I don't have access to any VPS-like environment that would be easy to run a series of Docker containers in without much work. So the natural thing I wanted to reach to was a Devcontainer and a temporary localhost tunnel. No paying for a temporary VPS, Docker just runs on my machine. It all lives inside of a devcontainer so it doesn't polute my local environment, I can easily interact with it through VSCode inspecting all the logs and containers, and it can be easily deleted.
How to do this wasn't immediately obvious. An undocumented set of ports need to be exposed to the internet and the self-host docs are aimed at those hosting this on something like a VPS where you can expose every port and I do not need the complex setup documented in the developing locally docs. So here are the steps that worked after experimentation.
Start up a new Devcontainer in VSCode
- "New Dev Container" option from the Open a Remote Window menu in the bottom left corner of VSCode
- Choose the "Docker in Docker"
- Give it a name, e.g. "posthog-selfhost-test"
Once it's running open a new terminal within VSCode and continue.
# Add cloudflare gpg key
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
# Stable: Add this repo to your apt repositories
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main' | sudo tee /etc/apt/sources.list.d/cloudflared.list
# install cloudflared
sudo apt-get update && sudo apt-get install cloudflaredDownload the Beta hobby installer mentioned in the Self-host PostHog documentation.
curl -OfsSL https://github.com/PostHog/posthog/releases/download/hobby-latest/hobby-installer
chmod +x hobby-installerOpen a second terminal in VSCode and start the following command:
cloudflared tunnel --url http://localhost:80Copy the .trycloudflare.com domain that is printed out after the "Your quick Tunnel has been created!" log line.
Return to the first terminal and run:
sudo ./hobby-installerThe installer will ask you a series of questions:
- Enter (to start installation)
- Enter (select the recommended default option of "latest")
- Paste in the .trycloudflare.com domain that you coppied in 6. then hit enter
- Wait... a long time.
- Seriously, wait a long time. It will take awhile for the installer to clone the PostHog repository, update the files, download a pile of Docker container images, and startup a bunch of containers it depends on.
- If you are bored run
sudo docker compose logs -fand watch as the logs stream past. If you're extra impatient you can also runwatch -n30 curl -iL http://localhost. You can even drag terminals into the editor area and watch all 3 commands at the same time.
- It took so long I eventually restarted the
sudo ./hobby-installercommand. - Eventually you'll stop getting 502 errors and can continue.

Now you can finally open the .trycloudflare.com domain that you coppied in your browser.
Go through the sign up wizard and you'll have a self-hosted PostHog instance with a project you can experiment against.
Now let me just go and delete the one I created so you can't see it.