Files
scripts/partdb-install.md

14 KiB

Installation of part-db on my nginx server at kuschel.at

Date: 2025-10-29 KW4NZ Thomas Kuschel Debian Version: (/etc/debian_version)

ssh kuschel cat /etc/debian_version 

A: 13.1 , i.e. trixie

ssh kuschel cat /etc/os-release

... to receive more information

Checks

Only available on a PC with credentials to kuschel.at via SSH

These settings should be established via the meeting server jitsi

Check if yarn is installed at mycarbon.at or kuschel.at

ssh kuschel yarn --version

A: 1.22.22

Check if nodejs is installed

ssh kuschel nodejs --version

A: 24.11.0

Check the database MariaDB

ssh kuschel mariadb --version

A: mariadb from 11.8.3-MariaDB, client 15.2 for debian-linux-gnu (x86_64) using EditLine wrapper

Check the php version

ssh kuschel php --version

A: PHP 8.4.14 (cli) (built: Oct 27 2025 21:20:52) (NTS) Copyright (c) The PHP Group Built by Debian Zend Engine v4.4.14, Copyright (c) Zend Technologies with Zend OPcache v8.4.14, Copyright (c), by Zend Technologies

Installation

Create a folder for Part-DB (partdb)

Please create a folder for Part-DB and proceed with downloading it. We have completed the installation of all prerequisites and are now prepared to proceed with the Part-DB installation. The next step is to create a folder for Part-DB in the webroot of Apache2/nginx and download it to this folder. The software is downloaded via Git, facilitating straightforward updates at a later date.

ssh kuschel
sudo git clone https://github.com/Part-DB/Part-DB-symfony.git /var/www/partdb

Make it available for nginx user, first check the name of the user with:

user=$(grep "user" /etc/nginx/nginx.conf | tr -d ';' | cut -d " " -f 2) | echo $user

Change the owner of the directory recursively

sudo chown -R $user':' /var/www/partdb

Create configuration for Part-DB from a template

sudo cp /var/www/partdb/.env /var/www/partdb/.env.local

Now you have to edit the created file .env.local, e.g. with

sudo nano -cl /var/www/partdb/.env.local

We will show this file to you right here:

...
##########################
# Database settings
##########################

# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml

# Use a file (SQLite) as database. For bigger instances you should use a real database server (like MySQL)
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db"

# Uncomment this line (and comment the line above to use a MySQL database
# DATABASE_URL=mysql://root:@127.0.0.1:3306/part-db?serverVersion=5.7
DATABASE_URL=mysql://partdb:wRHEFShdB9gG@127.0.0.1:3306/partdb

# Set this value to 1, if you want to use SSL to connect to the MySQL server. It will be tried to use the CA certificate
# otherwise a CA bundle shipped with PHP will be used.
# Leave it at 0, if you do not want to use SSL or if your server does not support it
DATABASE_MYSQL_USE_SSL_CA=0

# Set this value to 0, if you don't want to verify the CA certificate of the MySQL server
# Only do this, if you know what you are doing!
DATABASE_MYSQL_SSL_VERIFY_CERT=1

# Emulate natural sorting of strings even on databases that do not support it (like SQLite, MySQL or MariaDB < 10.7)
# This can be slow on big databases and might have some problems and quirks, so use it with caution
DATABASE_EMULATE_NATURAL_SORT=0
...

Configuration of the MySql database

Create a new database "partdb"

sudo mariadb -p

You have to enter the root password of the MariaDB database to git into it.

An SQL shell opens, the following commands creates a new database and a new user for the program Part-DB.

CREATE DATABASE partdb;
GRANT ALL PRIVILEGES ON partdb.* TO 'partdb'@'localhost' IDENTIFIED BY 'wRHEFShdB9gG';

Finaly, save the changes with:

FLUSH PRIVILEGES;

and exit the SQL shell with exit.

Install composer and dependencies for Part-DP

Download composer installer script:

wget -O /tmp/composer-setup.php https://getcomposer.org/installer

Install composer globally

sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
Check the composer's version
composer --version

