diff --git a/ct/deferred/manyfold.sh b/ct/deferred/manyfold.sh deleted file mode 100644 index 2d782d551..000000000 --- a/ct/deferred/manyfold.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) -# Copyright (c) 2021-2025 community-scripts ORG -# Author: bvdberg01 -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/manyfold3d/manyfold - -APP="Manyfold" -var_tags="${var_tags:-network}" -var_cpu="${var_cpu:-4}" -var_ram="${var_ram:-4096}" -var_disk="${var_disk:-15}" -var_os="${var_os:-debian}" -var_version="${var_version:-12}" -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/manyfold ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - RELEASE=$(curl -fsSL https://api.github.com/repos/benjaminjonard/manyfold/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') - if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then - msg_info "Stopping Service" - systemctl stop apache2 - msg_ok "Stopped Service" - - msg_info "Updating ${APP} to v${RELEASE}" - cd /opt - mv /opt/manyfold/ /opt/manyfold-backup - - echo "${RELEASE}" >/opt/${APP}_version.txt - msg_ok "Updated $APP to v${RELEASE}" - - msg_info "Starting Service" - systemctl start service - msg_ok "Started Service" - - msg_info "Cleaning up" - rm -r "/opt/${RELEASE}.zip" - rm -r /opt/manyfold-backup - msg_ok "Cleaned" - msg_ok "Updated Successfully" - else - msg_ok "No update required. ${APP} is already at v${RELEASE}" - 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}${CL}" diff --git a/ct/manyfold.sh b/ct/manyfold.sh new file mode 100644 index 000000000..a7f359d5f --- /dev/null +++ b/ct/manyfold.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: bvdberg01 +# Co-Author: SunFlowerOwl +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/manyfold3d/manyfold + +APP="Manyfold" +var_tags="${var_tags:-3d}" +var_cpu="${var_cpu:-4}" +var_ram="${var_ram:-4096}" +var_disk="${var_disk:-15}" +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/manyfold ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if check_for_gh_release "manyfold" "manyfold3d/manyfold"; then + msg_info "Stopping Service" + systemctl stop manyfold.target manyfold-rails.1 manyfold-default_worker.1 manyfold-performance_worker.1 + msg_ok "Stopped Service" + + msg_info "Backing up data" + source /opt/manyfold/.env + mv /opt/manyfold/app/storage /opt/manyfold/app/tmp /opt/manyfold/app/config/credentials.yml.enc /opt/manyfold/app/config/master.key ~/ + $STD tar -cvzf "/opt/manyfold_${APP_VERSION}_backup.tar.gz" /opt/manyfold/app/ + rm -rf /opt/manyfold/app/ + msg_ok "Backed-up data" + + fetch_and_deploy_gh_release "manyfold" "manyfold3d/manyfold" "tarball" "latest" "/opt/manyfold/app" + + msg_info "Configuring manyfold environment" + RUBY_INSTALL_VERSION=$(cat /opt/manyfold/app/.ruby-version) + YARN_VERSION=$(grep '"packageManager":' /opt/manyfold/app/package.json | sed -E 's/.*"(yarn@[0-9\.]+)".*/\1/') + RELEASE=$(get_latest_github_release "manyfold3d/manyfold") + sed -i "s/^export APP_VERSION=.*/export APP_VERSION=$RELEASE/" "/opt/manyfold/.env" + cat </opt/manyfold/user_setup.sh +#!/bin/bash + +source /opt/manyfold/.env +export PATH="/home/manyfold/.rbenv/bin:\$PATH" +eval "\$(/home/manyfold/.rbenv/bin/rbenv init - bash)" +cd /opt/manyfold/app +rbenv global $RUBY_INSTALL_VERSION +gem install bundler +bundle install +gem install sidekiq +gem install foreman +corepack enable yarn +corepack prepare $YARN_VERSION --activate +corepack use $YARN_VERSION +bin/rails db:migrate +bin/rails assets:precompile +EOF + msg_ok "Configured manyfold environment" + + RUBY_VERSION=${RUBY_INSTALL_VERSION} RUBY_INSTALL_RAILS="true" HOME=/home/manyfold setup_ruby + + msg_info "Installing Manyfold" + chown -R manyfold:manyfold /home/manyfold/.rbenv + rm -rf /opt/manyfold/app/storage /opt/manyfold/app/tmp /opt/manyfold/app/config/credentials.yml.enc + mv ~/storage ~/tmp /opt/manyfold/app/ + mv ~/credentials.yml.enc ~/master.key /opt/manyfold/app/config/ + chown -R manyfold:manyfold /opt/manyfold + chmod +x /opt/manyfold/user_setup.sh + $STD sudo -u manyfold bash /opt/manyfold/user_setup.sh + rm -f /opt/manyfold/user_setup.sh + msg_ok "Installed manyfold" + + msg_info "Restoring Service" + source /opt/manyfold/.env + export PATH="/home/manyfold/.rbenv/shims:/home/manyfold/.rbenv/bin:$PATH" + $STD foreman export systemd /etc/systemd/system -a manyfold -u manyfold -f /opt/manyfold/app/Procfile + for f in /etc/systemd/system/manyfold-*.service; do + sed -i "s|/bin/bash -lc '|/bin/bash -lc 'source /opt/manyfold/.env \&\& |" "$f" + done + systemctl enable -q --now manyfold.target manyfold-rails.1 manyfold-default_worker.1 manyfold-performance_worker.1 + msg_ok "Restored Service" + fi + + msg_info "Cleaning up" + $STD apt -y autoremove + $STD apt -y autoclean + $STD apt -y clean + msg_ok "Cleaned" + 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}${CL}" diff --git a/frontend/public/json/manyfold.json b/frontend/public/json/manyfold.json new file mode 100644 index 000000000..26bfa13d9 --- /dev/null +++ b/frontend/public/json/manyfold.json @@ -0,0 +1,40 @@ +{ + "name": "Manyfold", + "slug": "manyfold", + "categories": [ + 24 + ], + "date_created": "2025-03-18", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 80, + "documentation": "https://manyfold.app/sysadmin/", + "website": "https://manyfold.app/", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/manyfold.webp", + "config_path": "/opt/manyfold/.env", + "description": "Manyfold is an open source, self-hosted web application for managing a collection of 3d models, particularly focused on 3d printing.", + "install_methods": [ + { + "type": "default", + "script": "ct/manyfold.sh", + "resources": { + "cpu": 4, + "ram": 4096, + "hdd": 15, + "os": "debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [ + { + "text": "Setup library on first connection in /opt/manyfold/data", + "type": "info" + } + ] +} diff --git a/install/deferred/manyfold-install.sh b/install/manyfold-install.sh similarity index 51% rename from install/deferred/manyfold-install.sh rename to install/manyfold-install.sh index f7bb7c2f6..500a9f71c 100644 --- a/install/deferred/manyfold-install.sh +++ b/install/manyfold-install.sh @@ -2,6 +2,7 @@ # Copyright (c) 2021-2025 community-scripts ORG # Author: bvdberg01 +# Co-Author: SunFlowerOwl # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" @@ -14,21 +15,24 @@ update_os msg_info "Installing Dependencies" $STD apt-get install -y \ - lsb-release \ - rbenv \ - libpq-dev \ libarchive-dev \ git \ libmariadb-dev \ redis-server \ nginx \ - libffi-dev \ - libyaml-dev + libassimp-dev msg_ok "Installed Dependencies" +setup_imagemagick + PG_VERSION="16" setup_postgresql -msg_info "Setting up PostgreSQL" +fetch_and_deploy_gh_release "manyfold" "manyfold3d/manyfold" "tarball" "latest" "/opt/manyfold/app" + +msg_info "Configuring manyfold environment" +RUBY_INSTALL_VERSION=$(cat /opt/manyfold/app/.ruby-version) +YARN_VERSION=$(grep '"packageManager":' /opt/manyfold/app/package.json | sed -E 's/.*"(yarn@[0-9\.]+)".*/\1/') +RELEASE=$(get_latest_github_release "manyfold3d/manyfold") DB_NAME=manyfold DB_USER=manyfold DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13) @@ -37,32 +41,11 @@ $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMP $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';" $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';" -{ - echo "Manyfold Credentials" - echo "Manyfold Database User: $DB_USER" - echo "Manyfold Database Password: $DB_PASS" - echo "Manyfold Database Name: $DB_NAME" -} >>~/manyfold.creds -msg_ok "Set up PostgreSQL" - -fetch_and_deploy_gh_release "manyfold" "manyfold3d/manyfold" "tarball" "latest" "/opt/manyfold" - -RUBY_INSTALL_VERSION=$(cat /opt/manyfold/.ruby-version) -YARN_VERSION=$(grep '"packageManager":' /opt/manyfold/package.json | sed -E 's/.*"(yarn@[0-9\.]+)".*/\1/') - -NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs -RUBY_VERSION=${RUBY_INSTALL_VERSION} RUBY_INSTALL_RAILS="true" setup_ruby - -msg_info "Adding manyfold user" useradd -m -s /usr/bin/bash manyfold -msg_ok "Added manyfold user" - -msg_info "Setting .env file" -cat </opt/.env -export APP_VERSION=12345 +cat </opt/manyfold/.env +export APP_VERSION=${RELEASE} export GUID=1002 export PUID=1001 -export PUBLIC_HOSTNAME=subdomain.somehost.org export PUBLIC_PORT=5000 export REDIS_URL=redis://127.0.0.1:6379/1 export DATABASE_ADAPTER=postgresql @@ -75,53 +58,68 @@ export MULTIUSER=enabled export HTTPS_ONLY=false export RAILS_ENV=production EOF -msg_ok ".env file setup" +cat </opt/manyfold/user_setup.sh +#!/bin/bash + +source /opt/manyfold/.env +export PATH="/home/manyfold/.rbenv/bin:\$PATH" +eval "\$(/home/manyfold/.rbenv/bin/rbenv init - bash)" +cd /opt/manyfold/app +rbenv global $RUBY_INSTALL_VERSION +gem install bundler +bundle install +gem install sidekiq +gem install foreman +corepack enable yarn +rm -f /opt/manyfold/app/config/credentials.yml.enc +corepack prepare $YARN_VERSION --activate +corepack use $YARN_VERSION +export VISUAL="code --wait" +bin/rails credentials:edit +bin/rails db:migrate +bin/rails assets:precompile +EOF +$STD mkdir -p /opt/manyfold/data +msg_ok "Configured manyfold environment" + +NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs +RUBY_VERSION=${RUBY_INSTALL_VERSION} RUBY_INSTALL_RAILS="true" HOME=/home/manyfold setup_ruby msg_info "Installing Manyfold" -source /opt/.env -cd /opt/manyfold +chown -R manyfold:manyfold /home/manyfold/.rbenv chown -R manyfold:manyfold /opt/manyfold -$STD gem install bundler -$STD rbenv global $RUBY_INSTALL_VERSION -$STD bundle install -$STD gem install sidekiq -$STD npm install --global corepack -corepack enable yarn -# $STD corepack prepare $YARN_VERSION --activate -# $STD corepack use $YARN_VERSION -chown manyfold:manyfold /opt/.env -rm /opt/manyfold/config/credentials.yml.enc -$STD bin/rails credentials:edit -$STD bin/rails db:migrate -$STD bin/rails assets:precompile +chmod +x /opt/manyfold/user_setup.sh +npm install --global corepack +$STD sudo -u manyfold bash /opt/manyfold/user_setup.sh +rm -f /opt/manyfold/user_setup.sh msg_ok "Installed manyfold" -msg_info "Creating Service" -cat </etc/systemd/system/manyfold.service -[Unit] -Description=Manyfold3d -Requires=network.target - -[Service] -Type=simple -User=root -Group=root -WorkingDirectory=/opt/manyfold -ExecStart=/usr/bin/bash -lc 'source /opt/.env && /opt/manyfold/bin/rails server -b 127.0.0.1 --port 5000 --environment production' -TimeoutSec=30 -RestartSec=15s -Restart=always - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now manyfold - +msg_info "Creating Services" +source /opt/manyfold/.env +export PATH="/home/manyfold/.rbenv/shims:/home/manyfold/.rbenv/bin:$PATH" +$STD foreman export systemd /etc/systemd/system -a manyfold -u manyfold -f /opt/manyfold/app/Procfile +for f in /etc/systemd/system/manyfold-*.service; do + sed -i "s|/bin/bash -lc '|/bin/bash -lc 'source /opt/manyfold/.env \&\& |" "$f" +done +systemctl enable -q --now manyfold.target manyfold-rails.1 manyfold-default_worker.1 manyfold-performance_worker.1 cat </etc/nginx/sites-available/manyfold.conf server { listen 80; server_name manyfold; - root /opt/manyfold/public; + root /opt/manyfold/app/public; + + location /cable { + proxy_pass http://127.0.0.1:5000; + proxy_set_header Host \$host; + + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "Upgrade"; + + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + } location / { try_files \$uri/index.html \$uri @rails; @@ -139,7 +137,7 @@ EOF ln -s /etc/nginx/sites-available/manyfold.conf /etc/nginx/sites-enabled/ rm -f /etc/nginx/sites-enabled/default $STD systemctl reload nginx -msg_ok "Created Service" +msg_ok "Created Services" motd_ssh customize