A Python application that automatically manages torrent files for the latest Linux distribution ISO images on a Transmission server. It tracks 14 popular Linux distributions, automatically removing old torrents and adding new ones as they become available.
- Web Interface: User-friendly web UI for managing torrent updates (port 8084)
- CLI Mode: Command-line interface for automation and scripting
- Automatically detects the latest ISO torrents for 14 distributions:
- CentOS Stream 9 (via LinuxTracker.org)
- Debian (latest stable DVD)
- Ubuntu (latest LTS desktop)
- Arch Linux (latest release)
- Raspberry Pi OS (latest arm64 release)
- Linux Mint (latest Cinnamon edition)
- Fedora Workstation (latest official release)
- Pop!_OS (latest LTS)
- Rocky Linux (latest DVD)
- AlmaLinux (latest DVD)
- Manjaro (latest KDE edition)
- elementary OS (latest stable)
- Zorin OS (latest Core edition)
- EndeavourOS (latest release)
- Removes old torrents and their files when updates are available
- Integrates with Transmission via RPC
- Runs periodically via systemd timer
- Comprehensive logging
- Docker support with multiple configuration methods
Note: CentOS Stream no longer provides official torrent files. This script uses LinuxTracker.org as a community source for CentOS torrents.
- Docker Engine 20.10+
- Docker Compose (optional, for easier management)
- Transmission daemon (running on host or another container)
- Python 3.6+
- Transmission daemon
- Required Python packages:
transmission-rpcrequestsbeautifulsoup4flask(for web interface)python-dotenv
The application has two run modes: Web Interface (GUI) or CLI (command-line). You choose the mode when starting the application.
The web interface provides a user-friendly way to manage your Linux ISO torrents:
# Using Docker (Recommended)
docker-compose up -d web-interface
# Or using native Python
python web_interface.pyThen open http://localhost:8084 in your browser to:
- Select which distributions to check for updates
- View current torrent status
- Trigger manual update checks
- Monitor download progress in real-time
The web interface can be enabled in three ways:
- Environment variable (Docker/Portainer): Set
WEB_ENABLED=true - Command-line flag (Docker/Native): Use
--webflag - Direct execution (Native): Run
python web_interface.py
For automated scripts or cron jobs:
# Using Docker
docker-compose run --rm linux-iso-updater --distros debian,ubuntu,arch
# Or using native Python
python linux_iso_torrent_updater.py --distros debian,ubuntu,archYou can run this application either using Docker (recommended) or as a native Python script.
# Clone or navigate to the repository
cd LinuxTorentDownloader
# Build the Docker image
docker build -t linux-iso-updater:latest .Create an environment file:
# Copy the example file
cp .env.example .env
# Edit with your credentials
nano .envEdit the .env file with your Transmission credentials:
TRANSMISSION_HOST=localhost
TRANSMISSION_PORT=9091
TRANSMISSION_USER=your_username
TRANSMISSION_PASS=your_password
# Optional: Configure automatic scheduling (for web interface)
SCHEDULE_ENABLED=true # Enable automatic checks
SCHEDULE_FREQUENCY=1d # Check daily
SCHEDULE_TIME=02:00 # Check at 2am (for daily+ frequencies)
SELECT_DISTROS=debian,ubuntu,arch,raspberrypi # Distros selected by default in web UIYou can run the application in two modes: Web Interface (GUI) or CLI (command-line).
Start the web interface to manage torrents through a browser:
# Using docker-compose (recommended)
docker-compose up -d web-interface
# Or using docker run directly
docker run -d \
--name linux-iso-updater-web \
-p 8084:8084 \
--env-file .env \
linux-iso-updater:latest --web
# Access at http://localhost:8084The web interface provides:
- Real-time torrent status monitoring
- Interactive distro selection
- Manual update checking
- Auto-refresh every 5 seconds
- Progress tracking with visual indicators
- Automatic scheduled checks (default: daily at 2am local time)
For one-time runs or scheduled automation:
# Using docker run
docker run --rm \
--network host \
--env-file .env \
linux-iso-updater:latest
# Or using docker-compose
docker-compose run --rm linux-iso-updater
# With specific distros
docker-compose run --rm linux-iso-updater --distros debian,ubuntu,arch
# Dry-run mode (no changes)
docker-compose run --rm linux-iso-updater --dry-runIf you're using Portainer to manage Docker containers:
- In Portainer: Go to Stacks → Add stack
- Name:
linux-iso-updater - Upload or paste the
docker-compose.portainer.ymlfile (or use the regulardocker-compose.yml) - Add environment variables:
WEB_ENABLED= trueTRANSMISSION_HOST= your transmission hostTRANSMISSION_PORT= 9091TRANSMISSION_USER= your usernameTRANSMISSION_PASS= your passwordSCHEDULE_ENABLED= trueSCHEDULE_FREQUENCY= 1dWEB_PORT= 8084
- Deploy the stack
- Access the web interface:
http://your-server-ip:8084
Note: A Portainer-optimized docker-compose file is available: docker-compose.portainer.yml
See DOCKER.md for detailed Portainer documentation.
# Copy the systemd files
sudo cp linux-iso-updater.service /etc/systemd/system/
sudo cp linux-iso-updater.timer /etc/systemd/system/
# Copy credentials
sudo mkdir -p /etc/linux-iso-updater
sudo cp .env /etc/linux-iso-updater/credentials.env
sudo chmod 600 /etc/linux-iso-updater/credentials.env
# Reload systemd
sudo systemctl daemon-reload
# Enable and start the timer
sudo systemctl enable linux-iso-updater.timer
sudo systemctl start linux-iso-updater.timer# Check timer status
sudo systemctl status linux-iso-updater.timer
# View logs
sudo journalctl -u linux-iso-updater.service -f
# Manually trigger a run
sudo systemctl start linux-iso-updater.serviceIt's recommended to use a virtual environment to avoid conflicts with system packages:
# Clone or navigate to the repository
cd LinuxTorentDownloader
# Create a virtual environment
python -m venv venv
# Activate the virtual environment
source venv/bin/activate
# Install dependencies
pip install transmission-rpc requests beautifulsoup4 python-dotenv flaskOr install system-wide:
pip3 install transmission-rpc requests beautifulsoup4 python-dotenv flaskOr using your system package manager:
# Debian/Ubuntu
sudo apt install python3-requests python3-bs4 python3-dotenv
pip3 install transmission-rpc
# Arch Linux
sudo pacman -S python-requests python-beautifulsoup4 python-dotenv
pip install transmission-rpc# Copy the script to system location
sudo cp linux_iso_torrent_updater.py /usr/local/bin/
sudo chmod +x /usr/local/bin/linux_iso_torrent_updater.pyChoose one of the following methods:
# For user-level configuration
mkdir -p ~/.config/linux-iso-updater
cp config.json.example ~/.config/linux-iso-updater/config.json
nano ~/.config/linux-iso-updater/config.json
# For system-level configuration (when using systemd)
sudo mkdir -p /etc/linux-iso-updater
sudo cp credentials.env.example /etc/linux-iso-updater/credentials.env
sudo nano /etc/linux-iso-updater/credentials.env
sudo chmod 600 /etc/linux-iso-updater/credentials.envexport TRANSMISSION_HOST=localhost
export TRANSMISSION_PORT=9091
export TRANSMISSION_USER=your_username
export TRANSMISSION_PASS=your_passwordBy default, logs are output to the console only. You can optionally configure file logging in two ways:
# Log to a specific file
python linux_iso_torrent_updater.py --log-file /var/log/linux-iso-updater.log
# Or use a user-writable location
python linux_iso_torrent_updater.py --log-file ~/logs/linux-iso-updater.log# Set LOG_FILE environment variable
export LOG_FILE=/var/log/linux-iso-updater.log
python linux_iso_torrent_updater.py
# Or inline
LOG_FILE=~/logs/iso-updater.log python linux_iso_torrent_updater.pyNote: The command-line --log-file argument takes precedence over the LOG_FILE environment variable.
Note: For Docker installation, see the Docker Installation section above.
# Copy systemd files
sudo cp linux-iso-updater.service /etc/systemd/system/
sudo cp linux-iso-updater.timer /etc/systemd/system/
# Edit the service file to use native Python (not Docker)
sudo nano /etc/systemd/system/linux-iso-updater.service
# Change ExecStart to: /usr/bin/python3 /usr/local/bin/linux_iso_torrent_updater.py
# Set appropriate User/Group
# Reload systemd
sudo systemctl daemon-reload
# Enable and start the timer
sudo systemctl enable linux-iso-updater.timer
sudo systemctl start linux-iso-updater.timerThis application can be used in two modes:
The web interface provides an easy-to-use GUI for managing your Linux ISO torrents:
# Using Docker (recommended)
docker-compose up -d web-interface
# Or native Python
python web_interface.py
# With custom host/port
python web_interface.py --host 0.0.0.0 --port 8084
# With debug mode (for development)
python web_interface.py --debugAccess the web interface at http://localhost:8084
Web Interface Features:
- Real-time torrent status with auto-refresh (5 seconds)
- Select distributions to check for updates
- View download progress, speeds, and ratios
- Manual update checking with progress tracking
- Responsive design for mobile devices
- Visual status indicators and progress bars with hover effects
- ETA (estimated time remaining) display for active downloads
- Progress percentage tooltips on hover
- Automatic scheduled checks - runs daily at configured time (default: 2am)
Web Interface Command-Line Options:
# Basic usage
python web_interface.py
# Custom host and port
python web_interface.py --host 0.0.0.0 --port 8084
# With debug mode
python web_interface.py --debug
# Configure automatic scheduling
python web_interface.py --schedule-enabled true --schedule-frequency 1d --schedule-time 02:00
# Disable automatic scheduling
python web_interface.py --schedule-enabled false
# Check every 8 hours
python web_interface.py --schedule-frequency 8h
# With log file
python web_interface.py --log-file ~/logs/web-interface.logAvailable web interface options:
--host: Host to bind to (default: 0.0.0.0)--port: Port to bind to (default: 8084)--debug: Enable Flask debug mode--schedule-enabled: Enable/disable automatic checks (true/false, default: true)--schedule-frequency: Frequency for automatic checks (1h/8h/1d/7d/14d/30d, default: 1d)--schedule-time: Time for automatic checks in HH:MM format (default: 02:00, only used for daily+ frequencies)--select-distros: Distributions selected by default in web UI (comma-separated)--log-file,-l: Path to log file (default: console only)
When running the web interface, you can configure automatic torrent checks:
Via Environment Variables (recommended):
# In .env file
WEB_ENABLED=true # Enable web interface (default: false)
SCHEDULE_ENABLED=true # Enable/disable automatic checks (default: true)
SCHEDULE_FREQUENCY=1d # Check frequency (1h/8h/1d/7d/14d/30d)
SCHEDULE_TIME=02:00 # Time for daily+ checks (HH:MM format)
SELECT_DISTROS=debian,ubuntu,arch,raspberrypi # Distros selected by default in web UIImportant: SCHEDULE_ENABLED only works when WEB_ENABLED=true (automatic checks require the web interface to run).
Frequency Options:
1h- Check every hour8h- Check every 8 hours1d- Check daily (default)7d- Check weekly14d- Check every 2 weeks30d- Check monthly
Via Command Line:
# Enable with hourly checks
python web_interface.py --schedule-enabled true --schedule-frequency 1h
# Enable with daily checks at 2am
python web_interface.py --schedule-enabled true --schedule-frequency 1d --schedule-time 02:00
# Disable automatic checks
python web_interface.py --schedule-enabled falseVia Web UI:
You can also enable/disable automatic checks and change the frequency directly in the web interface settings menu.
Via Command-Line Arguments:
python web_interface.py --schedule-time 14:30 --select-distros debian,ubuntuVia Docker Environment:
docker run -d \
-p 8084:8084 \
--env-file .env \
-e WEB_ENABLED=true \
-e SCHEDULE_ENABLED=true \
-e SCHEDULE_FREQUENCY=1d \
-e SCHEDULE_TIME=02:00 \
-e SELECT_DISTROS=debian,ubuntu,arch \
linux-iso-updater:latestConfiguration Options:
- Web Interface: Set
WEB_ENABLED=trueto run web server (default: false) - Enable/Disable Scheduling: Set
SCHEDULE_ENABLED=trueorfalse(default: true, requires WEB_ENABLED=true) - Frequency:
1h,8h,1d,7d,14d,30d(default: 1d) - Time:
HH:MMin 24-hour format for daily+ frequencies (default: 02:00) - Distributions: Comma-separated list to select by default in web UI
- Default distros: debian,ubuntu,arch,centos,raspberrypi,mint,fedora,popos,rocky,alma,manjaro,elementary,zorin,endeavour
The scheduler runs in the background and automatically checks for new torrents based on the configured frequency.
The script supports several command-line options:
# If using virtual environment, activate it first
source venv/bin/activate
# Show help
python linux_iso_torrent_updater.py --help
# Normal run - update configured distributions
python linux_iso_torrent_updater.py
# Dry-run - show what would be done without making changes
python linux_iso_torrent_updater.py --dry-run
# Update specific distribution only (overrides config)
python linux_iso_torrent_updater.py --distro debian
# Update multiple distributions (overrides config)
python linux_iso_torrent_updater.py --distros debian,ubuntu
# Dry-run for specific distribution
python linux_iso_torrent_updater.py --dry-run --distro ubuntu
# Or use venv python directly without activating
venv/bin/python linux_iso_torrent_updater.py --dry-run
# With log file
python linux_iso_torrent_updater.py --log-file ~/logs/iso-updater.log
# Or via environment variable
LOG_FILE=~/logs/iso-updater.log python linux_iso_torrent_updater.pyAvailable options:
--dry-run,-n: Show what would be done without making any changes to Transmission--distro,-d <name>: Update specific distribution (choices: centos, debian, ubuntu, arch, raspberrypi, mint, fedora, popos, rocky, alma, manjaro, elementary, zorin, endeavour) - overrides config--distros <list>: Comma-separated list of distributions - overrides config--log-file,-l <path>: Path to log file (default: console only)
You can control which distributions are updated using three methods (in priority order):
# Update only Debian
python linux_iso_torrent_updater.py --distro debian
# Update Debian and Ubuntu
python linux_iso_torrent_updater.py --distros debian,ubuntu
# Docker
docker run --rm --network host --env-file .env \
linux-iso-updater:latest --distros debian,ubuntu# Set in shell
export DISTROS=debian,ubuntu
python linux_iso_torrent_updater.py
# Or inline
DISTROS=debian,ubuntu python linux_iso_torrent_updater.py
# In .env file
echo "DISTROS=debian,ubuntu,arch" >> .envEdit ~/.config/linux-iso-updater/config.json:
{
"host": "localhost",
"port": 9091,
"username": "myuser",
"password": "mypass",
"distros": ["debian", "ubuntu", "arch"]
}If none of the above are set, all distributions will be updated.
Priority order:
--distroor--distroscommand-line flags (highest)DISTROSenvironment variabledistrosin config.json- All distributions (default)
Run the container manually:
# Normal run - using docker run
docker run --rm \
--network host \
-e TRANSMISSION_HOST=localhost \
-e TRANSMISSION_PORT=9091 \
-e TRANSMISSION_USER=myuser \
-e TRANSMISSION_PASS=mypass \
linux-iso-updater:latest
# With DISTROS configured
docker run --rm \
--network host \
-e TRANSMISSION_HOST=localhost \
-e TRANSMISSION_PORT=9091 \
-e TRANSMISSION_USER=myuser \
-e TRANSMISSION_PASS=mypass \
-e DISTROS=debian,ubuntu \
linux-iso-updater:latest
# Dry-run mode
docker run --rm \
--network host \
--env-file .env \
linux-iso-updater:latest --dry-run
# Update specific distro only (overrides DISTROS env var)
docker run --rm \
--network host \
--env-file .env \
linux-iso-updater:latest --distro debian
# Dry-run for specific distro
docker run --rm \
--network host \
--env-file .env \
linux-iso-updater:latest --dry-run --distro ubuntu
# Using docker-compose (edit docker-compose.yml to add command arguments)
docker-compose upDocker containers don't have access to your host's files by default. Here are the methods to pass configuration:
The --env-file flag reads environment variables from a file on your host:
# Create a .env file with your credentials (if you haven't already)
cat > .env <<EOF
TRANSMISSION_HOST=localhost
TRANSMISSION_PORT=9091
TRANSMISSION_USER=myuser
TRANSMISSION_PASS=mypass
DISTROS=debian,ubuntu,raspberrypi
EOF
# Run with --env-file
docker run --rm \
--network host \
--env-file .env \
linux-iso-updater:latest --dry-run
# You can use any .env file location
docker run --rm \
--network host \
--env-file /etc/linux-iso-updater/credentials.env \
linux-iso-updater:latestPass environment variables individually:
docker run --rm \
--network host \
-e TRANSMISSION_HOST=localhost \
-e TRANSMISSION_PORT=9091 \
-e TRANSMISSION_USER=myuser \
-e TRANSMISSION_PASS=mypass \
-e DISTROS=debian,ubuntu \
linux-iso-updater:latest --dry-runMount a .env file from your host into the container:
# Mount .env file to /app/.env inside container
docker run --rm \
--network host \
-v "$(pwd)/.env:/app/.env:ro" \
linux-iso-updater:latest --dry-run
# The script will automatically load /app/.env if it existsIf you prefer config.json over .env files:
# Create config file
mkdir -p ~/.config/linux-iso-updater
cat > ~/.config/linux-iso-updater/config.json <<EOF
{
"host": "localhost",
"port": 9091,
"username": "myuser",
"password": "mypass",
"distros": ["debian", "ubuntu", "raspberrypi"]
}
EOF
# Mount config directory
docker run --rm \
--network host \
-v ~/.config/linux-iso-updater:/root/.config/linux-iso-updater:ro \
linux-iso-updater:latest --dry-runIn docker-compose.yml:
version: '3.8'
services:
linux-iso-updater:
image: linux-iso-updater:latest
network_mode: host
env_file:
- .env # Loads .env from project directory
# OR
- /etc/linux-iso-updater/credentials.env # System-wide config
# Optional: Override or add environment variables
environment:
- DISTROS=debian,ubuntuThen run:
docker-compose run --rm linux-iso-updater --dry-runIf you want to write logs to a file on the host:
# Create log directory on host
mkdir -p ~/logs
# Run with log file and volume mount
docker run --rm \
--network host \
--env-file .env \
-v ~/logs:/logs \
-e LOG_FILE=/logs/iso-updater.log \
linux-iso-updater:latest --dry-run
# Or use --log-file argument
docker run --rm \
--network host \
--env-file .env \
-v ~/logs:/logs \
linux-iso-updater:latest --log-file /logs/iso-updater.log --dry-runSecurity Notes:
- Never commit
.envfiles with real credentials to version control - Use
.env.localfor local development (it's gitignored) - Set proper permissions:
chmod 600 .env - Use
:ro(read-only) flag when mounting sensitive files - For production, consider using Docker secrets or environment variables from your orchestration platform
Priority Order in Docker:
- Command-line arguments (
--distro,--log-file) - Environment variables from
-eflags - Environment variables from
--env-file - Mounted
.envfiles inside container - Mounted
config.jsonfiles - Default values
After making changes to the script:
# Rebuild the image
docker build -t linux-iso-updater:latest .
# Or with docker-compose
docker-compose buildRun the script manually to test:
# Normal run
/usr/local/bin/linux_iso_torrent_updater.py
# Dry-run mode
/usr/local/bin/linux_iso_torrent_updater.py --dry-run
# Update specific distro
/usr/local/bin/linux_iso_torrent_updater.py --distro debian
# Dry-run for specific distro
/usr/local/bin/linux_iso_torrent_updater.py --dry-run --distro ubuntuOr with environment variables:
# Normal run
TRANSMISSION_USER=myuser TRANSMISSION_PASS=mypass python3 linux_iso_torrent_updater.py
# Dry-run mode
TRANSMISSION_USER=myuser TRANSMISSION_PASS=mypass python3 linux_iso_torrent_updater.py --dry-runDry-run mode allows you to see what the script would do without making any actual changes to Transmission. This is useful for:
- Testing configuration before running for real
- Seeing what torrents would be updated
- Verifying torrent URLs are found correctly
- Debugging without affecting your downloads
What happens in dry-run mode:
- ✅ Finds and downloads torrent files from distribution websites
- ✅ Shows torrent URLs and metadata
- ✅ Reports what actions would be taken
- ❌ Does NOT connect to Transmission (credentials optional)
- ❌ Does NOT add new torrents
- ❌ Does NOT remove old torrents
Example output:
[DRY-RUN MODE: No changes will be made to Transmission]
Found Debian torrent: https://cdimage.debian.org/.../debian-12.0.0-amd64-DVD-1.iso.torrent
[DRY-RUN] Downloaded torrent (hash: 1a2b3c4d5e6f7g8h...)
[DRY-RUN] No existing debian torrent found
[DRY-RUN] Would add new torrent from https://...
The timer runs automatically based on the configured schedule (default: daily at 3 AM).
Check timer status:
# View timer status
sudo systemctl status linux-iso-updater.timer
# List all timers
sudo systemctl list-timers
# View service logs
sudo journalctl -u linux-iso-updater.service -f
# Manually trigger the service
sudo systemctl start linux-iso-updater.serviceEdit /etc/systemd/system/linux-iso-updater.timer and modify the OnCalendar value:
# Daily at 3 AM
OnCalendar=daily
# Every 6 hours
OnCalendar=00/6:00:00
# Weekly on Sunday at 3 AM
OnCalendar=Sun *-*-* 03:00:00
# Every Monday and Friday at 2 AM
OnCalendar=Mon,Fri *-*-* 02:00:00After editing, reload systemd:
sudo systemctl daemon-reload
sudo systemctl restart linux-iso-updater.timerBy default, the script logs to console only (stdout). This is suitable for:
- Interactive use
- Docker containers (logs captured by Docker)
- systemd services (logs captured by journald)
- Debugging and testing
To also log to a file, use one of these methods:
# Log to console AND file
python linux_iso_torrent_updater.py --log-file /path/to/logfile.log
# Examples
python linux_iso_torrent_updater.py --log-file /var/log/linux-iso-updater.log
python linux_iso_torrent_updater.py --log-file ~/logs/iso-updater.log
python linux_iso_torrent_updater.py -l /tmp/updater.log# Set LOG_FILE environment variable
export LOG_FILE=/var/log/linux-iso-updater.log
python linux_iso_torrent_updater.py
# Or add to .env file
echo "LOG_FILE=/var/log/linux-iso-updater.log" >> .envNote: The --log-file command-line argument takes precedence over the LOG_FILE environment variable.
When run via Docker, logs are output to:
- Docker container logs (viewable with
docker logs) - systemd journal (when run via systemd)
- Optional log file (if LOG_FILE environment variable is set)
View logs:
# View Docker container logs
docker logs linux-iso-updater
# View systemd journal (when using systemd + Docker)
journalctl -u linux-iso-updater.service -f
# View logs from the last run
journalctl -u linux-iso-updater.service --since "1 hour ago"
# Follow docker-compose logs
docker-compose logs -f
# If using LOG_FILE environment variable, also check the log file
tail -f /path/to/logfile.logWhen running natively, logs are output to:
- Console (stdout) - always enabled
- Optional log file (if
--log-fileorLOG_FILEis set) - systemd journal (when run via systemd)
View logs:
# Console output (default)
python linux_iso_torrent_updater.py --dry-run
# If using log file, view it
tail -f /path/to/logfile.log
# View systemd journal (when run via systemd)
journalctl -u linux-iso-updater.service -f
# View logs from the last run
journalctl -u linux-iso-updater.service --since "1 hour ago"The script supports multiple .env files for different environments:
When running the script directly, it loads .env files in this order (highest priority last):
.env- Base configuration (can be committed).env.development- Development overrides (can be committed).env.local- Local overrides (NEVER commit - contains secrets)
Then checks:
4. Config file at ~/.config/linux-iso-updater/config.json
5. Environment variables from /etc/linux-iso-updater/credentials.env (systemd)
6. System environment variables
Docker uses environment variables in this order (highest priority first):
- Variables passed via
docker run -e - Variables from
--env-fileflag - Variables in docker-compose.yml environment section
- Variables in
/etc/linux-iso-updater/credentials.env(when using systemd)
# Copy and edit development config
cp .env.development.example .env.development
nano .env.development# Copy and edit local config (this file is gitignored)
cp .env.local.example .env.local
nano .env.local# Use the standard .env file
cp .env.example .env
nano .env- Team shared settings →
.envor.env.development(committed) - Personal local settings →
.env.local(never committed) - Production/Docker →
.envor systemd credentials
The Docker container uses environment variables (in order of precedence):
- Variables passed via
docker run -eor--env-file - Variables in
.envfile (when using docker-compose) - Variables in
/etc/linux-iso-updater/credentials.env(when using systemd)
The script connects to Transmission using these settings (in order of precedence):
- Environment variables from
.env.local(if exists) - Environment variables from
.env.development(if exists) - Environment variables from
.env(if exists) - Config file at
~/.config/linux-iso-updater/config.json - Environment variables from
/etc/linux-iso-updater/credentials.env(systemd) - System environment variables (
TRANSMISSION_HOST,TRANSMISSION_PORT,TRANSMISSION_USER,TRANSMISSION_PASS)
Default values:
- Host:
localhost - Port:
9091 - Username: (required)
- Password: (required)
Ensure Transmission RPC is enabled and configured:
# Edit Transmission settings
sudo systemctl stop transmission-daemon
sudo nano /etc/transmission-daemon/settings.jsonRequired settings:
{
"rpc-enabled": true,
"rpc-port": 9091,
"rpc-authentication-required": true,
"rpc-username": "your_username",
"rpc-password": "your_password",
"rpc-whitelist-enabled": false
}Restart Transmission:
sudo systemctl start transmission-daemonEnsure you're using --network host to allow the container to access localhost:
# Check Transmission is accessible
curl http://localhost:9091/transmission/rpc
# Verify Docker container can access host network
docker run --rm --network host alpine ping -c 3 localhostIf using a custom Docker network or Transmission in another container:
# Use container name instead of localhost
docker run --rm \
--network transmission-network \
-e TRANSMISSION_HOST=transmission \
-e TRANSMISSION_PORT=9091 \
-e TRANSMISSION_USER=user \
-e TRANSMISSION_PASS=pass \
linux-iso-updater:latest# Clean build without cache
docker build --no-cache -t linux-iso-updater:latest .
# Check disk space
docker system df
docker system prune -aCheck container logs:
# View logs from last run
docker logs linux-iso-updater
# Run container interactively for debugging
docker run -it --rm \
--network host \
--env-file .env \
--entrypoint /bin/bash \
linux-iso-updater:latest
# Then inside container, run manually:
python /app/linux_iso_torrent_updater.pyFor native installation, ensure the script runs as the Transmission user:
# Check Transmission user
ps aux | grep transmission
# Update service file (native only)
sudo nano /etc/systemd/system/linux-iso-updater.service
# Set User= and Group= to match Transmission userFor Docker, the container runs as a non-root user but needs network access to reach Transmission.
Check Transmission is running and RPC is enabled:
sudo systemctl status transmission-daemon
curl http://localhost:9091/transmission/rpc
# Check RPC credentials
transmission-remote localhost:9091 -n username:password -lThe script searches for torrents from various sources:
Torrent Sources:
- CentOS Stream 9: LinuxTracker.org (community source)
- Debian: Official Debian CDImage servers
- Ubuntu: Official Ubuntu releases
- Arch Linux: Official Arch Linux servers
- Raspberry Pi OS: Official Raspberry Pi downloads
- Linux Mint: LinuxTracker.org (community mirror)
- Fedora Workstation: Official Fedora torrent servers
- Pop!_OS: LinuxTracker.org (community mirror)
- Rocky Linux: LinuxTracker.org (community mirror)
- AlmaLinux: LinuxTracker.org (community mirror)
- Manjaro: LinuxTracker.org (community mirror)
- elementary OS: LinuxTracker.org (community mirror)
- Zorin OS: LinuxTracker.org (community mirror)
- EndeavourOS: LinuxTracker.org (community mirror)
If a torrent cannot be found:
- Check logs for specific errors
- Verify the source is accessible (some distributions may temporarily remove torrents)
- For CentOS, Mint, Pop!_OS, Rocky, AlmaLinux, Manjaro, elementary, Zorin, and EndeavourOS: LinuxTracker.org may be temporarily down or the page structure may have changed
- Try the
--dry-runflag to see what's happening without making changes
CentOS Note: CentOS Stream no longer provides official torrent files. This script uses LinuxTracker.org as a community-maintained source. If LinuxTracker is unavailable, CentOS torrents won't be found.
Test a single distribution to isolate issues:
# Test with dry-run
python linux_iso_torrent_updater.py --dry-run --distro debian
python linux_iso_torrent_updater.py --dry-run --distro centos
python linux_iso_torrent_updater.py --dry-run --distro ubuntu
python linux_iso_torrent_updater.py --dry-run --distro arch
python linux_iso_torrent_updater.py --dry-run --distro raspberrypi
python linux_iso_torrent_updater.py --dry-run --distro mint
python linux_iso_torrent_updater.py --dry-run --distro fedora
python linux_iso_torrent_updater.py --dry-run --distro popos
python linux_iso_torrent_updater.py --dry-run --distro rocky
python linux_iso_torrent_updater.py --dry-run --distro alma
python linux_iso_torrent_updater.py --dry-run --distro manjaro
python linux_iso_torrent_updater.py --dry-run --distro elementary
python linux_iso_torrent_updater.py --dry-run --distro zorin
python linux_iso_torrent_updater.py --dry-run --distro endeavour# Stop and disable timer
sudo systemctl stop linux-iso-updater.timer
sudo systemctl disable linux-iso-updater.timer
# Remove systemd files
sudo rm /etc/systemd/system/linux-iso-updater.{service,timer}
# Remove credentials
sudo rm -rf /etc/linux-iso-updater
# Remove Docker image
docker rmi linux-iso-updater:latest
# Reload systemd
sudo systemctl daemon-reload# Stop and disable timer
sudo systemctl stop linux-iso-updater.timer
sudo systemctl disable linux-iso-updater.timer
# Remove files
sudo rm /etc/systemd/system/linux-iso-updater.{service,timer}
sudo rm /usr/local/bin/linux_iso_torrent_updater.py
sudo rm -rf /etc/linux-iso-updater
sudo rm /var/log/linux-iso-updater.log
# Reload systemd
sudo systemctl daemon-reloadThis project includes tools for easy development with hot-reload support.
The easiest way to develop the web interface is using the provided development scripts:
# Make the script executable
chmod +x dev-web.sh
# Start development server with hot-reload on port 8099
./dev-web.sh
# With custom options
./dev-web.sh --port 8085 --host 0.0.0.0 --schedule-time 14:30Features:
- Automatic reload when Python files change
- Flask debug mode with detailed error pages
- Runs on port 8099 by default (avoids conflict with Docker on 8084)
- Automatic virtual environment setup
- Dependency checking and installation
- Colored output for better visibility
| Aspect | Development (./dev-web.sh) |
Production (Docker) |
|---|---|---|
| Port | 8099 | 8084 |
| Auto-reload | Yes | No |
| Debug mode | Enabled | Disabled |
| Performance | Slower (file monitoring) | Optimized |
| Error pages | Detailed with traceback | Simple messages |
-
Python code (
web_interface.py,linux_iso_torrent_updater.py):- Edit file → Server auto-restarts → Test in browser
-
HTML templates (
templates/index.html):- Edit file → Refresh browser
-
CSS/JavaScript (
static/css/style.css,static/js/app.js):- Edit file → Hard refresh browser (Ctrl+F5 or Cmd+Shift+R)
Two equivalent scripts are provided:
dev-web.sh- Bash script (recommended for Linux/Mac)dev-web.py- Python script (cross-platform alternative)
Both provide the same functionality. The Bash script has slightly better terminal output formatting.
You can run both at the same time on different ports:
# Terminal 1: Production via Docker on port 8084
docker-compose up web-interface
# Terminal 2: Development with hot-reload on port 8099
./dev-web.shSee DEVELOPMENT.md for comprehensive development documentation including:
- Environment file configuration (
.env.local,.env.development) - IDE setup (VS Code, PyCharm)
- Troubleshooting development issues
- Adding new distributions
- Testing strategies
- Contributing guidelines
- Store credentials securely with restricted permissions (600)
- Docker containers run as non-root user (uid 1000) for security
- Use
--network hostcarefully; consider Docker networks for better isolation - The systemd service runs with Docker, which requires root or docker group access
- Consider using Docker secrets for production deployments
- Review and audit the script before running with elevated privileges
- Keep the Docker image updated with security patches
Feel free to submit issues, fork the repository, and create pull requests for any improvements.
This project is provided as-is for educational and practical use.
This script downloads and seeds Linux distribution ISO files. Ensure you have:
- Sufficient disk space for multiple large ISO files
- Adequate bandwidth for seeding
- Permission from your network administrator if on a managed network
The script respects rate limiting and includes delays between requests to avoid overloading distribution servers.