Pterodactyl
Run the store on the same game panel as your Minecraft servers.
If you already rent a Pterodactyl panel, this costs you nothing extra and there is no new infrastructure to learn.
Assumed: you can create a server on the panel, you have SFTP access, and you have already seeded your Supabase project.
Pterodactyl gives you a random high port such as 25571, and most panels do not
provide HTTPS. Read Getting a proper domain at the bottom
before you start — it decides what you put in NEXT_PUBLIC_SITE_URL.
1. Create the server
Use a Node.js egg
Create a new server using the Node.js (sometimes "NodeJS Generic") egg. If your panel offers a version choice, pick Node.js 24. Older images will not run this theme.
Give it resources
| Setting | Minimum | Comfortable |
|---|---|---|
| Memory | 1024 MB | 2048 MB |
| Disk | 3072 MB | 5120 MB |
| CPU | 100% | 200% |
The memory is for the build. Once built, the site runs happily in about 512 MB — you can lower the limit afterwards.
Note your allocation
The panel shows something like 123.45.67.89:25571. You need both parts.
2. Upload the theme
Connect over SFTP
Use FileZilla or WinSCP with the SFTP details from the panel's Settings tab. The password is your panel password.
Upload the project
Upload the theme's files into /home/container so that package.json sits directly
in that folder — not inside a subfolder.
Do not upload node_modules or .next. They are large and get created on the
server.
Upload your .env.local
Create the file on your own computer, then upload it to /home/container/.env.local:
TEBEX_TOKEN=your_headless_store_token
SERVER_SECRET=your_game_server_secret
NEXT_PUBLIC_SITE_URL=http://123.45.67.89:25571
PAYLOAD_SECRET=paste_64_random_hex_characters
DATABASE_URI=postgresql://postgres.yourref:yourpassword@aws-0-region.pooler.supabase.com:5432/postgres
SUPABASE_URL=https://yourref.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_service_role_keyUse your real IP and port. If you are setting up a domain, use that instead.
Some SFTP clients hide files that start with a dot. Turn on "show hidden files" so
you can see .env.local after uploading it.
3. Install and build
Pterodactyl's console only talks to the running program — you cannot type shell commands into it. So you make the build be the program, once.
Set the startup command to the build
Startup tab → Startup Command:
npm install && npm run buildSome eggs lock this field. If yours does, ask your host to unlock it.
Start the server and watch
Press Start. It takes three to eight minutes, mostly the build. When it prints the build summary and stops by itself, that stage is done.
No seeding here. Seeding is a one-off against Supabase, not per-server — do it from your own computer (Install and seed). Nothing needs uploading afterwards; the content is already in your Supabase project.
That also means Bun is not needed on the panel at all.
4. Switch to the run command
Change the startup command
Startup tab → Startup Command:
node node_modules/next/dist/bin/next start -p {{SERVER_PORT}} -H 0.0.0.0-H 0.0.0.0 is required. Without it the site only listens inside the container and
the panel's port forwarding cannot reach it.
Start it
Press Start. Within a few seconds the console shows:
▲ Next.js 16.2.1
- Local: http://localhost:25571
✓ Ready in 398msYou will also see "next start" does not work with "output: standalone" configuration. Ignore it — a suggestion, not an error. The site serves correctly.
Open the site
Visit http://YOUR_IP:YOUR_PORT. Your store should be there.
The admin panel is at /admin. Log in with your seeded credentials and change the
password immediately.
Getting a proper domain
Running a shop on http://123.45.67.89:25571 is bad for trust and bad for SEO.
Three ways to fix it, best first.
Whichever you pick, NEXT_PUBLIC_SITE_URL must end up matching exactly what visitors
type — including https:// and any port. Restart after changing it.