manyfold3d / manyfold

A self-hosted digital asset manager for 3d print files.
https://manyfold.app
MIT License
826 stars 49 forks source link

Documentation how to install Manyfold without Docker/Podman #3251

Open vmario89 opened 1 day ago

vmario89 commented 1 day ago

Hi People,

i am usually trying to install software without the need of Docker. But i gave up for Manyfold after nearly 10 hours of trial and error. Its just a bit hard. I wanted to ask this as feature request. Please add some howto for installing on fresh environment. For now, i moved to docker, but like to switch back.

I am sharing my complete documentation for my process which failed at the end: EVERYTHING worked except the fact that uploaded files were not processed by Sidekiq, finally and sadly.

This documentation is for Version 0.90.2 with Ruby 3.3.6 - tested on an Ubuntu LTS 24

Allgemeine Bibliotheken

sudo apt install libarchive13t64 libglfw3 libpq-dev libmariadb-dev

PostgreSQL Datenbank installieren

sudo apt install postgresql postgresql-client

Datenbank und Nutzer erzeugen, Berechtigungen zum Schema hinzufügen

sudo -u postgres psql #als eine Zeile!
CREATE USER manyfold WITH PASSWORD 'PASSWORD_SEE_KEEPASS';
CREATE DATABASE manyfold WITH ENCODING 'UNICODE' LC_COLLATE 'C' LC_CTYPE 'C' TEMPLATE template0;
GRANT ALL PRIVILEGES ON DATABASE manyfold TO manyfold;

\c manyfold
GRANT ALL ON SCHEMA public TO manyfold;

Ruby Version Manager (RVM) installieren

Manyfold benötigt eine passende Ruby-Version. Deshalb stützen wir uns nicht auf die Version aus dem apt Repository und installieren deshalb eine ausgewählte Version mit rvm.

https://rvm.io/rvm/install

sudo apt-add-repository -y ppa:rael-gc/rvm
sudo apt-get update
sudo apt-get install rvm

Als Root-Nutzer installieren wir dann Ruby 3.3.6. Die Installation ist zunächst systemweit.

sudo su #als root
echo 'source "/etc/profile.d/rvm.sh"' >> ~/.bashrc
source ~/.bashrc
rvm install 3.3.6

Nutzer manyfold hinzufügen

Wir fügen einen regulären Nutzer hinzu, der später Manyfold ausführen wird und Eigentümer der Dateien ist. Ein Nutzer vom Typ "System" macht Probleme.

sudo useradd -m -d /srv/manyfold -s /usr/bin/bash manyfold
sudo usermod -a -G rvm manyfold

Ruby Version für manyfold setzen

su - manyfold
rvm use 3.3.6
source .bashrc

Node Version Manager (nvm NodeJS) installieren

Als Nutzer manyfold führen wir aus:

wget -q -O- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
source .bashrc
nvm install 20.11.0
nvm use 20.11.0
npm install -g yarn

Manyfold Version auschecken

https://github.com/manyfold3d/manyfold

#weiterhin als Nutzer manyfold
cd /srv/
git clone https://github.com/manyfold3d/manyfold.git
cd /srv/manyfold/
git checkout v0.90.2
git config --global --add safe.directory /srv/manyfold

Ruby gems installieren

#weiterhin als Nutzer manyfold
cd /srv/manyfold/
gem install bundler

Yarn ausführen

#weiterhin als Nutzer manyfold
cd /srv/manyfold/
corepack enable #ausführen, um yarn 3.8.5 zu erlauben
yarn install

Testserver starten

#weiterhin als Nutzer manyfold
cd /srv/manyfold/
bin/dev

Konfiguration

https://manyfold.app/sysadmin/configuration.html

Appkey erzeugen und in .env einfügen

UID und GID auslesen mit dem kurzen Kommando id und in .env einfügen

tr -dc A-Za-z0-9 </dev/urandom | head -c 64; echo
vim /srv/manyfold/.env

Host-Zeile anpassen

#host zeile mittendrin einfügen

vim /srv/manyfold/config/environment.rb
# Load the Rails application.
require_relative "application"

Rails.application.config.hosts << "subdomain.somehost.org"

# Initialize the Rails application.
Rails.application.initialize!

Datenverzeichnis anlegen

Wir speichern die Daten in /opt und nicht in /srv, weil Manyfold dies beim Start mit der Warnung "kann kein privilegierter Systempfad sein" abgelehnt wird.

sudo mkdir /opt/manyfold_data/
sudo chmod 750 /opt/manyfold_data/
sudo chown manyfold:manyfold /opt/manyfold_data/

nginx VHost

