Skip to content

Latest commit

 

History

History
681 lines (453 loc) · 25.9 KB

2- INSTALL.rdoc

File metadata and controls

681 lines (453 loc) · 25.9 KB

Installation instructions

New! Installation on Ubuntu 22.04 LTS or Mint 21

sudo apt-get update sudo apt-get install mysql-server sudo apt-get install git gcc curl zlib1g-dev libxml2-dev imagemagick libmagickcore-6.q16-dev libmagickwand-6.q16-dev openjdk-11-jdk-headless make libsqlite3-dev g++ nodejs

# For debian: openjdk-17-jre-headless

# This is important! do NOT install the mysql client sudo apt remove libmysqlclient-dev sudo apt install libmariadbd-dev

# How to go around a proxy… # On your local machine, connect to iself… ssh -N -D 54321 localhost

# On the remote machine, forward the remote port to the local one… ssh -R9080:localhost:54321 remote-machine

# Then in the remote machine… export http_proxy=socks5://localhost:9080 export https_proxy=socks5://localhost:9080 # For culr edit ~/.curlrc proxy = socks5://localhost:9080

# From the muscat user gpg –keyserver keyserver.ubuntu.com –recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB curl -sSL get.rvm.io | bash

source ~/.rvm/scripts/rvm

# For rails 5 #rvm pkg install openssl #rvm install 2.7.5 –with-openssl-dir=$HOME/.rvm/usr #rvm use 2.7.5 #rvm gemset create rails #rvm use 2.7.5@rails

rvm install 3.2 rvm gemset create rails7 rvm use 3.2.2@rails7

git clone github.com/rism-digital/muscat cd muscat git checkout develop-rails-7 cd config cp sample_database.yml database.yml cp sample_application.rb application.rb cp muscat-custom-sample.scss ../vendor/assets/stylesheets/muscat-custom.scss

cd .. #back to muscat root bundle install EDITOR=nano rails credentials:edit #copy the empty credential block

# Create db

sudo mysql # Or log in with a user that has user creation privileges

# Create the user, substitute with an appropriate user and password!

# CREATE DATABASE muscat_development CHARACTER SET utf8 COLLATE utf8_general_ci; # CREATE USER ‘rism’@‘localhost’; # ALTER USER ‘rism’@‘localhost’ IDENTIFIED WITH mysql_native_password BY ‘password’; # GRANT ALL ON muscat_development.* TO ‘rism’@‘localhost’;

# edit config/database.yml to match # NOTE socket is /var/run/mysqld/mysqld.sock

#sudo apt remove libmysqlclient-dev #sudo apt remove libmariadbd-dev #sudo apt install libmariadbd-dev #gem install mysql2 -v ‘0.5.3’ #gem uninstall mysql2 #bundle install rake db:migrate

This document describes how to bootstrap into the webapplication. The documentation is updated for Ubuntu 18.04 LTS and Debian 10 (Buster).

Requirements

The following other libraries and programs are needed

  • Ruby > 2.7

  • Apache 2.4

  • MySQL > 8.0.4 or MariaDB 10.x

  • Git

  • Passenger for Apache 2

  • rails

  • ruby-bundler

  • libmysqlclient-dev

  • imagemagick

  • libmagickwand-dev

  • Java RE 11+

NOTE From Muscat 6.1 MySQL *8.0.4 is required* for autocomplete and comments to properly work, as the REGEX library was changed. MariaDB 10.x, as provided by Debian 10 (Buster) also seems to work properly.

Mysql 8

Depending on your system, a package for Mysql 8 may not exist. In this case use the official package provided by Oracle dev.mysql.com/downloads/repo/apt/

NOTE: Download the latest version or the GPG keys may have been expired! Copy the file from the link provided in that page, there is no need for an account, follow the “No thanks, just start my download” link. In this case it points to dev.mysql.com/get/mysql-apt-config_0.8.15-1_all.deb

wget https://dev.mysql.com/get/mysql-apt-config_0.8.15-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.15-1_all.deb

(obviously subsitute with the exact file name in the link). dpk will prompt a screen to configure tha package, select option to configure the server version and select 8, then exit.

