Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions ct/libre-closet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env bash
_CS_DEFAULT_URL="https://raw.githubusercontent.com/community-scripts/DevScripts/main"
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Lazztech
# License: MIT | https://github.com/community-scripts/DevScripts/raw/main/LICENSE
# Source: https://github.com/Lazztech/Libre-Closet

APP="Libre-Closet"
var_tags="${var_tags:-wardrobe;lifestyle}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
#var_arm64="${var_arm64:-no}" # unset = ask the user; set yes/no only when verified
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/libre-closet ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi

if check_for_gh_tag "libre-closet" "Lazztech/Libre-Closet"; then
msg_info "Stopping Libre Closet"
systemctl stop libre-closet
msg_ok "Stopped Libre Closet"

NODE_VERSION="22" setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_tag "libre-closet" "Lazztech/Libre-Closet"

msg_info "Building Libre Closet"
cd /opt/libre-closet
$STD npm ci
$STD npm run build
msg_ok "Built Libre Closet"

msg_info "Starting Libre Closet"
systemctl start libre-closet
msg_ok "Started Libre Closet"
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 "${GATEWAY}${BGN}http://${IP}:3000${CL}"
61 changes: 61 additions & 0 deletions install/libre-closet-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash

# Copyright (c) 2021-2026 community-scripts ORG
# Author: Lazztech
# License: MIT | https://github.com/community-scripts/DevScripts/raw/main/LICENSE
# Source: https://github.com/Lazztech/Libre-Closet

source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os

NODE_VERSION="22" setup_nodejs

fetch_and_deploy_gh_tag "libre-closet" "Lazztech/Libre-Closet"

msg_info "Building Libre Closet"
cd /opt/libre-closet
$STD npm ci
$STD npm run build
msg_ok "Built Libre Closet"

msg_info "Configuring Libre Closet"
mkdir -p /opt/libre-closet_data
cat <<EOF >/opt/libre-closet_data/.env
NODE_ENV=production
APP_NAME=Libre Closet
DATA_PATH=/opt/libre-closet_data
AUTH_ENABLED=false
PWA_ENABLED=true
ACCESS_TOKEN_SECRET=$(openssl rand -base64 60)
EOF
chmod 600 /opt/libre-closet_data/.env
msg_ok "Configured Libre Closet"

msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/libre-closet.service
[Unit]
Description=Libre Closet
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/libre-closet
EnvironmentFile=/opt/libre-closet_data/.env
ExecStart=/usr/bin/node dist/main
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now libre-closet
msg_ok "Created Service"

motd_ssh
customize
cleanup_lxc
49 changes: 49 additions & 0 deletions json/libre-closet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "Libre Closet",
"slug": "libre-closet",
"categories": [0],
"date_created": "2026-10-14",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": "https://github.com/Lazztech/Libre-Closet",
"website": "https://librecloset.lazz.tech",
"repository": "https://github.com/Lazztech/Libre-Closet",
"architectures": ["amd64"],
"platforms": ["pve"],
"logo": "https://raw.githubusercontent.com/Lazztech/Libre-Closet/main/public/assets/lazztech_icon.png",
"description": "Libre Closet is a free, open-source, self-hosted wardrobe organizer. Catalog your clothes, upload photos, build outfits on a calendar, and open everything from your phone as an offline-ready PWA. It defaults to SQLite and local file storage, so there is no separate database to run. This script builds the Node.js app from source and runs it directly on the container without Docker.",
"install_methods": [
{
"type": "default",
"script": "ct/libre-closet.sh",
"config_path": "/opt/libre-closet_data/.env",
"resources": {
"cpu": 1,
"ram": 2048,
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "There is no login by default. Open http://<IP>:3000 and start cataloging. To require accounts, set AUTH_ENABLED=true in /opt/libre-closet_data/.env, set a long random ACCESS_TOKEN_SECRET, and restart the service.",
"type": "warning"
},
{
"text": "The SQLite database and uploaded photos live in /opt/libre-closet_data. Back that directory up to preserve your wardrobe across reinstalls.",
"type": "info"
},
{
"text": "This install builds from source with Node.js 22, so the first install and each update need a few minutes of CPU; at least 2 GB RAM is required for the build (1 GB is not enough).",
"type": "warning"
}
]
}
Loading