Docker Configuration and Management
May 15, 2026 · View on GitHub
Architecture Overview
Youtarr uses Docker Compose with two containers:
- youtarr: Main application container (Node.js/React)
- youtarr-db: MariaDB database container
Compose Files
Youtarr ships four Compose files so each supported runtime can layer the right overrides:
| File | Purpose |
|---|---|
docker-compose.yml | Production defaults with the bundled MariaDB container. Used by ./start.sh. |
docker-compose.dev.yml | Development mode: mounts ./server/ and migrations into the container, runs the backend with node --watch for hot reload, and uses a separate youtarr-db-dev database with its own named volume. Used by ./scripts/start-dev.sh. See DEVELOPMENT.md. |
docker-compose.arm.yml | Named-volume database override. The filename is historical: it was originally added for ARM systems, but it is also useful on Docker Desktop and NAS/virtualized filesystems. Layered on top of docker-compose.yml via -f. |
docker-compose.external-db.yml | Runs Youtarr against an external MariaDB/MySQL instance instead of the bundled database. Used by ./start-with-external-db.sh. |
Container Details
Application Container (youtarr)
- Image:
dialmaster/youtarr:latest - Exposed Ports:
- 3087 → 3011 (Web interface + WebSocket)
- Volumes:
${YOUTUBE_OUTPUT_DIR}:/usr/src/app/data- Videos directory./server/images:/app/server/images- Thumbnails/cache./config:/app/config- Configuration files./jobs:/app/jobs- Job state and artifacts
Database Container (youtarr-db)
- Image:
mariadb:10.3 - Port: 3321 inside the Docker network only; the bundled database is not published to the host
- Volumes:
./database:/var/lib/mysql- Database persistence (default)youtarr-db-data:/var/lib/mysql- Named volume (recommended for Docker Desktop/ARM/NAS)
- Character Set: utf8mb4 (full Unicode support)
Docker Desktop/ARM/NAS users: See Named-Volume Database Override below.
⚠️ Important: Do Not Mount the Migrations Directory
Avoid adding a ./migrations:/app/migrations volume. The production image already includes the migration files it needs.
Why This Matters
If you mount an empty or missing local migrations directory (common with Ansible, Terraform, or Kubernetes automation), it overwrites the packaged migrations and the database bootstrap will fail.
# ❌ WRONG - Causes DB initialization failures
volumes:
- ./migrations:/app/migrations
# ✅ CORRECT - Use migrations from the image
volumes:
- ${YOUTUBE_OUTPUT_DIR}:/usr/src/app/data
- ./server/images:/app/server/images
- ./config:/app/config
- ./jobs:/app/jobs
If your automation creates a migrations directory, remove it from both directory creation and volume mounts.
Named-Volume Database Override
Docker Desktop on Windows/macOS, ARM hosts, Synology/QNAP, and some virtualized filesystems can have trouble with MariaDB data stored on a bind mount. The named-volume override avoids that class of issue.
Using Start Scripts (Recommended)
./start.sh automatically uses docker-compose.arm.yml for fresh installs on every platform. Existing installs with real MariaDB data in ./database/ keep using the bind mount and print a migration warning instead, including on ARM hosts.
./start.sh
For an existing bind-mounted install, migrate with:
./scripts/migrate-to-named-volume.sh
Using Docker Compose Directly
For a fresh install, use the override file:
docker compose -f docker-compose.yml -f docker-compose.arm.yml up -d
This uses a named Docker volume instead of a bind mount for MariaDB data.
Manual Configuration
Alternatively, edit docker-compose.yml directly:
services:
youtarr-db:
volumes:
# Comment out bind mount:
# - ./database:/var/lib/mysql
# Use named volume:
- youtarr-db-data:/var/lib/mysql
# Add at the bottom:
volumes:
youtarr-db-data:
See Troubleshooting for more details on the underlying issue.
Configuration Setup
- Create a .env file to configure environment variables:
See: ENVIRONMENT_VARIABLES for more detailscp .env.example .env vim .env # Set YOUTUBE_OUTPUT_DIR to your video storage path - Alternative: Edit
docker-compose.ymlto hardcode your volume mount:volumes: - /your/host/path:/usr/src/app/data # Replace ${YOUTUBE_OUTPUT_DIR} with your path - Start containers with
docker compose up -d - Container auto-creates
config.json - UI Behavior: YouTube Output Directory field is read-only - shows "Docker Volume" chip
- Host Path Reminder: Create the
/your/host/pathdirectory ahead of time and ensure it is writable. Docker will otherwise create it as root-owned!
Network Storage
When using network storage:
- Mount your network storage BEFORE starting Youtarr
Examples:
- Linux with NFS mount:
/mnt/nas/youtube - Windows with mapped drive:
Z:/Youtube_videos - macOS with SMB mount:
/Users/username/nas-youtube - Docker volume mount:
/path/to/mounted/volume
If you need to change the directory later:
vim .env # Or your editor of choice
# Change your YOUTUBE_OUTPUT_DIR
Using an External Database
Some users prefer to supply their own MariaDB/MySQL instance instead of the bundled youtarr-db container. This is easily supported by setting up your external DB config in .env and then running
Youtarr without the bundled DB via:
./start-with-external-db.shordocker compose -f docker-compose.external-db.yml up -d- See External Database Guide
Both helpers automatically run migrations against the external database on boot, so no manual schema management is required once connectivity is in place.
Manual Setup Without Git Clone
This section covers setting up Youtarr when you cannot (or prefer not to) clone the full repository—common in Portainer, TrueNAS, and similar Docker-native environments.
Important Warnings
This is an advanced installation method with limitations:
- No helper scripts (
start.sh,stop.sh, etc.) - Manual updates required (can't just
git pull) - No access to development tools
- More error-prone setup process
- Community support may be limited for this approach
We strongly recommend cloning the repository if possible. If you must proceed, follow these steps carefully.
Critical - read this first if you use automation: If you are templating
docker-compose.ymlvia Ansible, Terraform, Kubernetes, Helm, or any tool that auto-creates empty directories for every listed volume, read Do Not Mount the Migrations Directory at the top of this document before continuing. Auto-creating an empty./migrationsdirectory will overwrite the packaged migrations and break the database bootstrap in a way that is hard to diagnose.
Prerequisites
- Docker and Docker Compose installed
- Terminal/SSH access to your system
- Basic understanding of Linux file permissions
Setup Steps
1. Create Working Directory
mkdir -p youtarr && cd youtarr
2. Download Required Files
# Download docker-compose.yml
wget https://raw.githubusercontent.com/DialmasterOrg/Youtarr/main/docker-compose.yml
# Download environment template
wget https://raw.githubusercontent.com/DialmasterOrg/Youtarr/main/.env.example -O .env.example
Alternative for systems without wget:
Using an external MariaDB/MySQL instance? Download docker-compose.external-db.yml instead of docker-compose.yml and rename it to docker-compose.yml locally so the rest of this guide works unchanged:
wget https://raw.githubusercontent.com/DialmasterOrg/Youtarr/main/docker-compose.external-db.yml -O docker-compose.yml
You will also need to set DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, and DB_NAME in your .env (see External Database Setup earlier in this document). Skip the bundled-database permission steps below if you go this route.
3. Configure Environment
# Create your environment file
cp .env.example .env
# Edit configuration
vim .env # or nano, or your preferred editor
Required settings:
YOUTUBE_OUTPUT_DIR- Must be set to your video storage path
Optional settings:
TZ- Your timezone (e.g.,America/New_York,Europe/London). Defaults toUTC. Set this if scheduled downloads and nightly cleanup should run in your local time.YOUTARR_HOST_PORT- Host port for the web interface. Defaults to3087; change this if another service already uses that port.AUTH_PRESET_USERNAMEandAUTH_PRESET_PASSWORD- Seed login credentials and skip the setup-token wizard for headless or automated deployments.YOUTARR_UID/YOUTARR_GID- Run the container as a non-root user (recommended for security, see step 5 below).- Changing bundled-database credentials? If you want to customize the MariaDB password, set BOTH
DB_PASSWORDandDB_ROOT_PASSWORDto the same value. Setting only one of them will cause the app to fail to connect because the app usesDB_PASSWORDwhile MariaDB's root account is initialized fromDB_ROOT_PASSWORD. This only applies to the bundled database; external-DB users setDB_PASSWORDto match their existing database. - See ENVIRONMENT_VARIABLES.md for the full reference.
4. Create Required Directories
Youtarr needs these directories to exist before first start:
# Youtarr app directories (always required)
mkdir -p config jobs server/images
# Your download directory (adjust path to match YOUTUBE_OUTPUT_DIR in .env)
mkdir -p downloads # If using default ./downloads
# OR
mkdir -p /path/to/your/custom/location # If using custom path
Bundled database only (skip if you are using an external database):
# MariaDB data directory for the bundled youtarr-db container
mkdir -p database
On most Linux hosts, Docker will auto-create ./database on first run and MariaDB's entrypoint will chown it to UID 999 (the mysql user inside the mariadb:10.3 image). On Synology, QNAP, and some other NAS platforms with strict UID enforcement you may need to pre-create and chown the directory yourself:
sudo chown -R 999:999 database
If you hit InnoDB: Operating system error number 13 at startup, you have hit this case - see Migrating from Bind Mount to Named Volume in the database docs for an alternative that sidesteps bind-mount permission issues entirely.
5. Set Permissions
By default, the container runs as root (UID 0). If you leave YOUTARR_UID and YOUTARR_GID unset in .env, you can skip this entire step: the container manages file ownership itself.
Recommended (non-root): run the container as a non-root user so files on the host are owned by a regular account. This requires both an .env change and a chown on the host, in this order:
-
Add your target UID/GID to
.env(1000:1000 is the typical first user on Linux, but use whatever matches your host account):YOUTARR_UID=1000 YOUTARR_GID=1000 -
Change ownership of the Youtarr directories on the host to match:
sudo chown -R 1000:1000 config jobs server/images downloadsReplace
1000:1000with whatever you put in.env. If you use a custom download path,chownthat path instead ofdownloads. -
Verify:
ls -la config jobs server/images downloads # All directories should show ownership matching YOUTARR_UID:YOUTARR_GID
Important: The
chownmust run after settingYOUTARR_UID/GIDin.env, and the numeric IDs must match. Runningchown 1000:1000without settingYOUTARR_UID=1000leaves the container running as root, which will then either overwrite your host-side ownership or fail to write into the chown'd directories depending on your filesystem. If you are already running as root and want to switch to non-root, stop the container first, chown everything (including yourYOUTUBE_OUTPUT_DIR), then update.envand start again.
6. Start Containers
docker compose up -d
7. Verify Startup
# Check container status
docker compose ps
# Check logs for errors
docker compose logs -f
# Access web interface
# Navigate to http://your-server-ip:3087
What You're Missing
By not cloning the repository, you lose access to:
| Missing Component | Impact |
|---|---|
start.sh / stop.sh | Convenient start/stop management |
start-with-external-db.sh | Easy external database setup |
| Helper scripts | Database migration tools, reset scripts |
| Local documentation | Offline access to guides |
| Development environment | Can't contribute changes easily |
Updating Youtarr
Without Git, updates require manual steps:
# 1. Stop containers
docker compose down
# 2. Backup your configuration (recommended)
tar -czf backup-$(date +%Y%m%d).tar.gz config jobs
# 3. Download updated compose file
wget https://raw.githubusercontent.com/DialmasterOrg/Youtarr/main/docker-compose.yml -O docker-compose.yml
# 4. Pull latest images
docker compose pull
# 5. Start with new version
docker compose up -d
# 6. Check logs for issues
docker compose logs -f
Notes:
- Check .env.example for new variables after major updates.
- If you originally downloaded
docker-compose.external-db.ymlfor an external database setup, swap step 3 above forwget https://raw.githubusercontent.com/DialmasterOrg/Youtarr/main/docker-compose.external-db.yml -O docker-compose.yml. Mixing compose files across updates will silently switch you between bundled and external database modes.
Platform-Specific Notes
Portainer
- Use "Stacks" feature to paste docker-compose.yml content
- Environment variables can be set in the Portainer UI under "Environment variables"
- Create required directories via Portainer console or host SSH access
- Ensure volume paths are accessible from the Docker host
TrueNAS Scale
- Use "Custom App" feature in Apps section
- Map host paths carefully in volume configuration
- Ensure datasets exist before creating the app
- Consider using IX-applications for easier management
Unraid
- See Unraid Guide for template-based installation
Troubleshooting Manual Setup
Problem: Container fails to start with "no such file or directory"
Solution: Verify all directories exist:
ls -la config jobs server/images
# All should exist and have correct permissions
Problem: "Permission denied" errors in logs
Solution:
# Check configured UID/GID in .env
grep YOUTARR_ .env
# Verify directory ownership matches
ls -ln config jobs server/images downloads
# Fix permissions (replace UID:GID with your values)
sudo chown -R 1000:1000 config jobs server/images downloads
Problem: "empty section between colons" error when starting
Solution: YOUTUBE_OUTPUT_DIR is not set in .env
grep YOUTUBE_OUTPUT_DIR .env
# Should show a valid path, not empty or commented out
Problem: Database initialization fails
Solution: Ensure database directory has correct permissions
# If using bind mount for database (default)
mkdir -p database
sudo chown -R 999:999 database # MariaDB runs as UID 999
# Or switch to named volume (see DATABASE.md)
Problem: Videos download but aren't visible in media server
Solution:
- Verify
YOUTUBE_OUTPUT_DIRpath is correct - Check that the path is accessible to both Youtarr and your media server
- Ensure permissions allow your media server to read files
- Trigger a manual library scan in your media server
When to Use This Method
Good use cases:
- Portainer/TrueNAS/similar Docker-native platforms where Git is unavailable
- Systems where Git is not installed or cannot be installed
- Testing Youtarr in isolated environments
- Automated deployment scripts (though Git is still recommended)
Bad use cases:
- Development or contribution work (clone the repo!)
- Systems with Git available (use Method 1 or 2 instead)
- Users uncomfortable with manual configuration and troubleshooting
- Production environments where easy updates are important
Getting Help
If you encounter issues with manual setup:
- Verify you followed all steps exactly as documented
- Check TROUBLESHOOTING.md for common issues
- Review Docker logs:
docker compose logs -f youtarr - When reporting issues on GitHub:
- Mention you're using manual installation (Method 3)
- Provide your
.envconfiguration (redact sensitive data) - Include relevant log output
- Describe your platform (Portainer, TrueNAS, etc.)
Note: Community support for manual installations may be limited compared to standard Git-based installations. The recommended installation methods provide better support and easier troubleshooting.
Docker Commands
Starting and Stopping
# Start containers
docker compose up -d
# Stop containers
docker compose down
# View status
docker compose ps
Viewing Logs
# All containers
docker compose logs -f
# Specific container
docker compose logs -f youtarr
docker compose logs -f youtarr-db
# Last 100 lines
docker compose logs --tail=100
Container Management
# Restart containers
docker compose restart
# Rebuild containers (after image updates)
docker compose up -d --build
# Remove containers (preserves data)
docker compose down
# Remove containers AND volumes (WARNING: deletes data)
docker compose down -v
Accessing Container Shell
# Application container
docker exec -it youtarr bash
# Database container
docker exec -it youtarr-db bash
# Direct database access
docker exec -it youtarr-db mysql -u root -p123qweasd youtarr
Environment Variables
Configuration Methods
You can configure environment variables in three ways:
-
Using .env file:
cp .env.example .env nano .env # Edit your configurationDocker Compose automatically reads
.envand substitutes variables in docker-compose.yml. -
Hardcoding in docker-compose.yml: Edit the compose file directly (not recommended - makes upgrades harder).
See: ENVIRONMENT_VARIABLES for more details
Platform Deployment Configuration
Youtarr supports platform-managed deployments (Elfhosted, Kubernetes, etc.) with four special environment variables:
Environment Variables
| Variable | Description | Example |
|---|---|---|
DATA_PATH | Video storage path inside container (only really needed for Elfhosted) | /storage/rclone/storagebox/youtube |
AUTH_ENABLED | Set to false to bypass internal authentication | false |
TRUST_PROXY | Controls whether Youtarr trusts proxy headers. Set false for direct exposure without a reverse proxy. | false |
PLEX_URL | Pre-configured Plex server URL, overrides plexIp and plexPort from config.json | http://plex:32400 |
Preset Credentials for Headless Deployments
For platforms where you cannot access http://localhost:3087 (Unraid, Kubernetes, etc.), you can either use the one-time setup token from container logs or seed the initial login without touching the UI by setting both environment variables below. These values will override and overwrite existing values in config.json
| Variable | Description |
|---|---|
AUTH_PRESET_USERNAME | Initial admin username. Trimmed and must be ≤ 32 characters. |
AUTH_PRESET_PASSWORD | Initial admin password (8–64 characters). Stored as a hash on first boot. |
If only one variable is present, or the values fall outside the validation rules, the preset is ignored and the setup-token wizard remains active.
What Happens in Platform Mode
When DATA_PATH is set:
-
Consolidated Storage: All persistent data aside from downloaded videos is stored under
/app/config/:/app/config/config.json- Configuration file/app/config/images/- Channel and video thumbnails/app/config/jobs/- Job state and metadata
-
Protected Settings: In the web UI:
- Plex URL field is disabled if
PLEX_URLis set - Users can still configure Plex API key and other settings
- Plex URL field is disabled if
When AUTH_ENABLED=false:
- No login required - authentication handled by platform (OAuth, Authelia, Cloudflared, etc...)
- Login/logout buttons hidden in UI
- All API endpoints accessible without token
Volume Management
Persistent Data Locations
- Database:
./databasedirectory - Config:
./configdirectory - Videos: User-specified directory (set via
YOUTUBE_OUTPUT_DIR) - Images/Jobs:
./server/imagesand./jobsdirectories
Network Storage (NAS) Configuration
Youtarr fully supports network-attached storage for your media library. This allows Youtarr and Plex to run on separate machines while sharing the same media storage.
Requirements
- Network share accessible from the Docker host
- Write permissions for Youtarr
- Read permissions for Plex (can be on a different machine)
Mounting NAS/Network Shares
Linux Example (NFS):
# Create mount point
sudo mkdir -p /mnt/nas/youtube
# Mount NFS share
sudo mount -t nfs nas-server:/volume/youtube /mnt/nas/youtube
# Make persistent (add to /etc/fstab)
nas-server:/volume/youtube /mnt/nas/youtube nfs defaults 0 0
Linux Example (SMB/CIFS):
# Create mount point
sudo mkdir -p /mnt/nas/youtube
# Mount SMB share (create credentials file for security)
echo "username=your_username" > ~/.smbcredentials
echo "password=your_password" >> ~/.smbcredentials
echo "domain=your_domain" >> ~/.smbcredentials
chmod 600 ~/.smbcredentials
# Mount
sudo mount -t cifs //nas-server/youtube /mnt/nas/youtube -o credentials=~/.smbcredentials,uid=1000,gid=1000
# Make persistent (add to /etc/fstab)
//nas-server/youtube /mnt/nas/youtube cifs credentials=/home/user/.smbcredentials,uid=1000,gid=1000 0 0
Windows Example (Network Drive):
# Map network drive in Windows
net use Z: \\nas-server\youtube /persistent:yes
# Use the mapped drive path in .env or during initial ./start.sh setup
# Enter: Z:/Youtube_videos
macOS Example (SMB):
# Mount via Finder or command line
mkdir ~/nas-youtube
mount_smbfs //username@nas-server/youtube ~/nas-youtube
# Use the mount path in .env or during initial ./start.sh setup
# Enter: /Users/username/nas-youtube
Docker Compose Configuration
Once your network storage is mounted on the host, configure it using YOUTUBE_OUTPUT_DIR:
Troubleshooting NAS Issues
Permission Denied Errors:
- Ensure the Docker user has write permissions to the NAS mount
- On Linux, check uid/gid in mount options match Docker container user
- Test write permissions:
touch /mnt/nas/youtube/test.txt
Mount Not Accessible in Container:
# Verify mount is active on host
mount | grep nas
# Test access from container
docker exec youtarr ls -la /usr/src/app/data
# Check permissions
docker exec youtarr touch /usr/src/app/data/test.txt
Slow Performance:
- Check network connectivity between Docker host and NAS
- Consider mounting with performance options:
# NFS with async writes mount -t nfs -o async,noatime nas-server:/youtube /mnt/nas/youtube # SMB with larger buffer mount -t cifs -o cache=loose,rsize=130048,wsize=130048 //nas-server/youtube /mnt/nas/youtube
Plex Can't See Files:
- Verify Plex has read access to the same network path
- Ensure consistent file paths between Youtarr and Plex
- Check file permissions after download (should be readable by Plex user)
Backup and Restore
Backup database:
docker exec youtarr-db mysqldump -u root -p123qweasd youtarr > backup.sql
Restore database:
docker exec -i youtarr-db mysql -u root -p123qweasd youtarr < backup.sql
Backup all data:
# Stop containers first
./stop.sh
# Create backup
tar -czf youtarr-backup.tar.gz config/ database/ jobs/ server/images/
# Include database directory (default compose setup)
tar -czf db-backup.tar.gz database/
# If you switched to a named Docker volume, adjust the command accordingly:
# docker run --rm -v your_volume_name:/data -v $(pwd):/backup alpine tar -czf /backup/db-backup.tar.gz -C /data .
Health Checks
The application container includes health checks:
- Checks database connectivity before starting
- Retries on failure with exponential backoff
- Maximum 30 retry attempts
Network Configuration
- Internal network:
youtarr-network - Container communication uses internal hostnames
- External access through mapped ports
Plex Server Communication
Same Machine Setup
When Youtarr and Plex run on the same machine:
- Docker Desktop (Windows/macOS):
host.docker.internalor host LAN IP (e.g.,192.168.x.x) - Docker on macOS without Docker Desktop (e.g., Colima): host LAN IP (e.g.,
192.168.x.x) orhost.lima.internal - Docker on Linux: host LAN IP (e.g.,
192.168.x.x). The default bridge IP (172.17.0.1) usually won't work unless Plex is bound to the Docker bridge. - Explicit host mapping: add
--add-host host.docker.internal:<host-ip>when starting the container if you prefer that hostname on Linux. - Plex defaults to port
32400. If you use a custom Plex port, update the Plex Port field or include the port inPLEX_URL.
Separate Machine Setup
When Youtarr and Plex run on different machines:
- Use Plex server's IP address or hostname
- Example:
http://192.168.1.100:32400orhttp://plex-server.local:32400 - Ensure network connectivity between machines
- Both machines must have access to the same media storage location
Testing Plex Connection
# From Youtarr container
docker exec youtarr curl -I http://your-plex-server:32400/web
# Should return HTTP 200 or 301
Updating to Latest Version
# Stop containers
docker compose down
# Ensure you are on the `main` branch and then
git pull
# Pull latest images
docker compose pull
# Start with new images
docker compose up -d
Performance Tuning
Memory Limits
Add to docker-compose.yml if needed:
services:
youtarr:
mem_limit: 2g
mem_reservation: 1g
CPU Limits
services:
youtarr:
cpus: '2.0'
Common Docker Issues
Disk Space
Check available space:
docker system df
Clean up unused resources:
docker system prune -a
Permission Issues
If videos aren't accessible:
- Check directory permissions
- Ensure Docker has access to the directory
- On Linux, may need to adjust user/group IDs
Port Conflicts
If ports are already in use:
-
Check what's using the port:
netstat -tulpn | grep 3087 -
Either stop the conflicting service or change Youtarr's ports in docker-compose.yml
Docker Compose Version
The start/stop scripts automatically detect your Docker Compose version:
docker compose(v2) - Recommendeddocker-compose(v1) - Legacy support
To check your version:
docker compose version
# or
docker-compose version
Security Considerations
Network Isolation
Containers communicate on isolated network. External access only through explicitly mapped ports.
Running as Non-Root
For enhanced security on Linux, configure user in .env:
YOUTARR_UID=1000
YOUTARR_GID=1000
** WARNING, if previously running as root, you will need to MANUALLY change ownership of your YOUTUBE_OUTPUT_DIR as well as: **
config/*
jobs/*
server/images/*
If adjusting these settings, stop Youtarr, then fix ownership, then update .env, then restart.
Example to fix ownership (example YOUTUBE_OUTPUT_DIR given)
sudo chown -R 1000:1000 /mnt/c/my_youtarr_videos ./config ./jobs ./server/images
Development with Docker
See DEVELOPMENT.md for running Youtarr in development mode with Docker.