Then update and install mysql:

sudo apt-get update
sudo apt-get install mysql-server

When prompted, select *use legacy passwords* as not all connectors for the moment work with the new system. This will be updated in the future. Also install the newest versions of the connector libraries:

sudo apt-get install libmysqlclient21 libmysqlclient-dev

MariaDB 10

If you are using Debian 10 (Buster), the default MariaDB server (mariadb-server, that pulls 10.3) and clients (ruby-mysql2) are just fine.

Ruby and Rails

Muscat 6 requires Ruby 2.3 or higher and Bundler 2.1.4 or higher. Rails (5.2) is installed with the correct version with bundle.

Recent Ubuntu releases (from 18.4 LTS) and Debian 10 (Buster) provide come Ruby 2.5 by default so no actions are necessary. On Debian Buster, Bundler 2.1.4 is provided as a backport. Versions for Passenger, Java (as required for Solr) are also fine.

Base packages

sudo apt-get update
sudo apt-get install mysql-server libmysqlclient-dev # If mysql was not installed separately
sudo apt-get install apache2 git ruby ruby-dev gcc zlib1g-dev libxml2-dev imagemagick libmagickcore-6.q16-dev libmagickwand-6.q16-dev  openjdk-11-jdk-headless passenger make libapache2-mod-passenger libsqlite3-dev g++ default-libmysqld-dev nodejs
sudo a2enmod passenger

Passenger also wants to compile a binary module, this is optional but will enable it

sudo mkdir /var/www/.passenger
sudo chown -R www-data:www-data /var/www/.passenger

Bootstrap the application

Get the sources if necessary (github.com/rism-ch/muscat and github.com/rism-ch/muscat-guidelines):

git clone https://github.com/rism-ch/muscat.git --recursive
sudo gem install bundler # We are compatibile with 2.1 now
sudo bundle install #--deployment # deployment is only for the production system

Alternatively, you can just download and use the stable release tarballs found in github.com/rism-ch/muscat/releases.

Install base configuration:

cd muscat/config
cp sample_database.yml database.yml
cp sample_application.rb application.rb

Install the base css:

cd muscat/config
cp muscat-custom-sample.scss ../vendor/assets/stylesheets/muscat-custom.scss

Make sure the directory is owned by the right user (www-data on Ubuntu or Debian)

sudo chown -R www-data:www-data muscat/

Set up databases access:

sudo mysql # Or log in with a user that has user creation privileges

Create the user, substitute with an appropriate user and password!

CREATE DATABASE muscat_development CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'rism'@'localhost';
ALTER USER 'rism'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
GRANT ALL ON muscat_development.* TO 'rism'@'localhost';

Remember username and pass should be the same as in database.yml. Then, migrate the database (that us, update the structure):

bundle exec rake db:migrate # development

NOTE: in a production environment all the tasks must declare RAILS_ENV=production to run. For local development this is not necessary

sudo RAILS_ENV=production bundle exec rake db:migrate ## on a production system

Add basic dataset:

bundle exec rake db:seed

Create credential file

All the secret keys are now stored in the rails 5.2 credentials file, which is not included in the repo. A blank on must be created with:

rails credentials:edit

This will automatically create credentials.yml.enc and the master key, along with a cookie secret key. If you are not familiarised with this Rails 5.2 feature, this guide is very didactic: youtu.be/BHgvPPr2nLE.

The user and password are needed for background search and export, and should be a muscat user with minimum guest access. So, to use the other services on Muscat, such as history, add to this file:

export:
  user: "xx"
  password: "xx"

Remember that they key must be readable from the user running apache, so check the permissions and change the user is needed:

chown www-data:www-data config/master.key

Solr installation and configuration

Muscat 7.1 now supports Solr 8.8 installed externally. This means for example that it is possible to use a Solr cluster installed on a different server. The internal Solr 5.5 server still works, but will not be supported anymore in the future since the bundled Solr unsupported and has problems with modern Java versions. The Muscat core should work with any installation of Solr, here a sample installation procedure is shown but it should be adapted for each installation.

Installation using a “stock” solr using included setup script

