Zoom calls that cut off at 40 minutes, a "you've reached your meeting limit" banner, or a company deciding your video data belongs on someone else's servers — any of those is reason enough to look for an alternative. Jitsi Meet is a solid one, and if you're already running Proxmox VE, you have everything you need to host it yourself.

This guide walks you through installing Jitsi Meet inside a Linux container (LXC) on Proxmox VE, using Docker to run the actual Jitsi services. By the end you'll have a working video call room reachable from your home network, with a clear path to opening it up to the outside world if you want that later.

What You Will Learn

Here's what this tutorial covers, in order:

  • What Jitsi Meet actually is and which pieces make it up
  • Why you'd want to self-host video calls instead of using a hosted service
  • What your Proxmox host needs before you start
  • How to build a Debian LXC container that can run Docker properly
  • How to deploy the official Jitsi Docker stack inside that container
  • What each command and setting actually does
  • The errors people run into most often, and how to fix them
  • A few habits that will save you a support call to yourself at 11pm

What Is This Feature?

Jitsi Meet is a free, open-source video conferencing platform. You can try the public version at meet.jit.si without creating an account, but the software behind it is exactly what you're going to install on your own container — same code, just running on hardware you control.

Under the hood, Jitsi Meet isn't one program. It's four services working together:

ComponentWhat it does
webServes the browser interface — the page you actually see and click around in
prosodyAn XMPP server that handles signaling: who's in the room, who's talking, chat messages
jicofoThe Jitsi Conference Focus. It manages call sessions and tells the video bridge who needs what stream
jvbThe Jitsi Videobridge — the component that actually routes audio and video between participants

You don't need to memorize that table before moving on. It matters later, when you're staring at logs trying to figure out which container is unhappy.

The official way to run all four together is Docker Compose, using the jitsi/docker-jitsi-meet project. That's the method this guide uses, because it's the one the Jitsi maintainers actually support and update.

Why Would You Use It?

A few reasons come up constantly in homelab and small-business circles:

Hosted video platforms cap free tiers hard. Google Meet, Zoom, and Microsoft Teams all put limits on call length or participant count unless you pay. If you just want a private room for your family, a study group, or a small team, those limits get annoying fast.

Privacy is the other big one. Your calls, your metadata, your recordings — all of it stays on hardware you own. Nobody's business model depends on knowing who you talked to and for how long.

And honestly, it's satisfying to click a link, watch your friends join a call running on a mini PC in your closet, and have it just work. That's most of what draws people to self-hosting in the first place.

I'll be upfront about the tradeoff though: video calls are one of the more resource-hungry things you can self-host. A two-person call on your LAN is trivial. A ten-person call with everyone's camera on, especially if some of them are outside your network, will actually tax a small server. Set your expectations accordingly — this isn't a drop-in Zoom replacement for a 50-person webinar.

Prerequisites

Before you start, make sure you have:

  • Proxmox VE 8.x or 9.x, already installed and reachable through the web UI
  • A Debian 12 (Bookworm) LXC template downloaded on your Proxmox host
  • At least 4 vCPU cores and 4 GB of RAM you can dedicate to the container — Jitsi is fine with less for a two-person call, but give it room to breathe
  • 20 GB or more of free storage for the container
  • Basic comfort with the Linux command line — you'll be typing commands inside the container's console
  • A rough idea of whether this will stay on your local network or get exposed to the internet later, since that changes a couple of settings

None of this requires a cluster or fancy shared storage. A single Proxmox node with local ZFS or LVM-thin storage is plenty.

Step-by-Step Tutorial

Step 1: Download the Debian 12 template

In the Proxmox web UI, click your storage (commonly local) in the left tree, then open CT Templates. Click Templates, find debian-12-standard in the list, and download it. This is the base image your container will be built from.

Step 2: Create the LXC container

Click Create CT at the top of the Proxmox UI. Work through the wizard with these settings:

  • Hostname: something like jitsi
  • Template: the debian-12-standard image you just downloaded
  • Disk size: 20 GB minimum
  • CPU cores: 4
  • Memory: 4096 MB (bump to 8192 if you plan on calls with more than a handful of people)
  • Network: a bridge like vmbr0, with either DHCP or a static IP — a static IP is worth setting here since you'll be typing this address a lot

