Nomploy Nomad Packs

← All packs

metube v0.1.0

Apps

MeTube — a clean, self-hosted web UI for yt-dlp: paste a video or playlist URL and download it (video or audio, chosen quality/format) straight to your server. Deployed as a host-networked Nomad service with a downloads volume.

nomad-pack run metube --registry nomploy
…or one line (add registry + run)
curl -fsSL https://packs.nomploy.com/install.sh | sh -s -- metube

Needs nomad-pack on PATH. The script only adds the nomploy registry and runs this pack.

1 task http 8081 1 volume image ghcr.io/alexta69/metube:latest tracks :latest image bumped today
Variables 10
values.hcl

Save as values.hcl, edit, then run:

nomad-pack run metube -f values.hcl --registry nomploy
# The name of the Nomad job.
job_name = "metube"

# The Nomad namespace to deploy into.
namespace = "default"

# The datacenters to deploy to.
datacenters = ["*"]

# The MeTube container image. Pin a tag in production.
image = "ghcr.io/alexta69/metube:latest"

# Host port for the MeTube web UI. The container listens on 8081.
port = 8081

# User ID that owns downloaded files (UID).
uid = 1000

# Group ID that owns downloaded files (GID).
gid = 1000

# Named volume for downloaded files (/downloads).
downloads_volume = "metube_downloads"

# Placement constraints. Pin to the node holding the volume. On a nomploy cluster: attribute = "$${meta.nomploy_control_plane}", operator = "=", value = "true".
constraints = []

# Resources for the MeTube task.
resources = {
    cpu    = 500
    memory = 256
  }
NameTypeDefaultDescription
job_name string
"metube"
The name of the Nomad job.
namespace string
"default"
The Nomad namespace to deploy into.
datacenters list
["*"]
The datacenters to deploy to.
image string
"ghcr.io/alexta69/metube:latest"
The MeTube container image. Pin a tag in production.
port number
8081
Host port for the MeTube web UI. The container listens on 8081.
uid number
1000
User ID that owns downloaded files (UID).
gid number
1000
Group ID that owns downloaded files (GID).
downloads_volume string
"metube_downloads"
Named volume for downloaded files (/downloads).
constraints list
[]
Placement constraints. Pin to the node holding the volume. On a nomploy cluster: attribute = "$${meta.nomploy_control_plane}", operator = "=", value = "true".
resources object
{
    cpu    = 500
    memory = 256
  }
Resources for the MeTube task.
Back up this pack

This pack stores data in one Docker named volume: metube_downloads

restic

# Run on the node hosting this pack. Point restic at your repo first:
#   export RESTIC_REPOSITORY="s3:https://<account>.r2.cloudflarestorage.com/<bucket>"
#   export RESTIC_PASSWORD="<repo-password>"
#   export AWS_ACCESS_KEY_ID=<key>  AWS_SECRET_ACCESS_KEY=<secret>
restic backup \
  /var/lib/docker/volumes/metube_downloads/_data

rclone (sync to S3/R2)

rclone sync /var/lib/docker/volumes/metube_downloads/_data backup:<bucket>/metube_downloads

Paths assume the default Docker volume location (/var/lib/docker/volumes). Restore by stopping the job, restoring files into the same volume, and re-running the pack.

Readme

metube

MeTube — a clean, self-hosted web UI for yt-dlp. Paste a video or playlist URL, choose the format and quality, and it downloads straight to your server — great for archiving talks, music, and playlists to your own storage.

Single host-networked Nomad service with a downloads volume.

Deploy

nomad-pack registry add nomploy https://github.com/Nomploy/nomad-packs
nomad-pack run metube --registry=nomploy

Configure

Variable Default Description
port 8081 Web UI port (PORT).
downloads_volume metube_downloads /downloads — where files are saved.
uid / gid 1000 / 1000 Ownership of downloaded files (UID/GID).
image ghcr.io/alexta69/metube:latest Container image. Pin a tag in production.
resources { cpu = 500, memory = 256 } Task resources.

Paste a URL and download; files land in the downloads_volume (point a media pack like jellyfin or navidrome at them). MeTube has no authentication — keep it internal or behind an authenticating reverse proxy, and only download content you have the rights to. Pin the job to the node holding the volume with constraints.