NOTE this was tested on Linux distributions only. Grab a copy of the official distribution (8.11.1 at the time of writing) and unpack it in a suitable place

wget https://www.apache.org/dyn/closer.lua/lucene/solr/8.11.1/solr-8.11.1.tgz?action=download -O solr-8.11.1.tgz
tar -xvzf solr-8.11.1.tgz

Solr needs two directories, one for data and one for the binaries. The latter is generally /opt/solr, and the data installation for this example will be /data/solr. Extract just the installation script:

tar xzf solr-8.11.1.tgz solr-8.11.1/bin/install_solr_service.sh --strip-components=2

And execute it:

sudo ./install_solr_service.sh solr-8.11.1.tgz -d /data/solr -p 8983

This will create the directory layout as above. It will also create a solr user. For the complete reference see solr.apache.org/guide/8_8/taking-solr-to-production.html Now copy over the Muscat core:

cp -R $MUSCAT_HOME/solr-configuration/muscat /data/solr/data
cp $MUSCAT_HOME/solr-configuration/jar-8.8-linux/ThemaxQuery-1.0-SNAPSHOT.jar /data/solr/data/lib/

Where /data/solr/ in the directory specified above with -d. Solr includes a startup script so

systemctl daemon-reload
service solr start

Should start it. The logfiles in this case are found in /data/solr/logs.

Installation using a “stock” solr

Grab a copy of the official distribution (8.11.1 at the time of writing) and unpack it in a suitable place

wget https://www.apache.org/dyn/closer.lua/lucene/solr/8.11.1/solr-8.11.1.tgz?action=download -O solr-8.11.1.tgz
tar -xvzf solr-8.11.1.tgz

When using this distribution, you can copy the muscat core bundled with Muscat directly into the binary distibution

cp -R $MUSCAT_HOME/solr-configuration/muscat solr-8.11.1/server/solr
cp $MUSCAT_HOME/solr-configuration/jar-8.8-linux/ThemaxQuery-1.0-SNAPSHOT.jar solr-8.11.1/server/solr/lib/

NOTE The bundled ThemaxQuery-1.0-SNAPSHOT.jar contains the PAE incipit indexer used in Muscat. A version for macOS 11 is provided in jar-8.8-mac, the linux version should work with any recent Ubuntu/Debian system. In muscat/solrconfig.xml the path for this jar is hardcoded <lib dir=“../../jar”/> so it will find it in the stock Solr installation. For a different installation the path should made to point to the correct jar file path. Solr should run at this point:

sudo -u www-data ./bin/solr start -p 8983

Or an appropriate startup script may be used

Installation on macOS with Homebrew

Install solr with brew, use solr-8.11.1 at least

brew install solr

As above, copy the configuration and jar file:

cp -R $MUSCAT_HOME/solr-configuration/muscat /usr/local/var/lib/solr
cd /usr/local/Cellar/solr/8.11.1/contrib
mkdir themax
cp $MUSCAT_HOME/solr-configuration/jar-8.8-mac/ThemaxQuery-1.0-SNAPSHOT.jar /usr/local/Cellar/solr/8.11.1/contrib/themax

NOTE depending on the Homebrew version used, the path for the configuration might be /opt/homebrew/var/lib/solr

Edit /usr/local/var/lib/solr/muscat-index/solrconfig.xml To point to the correct jar. Remove <lib dir=“../../jar”/> and add:

<lib dir="${solr.install.dir:../../../..}/contrib/themax" regex=".*\.jar"/>

to the list of lib directories at the top. This will tell Solr to load the jar files in the contrib/themax directory. Restart Solr:

brew services restart solr

Matching Muscat configuration to Solr

By default Solr listens on port 8983 with a core named muscat. To change this edit the files

config/sunspot.yml

To change the core name or port

Legacy Solr 5.5

# Make sure solr is not running as root if used in production
sudo -u www-data bundle exec rake RAILS_ENV=production sunspot:solr:start
# else just do:
bundle exec rake sunspot:solr:start

NOTE sunspot.yml and blacklight.yml now point to the muscat core as used for 8.8. To run with 5.5 and the default configuration, edit those files to use

  • production: port 8983 core production

  • development: port 8982 core development

