home / selfhost / install / systemd
Installation via Systemd¶
Install Tux directly on your system without Docker. This guide covers both quick start for development and production deployment with systemd.
Quick Start (Development)¶
For quick testing or development, you can run Tux directly:
# Clone repository
git clone https://github.com/allthingslinux/tux.git
cd tux
# Install dependencies
uv sync
# Generate configuration files
uv run config generate
# Copy and edit .env
cp .env.example .env
nano .env
# Run migrations
uv run db push
# Start bot
uv run tux start
For production deployment, continue with the systemd setup below.
Production Deployment with Systemd¶
Prerequisites¶
Before deploying with systemd, ensure you have:
- Linux system with systemd (most modern distributions)
- Python 3.13+ installed
- uv package manager installed
- PostgreSQL 13+ database running
- Discord bot token from Discord Developer Portal
- Root or sudo access for systemd service creation
Installation Steps¶
1. Create System User¶
Create a dedicated user for running Tux (recommended for security):
sudo useradd -r tux
2. Clone Repository to /opt/tux¶
Clone the Tux repository directly to the installation directory:
# Clone repository as tux user
sudo -u tux git clone https://github.com/allthingslinux/tux.git /opt/tux
# Set ownership (ensure tux user owns everything)
sudo chown -R tux:tux /opt/tux
# Set appropriate permissions
sudo chmod 755 /opt/tux
3. Install Dependencies¶
Install Tux dependencies using uv:
# Switch to tux user and install dependencies
sudo -u tux bash -c "cd /opt/tux && uv sync"
# Generate configuration files
sudo -u tux bash -c "cd /opt/tux && uv run config generate"
# Create and protect .env file
sudo -u tux cp /opt/tux/.env.example /opt/tux/.env
sudo chmod 600 /opt/tux/.env
sudo chown tux:tux /opt/tux/.env
4. Configure Environment¶
Edit the .env file and setup necessary environment variables:
# Create or edit .env file
sudo -u tux nano /opt/tux/.env
Alternative: Systemd Environment File
You can also use a separate systemd environment file at /etc/tux/environment if you prefer to separate system-level configuration from application configuration. If using this approach, add EnvironmentFile=/etc/tux/environment to the systemd service file.
5. Configure Database¶
Ensure PostgreSQL is configured and accessible:
# Create database user (if not exists)
sudo -u postgres createuser -P tux_user
# Create database
sudo -u postgres createdb -O tux_user tux
# Run migrations
cd /opt/tux
sudo -u tux uv run db push
6. Find uv Installation Path¶
Before creating the service file, find where uv is installed:
# Find uv executable
which uv
# Common locations:
# - /usr/local/bin/uv (standalone installer)
# - /usr/bin/uv (package manager)
# - ~/.cargo/bin/uv (cargo installation)
# - ~/.local/bin/uv (pip --user)
If uv is not in a system path, you can either:
- Create a symlink (recommended):
sudo ln -s $(which uv) /usr/local/bin/uv
- Use full path in the service file (replace
/usr/local/bin/uvwith your path)
7. Create Systemd Service File¶
Create the systemd service unit:
sudo nano /etc/systemd/system/tux.service
Use this configuration (adjust the uv path if needed):
[Unit]
Description=Tux Discord Bot
Documentation=https://tux.atl.dev
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
Type=simple
User=tux
Group=tux
WorkingDirectory=/opt/tux
ExecStart=/usr/local/bin/uv run tux start
Restart=always
RestartSec=10
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=tux
[Install]
WantedBy=multi-user.target
8. Enable and Start Service¶
# Reload systemd to recognize new service
sudo systemctl daemon-reload
# Enable service to start on boot
sudo systemctl enable tux
# Start the service
sudo systemctl start tux
# Check status
sudo systemctl status tux
Configuration Updates¶
Updating Environment Variables¶
# Edit .env file
sudo -u tux nano /opt/tux/.env
# Reload service to apply changes
sudo systemctl daemon-reload
sudo systemctl restart tux
Updating Tux Code¶
# Stop service
sudo systemctl stop tux
# Backup current installation
sudo cp -r /opt/tux /opt/tux.backup.$(date +%Y%m%d)
# Update code
cd /opt/tux
sudo -u tux git pull origin main
# Update dependencies
sudo -u tux uv sync
# Run database migrations
sudo -u tux uv run db push
# Start service
sudo systemctl start tux
# Verify status
sudo systemctl status tux
Troubleshooting¶
Service Won't Start¶
Check service status:
sudo systemctl status tux
Common issues:
- Permission errors:
# Check file ownership
ls -la /opt/tux
sudo chown -R tux:tux /opt/tux
- Missing dependencies:
# Verify uv is installed
which uv
# Check Python version
python3 --version
- Database connection issues:
# Test database connection
sudo -u tux uv run db health
# Check PostgreSQL is running
sudo systemctl status postgresql
- Invalid bot token:
# Check .env file
sudo cat /opt/tux/.env | grep BOT_TOKEN
Service Crashes Repeatedly¶
Check logs for errors:
sudo journalctl -u tux -n 100 --no-pager
Common causes:
- Invalid configuration
- Database connection failures
- Missing environment variables
- Permission issues
- Resource exhaustion
Check restart count:
systemctl show tux | grep NRestarts
Logs Not Appearing¶
Verify logging configuration:
# Check journald is working
sudo journalctl -u tux -n 10
# Check service output
sudo systemctl status tux
# Verify log directory permissions
ls -la /var/log/tux
Permission Denied Errors¶
Fix ownership:
sudo chown -R tux:tux /opt/tux
sudo chown tux:tux /var/log/tux
Check service user:
# Verify service runs as correct user
systemctl show tux | grep User
Database Connection Issues¶
Test connection manually:
# As tux user
sudo -u tux bash -c "cd /opt/tux && uv run db health"
# Check PostgreSQL is accessible
sudo -u postgres psql -c "SELECT version();"
Verify environment:
# Check DATABASE_URL or POSTGRES_* variables are set
sudo cat /opt/tux/.env | grep -E "DATABASE_URL|POSTGRES_"
Security Best Practices¶
File Permissions¶
# Protect .env file
sudo chmod 600 /opt/tux/.env
sudo chown tux:tux /opt/tux/.env
# Protect configuration files
sudo chmod 600 /opt/tux/config/config.toml
sudo chown tux:tux /opt/tux/config/config.toml
Network Security¶
# If using firewall, allow Discord connections
# Discord uses ports 443 (HTTPS) and 80 (HTTP)
# No special firewall rules needed for outbound connections
Advanced Configuration¶
Custom Working Directory¶
If installing to a different location:
[Service]
WorkingDirectory=/home/tux/tux
ExecStart=/usr/local/bin/uv run tux start
Finding uv Path
Use which uv to find the correct path to the uv executable on your system.
Debug Mode¶
Enable debug logging:
# Edit .env file
sudo -u tux nano /opt/tux/.env
# Add or modify:
DEBUG=true
LOG_LEVEL=DEBUG
# Restart service
sudo systemctl restart tux
Resource Limits¶
Adjust resource limits in service file:
[Service]
# Memory limit (512MB)
MemoryMax=512M
# CPU limit (50% of one core)
CPUQuota=50%
# I/O limits
IOWeight=100
Maintenance¶
Regular Updates¶
Create update script (/usr/local/bin/update-tux.sh):
#!/bin/bash
set -e
echo "Stopping Tux..."
sudo systemctl stop tux
echo "Backing up installation..."
sudo cp -r /opt/tux /opt/tux.backup.$(date +%Y%m%d)
echo "Updating Tux..."
cd /opt/tux
sudo -u tux git pull origin main
echo "Updating dependencies..."
sudo -u tux uv sync
echo "Running migrations..."
sudo -u tux uv run db push
echo "Starting Tux..."
sudo systemctl start tux
echo "Update complete!"
Make executable:
sudo chmod +x /usr/local/bin/update-tux.sh
Backup Strategy¶
# Backup script
#!/bin/bash
BACKUP_DIR=/backup/tux
DATE=$(date +%Y%m%d_%H%M%S)
# Stop service
sudo systemctl stop tux
# Backup database
sudo -u postgres pg_dump tux > $BACKUP_DIR/db_$DATE.sql
# Backup configuration
sudo tar -czf $BACKUP_DIR/config_$DATE.tar.gz /etc/tux /opt/tux/.env /opt/tux/config
# Start service
sudo systemctl start tux
echo "Backup complete: $BACKUP_DIR"
Related Documentation¶
- Environment Configuration - Environment variable reference
- Database Setup - Database configuration
- System Operations - Monitoring and maintenance
- First Run - Initial setup verification
Next Steps: After deploying with systemd, verify your installation with the First Run Guide.