Complete guide for installing AVRDisco-Web as a systemd service on Raspberry Pi (Debian/Raspbian).
The systemd service needs to know:
- Your username (default:
pi) - Installation directory (default:
/home/pi/AVRDisco-Web)
Two ways to handle this:
✅ Recommended: Use ./install_service.sh - automatically detects your setup
📝 Manual: Edit avrdisco.service to match your username/path (see Step 7)
- Raspberry Pi (any model with network)
- Raspbian/Debian OS installed
- Network connection
- AV receiver on same network
# 1. Install system dependencies
sudo apt update
sudo apt install -y python3 python3-pip python3-venv git
# 2. Clone repository
cd ~
git clone https://github.com/lorton/AVRDisco-Web.git
cd AVRDisco-Web
# 3. Create virtual environment
python3 -m venv venv
source venv/bin/activate
# 4. Install dependencies (async version)
pip install -r requirements/async.txt
# 5. Configure your receiver
cp .env.example .env
nano .env # Edit with your receiver's IP address
# 6. Test it works
python async_app.py --debug
# Press Ctrl+C to stop after testing
# 7. Install as systemd service
sudo cp avrdisco.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable avrdisco
sudo systemctl start avrdisco
# 8. Check status
sudo systemctl status avrdiscoAccess at: http://[raspberry-pi-ip]:5000
sudo apt update
sudo apt install -y python3 python3-pip python3-venv gitcd /home/pi
git clone https://github.com/lorton/AVRDisco-Web.git
cd AVRDisco-Webpython3 -m venv venv
source venv/bin/activateYour prompt should now show (venv).
For Async Version (Recommended):
pip install -r requirements/async.txtFor Standard Version:
pip install -r requirements.txtIMPORTANT: When running as a systemd service with hypercorn, all configuration must be done via the .env file (environment variables). Command-line arguments are not used.
Create and edit the configuration file:
cp .env.example .env
nano .envEdit these values:
# Your AV receiver's IP address (REQUIRED)
AVR_HOST=192.168.1.100
# Your receiver's telnet port (60128 for Denon/Marantz, 23 for others)
AVR_PORT=60128
# Web server port - Note: This is set in the service file's hypercorn command
# The service uses --bind 0.0.0.0:5000 so PORT in .env is ignored
# Change the port in the service file if needed (see Troubleshooting section)
# PORT=5000
# Allowed CORS origins (use * for development, specific URLs for production)
CORS_ORIGINS=*
# Log level (DEBUG, INFO, WARNING, ERROR)
LOG_LEVEL=INFO
# Debug mode (true/false) - set to false for production
DEBUG=falseSave with Ctrl+X, then Y, then Enter.
Note: The web server port (5000) is configured in the systemd service file with hypercorn's --bind 0.0.0.0:5000. To change the port, edit the service file (see "Changing the Port" in Troubleshooting section).
# Activate virtual environment if not already active
source venv/bin/activate
# Test in debug mode (no receiver needed)
python async_app.py --debugOpen browser to http://[raspberry-pi-ip]:5000 and verify it loads.
Press Ctrl+C to stop.
You have two options: automated installation or manual setup.
Use the installation script which automatically detects your username and directory:
./install_service.shThe script will:
- Detect your username and installation directory
- Customize the service file automatically
- Install and enable the service
- Show you the access URL
If you need to install manually or customize further:
1. Edit the service file for your setup:
# Make a copy
cp avrdisco.service avrdisco.service.custom
# Edit the custom file
nano avrdisco.service.customUpdate these lines to match your setup:
# Change 'pi' to your username
User=yourusername
Group=yourusername
# Change '/home/pi/AVRDisco-Web' to your installation path
WorkingDirectory=/home/yourusername/AVRDisco-Web
Environment="PATH=/home/yourusername/AVRDisco-Web/venv/bin:/usr/local/bin:/usr/bin:/bin"
EnvironmentFile=-/home/yourusername/AVRDisco-Web/.env
ExecStart=/home/yourusername/AVRDisco-Web/venv/bin/hypercorn async_app:app --bind 0.0.0.0:5000 --workers 22. Install the customized service:
# Copy customized service file
sudo cp avrdisco.service.custom /etc/systemd/system/avrdisco.service
# Reload systemd
sudo systemctl daemon-reload
# Enable auto-start on boot
sudo systemctl enable avrdisco
# Start the service now
sudo systemctl start avrdiscoIf you installed in /opt instead of /home/pi:
# Example for /opt/AVRDisco-Web
User=yourusername
WorkingDirectory=/opt/AVRDisco-Web
Environment="PATH=/opt/AVRDisco-Web/venv/bin:/usr/local/bin:/usr/bin:/bin"
EnvironmentFile=-/opt/AVRDisco-Web/.env
ExecStart=/opt/AVRDisco-Web/venv/bin/hypercorn async_app:app --bind 0.0.0.0:5000 --workers 2If you're using a system user (no home directory):
# Example for dedicated avrdisco user
User=avrdisco
Group=avrdisco
WorkingDirectory=/var/lib/avrdisco
Environment="PATH=/var/lib/avrdisco/venv/bin:/usr/local/bin:/usr/bin:/bin"
EnvironmentFile=-/var/lib/avrdisco/.env
ExecStart=/var/lib/avrdisco/venv/bin/hypercorn async_app:app --bind 0.0.0.0:5000 --workers 2# Check service status
sudo systemctl status avrdisco
# Should show:
# ● avrdisco.service - AVRDisco Web Interface for AV Receiver Control
# Loaded: loaded (/etc/systemd/system/avrdisco.service; enabled)
# Active: active (running)# Start service
sudo systemctl start avrdisco
# Stop service
sudo systemctl stop avrdisco
# Restart service
sudo systemctl restart avrdisco
# Check status
sudo systemctl status avrdisco
# Enable auto-start on boot
sudo systemctl enable avrdisco
# Disable auto-start on boot
sudo systemctl disable avrdisco
# View logs (live)
sudo journalctl -u avrdisco -f
# View logs (last 100 lines)
sudo journalctl -u avrdisco -n 100
# View logs since boot
sudo journalctl -u avrdisco -bThe service is configured to automatically restart if it crashes:
- Restart Policy: Always restart
- Restart Delay: 10 seconds
- Max Retries: 3 attempts in 60 seconds
If the service fails 3 times in 60 seconds, it will stop trying. Check logs:
sudo journalctl -u avrdisco -n 50AVRDisco-Web supports multiple configuration methods:
1. Environment Variables (.env file) - ✅ Recommended for systemd service
# Edit .env file
AVR_HOST=192.168.1.100
AVR_PORT=60128
DEBUG=false2. Command-line Arguments - Only when running directly
# Works with: python async_app.py
python async_app.py --avr-host 192.168.1.100 --port 80803. Defaults - Built-in fallback values
Configuration is read from:
- ✅
.envfile (environment variables) - ✅ Service file
EnvironmentFiledirective - ❌ Command-line arguments are NOT used
Port configuration:
- Web server port is set in the service file:
--bind 0.0.0.0:5000 - To change port, edit the service file (not
.env)
Example .env for service:
AVR_HOST=192.168.1.100
AVR_PORT=60128
CORS_ORIGINS=*
LOG_LEVEL=INFO
DEBUG=falseConfiguration is read from:
- ✅ Command-line arguments (highest priority)
- ✅
.envfile (environment variables) - ✅ Defaults
Example:
# Use .env file
python async_app.py
# Override with command-line
python async_app.py --avr-host 192.168.1.50 --debug# 1. Stop the service
sudo systemctl stop avrdisco
# 2. Navigate to directory
cd /home/pi/AVRDisco-Web
# 3. Pull latest changes
git pull origin main
# 4. Activate virtual environment
source venv/bin/activate
# 5. Update dependencies
pip install --upgrade -r requirements/async.txt
# 6. Restart service
sudo systemctl start avrdisco
# 7. Check status
sudo systemctl status avrdiscoCheck service status:
sudo systemctl status avrdiscoCheck logs:
sudo journalctl -u avrdisco -n 50Common issues:
-
Wrong username or path in service file:
# Error: "Failed to determine user credentials" # or "Failed to execute command: No such file or directory" # Check what's in the service file grep -E 'User=|WorkingDirectory=|ExecStart=' /etc/systemd/system/avrdisco.service # If paths are wrong, reinstall with install_service.sh # OR manually edit: sudo nano /etc/systemd/system/avrdisco.service # Update User, Group, WorkingDirectory, and ExecStart paths # Then reload and restart sudo systemctl daemon-reload sudo systemctl restart avrdisco
-
Port already in use:
# Find what's using port 5000 sudo lsof -i :5000 # Kill the process or change PORT in .env
-
Virtual environment missing:
cd /home/pi/AVRDisco-Web # Or your installation directory python3 -m venv venv source venv/bin/activate pip install -r requirements/async.txt
-
Permissions error:
# Fix ownership (replace 'pi' with your username and path with your installation) sudo chown -R pi:pi /home/pi/AVRDisco-Web # If you installed in /opt or another location: sudo chown -R yourusername:yourusername /your/installation/path
-
Python module not found:
source venv/bin/activate pip install -r requirements/async.txt sudo systemctl restart avrdisco -
User doesn't exist:
# If service file references wrong user # Check current user: whoami # Edit service file with correct username: sudo nano /etc/systemd/system/avrdisco.service # Change User= and Group= lines sudo systemctl daemon-reload sudo systemctl restart avrdisco
The default web server port is 5000. To use a different port:
Edit the service file:
sudo nano /etc/systemd/system/avrdisco.serviceFind and change the --bind argument:
# Change from:
ExecStart=/path/to/venv/bin/hypercorn async_app:app --bind 0.0.0.0:5000 --workers 2
# To (for example, port 8080):
ExecStart=/path/to/venv/bin/hypercorn async_app:app --bind 0.0.0.0:8080 --workers 2Reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart avrdiscoNote: The PORT variable in .env is not used when running with hypercorn. The port is set in the hypercorn command with --bind 0.0.0.0:PORT.
Test telnet connection manually:
telnet 192.168.1.100 60128
# Should connect. Press Ctrl+] then type 'quit' to exitCheck receiver settings:
- Network control enabled in receiver settings
- Correct IP address in
.env - Correct port (60128 for Denon/Marantz, 23 for standard telnet)
- Receiver and Pi on same network
Check service is running:
sudo systemctl status avrdiscoTest locally on Pi:
curl http://localhost:5000Check firewall:
# If using ufw
sudo ufw allow 5000/tcp
sudo ufw reloadFind Pi's IP address:
hostname -ISet a static IP for your Raspberry Pi:
sudo nano /etc/dhcpcd.confAdd at the end:
interface eth0
static ip_address=192.168.1.50/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1 8.8.8.8
# Or for WiFi:
interface wlan0
static ip_address=192.168.1.50/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1 8.8.8.8
Reboot:
sudo rebootOnce running, access from any device on your network:
- Computer:
http://192.168.1.50:5000 - Phone:
http://192.168.1.50:5000 - Tablet:
http://192.168.1.50:5000
Bookmark it on your phone for quick access!
Use fewer workers:
sudo nano /etc/systemd/system/avrdisco.serviceChange:
ExecStart=/home/pi/AVRDisco-Web/venv/bin/hypercorn async_app:app --bind 0.0.0.0:5000 --workers 1
Can use more workers:
ExecStart=/home/pi/AVRDisco-Web/venv/bin/hypercorn async_app:app --bind 0.0.0.0:5000 --workers 4
After changes:
sudo systemctl daemon-reload
sudo systemctl restart avrdiscoFor secure access with Let's Encrypt:
# Install certbot
sudo apt install certbot
# Get certificate (requires domain name)
sudo certbot certonly --standalone -d avr.yourdomain.com
# Update service file
sudo nano /etc/systemd/system/avrdisco.serviceChange ExecStart to:
ExecStart=/home/pi/AVRDisco-Web/venv/bin/hypercorn async_app:app \
--bind 0.0.0.0:443 \
--certfile /etc/letsencrypt/live/avr.yourdomain.com/fullchain.pem \
--keyfile /etc/letsencrypt/live/avr.yourdomain.com/privkey.pem
Note: Requires port forwarding and domain name. Most home users won't need this.
Only start service when connected to home WiFi:
sudo nano /etc/systemd/system/avrdisco.serviceAdd under [Unit]:
ConditionPathExists=/sys/class/net/wlan0/operstate
# CPU and memory usage
htop
# Just the AVRDisco process
ps aux | grep hypercornLogs are automatically rotated by systemd. Configure retention:
sudo nano /etc/systemd/journald.confSet:
SystemMaxUse=100M
Restart journald:
sudo systemctl restart systemd-journald# Stop and disable service
sudo systemctl stop avrdisco
sudo systemctl disable avrdisco
# Remove service file
sudo rm /etc/systemd/system/avrdisco.service
sudo systemctl daemon-reload
# Remove application (optional)
rm -rf /home/pi/AVRDisco-Web- Bookmark on Phone: Add to home screen for app-like experience
- Use Static IP: Prevents IP address from changing
- Monitor Logs: Check occasionally for errors
- Keep Updated: Pull latest improvements from GitHub
- Backup .env: Save your configuration before updates
- GitHub Issues: https://github.com/lorton/AVRDisco-Web/issues
- Documentation: See README.md and other docs in repository
- Logs:
sudo journalctl -u avrdisco -f
# Service commands
sudo systemctl {start|stop|restart|status} avrdisco
# View logs
sudo journalctl -u avrdisco -f
# Update app
cd /home/pi/AVRDisco-Web && git pull && sudo systemctl restart avrdisco
# Find IP
hostname -I
# Test connection
curl http://localhost:5000Default (user: pi, home directory):
User=pi
WorkingDirectory=/home/pi/AVRDisco-Web
ExecStart=/home/pi/AVRDisco-Web/venv/bin/hypercorn async_app:app ...Different username (e.g., john):
User=john
WorkingDirectory=/home/john/AVRDisco-Web
ExecStart=/home/john/AVRDisco-Web/venv/bin/hypercorn async_app:app ...System-wide installation (/opt):
User=youruser
WorkingDirectory=/opt/AVRDisco-Web
ExecStart=/opt/AVRDisco-Web/venv/bin/hypercorn async_app:app ...Dedicated user (no login):
User=avrdisco
Group=avrdisco
WorkingDirectory=/var/lib/avrdisco
ExecStart=/var/lib/avrdisco/venv/bin/hypercorn async_app:app ...# Check what user/path is configured
grep -E 'User=|WorkingDirectory=|ExecStart=' /etc/systemd/system/avrdisco.service
# Check if user exists
id USERNAME
# Check if directory exists
ls -la /path/to/AVRDisco-Web
# Check virtual environment
ls /path/to/AVRDisco-Web/venv/bin/hypercornEnjoy your automated AV receiver control! 🎵