Development Startup

Make sure Solr and Mysql are running. Default (development) startup:

rails s -e development

Try to open $IP_ADDRESS:3000/

For startup in production mode see “Starting Daemons in Production Mode”

For refreshing an installation in production mode (with sudo, as root or sudo -u www-data depending on the permissions on the installation dir):

bundle exec rake RAILS_ENV=production assets:clean
bundle exec rake RAILS_ENV=production assets:precompile

Logging In

A default administrative user has been created as part of the installation process. To log in, go to http://ip:3000/admin and log in with the following credentials:

username: admin@example.com
password: Password1234

It is advised that you delete this account after creating a new administrative user in the admin interface.

Index rebuilding:

rake sunspot:reindex

In production mode run:

RAILS_ENV=production rake sunspot:reindex

Specify only a model:

rake sunspot:reindex[,Person]

Do reindex in 1 record batches, useful if reindex crashes to see in which one (very slow to start)

rake sunspot:reindex[1]

Passenger standalone and Nginx

It is possible to run muscat with rvm/rbenv, passanger standalone and nginx as a fronted.

First, create a dedicated user for Muscat:

sudo adduser muscat

Make then sure the user can not login via ssh. Add it temporarly to sudoers for the next step.

Install rvm following the instructions here: rvm.io/rvm/install. If you are behind a proxy you need to edit .curlrc for muscat user and add:

proxy = the-proxy.com:1234

Then proceed with the installation and add the needed ruby version (here 2.7.5)

rvm install 3.2.2
rvm gemset create rails7
rvm use 3.2.2
rvm --default use 3.2.2@rails7

You can disable muscat from sudoers after this step. Make sure the gem form passenger is in the Gemfile:

gem 'passenger'

Edit ‘/etc/systemd/system/muscat.service` for the application startup

[Unit]
Description=Muscat
After=network-online.target

[Service]
Restart=always
RestartSec=5
TimeoutSec=5
User=muscat
Group=muscat
WorkingDirectory=/INSTALLATION/DIR/muscat
ExecStart=/home/muscat/.rvm/bin/rvm 3.2.2@rails do bundle exec passenger start

[Install]
WantedBy=multi-user.target

Change ‘/INSTALLATION/DIR/` to the actual installation dir. Then Edit `Passengerfile.json` for the basic configuration

{
  "environment": "production",
  "port": 8081,
  // Passenger is managed by systemd
  "daemonize": false,
}

here is a sample nginx configuration:

# These are some "magic" Nginx configuration options that aid in making
# WebSockets work properly with Passenger Standalone. Please learn more
# at http://nginx.org/en/docs/http/websocket.html
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

// Same as Passenger.json
upstream muscat {
    server localhost:8081;
}

# Virtual host configuration for muscat.
server {
    server_name         www.muscat.com;
    root                /var/www/muscat-dir-for-nginx;

    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    keepalive_timeout 70;

    ssl_certificate		    /CERTS/fullchain.pem;
    ssl_certificate_key		/CERTS/privkey.pem;
    include               ssl_include;

    # ignore all location requests that start with a dot.
    # Return 404 to make it look like it's not found (otherwise
    # a 403 would say it is there, you just can't access it)
    location ~ /\. {
        deny all;
        access_log off;
        return 404;
    }

    if (-f /etc/nginx/muscat-test.unavailable) {
        return 503;
    }

    error_page 503 @custom503;
    location @custom503 {
        root    /var/www/muscat-dir-for-nginx/www;
        rewrite ^(.*)$ /nginx_errors/503.html break;
        internal;
    }

    location / {
        proxy_pass http://muscat;

        proxy_http_version 1.1;
        proxy_set_header        Host                $http_host;
        proxy_set_header        Upgrade             $http_upgrade;
        proxy_set_header        Connection          $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;
        proxy_set_header        X-Scheme            $scheme;

        proxy_buffering off;
    }
}

