Skip to content

Commit 3bbc638

Browse files
committed
Add: Downtify
1 parent 7e4d26b commit 3bbc638

3 files changed

Lines changed: 201 additions & 0 deletions

File tree

‎ct/downtify.sh‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env bash
2+
_CS_DEFAULT_URL="https://raw.githubusercontent.com/community-scripts/DevScripts/main"
3+
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
4+
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
5+
# Copyright (c) 2021-2026 community-scripts ORG
6+
# Author: MickLesk (CanbiZ)
7+
# License: MIT | https://github.com/community-scripts/DevScripts/raw/main/LICENSE
8+
# Source: https://github.com/henriquesebastiao/downtify
9+
10+
APP="Downtify"
11+
var_tags="${var_tags:-music;downloader}"
12+
var_cpu="${var_cpu:-2}"
13+
var_ram="${var_ram:-1024}"
14+
var_disk="${var_disk:-8}"
15+
var_os="${var_os:-debian}"
16+
var_version="${var_version:-13}"
17+
var_arm64="${var_arm64:-yes}"
18+
var_unprivileged="${var_unprivileged:-1}"
19+
20+
header_info "$APP"
21+
variables
22+
color
23+
catch_errors
24+
25+
function update_script() {
26+
header_info
27+
check_container_storage
28+
check_container_resources
29+
30+
if [[ ! -d /opt/downtify ]]; then
31+
msg_error "No Downtify Installation Found!"
32+
exit
33+
fi
34+
35+
if check_for_gh_release "downtify" "henriquesebastiao/downtify"; then
36+
msg_info "Stopping Downtify"
37+
systemctl stop downtify
38+
msg_ok "Stopped Downtify"
39+
40+
PYTHON_VERSION="3.14" setup_uv
41+
NODE_VERSION="26" setup_nodejs
42+
fetch_and_deploy_gh_release "deno" "denoland/deno" "prebuild" "latest" "/usr/local/bin" "deno-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.zip"
43+
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "downtify" "henriquesebastiao/downtify" "tarball"
44+
45+
msg_info "Building Downtify"
46+
cd /opt/downtify/frontend
47+
$STD npm ci
48+
$STD npm run build
49+
rm -rf /opt/downtify/frontend/node_modules
50+
cd /opt/downtify
51+
$STD uv sync --frozen --no-dev --python 3.14
52+
msg_ok "Built Downtify"
53+
54+
msg_info "Starting Downtify"
55+
systemctl start downtify
56+
msg_ok "Started Downtify"
57+
msg_ok "Updated successfully!"
58+
fi
59+
exit
60+
}
61+
62+
start
63+
build_container
64+
description
65+
66+
msg_ok "Completed Successfully!\n"
67+
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
68+
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
69+
echo -e "${GATEWAY}${BGN}http://${IP}:8000${CL}"
70+
echo -e "${INFO}${YW}Sign in as admin / downtify and change the password right away${CL}"

‎install/downtify-install.sh‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright (c) 2021-2026 community-scripts ORG
4+
# Author: MickLesk (CanbiZ)
5+
# License: MIT | https://github.com/community-scripts/DevScripts/raw/main/LICENSE
6+
# Source: https://github.com/henriquesebastiao/downtify
7+
8+
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
9+
color
10+
verb_ip6
11+
catch_errors
12+
setting_up_container
13+
network_check
14+
update_os
15+
16+
setup_ffmpeg
17+
PYTHON_VERSION="3.14" setup_uv
18+
NODE_VERSION="26" setup_nodejs
19+
# yt-dlp solves YouTube's JavaScript challenges with Deno
20+
fetch_and_deploy_gh_release "deno" "denoland/deno" "prebuild" "latest" "/usr/local/bin" "deno-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.zip"
21+
fetch_and_deploy_gh_release "downtify" "henriquesebastiao/downtify" "tarball"
22+
23+
msg_info "Building Downtify"
24+
cd /opt/downtify/frontend
25+
$STD npm ci
26+
$STD npm run build
27+
rm -rf /opt/downtify/frontend/node_modules
28+
cd /opt/downtify
29+
# pyproject.toml sets [tool.uv] upgrade = true, so --locked fails whenever PyPI has anything newer than uv.lock
30+
$STD uv sync --frozen --no-dev --python 3.14
31+
msg_ok "Built Downtify"
32+
33+
msg_info "Configuring Downtify"
34+
mkdir -p /opt/downtify_data/{data,downloads}
35+
cat <<EOF >/opt/downtify_data/.env
36+
DATABASE_DIR=/opt/downtify_data/data
37+
DOWNLOAD_DIR=/opt/downtify_data/downloads
38+
EOF
39+
msg_ok "Configured Downtify"
40+
41+
msg_info "Creating Downtify Service"
42+
cat <<EOF >/etc/systemd/system/downtify.service
43+
[Unit]
44+
Description=Downtify
45+
After=network-online.target
46+
Wants=network-online.target
47+
48+
[Service]
49+
Type=simple
50+
User=root
51+
WorkingDirectory=/opt/downtify
52+
EnvironmentFile=/opt/downtify_data/.env
53+
Environment=WEB_GUI_LOCATION=/opt/downtify/frontend/dist
54+
ExecStart=/opt/downtify/.venv/bin/python /opt/downtify/main.py web
55+
Restart=on-failure
56+
RestartSec=5
57+
58+
[Install]
59+
WantedBy=multi-user.target
60+
EOF
61+
systemctl enable -q --now downtify
62+
msg_ok "Created Downtify Service"
63+
64+
motd_ssh
65+
customize
66+
cleanup_lxc