sudo vim /etc/nginx/sites-available/subdomain.somehost.org.conf
server 
    {
    server_name subdomain.somehost.org;
    listen [::]:443 ssl;
    listen 443 ssl;

    include /etc/nginx/ssl-config.conf;

    error_log /var/log/nginx/subdomain.somehost.org.error.log;

    #add_header X-Frame-Options SAMEORIGIN always; #allow from all!
    add_header X-Xss-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy same-origin always;
    add_header Content-Security-Policy "default-src * 'unsafe-inline' 'unsafe-eval' data: blob:;" always;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header Permissions-Policy "geolocation 'none'; camera 'none'; speaker 'none';";

    #static assets durch nginx bedienen. Alternativ kann das auch durch Rails erfolgen! Siehe manyfold.sh
    location ~ \.(jpg|jpeg|png|gif|ico|css|js|html|svg)$ {
        root /var/www/vhosts/subdomain.somehost.org/public;
        add_header Cache-Control "public, max-age=31536000, immutable";
    }

    client_max_body_size 500M;

    location / {
        proxy_set_header Host $host;
        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 https;
        proxy_set_header Proxy "";
        proxy_pass_header Server;
        proxy_pass http://127.0.0.1:5000;
        proxy_buffering off;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        tcp_nodelay on;
    }
}

server {
    listen 80;
    listen [::]:80;
    server_name subdomain.somehost.org;
    location / {
        return 301 https://$host$request_uri;
    }
}
sudo ln -sf /etc/nginx/sites-available/subdomain.somehost.org.conf /etc/nginx/sites-enabled/

Public-Verzeichnis verschieben und Eigentümer anpassen

sudo mkdir -p var/www/vhosts/subdomain.somehost.org/
sudo mv vim /srv/manyfold/public/ /var/www/vhosts/subdomain.somehost.org/public/
sudo chown -R www-data:www-data /var/www/vhosts/subdomain.somehost.org/public/

Produktivserver bauen und manuell starten

Wir löschen alte Credentials und erzeugen alle nötigen Assets wie CSS, JS, etc.

#delete old crendetials if start fails (z.b. wenn bin/dev ausgeführt wird!)
rm config/credentials.yml.enc
#run once (Encryption Key erzeugen)
bin/rails credentials:edit
bin/bundle
bin/rake --tasks
RAILS_ENV=production bin/rake db:migrate
RAILS_ENV=production bin/rails assets:precompile
bin/rails server -b 127.0.0.1 --port 5000 --environment production

Als Service installieren

Der Server in Produktivumgebung ignoriert nicht alle, aber einige Settings aus .env, deshalb bauen wir ein Bash Script und packen diese Umgebungsvariablen als Exports ein und erzeugen ein eigenes Startscript:

sudo vim /srv/manyfold/manyfold.sh
#!/bin/bash

export GUID=1002
export PUID=1001
export PUBLIC_HOSTNAME=subdomain.somehost.org
export PUBLIC_PORT=5000
export SECRET_KEY_BASE=THE_SECRET
export REDIS_URL=redis://127.0.0.1:6379/1
export DATABASE_ADAPTER=postgresql
export DATABASE_HOST=127.0.0.1
export DATABASE_PASSWORD=PASSWORD
export DATABASE_USER=manyfold
export DATABASE_NAME=manyfold
export DATABASE_CONNECTION_POOL=16
export MULTIUSER=enabled
export HTTPS_ONLY=enabled

#das ist eine Legacy-Option und veraltet
#export RAILS_SERVE_STATIC_FILES=enabled

#RAILS_RELATIVE_URL_ROOT=/manyfold

#exec
bin/rails server -b 127.0.0.1 --port 5000 --environment production
#bin/rails server -b 127.0.0.1 --port 5000 --environment development
#bin/rails server -b 0.0.0.0 --port 5000 --environment development
sudo chmod +x /srv/manyfold/manyfold.sh
sudo vim /etc/systemd/system/manyfold.service
[Unit]
Description=Manyfold (FabHardware)
Requires=network.target

[Service]
Type=simple
User=manyfold
Group=manyfold
WorkingDirectory=/srv/manyfold
ExecStart=/usr/bin/bash -lc '/srv/manyfold/manyfold.sh'
TimeoutSec=30
RestartSec=15s
Restart=always

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable manyfold.service --now
sudo journalctl -f -u manyfold.service

Log Level bei Bedarf anpassen

vim /srv/manyfold/config/environments/production.rb
#:debug
#config.active_record.verbose_query_logs = true
vmario89 commented 1 day ago

finally the problem was:

undefined method `perform_async' for an instance of ActiveJob::ConfiguredJob
Did you mean?

    perform_now

Extracted source (around line #102):

      def enqueue_sidekiq_worker(klass_const)
        klass_const.set(queue: queue_name_with_prefix).perform_async(*enqueue_args)
      end

      # Sidekiq worker message.

and the url failed: /admin/sidekiq/cron/__all__/enque

Screenshot 2024-11-11 at 05-57-58 We're sorry but something went wrong (500)

Screenshot 2024-11-11 at 06-32-42 Action Controller Exception caught