server {
    server_name         muscat.com;
    listen              80;
    listen              [::]:80;

    # Since we're just redirecting from this configuration, we don't need to count it in the
    # access logs.
    access_log off;

    # Ensure any challenges from Let's Encrypt are served.
    # directory on the server for this.
    location ~ /\.well-known/acme-challenge {
        root /var/www/muscat-dir-for-nginx/www;
    }

    # Redirect all other traffic to the muscat instance.
    location / {
        return      301 https://muscat.com/$request_uri;
    }
}

Change ‘muscat.com` to the actual address, and create muscat-dir-for-nginx and muscat-dir-for-nginx/www Create the file `/etc/nginx/ssl_include` for the SSL configuration:

add_header Strict-Transport-Security "max-age=63072000";
ssl_stapling                on;
ssl_stapling_verify         on;
ssl_session_tickets         on;
ssl_session_timeout         24h;
ssl_session_cache           shared:SSL:100m;
ssl_session_ticket_key      /etc/nginx/ssl/ticket.key;
ssl_dhparam                 /etc/nginx/ssl/dhparam.pem;
ssl_prefer_server_ciphers   on;
ssl_protocols               TLSv1.2 TLSv1.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;
resolver                    8.8.8.8 [2001:4860:4860::8888] 1.1.1.1 [2606:4700:4700::1111] 8.8.4.4 1.0.0.1;

Production Installation and daemons

DelayedJob now is a bit more tricky, as different queues get different worker pools:

sudo -u www-data RAILS_ENV=production bin/delayed_job start --pool=reindex,triggers,folders:10 --pool=sub_reindex:10 --pool=resave --pool=export

Other ways to start delayed_job:

sudo RAILS_ENV=production bin/delayed_job start
rake jobs:work # Run in foreground
rake jobs:workoff # Run all jobs in foreground and exit
rake jobs:clear # Clear failed jobs
## in production it is then...
RAILS_ENV=production bundle exec rake jobs:<xxx>

Depending on the env, remove sudo if necessary. RAILS_ENV is needed only on production, and has to come after sudo.

It is also good to block access to Solr:

sudo iptables -A INPUT -p tcp -s localhost --dport 8983 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8983 -j DROP

Crontab installation

In version 7.0 the crono scheduler was removed and a normal crontab plus a script is provided. The default crontab file should be linked in /etc/conn.d. Edit the muscat_crontab to set PATH_TO to the correct muscat installation, you will need to do it by hand.

On debian/ubuntu this should work:

ln -s config/muscat_crontab /etc/cron.d
chmod +x /etc/cron/muscat_crontab
sudo service cron restart

If your crontab still has this line:

0 2 * * * cd $PATH_TO && $PATH_TO/bin/rake blacklight:delete_old_searches[7] RAILS_ENV=production

It is save to delete it as it is now taken care but the global muscat crontab. NOTE If you ever change the cron file name, it CANNOT contains dots! Or it will silently fail.

Some MySQL optimizations

Add to /etc/mysql.cnf

[mysqld]

innodb_buffer_pool_size = 8G
innodb_log_buffer_size = 512M
innodb_log_file_size = 1G
innodb_write_io_threads = 16
innodb_flush_log_at_trx_commit = 0

To speed up imports. (See here for more)

Lazy’s man import speedup

On a full muscat DB there can be many many _old versions_ in the versions table, since version snapshots are kept for each saved item. When doing development this can be quite annoying since it can take up to 30 minutes to restore a db.

sed '/INSERT INTO `versions`/d' muscat_dump.sql > muscat_no_versions.sql

Removes all the old versions. From 30 minutes to 9.

Validation Exclusions

This concerns really only the internal use of the source validator job, which can validate al the sources periodically. Often it is useful to add blanket exclusions if some data will not be corrected. They must be placed in the folder ‘validation_exclusions` in config/, with subfolders containing the exclusions for each model, for example:

config/validation_exclusions/source/exclusions.yml

is the configuration file for sources. This is a sample configuration

exclude:
  "650":
    tags:
      "0":
        from_file_list: 650_0_exclude
  "588":
    tags:
      "a":
        and_rules: 
          id_prefix: "234"
          creation_date: "2023-06-06"