A: Composer version 2.8.12 2025-09-19 13:41:59 PHP version 8.4.14 (/usr/bin/php8.4) Run the "diagnose" command to get more detailed diagnostics output.

Install composer dependencies (please note the sudo command, to run it under the web server user)

First change to the folder partdb with:

cd /var/www/partdb

Create a cache directory for composer at /var/www/.cache

sudo mkdir /var/www/.cache
sudo chown www-data: /var/www/.cache
sudo -u www-data composer install --no-dev -o
Note:

Additionally, I had to install the missing ext-bcmath because the tc-lib-barcode requires ext-bcmath, so I installed the package:

sudo apt install php-bcmath

And again call the sudo -u www-data composer install --no-dev -o under the user www-data.

Install and Run yarn in that directory

sudo yarn install 

A: yarn install v1.22.22

sudo yarn build

A: yarn run v1.22.22 ... encore production --progress ...

Clear Console cache

sudo -u www-data php bin/console cache:clear

Checking the PHP configuration

sudo -u www-data php bin/console partdb:check-requirements

There should be all green OK's in the console, except pdo_sqlite.

For a better performance we installed php-curl:

sudo apt install php-curl

Also, we got a warning [WARNING] Opcache configuration can be improved. See https://symfony.com/doc/current/performance.html for more info.

So we changed the following lines at: /etc/php/8.4/cli/conf.d/10-opcache.ini

; configuration for php opcache module
; priority=10
zend_extension=opcache.so
opcache.jit=off
; ADDED by KW4NZ to configure OPcache for Maximum Performance, Symphony related (Part-DB)
;opcache.memory_consumption=128
opcache.memory_consumption=256

; The amount of memory for interned strings in Mbytes.
;opcache.interned_strings_buffer=8

; The maximum number of keys (scripts) in the OPcache hash table.
; Only numbers between 200 and 1000000 are allowed.
;opcache.max_accelerated_files=10000
opcache.max_accelerated_files=20000

Database Schema

Now you create a database schema with the following command:

sudo -u www-data php /var/www/partdb/bin/console doctrine:migrations:migrate

As a result we got the following warning line:

[notice] Migrating up to DoctrineMigrations\Version20250813214628
[warning] 
[warning] The initial password for the "admin" user is: 9dd3255565

NGINX setup:

My nginx/sites-available/kuschel.at

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#
#upstream nodered {
#	server 127.0.0.1:1880;
#}

