From 798ae8f1a4abc954063de007023c0a4eeb23d0b9 Mon Sep 17 00:00:00 2001 From: Disassembler Date: Sun, 14 May 2023 16:31:15 +0200 Subject: [PATCH] SeedDMS 6.0.24 --- .env | 14 ++++ README.md | 45 +++++++++++ docker-compose.yml | 34 +++++++++ seeddms/Dockerfile | 49 ++++++++++++ seeddms/image.d/entrypoint.sh | 30 ++++++++ seeddms/image.d/etc/crontabs/seeddms | 1 + seeddms/image.d/etc/nginx/nginx.conf | 44 +++++++++++ seeddms/image.d/etc/php7/php-fpm.conf | 17 +++++ .../image.d/etc/services.d/.s6-svscan/finish | 5 ++ seeddms/image.d/etc/services.d/cron/run | 4 + seeddms/image.d/etc/services.d/nginx/run | 3 + seeddms/image.d/etc/services.d/php-fpm/run | 4 + seeddms/image.d/srv/seeddms/conf/settings.xml | 76 +++++++++++++++++++ .../seeddms/seeddms-6.0.24/install/custom.sql | 13 ++++ .../seeddms-6.0.24/utils/seeddms-indexer | 15 ++++ .../srv/seeddms/settings-from-env-vars.php | 43 +++++++++++ 16 files changed, 397 insertions(+) create mode 100644 .env create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 seeddms/Dockerfile create mode 100755 seeddms/image.d/entrypoint.sh create mode 100644 seeddms/image.d/etc/crontabs/seeddms create mode 100644 seeddms/image.d/etc/nginx/nginx.conf create mode 100644 seeddms/image.d/etc/php7/php-fpm.conf create mode 100755 seeddms/image.d/etc/services.d/.s6-svscan/finish create mode 100755 seeddms/image.d/etc/services.d/cron/run create mode 100755 seeddms/image.d/etc/services.d/nginx/run create mode 100755 seeddms/image.d/etc/services.d/php-fpm/run create mode 100644 seeddms/image.d/srv/seeddms/conf/settings.xml create mode 100644 seeddms/image.d/srv/seeddms/seeddms-6.0.24/install/custom.sql create mode 100755 seeddms/image.d/srv/seeddms/seeddms-6.0.24/utils/seeddms-indexer create mode 100644 seeddms/image.d/srv/seeddms/settings-from-env-vars.php diff --git a/.env b/.env new file mode 100644 index 0000000..fab3e08 --- /dev/null +++ b/.env @@ -0,0 +1,14 @@ +POSTGRES_HOST=seeddms-postgres +POSTGRES_USER=seeddms +POSTGRES_PASSWORD=seeddms +POSTGRES_DB=seeddms + +SEEDDMS_ADMIN_USER=admin +SEEDDMS_ADMIN_EMAIL=admin@example.com +SEEDDMS_ADMIN_PASSWORD=seedDMS123! + +SMTP_HOST=seeddms-smtp +SMTP_PORT=25 +SMTP_SENDER=admin@example.com +SMTP_USERNAME= +SMTP_PASSWORD= diff --git a/README.md b/README.md new file mode 100644 index 0000000..198a6a7 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +SeedDMS +======= + +Overview +-------- + +SeedDMS is a free document management system with an easy to use web based user interface for small +and medium sized enterprises. SeedDMS 6.0 runs on PHP 7.4 and is configured to use PostgreSQL +as backend. SeedDMS integrates with LibreOffice via [unoconv](https://github.com/unoconv/unoconv) +in order to provide previews and conversions for commonly used document formats. + +Development without docker-compose +---------------------------------- + +```bash +rm -rf ~/postgres_data +mkdir ~/postgres_data +podman run -it --rm \ + --env "POSTGRES_USER=seeddms" \ + --env "POSTGRES_PASSWORD=seeddms" \ + --env "POSTGRES_DB=seeddms" \ + --volume ~/postgres_data:/var/lib/postgresql/data \ + --ip 10.88.0.2 \ + docker.io/postgres:14-alpine +``` + +```bash +podman build -t seeddms:latest seeddms + +rm -rf ~/seeddms_{conf,data} +mkdir ~/seeddms_{conf,data} +podman run --rm \ + --volume ~/seeddms_conf:/mnt/conf \ + --volume ~/seeddms_data:/mnt/data \ + seeddms:latest \ + sh -c "cp -rp /srv/seeddms/conf /mnt; cp -rp /srv/seeddms/data /mnt" + +podman run -it --rm \ + --env-file .env \ + --volume ~/seeddms_conf:/srv/seeddms/conf \ + --volume ~/seeddms_data:/srv/seeddms/data \ + --add-host seeddms-postgres:10.88.0.2 \ + --ip 10.88.0.3 \ + seeddms:latest +``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..84f87b2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,34 @@ +--- +version: '3' +services: + + seeddms: + build: seeddms + image: seeddms:6.0.24-230514 + restart: unless-stopped + depends_on: + - seeddms-postgres + env_file: + - .env + expose: + - 8080 + ports: + - 8080:8080 + volumes: + - seeddms_conf:/srv/seeddms/conf + - seeddms_data:/srv/seeddms/data + + seeddms-postgres: + image: postgres:14-alpine + restart: unless-stopped + environment: + - POSTGRES_USER + - POSTGRES_PASSWORD + - POSTGRES_DB + volumes: + - postgres_data:/var/lib/postgresql/data + +volumes: + seeddms_conf: + seeddms_data: + postgres_data: diff --git a/seeddms/Dockerfile b/seeddms/Dockerfile new file mode 100644 index 0000000..c6e4302 --- /dev/null +++ b/seeddms/Dockerfile @@ -0,0 +1,49 @@ +FROM docker.io/alpine:3.15 + +ARG SEEDDMS_VERSION=6.0.24 + +RUN \ + # Update packages + apk --no-cache upgrade && \ + # Install common packages + apk --no-cache add libbz2 libgcc libressl libstdc++ libxml2 libxslt ncurses-libs pcre readline s6 xz-libs && \ + # Install PHP + apk --no-cache add nginx php7 php7-ctype php7-curl php7-fileinfo php7-fpm php7-gd php7-iconv php7-intl php7-json php7-mbstring php7-mcrypt php7-opcache php7-openssl php7-pear php7-pdo_pgsql php7-session php7-simplexml php7-xml php7-xsl php7-zip && \ + # Install glibc-compiled iconv (see https://github.com/docker-library/php/issues/240) + # Provides /usr/lib/preloadable_libiconv.so for LD_PRELOAD + apk --no-cache --repository https://dl-cdn.alpinelinux.org/alpine/v3.13/community/ add gnu-libiconv=1.15-r3 && \ + # Install other dependencies + apk --no-cache add ghostscript imagemagick libreoffice-calc libreoffice-impress libreoffice-writer poppler-utils postgresql-client python3 ttf-opensans && \ + # Set time zone data + apk --no-cache add tzdata && \ + cp /usr/share/zoneinfo/UTC /etc/localtime && \ + apk --no-cache del tzdata && \ + # Set python interpret + ln -s /usr/bin/python3 /usr/bin/python && \ + # Install unoconv + wget https://raw.githubusercontent.com/dagwieers/unoconv/master/unoconv -O /usr/bin/unoconv && \ + chmod +x /usr/bin/unoconv && \ + # Cleanup + rm -rf /etc/crontabs/root /etc/periodic + +RUN \ + # Install SeedDMS + wget https://sourceforge.net/projects/seeddms/files/seeddms-${SEEDDMS_VERSION}/seeddms-quickstart-${SEEDDMS_VERSION}.tar.gz/download -O - | tar xzf - -C /srv && \ + mv /srv/seeddms* /srv/seeddms && \ + rm -rf /srv/seeddms/www/install /srv/seeddms/www/ext/example && \ + # Create OS user + addgroup -S -g 8080 seeddms && \ + adduser -S -u 8080 -h /srv/seeddms -s /bin/false -g seeddms -G seeddms seeddms && \ + chown -R seeddms:seeddms /srv/seeddms + +RUN \ + # Fix missing "secret" column in create_tables-postgres.sql inserts + sed -i "s/'21232f297a57a5a743894a0e4a801fc3'/'21232f297a57a5a743894a0e4a801fc3', ''/" /srv/seeddms/seeddms/install/create_tables-postgres.sql + +COPY --chown=seeddms:seeddms image.d/srv/seeddms/ /srv/seeddms/ +COPY image.d/etc/ /etc/ +COPY image.d/entrypoint.sh / + +VOLUME ["/srv/seeddms/conf", "/srv/seeddms/data"] +EXPOSE 8080 +ENTRYPOINT ["/entrypoint.sh"] diff --git a/seeddms/image.d/entrypoint.sh b/seeddms/image.d/entrypoint.sh new file mode 100755 index 0000000..fb23efd --- /dev/null +++ b/seeddms/image.d/entrypoint.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -e + +if [ "$*" != "" ]; then + exec "$@" +fi + +echo "Starting SeedDMS..." + +# Fix volume permissions +chown -R seeddms:seeddms /srv/seeddms/conf /srv/seeddms/data + +# Populate database +export PGPASSWORD=${POSTGRES_PASSWORD} +DB_EXISTS=$(psql -h "${POSTGRES_HOST}" -Atc "SELECT 1 FROM \"tblVersion\"" "${POSTGRES_DB}" "${POSTGRES_USER}" 2>/dev/null || true) +if [ -z "${DB_EXISTS}" ]; then + cat /srv/seeddms/seeddms/install/create_tables-postgres.sql | psql -h "${POSTGRES_HOST}" "${POSTGRES_DB}" "${POSTGRES_USER}" + cat /srv/seeddms/seeddms/install/custom.sql | psql -h "${POSTGRES_HOST}" "${POSTGRES_DB}" "${POSTGRES_USER}" +fi +psql -h "${POSTGRES_HOST}" -Atc "UPDATE \"tblUsers\" SET login = '${SEEDDMS_ADMIN_USER}', pwd = MD5('${SEEDDMS_ADMIN_PASSWORD}'), email = '${SEEDDMS_ADMIN_EMAIL}' WHERE id = 1" "${POSTGRES_DB}" "${POSTGRES_USER}" +# TODO: Update database +# Looks like database schema updates are done only in new minor version (e.g. 6.0.x -> 6.1.x) +unset PGPASSWORD + +# Configure SeedDMS +/usr/bin/php -f /srv/seeddms/settings-from-env-vars.php +chown seeddms:seeddms /srv/seeddms/conf/settings.xml + +# Exec into s6 supervisor +exec /bin/s6-svscan /etc/services.d diff --git a/seeddms/image.d/etc/crontabs/seeddms b/seeddms/image.d/etc/crontabs/seeddms new file mode 100644 index 0000000..c2331f6 --- /dev/null +++ b/seeddms/image.d/etc/crontabs/seeddms @@ -0,0 +1 @@ +*/10 * * * * /srv/seeddms/seeddms/utils/seeddms-indexer >/dev/null diff --git a/seeddms/image.d/etc/nginx/nginx.conf b/seeddms/image.d/etc/nginx/nginx.conf new file mode 100644 index 0000000..293c310 --- /dev/null +++ b/seeddms/image.d/etc/nginx/nginx.conf @@ -0,0 +1,44 @@ +user nginx; +pid /run/nginx.pid; +worker_processes 1; +error_log /dev/stderr warn; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + access_log off; + server_tokens off; + client_max_body_size 100m; + sendfile on; + tcp_nodelay on; + send_timeout 300; + + server { + listen 8080; + server_name localhost; + + root /srv/seeddms/www; + index index.php; + + location / { + try_files $uri $uri/ /index.php$is_args$args; + } + + location ~ \.php$ { + fastcgi_pass unix:/var/run/seeddms.sock; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $request_filename; + fastcgi_param HTTP_HOST $http_x_forwarded_host if_not_empty; + fastcgi_param HTTPS "on"; + fastcgi_param REQUEST_SCHEME "https"; + fastcgi_param SERVER_NAME $http_x_forwarded_server_name if_not_empty; + fastcgi_param SERVER_PORT $http_x_forwarded_server_port if_not_empty; + } + } +} diff --git a/seeddms/image.d/etc/php7/php-fpm.conf b/seeddms/image.d/etc/php7/php-fpm.conf new file mode 100644 index 0000000..5df55ab --- /dev/null +++ b/seeddms/image.d/etc/php7/php-fpm.conf @@ -0,0 +1,17 @@ +[global] +error_log = /proc/self/fd/2 +daemonize = no + +[seeddms] +catch_workers_output = yes +user = seeddms +group = seeddms +listen.owner = nginx +listen.group = nginx +listen = /var/run/seeddms.sock +pm = ondemand +pm.max_children = 16 +php_admin_value[error_reporting] = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED +php_admin_value[upload_max_filesize] = 100M +php_admin_value[post_max_size] = 100M +env[LANG]=en_US.UTF-8 diff --git a/seeddms/image.d/etc/services.d/.s6-svscan/finish b/seeddms/image.d/etc/services.d/.s6-svscan/finish new file mode 100755 index 0000000..3b6c8bf --- /dev/null +++ b/seeddms/image.d/etc/services.d/.s6-svscan/finish @@ -0,0 +1,5 @@ +#!/bin/execlineb -P + +/bin/foreground { /bin/s6-svwait -d -t 3000 cron } +/bin/foreground { /bin/s6-svwait -d -t 3000 nginx } +/bin/foreground { /bin/s6-svwait -d -t 3000 php-fpm } diff --git a/seeddms/image.d/etc/services.d/cron/run b/seeddms/image.d/etc/services.d/cron/run new file mode 100755 index 0000000..d4aecef --- /dev/null +++ b/seeddms/image.d/etc/services.d/cron/run @@ -0,0 +1,4 @@ +#!/bin/execlineb -P + +/bin/fdmove -c 2 1 +/usr/sbin/crond -f -d 8 diff --git a/seeddms/image.d/etc/services.d/nginx/run b/seeddms/image.d/etc/services.d/nginx/run new file mode 100755 index 0000000..d09b7cd --- /dev/null +++ b/seeddms/image.d/etc/services.d/nginx/run @@ -0,0 +1,3 @@ +#!/bin/execlineb -P + +/usr/sbin/nginx -g "daemon off;" diff --git a/seeddms/image.d/etc/services.d/php-fpm/run b/seeddms/image.d/etc/services.d/php-fpm/run new file mode 100755 index 0000000..ad7756f --- /dev/null +++ b/seeddms/image.d/etc/services.d/php-fpm/run @@ -0,0 +1,4 @@ +#!/bin/execlineb -P + +/bin/export LD_PRELOAD /usr/lib/preloadable_libiconv.so +/usr/sbin/php-fpm7 -F diff --git a/seeddms/image.d/srv/seeddms/conf/settings.xml b/seeddms/image.d/srv/seeddms/conf/settings.xml new file mode 100644 index 0000000..a040a5f --- /dev/null +++ b/seeddms/image.d/srv/seeddms/conf/settings.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + pdftotext -enc UTF-8 -nopgbrk %s - + unoconv -d document -f txt --stdout %s + unoconv -d document -f txt --stdout %s + unoconv -d document -f txt --stdout %s + unoconv -d document -f txt --stdout %s + unoconv -d spreadsheet -f csv --stdout %s + unoconv -d spreadsheet -f csv --stdout %s + unoconv -d spreadsheet -f csv --stdout %s + unoconv -d presentation -f pdf --stdout %s | pdftotext -enc UTF-8 -nopgbrk - - + unoconv -d presentation -f pdf --stdout %s | pdftotext -enc UTF-8 -nopgbrk - - + unoconv -d presentation -f pdf --stdout %s | pdftotext -enc UTF-8 -nopgbrk - - + unoconv -d document -f txt --stdout %s + cat %s + + + convert -resize %wx '%f' '%o' + convert -resize %wx '%f' '%o' + convert -resize %wx '%f' '%o' + convert -resize %wx '%f' '%o' + convert -resize %wx '%f' '%o' + convert -density 100 -resize %wx '%f[0]' '%o' + unoconv -d document -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d document -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d document -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d document -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d spreadsheet -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d spreadsheet -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d spreadsheet -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d presentation -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d presentation -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d presentation -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d document -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + unoconv -d document -e PageRange=1-1 -f pdf --stdout '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72 -sOutputFile=- -q - | convert -resize %wx png:- '%o' + + + unoconv -d document -f pdf -o '%o' '%f' + unoconv -d document -f pdf -o '%o' '%f' + unoconv -d document -f pdf -o '%o' '%f' + unoconv -d document -f pdf -o '%o' '%f' + unoconv -d spreadsheet -f pdf -o '%o' '%f' + unoconv -d spreadsheet -f pdf -o '%o' '%f' + unoconv -d spreadsheet -f pdf -o '%o' '%f' + unoconv -d presentation -f pdf -o '%o' '%f' + unoconv -d presentation -f pdf -o '%o' '%f' + unoconv -d presentation -f pdf -o '%o' '%f' + unoconv -d document -f pdf -o '%o' '%f' + unoconv -d document -f pdf -o '%o' '%f' + + + + diff --git a/seeddms/image.d/srv/seeddms/seeddms-6.0.24/install/custom.sql b/seeddms/image.d/srv/seeddms/seeddms-6.0.24/install/custom.sql new file mode 100644 index 0000000..1ac5995 --- /dev/null +++ b/seeddms/image.d/srv/seeddms/seeddms-6.0.24/install/custom.sql @@ -0,0 +1,13 @@ +INSERT INTO "tblAttributeDefinitions" (name, objtype, type) VALUES +('Licence', 2, 3), +('Autor', 2, 3), +('Source URL', 2, 5), +('Email', 2, 6), +('Organization', 2, 3), +('ISBN', 2, 3), +('Published', 2, 7), +('Language', 0, 3), +('Phone', 2, 1), +('Region', 0, 3), +('Org. abbreviation', 2, 3), +('ISSN', 2, 3); diff --git a/seeddms/image.d/srv/seeddms/seeddms-6.0.24/utils/seeddms-indexer b/seeddms/image.d/srv/seeddms/seeddms-6.0.24/utils/seeddms-indexer new file mode 100755 index 0000000..e6c8bc1 --- /dev/null +++ b/seeddms/image.d/srv/seeddms/seeddms-6.0.24/utils/seeddms-indexer @@ -0,0 +1,15 @@ +#!/bin/sh + +if [ -z "${SEEDDMS_HOME}" ]; then + parentdir=$(dirname "$0") + export SEEDDMS_HOME=$(dirname "$parentdir") +fi + +# Prevent indexer jobs to run simultaneously by using a file lock +( + if ! flock -n 3; then + echo "Previous indexer job is still running" + exit 1 + fi + php -f "${SEEDDMS_HOME}/utils/indexer.php" -- "${@}" +) 3>/srv/seeddms/indexer.lock diff --git a/seeddms/image.d/srv/seeddms/settings-from-env-vars.php b/seeddms/image.d/srv/seeddms/settings-from-env-vars.php new file mode 100644 index 0000000..2fcd2e6 --- /dev/null +++ b/seeddms/image.d/srv/seeddms/settings-from-env-vars.php @@ -0,0 +1,43 @@ +_dbHostname = $dbHostname; +} +$dbDatabase = getenv("POSTGRES_DB"); +if ($dbDatabase) { + $settings->_dbDatabase = $dbDatabase; +} +$dbUser = getenv("POSTGRES_USER"); +if ($dbUser) { + $settings->_dbUser = $dbUser; +} +$dbPass = getenv("POSTGRES_PASSWORD"); +if ($dbPass) { + $settings->_dbPass = $dbPass; +} + +$smtpServer = getenv("SMTP_HOST"); +if ($smtpServer) { + $settings->_smtpServer = $smtpServer; +} +$smtpPort = getenv("SMTP_PORT"); +if ($smtpPort) { + $settings->_smtpPort = $smtpPort; +} +$smtpSendFrom = getenv("SMTP_SENDER"); +if ($smtpSendFrom) { + $settings->_smtpSendFrom = $smtpSendFrom; +} +$smtpUser = getenv("SMTP_USERNAME"); +if ($smtpUser) { + $settings->_smtpUser = $smtpUser; +} +$smtpPassword = getenv("SMTP_PASSWORD"); +if ($smtpPassword) { + $settings->_smtpPassword = $smtpPassword; +} + +$settings->save();