Every tag specifies some rules for the subtags to be excluded:

  • ‘from_file_list`: read ids to be excluded from a file, one by line

  • ‘id_prefix`: ignore records with the id starting with these digits

  • ‘creation_date`: ignore records created exactly on this date

Other rules will be implemented in the future.

No rules are provided by default in muscat and none should be pushed to the repo since the use depends on the user data.

Installing new ruby and passanger on legacy systems

On older Ubuntu systems add the following repositories

deb http://ppa.launchpad.net/brightbox/ruby-ng/ubuntu trusty main
deb https://oss-binaries.phusionpassenger.com/apt/passenger trusty main

(On some systems it is necessary to uncomment therubyracer from the gemfile) On Ubuntu 18.04 only passenger is needed:

deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main

(Add /etc/apt/sources.list or create a relevant file in /etc/apt/sources.list.d) Also make sure that universe repositories are enabled!

On 18.40, also enable GPG verification of Passenger:

sudo apt-get install -y dirmngr gnupg
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates

Then install all the dependencies and setup passenger:

Muscat user authentication

In Muscat’s default configuration, users are created and authenticated in Muscat’s own local database. This authentication method is called ‘:database_authenticatable`, and if it is fine to you, there is no need to modify nor configure anything further.

There is an alternative Single Sign On (SSO) authentication for corporate environments, and it is implemented using SAML integration. If you are interested, please follow this steps as described:

  1. First, run the generator with ‘bin/rails g muscat:install_saml` to get the required configuration files.

  2. Add :saml_authenticatable as one of the AUTHENTICATION_METHODS in ‘config/application.rb` (order of methods is not important)

  3. SAML users will have the role defined by ‘RISM::SAML_AUTHENTICATION_CREATE_USER_ROLE` which is “guest” by default. Edit `config/application.rb` and uncomment `RISM::SAML_AUTHENTICATION_CREATE_USER_ROLE` and set the desired role if you prefer another one.

  4. Customize the new devise login form that the generator created at ‘“app/views/active_admin/devise/sessions/new.html.erb”`. At least, edit the file and remove the unused link to the IdP or define yours if it’s none of the two.

  5. Configure the SAML settings at ‘config/initializers/devise_saml_authenticatable.rb`

- To automatically parse IdP's metadata, parse the remote url just before ruby_saml's settings
```
 ...
 idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
 config.saml_config= idp_metadata_parser.parse_remote "https://remote-sso-server.example.org/saml/idp/metadata"
 config.saml_configure do |settings|
 ...
```
  1. Configure the mapping between SAML user attributes (keys) and application user attributes (values).

  2. Muscat must be restarted if any configuration is changed.

The SSO authentication method is added as convenience to Muscat to serve some external users, but it is not supported by upstream developers. If you need support, please contact its authors: coditramuntana.com/en/contact .

Basic Apache configuration (deprecated)

Example Apache configuration:

# create /usr/local/etc/apache/Includes/default.conf
# and add default site:
<VirtualHost *:80>
        # ServerName www..org
        DocumentRoot /var/rails/rism-ch/public
        <Directory "/var/rails/rism-ch/public">
                Options All -Indexes +ExecCGI -Includes +MultiViewsny
                Require all granted
        </Directory>
        RailsEnv production
</VirtualHost>

Double check permissions in the muscat installation. Also make sure DocumentRoot and Directory point to public/ in the muscat installation location.

Start Apache and the related services in production mode (see below).

Apache-itk option

Alternatively, you can take advantatge of the Apache itk module, that simplifies not only having more than one Muscat in a single server using virtual hosts, but also the whole file permissions and ownership altogether. This Apache module (mpm-itk.sesse.net/) makes the Apache web server to run as a plain user, so it is the owner of the files, and it is no longer necessary file ownership via chown or users via sudo. Apache-itk is an official Debian and Ubuntu package, so:

apt install libapache2-mpm-itk

And add the following stanza in the apache configuration file, for example just before the DocumentRoot declaration:

<IfModule mpm_itk_module>
   AssignUserId muscat_linux_user_name muscat_linux_group
</IfModule>

where muscat_linux_user_name and muscat_linux_group are the first two fields of the output of the id shell command.