‎json/downtify.json‎

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"name": "Downtify",
3+
"slug": "downtify",
4+
"categories": [
5+
13
6+
],
7+
"date_created": "2026-10-11",
8+
"type": "ct",
9+
"updateable": true,
10+
"privileged": false,
11+
"architectures": [
12+
"amd64",
13+
"arm64"
14+
],
15+
"interface_port": 8000,
16+
"documentation": "https://downtify.henriquesebastiao.com/getting-started/",
17+
"website": "https://downtify.henriquesebastiao.com/",
18+
"repository": "https://github.com/henriquesebastiao/downtify",
19+
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/downtify.webp",
20+
"description": "Downtify is a self-hosted music downloader with a web interface. Paste a Spotify, YouTube Music or Deezer link, or search by name, and it reads the metadata without a Spotify account or API key, downloads the matching audio from YouTube Music with yt-dlp and tags it with cover art and lyrics. It also has a library with a built-in player, a Playlist Monitor that downloads new tracks from watched playlists and artists, podcasts, M3U export for Jellyfin, Navidrome and Plex, and accounts for several users.",
21+
"install_methods": [
22+
{
23+
"type": "default",
24+
"script": "ct/downtify.sh",
25+
"config_path": "/opt/downtify_data/.env",
26+
"resources": {
27+
"cpu": 2,
28+
"ram": 1024,
29+
"hdd": 8,
30+
"os": "Debian",
31+
"version": "13"
32+
}
33+
}
34+
],
35+
"default_credentials": {
36+
"username": "admin",
37+
"password": "downtify"
38+
},
39+
"notes": [
40+
{
41+
"text": "Every Downtify server starts with the same login, admin / downtify. Change the password right after the first sign-in in Settings > General > Account. If you forget it, reset it to the default with: cd /opt/downtify && set -a && . /opt/downtify_data/.env && set +a && .venv/bin/python main.py auth-reset",
42+
"type": "warning"
43+
},
44+
{
45+
"text": "Downtify serves plain HTTP on port 8000. Do not expose it to the internet directly; put it behind a reverse proxy with HTTPS. Add the proxy's address as DOWNTIFY_TRUSTED_PROXIES=<ip> to /opt/downtify_data/.env and have the proxy send X-Forwarded-Host/-Proto/-For, otherwise Downtify answers \"Cross-site request refused\" when the proxy rewrites the Host header, and rate-limits sign-ins by the proxy's address.",
46+
"type": "warning"
47+
},
48+
{
49+
"text": "Music is saved to /opt/downtify_data/downloads. To keep it on a NAS or share it with a media server, bind-mount that folder from the host, e.g. pct set <CTID> -mp0 /mnt/media/music,mp=/opt/downtify_data/downloads. In an unprivileged container the host folder must be writable by UID 100000.",
50+
"type": "info"
51+
},
52+
{
53+
"text": "Settings, accounts, the Playlist Monitor database and an uploaded cookies.txt live in /opt/downtify_data/data, outside the app directory, so updates keep them. Optional variables from the documentation (TZ, DOWNTIFY_MONITOR_SYNC_TIME, DOWNTIFY_FORCE_IPV4, ...) go in /opt/downtify_data/.env, followed by systemctl restart downtify.",
54+
"type": "info"
55+
},
56+
{
57+
"text": "If YouTube starts refusing downloads (\"Sign in to confirm you're not a bot\", age-restricted tracks), upload a cookies.txt from a logged-in browser in Settings > YouTube cookies.",
58+
"type": "info"
59+
},
60+
{
61+
"text": "Downtify downloads the audio from YouTube. Whether that is allowed depends on YouTube's terms of service and the law where you live.",
62+
"type": "info"
63+
}
64+
]
65+
}

0 commit comments

Comments
 (0)