Leave the container as unprivileged unless you have a specific reason not to. It's the safer default, and Docker will run fine in it once you flip one setting in the next step.

Step 3: Enable nesting so Docker can run inside the container

Docker needs to create its own network namespaces and cgroups, and an unprivileged LXC container blocks that by default. You need to turn on nesting before Docker will start cleanly.

Don't start the container yet. Instead, open a shell on the Proxmox host itself and run:

pct set 200 --features nesting=1,keyctl=1

Replace 200 with your container's actual ID — you'll see it next to the container name in the Proxmox UI. If you'd rather use the GUI, select the container, go to OptionsFeatures, and tick both Nesting and Keyctl there instead.

Step 4: Start the container and install Docker

Start the container and open its console (either through the Proxmox UI or pct enter 200 from the host shell). Update the package list first:

apt update && apt full-upgrade -y

Then install Docker using the official convenience script — it's the fastest reliable way to get a current Docker release on Debian:

curl -fsSL https://get.docker.com | sh

This installs Docker Engine along with the Compose plugin, so you get the docker compose command for free. Confirm it worked:

docker --version
docker compose version

If both print a version number instead of an error, you're set.

Step 5: Download the Jitsi Docker configuration

Install git if it isn't already there, then clone the official repository:

apt install -y git
git clone https://github.com/jitsi/docker-jitsi-meet.git
cd docker-jitsi-meet

Copy the example environment file — this is where all your settings live:

cp env.example .env

Step 6: Generate secure passwords

The stack needs several internal passwords (for the XMPP components to talk to each other securely). Jitsi ships a script that generates them for you:

./gen-passwords.sh

Run this exactly once, before you first bring the stack up. Running it again later will overwrite passwords that existing containers depend on, and you'll end up locking Prosody and Jicofo out of each other. If that happens, the fix is a full docker compose down, delete the stored config volumes, and start over — annoying, but not dangerous to anything outside the container.

Step 7: Set your public URL

Open .env in a text editor:

nano .env

Find the line starting with PUBLIC_URL= and set it to how you'll actually reach the container. For LAN-only use, that's usually the container's IP address or hostname:

PUBLIC_URL=https://192.168.1.50

If you have a domain pointed at this container and plan to expose it externally later, use that domain instead. Save and exit (Ctrl+O, then Ctrl+X in nano).

Step 8: Bring the stack up

docker compose up -d

The first run pulls several images, so give it a few minutes on a typical home connection. Check that everything is running:

docker compose ps

You should see four containers — web, prosody, jicofo, and jvb — all showing as Up.

Step 9: Open a call

From any device on your network, open a browser and go to the address you set as PUBLIC_URL. Your browser will warn you about a self-signed certificate the first time — that's expected, since you haven't set up a real TLS certificate yet. Accept the warning, type in a room name, and click join. If your microphone and camera prompts show up and the room loads, it's working.

Commands Explained

A quick reference for what you actually typed above:

  • pct set 200 --features nesting=1,keyctl=1 — changes the container's LXC feature flags. Nesting lets the container manage its own namespaces (required for Docker); keyctl allows kernel keyring operations some container runtimes rely on.
  • curl -fsSL https://get.docker.com | sh — downloads and runs Docker's official install script, which detects your distro and sets up the correct package repository automatically.
  • docker compose up -d — reads docker-compose.yml and starts every service it defines, in the background (-d for detached).
  • docker compose ps — lists the containers Compose is managing in the current directory, along with their status.
  • docker compose logs -f jvb — streams live logs from a single service, useful when one component is misbehaving and you need to watch it in real time.

Common Errors

A handful of problems account for almost every Jitsi-on-LXC support thread you'll find.

Docker daemon fails to start, or containers immediately exit. This is almost always the nesting feature. If you skipped Step 3 or set the flag after the container was already running, stop and restart the container from the Proxmox UI so the new features actually apply.

