Compare commits

...

9 Commits

Author SHA1 Message Date
CanbiZ (MickLesk)
e987ed1892 Update linkding-install.sh 2026-02-16 09:50:20 +01:00
CanbiZ (MickLesk)
24bc2ffdfd Update date_created to 2026-02-16 2026-02-16 09:49:35 +01:00
CanbiZ (MickLesk)
20d06bab03 Update messages for LinkDing in script 2026-02-16 09:49:09 +01:00
push-app-to-main[bot]
c93f3c40c4 Add linkding (ct) 2026-02-16 08:45:21 +00:00
CanbiZ (MickLesk)
704f8d7e10 hotfix pipefail issue alpine-teamspeak
Replace the final '| head -1' in both install and ct scripts with 'awk 'NR==1'' to pick the first matching Teamspeak release line. In the ct script the previous temporary toggling of pipefail was also removed, simplifying the command. This improves compatibility and reduces reliance on an extra utility in minimal environments.
2026-02-16 08:57:06 +01:00
community-scripts-pr-app[bot]
d7fbbbde0f Update CHANGELOG.md (#11974)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-16 07:51:33 +00:00
CanbiZ (MickLesk)
2edd2ffaf8 fix: remove duplicate error handler from alpine-install.func (#11971)
- Remove legacy error_handler(), on_exit(), on_interrupt(), on_terminate() and set/trap definitions from alpine-install.func (already provided by error_handler.func which is sourced on line 10)

- The local error_handler() expected positional args as required, but catch_errors() sets trap as 'error_handler' (without args), causing unbound variable error with set -u (nounset)

- error_handler.func uses default values which is set -u safe

- Also align legacy trap in install.func network_check() to standard format

Fixes #11929
2026-02-16 08:51:05 +01:00
community-scripts-pr-app[bot]
cba1a0bb6b Update CHANGELOG.md (#11972)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-16 07:50:08 +00:00
summoningpixels
97bc69452d Update OpenCloud LXC webpage to include services ports for reverse proxy users (#11969)
Included it directly in the reverse proxy warning note
2026-02-16 08:49:42 +01:00
9 changed files with 261 additions and 40 deletions

View File

@@ -412,6 +412,18 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- jellyseerr/overseerr: Migrate update script to Seerr; prompt rerun [@MickLesk](https://github.com/MickLesk) ([#11965](https://github.com/community-scripts/ProxmoxVE/pull/11965))
### 💾 Core
- #### 🔧 Refactor
- core: remove duplicate error handler from alpine-install.func [@MickLesk](https://github.com/MickLesk) ([#11971](https://github.com/community-scripts/ProxmoxVE/pull/11971))
### 🌐 Website
- #### 📝 Script Information
- Update OpenCloud LXC webpage to include services ports [@summoningpixels](https://github.com/summoningpixels) ([#11969](https://github.com/community-scripts/ProxmoxVE/pull/11969))
## 2026-02-15
### 🆕 New Scripts

View File

@@ -27,7 +27,7 @@ function update_script() {
exit
fi
set +o pipefail && RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9.]*[0-9]\).*/\1/p' | head -1) && set -o pipefail
RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9.]*[0-9]\).*/\1/p' | awk 'NR==1')
if [ "${RELEASE}" != "$(cat ~/.teamspeak-server)" ] || [ ! -f ~/.teamspeak-server ]; then
msg_info "Updating ${APP} LXC"

79
ct/linkding.sh Normal file
View File

@@ -0,0 +1,79 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (MickLesk)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://linkding.link/
APP="linkding"
var_tags="${var_tags:-bookmarks;management}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/linkding ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "linkding" "sissbruecker/linkding"; then
msg_info "Stopping Services"
systemctl stop nginx linkding linkding-tasks
msg_ok "Stopped Services"
msg_info "Backing up Data"
cp -r /opt/linkding/data /opt/linkding_data_backup
cp /opt/linkding/.env /opt/linkding_env_backup
msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "linkding" "sissbruecker/linkding"
msg_info "Restoring Data"
cp -r /opt/linkding_data_backup/. /opt/linkding/data
cp /opt/linkding_env_backup /opt/linkding/.env
rm -rf /opt/linkding_data_backup /opt/linkding_env_backup
ln -sf /usr/lib/x86_64-linux-gnu/mod_icu.so /opt/linkding/libicu.so
msg_ok "Restored Data"
msg_info "Updating LinkDing"
cd /opt/linkding
rm -f bookmarks/settings/dev.py
touch bookmarks/settings/custom.py
$STD npm ci
$STD npm run build
$STD uv sync --no-dev --frozen
$STD uv pip install gunicorn
set -a && source /opt/linkding/.env && set +a
$STD /opt/linkding/.venv/bin/python manage.py migrate
$STD /opt/linkding/.venv/bin/python manage.py collectstatic --no-input
msg_ok "Updated LinkDing"
msg_info "Starting Services"
systemctl start nginx linkding linkding-tasks
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9090${CL}"

View File

@@ -0,0 +1,40 @@
{
"name": "linkding",
"slug": "linkding",
"categories": [
12
],
"date_created": "2026-02-16",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 9090,
"documentation": "https://linkding.link/",
"website": "https://linkding.link/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/linkding.webp",
"config_path": "/opt/linkding/.env",
"description": "linkding is a self-hosted bookmark manager that is designed to be minimal, fast, and easy to set up. It features a clean UI, tag-based organization, bulk editing, Markdown notes, read it later functionality, sharing, REST API, and browser extensions for Firefox and Chrome.",
"install_methods": [
{
"type": "default",
"script": "ct/linkding.sh",
"resources": {
"cpu": 2,
"ram": 1024,
"hdd": 4,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "admin",
"password": null
},
"notes": [
{
"text": "Admin credentials are stored in /opt/linkding/.env",
"type": "info"
}
]
}

View File

@@ -33,7 +33,7 @@
},
"notes": [
{
"text": "Valid TLS certificates and fully-qualified domain names behind a reverse proxy (Caddy) for 3 services - OpenCloud, Collabora, and WOPI are **REQUIRED**",
"text": "Valid TLS certificates and fully-qualified domain names behind a reverse proxy (Caddy) for 3 services - OpenCloud (port: 9200), Collabora (port: 9980), and WOPI (port: 9300) are **REQUIRED**",
"type": "warning"
},
{

View File

@@ -20,7 +20,7 @@ $STD apk add --no-cache \
libc6-compat
msg_ok "Installed dependencies"
RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9.]*[0-9]\).*/\1/p' | head -1)
RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9.]*[0-9]\).*/\1/p' | awk 'NR==1')
msg_info "Installing Teamspeak Server v${RELEASE}"
mkdir -p /opt/teamspeak-server
cd /opt/teamspeak-server

126
install/linkding-install.sh Normal file
View File

@@ -0,0 +1,126 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (MickLesk)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://linkding.link/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
pkg-config \
python3-dev \
nginx \
libpq-dev \
libicu-dev \
libsqlite3-dev \
libffi-dev
msg_ok "Installed Dependencies"
NODE_VERSION="22" setup_nodejs
setup_uv
fetch_and_deploy_gh_release "linkding" "sissbruecker/linkding"
msg_info "Building Frontend"
cd /opt/linkding
$STD npm ci
$STD npm run build
ln -sf /usr/lib/x86_64-linux-gnu/mod_icu.so /opt/linkding/libicu.so
msg_ok "Built Frontend"
msg_info "Setting up LinkDing"
rm -f bookmarks/settings/dev.py
touch bookmarks/settings/custom.py
$STD uv sync --no-dev --frozen
$STD uv pip install gunicorn
mkdir -p data/{favicons,previews,assets}
ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
cat <<EOF >/opt/linkding/.env
LD_SUPERUSER_NAME=admin
LD_SUPERUSER_PASSWORD=${ADMIN_PASS}
LD_CSRF_TRUSTED_ORIGINS=http://${LOCAL_IP}:9090
EOF
set -a && source /opt/linkding/.env && set +a
$STD /opt/linkding/.venv/bin/python manage.py generate_secret_key
$STD /opt/linkding/.venv/bin/python manage.py migrate
$STD /opt/linkding/.venv/bin/python manage.py enable_wal
$STD /opt/linkding/.venv/bin/python manage.py create_initial_superuser
$STD /opt/linkding/.venv/bin/python manage.py collectstatic --no-input
msg_ok "Set up LinkDing"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/linkding.service
[Unit]
Description=linkding Bookmark Manager
After=network.target
[Service]
User=root
WorkingDirectory=/opt/linkding
EnvironmentFile=/opt/linkding/.env
ExecStart=/opt/linkding/.venv/bin/gunicorn \
--bind 127.0.0.1:8000 \
--workers 3 \
--threads 2 \
--timeout 120 \
bookmarks.wsgi:application
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/linkding-tasks.service
[Unit]
Description=linkding Background Tasks
After=network.target
[Service]
User=root
WorkingDirectory=/opt/linkding
EnvironmentFile=/opt/linkding/.env
ExecStart=/opt/linkding/.venv/bin/python manage.py run_huey
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<'EOF' >/etc/nginx/sites-available/linkding
server {
listen 9090;
server_name _;
client_max_body_size 20M;
location /static/ {
alias /opt/linkding/static/;
expires 30d;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
}
EOF
$STD rm -f /etc/nginx/sites-enabled/default
$STD ln -sf /etc/nginx/sites-available/linkding /etc/nginx/sites-enabled/linkding
systemctl enable -q --now nginx linkding linkding-tasks
systemctl restart nginx
msg_ok "Created Services"
motd_ssh
customize
cleanup_lxc

View File

@@ -34,42 +34,6 @@ EOF
fi
}
set -Eeuo pipefail
trap 'error_handler $? $LINENO "$BASH_COMMAND"' ERR
trap on_exit EXIT
trap on_interrupt INT
trap on_terminate TERM
error_handler() {
local exit_code="$1"
local line_number="$2"
local command="$3"
if [[ "$exit_code" -eq 0 ]]; then
return 0
fi
printf "\e[?25h"
echo -e "\n${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\n"
exit "$exit_code"
}
on_exit() {
local exit_code="$?"
[[ -n "${lockfile:-}" && -e "$lockfile" ]] && rm -f "$lockfile"
exit "$exit_code"
}
on_interrupt() {
echo -e "\n${RD}Interrupted by user (SIGINT)${CL}"
exit 130
}
on_terminate() {
echo -e "\n${RD}Terminated by signal (SIGTERM)${CL}"
exit 143
}
# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection
setting_up_container() {
msg_info "Setting up Container OS"

View File

@@ -172,7 +172,7 @@ network_check() {
fi
set -e
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
trap 'error_handler' ERR
}
# ==============================================================================