Introduction
After contributing to Ghost, I wanted to push myself further by working on a larger and more complex backend system.
That curiosity led me to Zulip, an open-source team collaboration tool known for its topic-based threading and production-grade architecture.
Zulip is built with:
- Django
- Tornado
- PostgreSQL
- RabbitMQ
Setting up Zulip locally isn’t hard, but it’s very different from a typical Django project. I ran into a few unexpected issues, especially around Python virtual environments and WSL configuration.
In this post, I’ll walk through:
- How I set up Zulip locally on WSL2
- The issues I faced during setup
- How I fixed them, including the
activate_this.pyproblem
If you’re new to Zulip or moving into larger backend systems, this guide should help you avoid common setup blockers.
Who This Post Is For
This post is for:
- Developers contributing to Zulip for the first time
- Open-source contributors moving beyond small projects
- Anyone using WSL2 on Windows
- Developers stuck with Python 3.12 or
activate_this.pyerrors
Prerequisites
Before starting, make sure you have:
General
- 2GB+ RAM
- Stable internet connection
- GitHub account
Windows
- Windows 10/11 (64-bit)
- Virtualisation enabled (VT-x / AMD-V)
- Admin access
Git and GitHub Setup
If Git is already configured, you can skip this section.
Generate an SSH key:
ssh-keygen -t ed25519 -C "your_email@example.com"
Copy the public key:
cat ~/.ssh/id_ed25519.pub
Add it to GitHub → Settings → SSH and GPG Keys.
Setting Up WSL2 for Zulip
If you already use native Ubuntu or WSL2, feel free to skip ahead.
Enable Virtualisation
Make sure VT-x / AMD-V is enabled in BIOS.
Install WSL2
wsl --install
This installs Ubuntu automatically.
Enable systemd (Required)
Zulip relies on background services like PostgreSQL, Redis, and RabbitMQ.
Edit:
sudo nano /etc/wsl.conf
Add:
[boot]
systemd=true
Restart WSL:
wsl --shutdown
Install Required Services
Update your system:
sudo apt update && sudo apt upgrade
Install services:
sudo apt install rabbitmq-server memcached redis-server postgresql
RabbitMQ Configuration
sudo nano /etc/rabbitmq/rabbitmq-env.conf
Add:
NODE_IP_ADDRESS=127.0.0.1
NODE_PORT=5672
Cloning the Zulip Repository
Fork Zulip from GitHub, then clone your fork:
git clone --config pull.rebase git@github.com:YOURUSERNAME/zulip.git
cd zulip
git remote add -f upstream https://github.com/zulip/zulip.git
Running Zulip Locally
Install dependencies:
./tools/provision
Activate the virtual environment:
source .venv/bin/activate
Start the dev server:
./tools/run-dev
Visit:
http://localhost:9991
Common Issues I Faced (and How I Fixed Them)
Issue 1: Missing activate_this.py
Error
FileNotFoundError: No such file or directory ... activate_this.py
Why this happens
Zulip now uses uv, which doesn’t automatically create activate_this.py. Some scripts still expect it.
Fix
Manually create the file:
cat > .venv/bin/activate_this.py << 'EOF'
import os
import site
import sys
bin_dir = os.path.dirname(os.path.abspath(__file__))
os.environ["PATH"] = os.pathsep.join([bin_dir] + os.environ.get("PATH", "").split(os.pathsep))
base = os.path.dirname(bin_dir)
os.environ["VIRTUAL_ENV"] = base
site_packages = os.path.join(base, 'lib', 'python{}.{}'.format(*sys.version_info[:2]), 'site-packages')
prev = set(sys.path)
site.addsitedir(site_packages)
sys.real_prefix = sys.prefix
sys.prefix = base
new = list(sys.path)
sys.path[:] = [i for i in new if i not in prev] + [i for i in new if i in prev]
EOF
Issue 2: Django Not Found (Python 3.12)
Error
ModuleNotFoundError: No module named 'django'
Cause
Older scripts used:
sys.version[:3]
This breaks with Python 3.12.
Fix
Use:
'{}.{}'.format(*sys.version_info[:2])
Then rerun:
./tools/provision
What I Learned
Technical
- Modern Python tooling like
uvchanges old assumptions - Understanding virtual environments helps with debugging
- WSL2 + systemd setup is critical for backend services
Non-Technical
- Large codebases require patience
- Error messages usually point to the real issue
- Open-source communities are incredibly helpful
Final Thoughts
Moving from Ghost to Zulip has been a rewarding step in my open-source journey.
Zulip’s setup may feel overwhelming at first, but once the environment is running, contributing becomes much smoother. If you’re stuck on setup issues like activate_this.py, you’re definitely not alone.
I hope this post helps you get unblocked.
Useful Links
- Zulip GitHub: https://github.com/zulip/zulip
- Zulip Dev Docs: https://zulip.readthedocs.io/en/latest/development/overview.html
- Zulip Community Chat: https://chat.zulip.org
- WSL Docs: https://docs.microsoft.com/en-us/windows/wsl
- uv: https://github.com/astral-sh/uv
Top comments (2)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.