"Waiting for the moderator" message that never goes away. This usually means Jicofo can't reach Prosody, often because .env was edited after gen-passwords.sh ran, or the stack was started before the passwords were generated at all. Tear it down with docker compose down, confirm your .env values are intact, and bring it back up.

Audio and video connect fine on your LAN but fail between two people on different networks. That's a NAT traversal problem with the video bridge, not a bug. JVB needs UDP port 10000 reachable from the outside for real-time media. If you're testing across the internet, forward UDP 10000 on your router to the container's IP, and set JVB_ADVERTISE_IPS in .env to your public IP address.

Browser refuses to load the page at all. Double-check the container actually got an IP address (ip a inside the container) and that nothing else on your network is using the same address. A duplicate IP will make the page seem to hang forever with no useful error.

Troubleshooting

When something's off and it's not one of the errors above, work through this order:

Start with docker compose ps. Any container not showing Up is your starting point — check its logs specifically rather than guessing:

docker compose logs -f prosody

If everything shows as running but calls still fail to connect, check disk space next. Prosody's logs and JVB's session data can quietly fill a small disk over weeks of use:

df -h

A container stuck at 100% disk usage will behave strangely in ways that don't obviously point back to storage — services silently failing to write config, restart loops, that sort of thing.

If you changed anything in .env, remember that Docker Compose doesn't pick up environment file changes automatically for running containers. You have to recreate them:

docker compose down
docker compose up -d

And if you're truly stuck, a clean restart of the whole container from Proxmox (not just the Docker stack) rules out anything weird at the LXC level before you keep debugging inside it.

Best Practices

A few habits worth building in from day one:

Take a Proxmox backup of the container before you touch .env or upgrade the Docker images. A vzdump snapshot takes a few minutes and turns a bad config change into a two-click rollback instead of a rebuild.

Don't expose port 443 to the internet without setting a real domain and TLS certificate, and think about authentication before you do. Out of the box, anyone who knows or guesses your room name can join. For anything beyond casual family use, look at Jitsi's built-in JWT authentication or at minimum keep it LAN-only or behind a VPN like Tailscale or WireGuard.

Pin your Docker image versions once you have a setup you're happy with, rather than always pulling latest. Jitsi updates fairly often, and an unplanned image change right before an important call is not a fun surprise.

Give the container real resources and don't oversubscribe your host. Video bridging is CPU-heavy, especially with several participants and screen sharing running at once. If your Proxmox node is already tight on cores, this is not the container to squeeze into leftover capacity.

Frequently Asked Questions

Is Jitsi Meet actually free?
Yes. It's open source under the Apache 2.0 license, and self-hosting it costs you nothing beyond your own hardware and bandwidth.

How many people can my homelab handle on a call?
For a modest setup like the one in this guide, two to eight participants with cameras on is realistic. Beyond that you'll want more CPU cores dedicated to the container, and possibly a separate TURN server for anyone behind restrictive NAT.

Do I need a domain name?
Not for local network use — an IP address works fine. You'll want a real domain if you plan to get a proper Let's Encrypt certificate and access Jitsi from outside your home.

Can I run this in a full VM instead of an LXC container?
Yes, and some people prefer it for the extra isolation. The container route just uses less RAM and disk for the same result, which is why it's the more common choice for a homelab.

Why does the browser warn me about the certificate?
Because Jitsi generates a self-signed certificate by default. It's not a sign of anything broken — it just means the browser can't verify the certificate against a trusted authority. Set up Let's Encrypt or a reverse proxy with a valid cert once you're ready to move past testing.

Does Jitsi record calls?
It can, through an optional Jibri component, but Jibri isn't part of this basic setup — it needs its own container and considerably more resources. Treat it as a follow-up project once the core stack is stable.

Conclusion

You've now got a working Jitsi Meet stack running in its own LXC container, isolated from the rest of your Proxmox host and easy to snapshot or roll back if you break something later. That's the real advantage of doing this on Proxmox instead of bare metal — the blast radius of any mistake is one container you can delete and rebuild in ten minutes.

From here, the natural next steps are a proper TLS certificate if you want to use this outside your LAN, and maybe a look at authentication if you're going to share the link more widely than your immediate household. Either way, you've got a private video calling setup that answers to nobody but you.