server {
	listen 80;
	listen [::]:80;
	server_name www.kuschel.at kuschel.at;
	## sending users to https with no www
#	return 301 https://www.mycarbon.at$request_uri;
	root /var/www/kuschel.at;
	# Add index.php to the list if you are using PHP
	index index.php index.html index.htm index.nginx-debian.html;
	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}
	# pass PHP scripts to FastCGI server
	#
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
	#
	#	# With php-fpm (or other unix sockets):
		fastcgi_pass unix:/var/run/php/php-fpm.sock;
	#	# With php-cgi (or other tcp sockets):
	#	fastcgi_pass 127.0.0.1:9000;
	}
	location /us-license/ {
		auth_basic "Restricted";
		auth_basic_user_file /etc/nginx/.htpasswd;
	}
	location = /1945/ {
		autoindex on;
		#autoindex_exact_size off;
		#autoindex_format jsonp;
		#autoindex_format xml;
		autoindex_localtime on;
	}
	location = /spanisch/ {
		autoindex on;
		autoindex_localtime on;
	}
	# this is for LETSENCRYPT
	location ^~ /.well-known/acme-challenge/ {
		default_type "text/plain";
		root	/var/www/letsencrypt;
	}
	location = /.well-known/acme-challenge/ {
		return 404;
	}
}
server {
	listen 443 ssl default_server;
	listen [::]:443 ssl default_server;
	http2 on;
#	if ($http_host = git.kuschel.at) {
#		proxy_pass http://localhost:3000/;
#	}
# since nginx V	1.25+ (we are still at 1.22.x)
#	listen 443 ssl http2 default_server;
#	listen [::]:443 ssl default_server;
#	http2 on;

	server_name www.kuschel.at kuschel.at;
	root /var/www/kuschel.at;
	ssl_certificate /etc/letsencrypt/kuschel.at/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/kuschel.at/key.pem;
	# This should be ca.pem (certificate with the additional intermediate certificate)
	# See here: https://certbot.err.org/docs/using.html
	ssl_trusted_certificate /etc/letsencrypt/kuschel.at/ca.pem;

	#ssl_protocols TLSv1.2 TLSv1.3;
	ssl_session_timeout 24h;
	ssl_session_cache shared:SSL:50m;
	#ssl_session_tickets off;
	# Prefer the SSL ciphers for ECDSA: (the both TLS-* are for TLS 1.3)
	ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
	#   ssl_ciphers TLS-CHACHA20-POLY1305-SHA256:TLS-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384;

	# Use multiple curves
	#ssl_ecdh_curve secp521r1:secp384r1;

	#ssl_prefer_server_ciphers off;
	ssl_prefer_server_ciphers on;

	# HSTS (ngx_http_headers_module is required) max-age in seconds
	add_header Strict-Transport-Security "max-age=63072000" always;

	# OCSP stapling
	ssl_stapling on;
	ssl_stapling_verify on;

	# This is the IP of the DNS server (in most cases: your router's IP)
	resolver 213.133.98.98 213.133.99.99 213.133.100.100;
	index index.html index.htm index.php;

#	location / {
		# fastcgi_pass unix:/var/run/php/php-fpm.sock;
#	}
	location /1945/ {
                autoindex on;
                #autoindex_exact_size off;
                #autoindex_format jsonp;
                #autoindex_format xml;
                autoindex_localtime on;
	}
	location /spanisch/ {
		autoindex on;
		autoindex_localtime on;
	}
	location ~ ^/gimplfest/(.*) {
		return 301 /gimpelfest/$1;
	}
	location /gimplfest/ {
		autoindex on;
		autoindex_localtime on;
	}
	location /gimpelfest/ {
		# rewrite ^/gimpelfest/Mitternachtseinlage_4D.mp4 /gimpelfest/Mitternachtseinlage_8D.mp4 last;
		rewrite ^/gimpelfest/Mitternachtseinlage_4D.mp4 /gimpelfest/Mitternachtseinlage_8D.mp4 redirect;
		autoindex on;
		autoindex_localtime on;
	}
	location ~ ^/index\.php(/|$) {
		fastcgi_pass unix:/var/run/php/php-fpm.sock;
		fastcgi_split_path_info ^(.+\.php)(/.+)$;
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
		fastcgi_param DOCUMENT_ROOT $realpath_root;

		internal;
	}

	location ~ \.php$ {
                include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
                fastcgi_pass unix:/var/run/php/php-fpm.sock;
		# old version: fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        }
	location /nodered/ {
		proxy_set_header Host $http_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 $scheme;
		#proxy_http_version 1.1;
		#proxy_set_header Upgrade $http_upgrade;
		#proxy_set_header Connection "upgrade";
		proxy_pass http://127.0.0.1:1880/;
		#include proxy_params;
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
	}
	location /ui/ {
		auth_basic	"Secure UI area";
		auth_basic_user_file /etc/nginx/.htpasswd;
		proxy_pass http://127.0.0.1:1880/ui/;
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
	}
	location /partdb/ {
		# error_log /var/log/nginx/parts.error.log;
		# access_log /var/log/nginx/parts.access.log;
		try_files $uri /partdb/index.php$is_args$args;
	}
	location /bilder/ {
		auth_basic	"Secure Picture area";
		auth_basic_user_file /etc/nginx/.htpasswd_bilder;
                autoindex on;
                autoindex_localtime on;
	}
	location ~* ^/admin/(.+\.(css|js)) {
		rewrite ^/static/contents/$1 break;
		proxy_pass http://127.0.0.1:1880;
	}
}

Troubleshooting

Password of the admin, login failed

I tried to change the password for the admin, using a passphrase like: ensnare flaccid backslid DECIDABLE morphine sturdily charting

But a new login didn't work any more, I had to reset the admin password, switching to the site via SSH and cd to /var/www/partdb

sudo -u www-data php bin/console app:set-password admin

-- eof --