Vagrant Development¶
Use Pyreload in Vagrant virtual machines for consistent development environments.
Why Pyreload with Vagrant?¶
Vagrant provides:
- Consistent development environments
- Isolated system dependencies
- Team-wide reproducibility
Pyreload enhances Vagrant workflows by:
- Auto-restarting applications on file changes
- Watching files across host/guest boundaries
- Enabling rapid development iteration
Setup¶
Install Pyreload in Guest¶
Add to your Vagrantfile provisioning:
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.network "forwarded_port", guest: 8000, host: 8000
config.vm.synced_folder ".", "/vagrant"
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y python3 python3-pip
pip3 install pyreload
SHELL
end
Alternative: Install in Project¶
config.vm.provision "shell", inline: <<-SHELL
cd /vagrant
pip3 install -e .
pip3 install pyreload
SHELL
File Watching with Synced Folders¶
Use Polling Mode¶
Native file watching doesn't work well across synced folders. Use polling:
# .pyreload.yml
polling: true
poll_interval: 1.0
watch:
- /vagrant/src
- /vagrant/config
ignore:
- "**/__pycache__/**"
- ".vagrant/**"
Start Pyreload¶
Example: Flask Application¶
Project Structure¶
myproject/
├── Vagrantfile
├── .pyreload.yml
├── app.py
├── requirements.txt
└── templates/
└── index.html
Vagrantfile¶
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
# Forward Flask port
config.vm.network "forwarded_port", guest: 5000, host: 5000
# Mount project directory
config.vm.synced_folder ".", "/vagrant",
type: "virtualbox",
owner: "vagrant",
group: "vagrant"
# Provision
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y python3 python3-pip
pip3 install -r /vagrant/requirements.txt
pip3 install pyreload
SHELL
# Auto-start application
config.vm.provision "shell", run: "always", inline: <<-SHELL
cd /vagrant
nohup pyreload --polling app.py > /vagrant/pyreload.log 2>&1 &
SHELL
end
.pyreload.yml¶
polling: true
poll_interval: 1.0
watch:
- /vagrant
extensions:
- py
- html
- css
ignore:
- ".vagrant/**"
- "**/__pycache__/**"
- "**/*.pyc"
clean: true
Start Development¶
# Start VM
vagrant up
# SSH into VM
vagrant ssh
# Start Pyreload (if not auto-started)
cd /vagrant
pyreload app.py
# Edit files on host, see changes in VM
Example: Django Project¶
Vagrantfile¶
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.network "forwarded_port", guest: 8000, host: 8000
config.vm.synced_folder ".", "/vagrant"
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y python3-pip postgresql
pip3 install Django pyreload psycopg2-binary
SHELL
end
.pyreload.yml¶
polling: true
poll_interval: 1.5
watch:
- /vagrant/mysite
- /vagrant/templates
- /vagrant/static
extensions:
- py
- html
- css
- js
ignore:
- ".vagrant/**"
- "staticfiles/**"
- "**/__pycache__/**"
Run Django¶
Performance Optimization¶
Reduce Synced Folder Overhead¶
Use NFS for better performance:
Adjust Poll Interval¶
Balance responsiveness vs. CPU usage:
# Fast (more CPU)
poll_interval: 0.5
# Normal
poll_interval: 1.0
# Slow (less CPU)
poll_interval: 2.0
Exclude Large Directories¶
Multi-VM Setup¶
Vagrantfile¶
Vagrant.configure("2") do |config|
# API Server
config.vm.define "api" do |api|
api.vm.box = "ubuntu/focal64"
api.vm.network "forwarded_port", guest: 5000, host: 5000
api.vm.network "private_network", ip: "192.168.50.4"
api.vm.synced_folder "./api", "/vagrant"
api.vm.provision "shell", inline: <<-SHELL
pip3 install pyreload flask
SHELL
end
# Worker
config.vm.define "worker" do |worker|
worker.vm.box = "ubuntu/focal64"
worker.vm.network "private_network", ip: "192.168.50.5"
worker.vm.synced_folder "./worker", "/vagrant"
worker.vm.provision "shell", inline: <<-SHELL
pip3 install pyreload celery
SHELL
end
end
Start Services¶
# Terminal 1: API server
vagrant ssh api
cd /vagrant
pyreload --polling app.py
# Terminal 2: Worker
vagrant ssh worker
cd /vagrant
pyreload --polling worker.py
Troubleshooting¶
File Changes Not Detected¶
Use polling mode:
High CPU Usage¶
Increase poll interval:
Permission Errors¶
Fix synced folder permissions:
Slow Syncing¶
Use NFS or rsync:
Best Practices¶
- Always use polling: Native watching doesn't work with synced folders
- Optimize poll interval: Balance speed and CPU usage
- Exclude unnecessary files: Ignore build artifacts and dependencies
- Use NFS: Faster than VirtualBox shared folders
- Forward ports: Make services accessible from host
Complete Example¶
Directory Structure¶
myproject/
├── Vagrantfile
├── .pyreload.yml
├── requirements.txt
├── src/
│ ├── app.py
│ └── config.py
└── tests/
└── test_app.py
Vagrantfile¶
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.network "forwarded_port", guest: 8000, host: 8000
config.vm.synced_folder ".", "/vagrant", type: "nfs"
config.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
vb.cpus = 2
end
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y python3-pip
pip3 install -r /vagrant/requirements.txt
pip3 install pyreload
SHELL
end
.pyreload.yml¶
polling: true
poll_interval: 1.0
watch:
- /vagrant/src
- /vagrant/config
extensions:
- py
- yaml
ignore:
- ".vagrant/**"
- "tests/**"
- "**/__pycache__/**"
clean: true
verbose: false
Workflow¶
# Start VM
vagrant up
# SSH and start development
vagrant ssh
cd /vagrant
pyreload src/app.py
# Edit files on host machine
# See changes automatically reflected in VM