From 870bf7b31463a748cf317cce2cfae2b04940d84e Mon Sep 17 00:00:00 2001 From: Florian Charlaix Date: Thu, 12 Sep 2024 11:16:01 +0200 Subject: [PATCH 1/5] Allow the use of variants of the PHP image --- Dockerfile.template | 10 ++-- update.sh | 128 ++++++++++++++++++++++++++++---------------- 2 files changed, 86 insertions(+), 52 deletions(-) diff --git a/Dockerfile.template b/Dockerfile.template index fdf7553..4a64a72 100644 --- a/Dockerfile.template +++ b/Dockerfile.template @@ -40,11 +40,7 @@ ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M ENV PHP_INI_POST_MAX_SIZE 8M ENV PHP_INI_ALLOW_URL_FOPEN 0 -RUN sed -i \ - -e 's/^\(ServerSignature On\)$/#\1/g' \ - -e 's/^#\(ServerSignature Off\)$/\1/g' \ - -e 's/^\(ServerTokens\) OS$/\1 Prod/g' \ - /etc/apache2/conf-available/security.conf +%EXTRAS% RUN apt-get update -y \ && apt-get dist-upgrade -y \ @@ -84,7 +80,7 @@ RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar. mkdir -p /var/www/html/custom && \ chown -R www-data:www-data /var/www -EXPOSE 80 +EXPOSE %EXPOSE% VOLUME /var/www/documents VOLUME /var/www/html/custom @@ -92,4 +88,4 @@ COPY docker-init.php /var/www/scripts/ COPY docker-run.sh /usr/local/bin/ ENTRYPOINT ["docker-run.sh"] -CMD ["apache2-foreground"] +CMD ["%CMD%"] diff --git a/update.sh b/update.sh index 1195b50..7b24d0a 100755 --- a/update.sh +++ b/update.sh @@ -2,7 +2,7 @@ # # Run this script to generate all files found into images directory, used for each image. # The source files are the files into the root. -# +# set -e @@ -11,6 +11,25 @@ DOCKER_PUSH=${DOCKER_PUSH:-0} BASE_DIR="$( cd "$(dirname "$0")" && pwd )" +VARIANTS=( apache-buster fpm ) +DEFAULT_VARIANT="apache-buster" +declare -A VARIANTS_EXTRAS=( + [apache-buster]="RUN sed -i \ +-e 's/^\(ServerSignature On\)\$/#\1/g' \ +-e 's/^#\(ServerSignature Off\)\$/\1/g' \ +-e 's/^\(ServerTokens\) OS\$/\1 Prod/g' \ +/etc/apache2/conf-available/security.conf" + [fpm]="" +) +declare -A VARIANTS_CMD=( + [apache-buster]=apache2-foreground + [fpm]=php-fpm +) +declare -A VARIANTS_EXPOSE=( + [apache-buster]="80" + [fpm]="9000" +) + source "${BASE_DIR}/versions.sh" tags="" @@ -36,56 +55,75 @@ for dolibarrVersion in "${DOLIBARR_VERSIONS[@]}"; do # Mapping version according https://wiki.dolibarr.org/index.php/Versions # Regarding PHP Supported version : https://www.php.net/supported-versions.php if [ "${dolibarrVersion}" = "develop" ] || [ "${dolibarrMajor}" -ge "19" ] || [ "${dolibarrMajor}" -ge "20" ]; then - php_base_images=( "8.2-apache-buster" ) + phpVersions=( "8.2" ) elif [ "${dolibarrMajor}" -ge "16" ]; then - php_base_images=( "8.1-apache-buster" ) + phpVersions=( "8.1" ) else - php_base_images=( "7.4-apache-buster" ) + phpVersions=( "7.4" ) fi - for php_base_image in "${php_base_images[@]}"; do - php_version=$(echo "${php_base_image}" | cut -d\- -f1) - - if [ "${dolibarrVersion}" = "develop" ]; then - currentTag="${dolibarrVersion}" - else - currentTag="${dolibarrVersion}-php${php_version}" - tags="${tags} ${currentTag}" - fi - - buildOptionTags="--tag dolibarr/dolibarr:${currentTag}" - if [ "${dolibarrVersion}" != "develop" ]; then - buildOptionTags="${buildOptionTags} --tag dolibarr/dolibarr:${dolibarrVersion} --tag dolibarr/dolibarr:${dolibarrMajor}" - fi - if [ "${dolibarrVersion}" = "${DOLIBARR_LATEST_TAG}" ]; then - buildOptionTags="${buildOptionTags} --tag dolibarr/dolibarr:latest" - fi - - dir="${BASE_DIR}/images/${currentTag}" - - mkdir -p "${dir}" - sed 's/%PHP_BASE_IMAGE%/'"${php_base_image}"'/;' "${BASE_DIR}/Dockerfile.template" | \ - sed 's/%DOLI_VERSION%/'"${dolibarrVersion}"'/;' \ - > "${dir}/Dockerfile" - - cp -a "${BASE_DIR}/docker-init.php" "${dir}/docker-init.php" - cp -a "${BASE_DIR}/docker-run.sh" "${dir}/docker-run.sh" - - if [ "${DOCKER_BUILD}" = "1" ]; then - if [ "${DOCKER_PUSH}" = "1" ]; then - docker buildx build \ - --push \ - --compress \ - --platform linux/arm/v7,linux/arm64,linux/amd64 \ - ${buildOptionTags} \ - "${dir}" + for phpVersion in "${phpVersions[@]}"; do + for imageVariant in "${VARIANTS[@]}"; do + echo "- Variant $imageVariant" + phpBaseImage="$phpVersion-$imageVariant" + + if [ "${dolibarrVersion}" = "develop" ]; then + currentTag="${dolibarrVersion}" else - docker build \ - --compress \ - ${buildOptionTags} \ - "${dir}" + currentTag="${dolibarrVersion}-php${phpVersion}" + + if [ "$imageVariant" != "$DEFAULT_VARIANT" ]; then + currentTag+="-$imageVariant" + fi + + tags="${tags} ${currentTag}" + fi + + buildOptionTags="--tag dolibarr/dolibarr:${currentTag}" + if [ "${dolibarrVersion}" != "develop" ]; then + if [ "$imageVariant" = "$DEFAULT_VARIANT" ]; then + buildOptionTags="${buildOptionTags} --tag dolibarr/dolibarr:${dolibarrVersion} --tag dolibarr/dolibarr:${dolibarrMajor}" + else + buildOptionTags="${buildOptionTags} --tag dolibarr/dolibarr:${dolibarrVersion}-${imageVariant} --tag dolibarr/dolibarr:${dolibarrMajor}-${imageVariant}" + fi + fi + if [ "${dolibarrVersion}" = "${DOLIBARR_LATEST_TAG}" ]; then + if [ "$imageVariant" = "$DEFAULT_VARIANT" ]; then + buildOptionTags="${buildOptionTags} --tag dolibarr/dolibarr:latest" + else + buildOptionTags="${buildOptionTags} --tag dolibarr/dolibarr:latest-${imageVariant}" + fi + fi + + dir="${BASE_DIR}/images/${dolibarrVersion}/${imageVariant}" + + mkdir -p "${dir}" + sed 's/%PHP_BASE_IMAGE%/'"${phpBaseImage}"'/;' "${BASE_DIR}/Dockerfile.template" | \ + sed 's/%DOLI_VERSION%/'"${dolibarrVersion}"'/;' | \ + sed 's~%EXTRAS%~'"$(sed 's/[&/\]/\\&/g' <<< "${VARIANTS_EXTRAS[$imageVariant]}")"'~;' | \ + sed 's/%EXPOSE%/'"${VARIANTS_EXPOSE[$imageVariant]}"'/;' | \ + sed 's/%CMD%/'"${VARIANTS_CMD[$imageVariant]}"'/;' \ + > "${dir}/Dockerfile" + + cp -a "${BASE_DIR}/docker-init.php" "${dir}/docker-init.php" + cp -a "${BASE_DIR}/docker-run.sh" "${dir}/docker-run.sh" + + if [ "${DOCKER_BUILD}" = "1" ]; then + if [ "${DOCKER_PUSH}" = "1" ]; then + docker buildx build \ + --push \ + --compress \ + --platform linux/arm/v7,linux/arm64,linux/amd64 \ + ${buildOptionTags} \ + "${dir}" + else + docker build \ + --compress \ + ${buildOptionTags} \ + "${dir}" + fi fi - fi + done done if [ "${dolibarrVersion}" = "develop" ]; then From ad408d9ff646a518b26b69408097918fa6e3eb63 Mon Sep 17 00:00:00 2001 From: Florian Charlaix Date: Thu, 12 Sep 2024 12:12:24 +0200 Subject: [PATCH 2/5] Put htdocs into a volume to allow external web server or dev --- Dockerfile.template | 5 ++++- docker-run.sh | 12 +++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Dockerfile.template b/Dockerfile.template index 4a64a72..33dfdd1 100644 --- a/Dockerfile.template +++ b/Dockerfile.template @@ -57,6 +57,7 @@ RUN apt-get update -y \ default-mysql-client \ postgresql-client \ cron \ + rsync \ && apt-get autoremove -y \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ @@ -72,7 +73,8 @@ RUN apt-get update -y \ # Get Dolibarr RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ tar -C /tmp -xz && \ - cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /var/www/html/ && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ ln -s /var/www/html /var/www/htdocs && \ cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ rm -rf /tmp/* && \ @@ -82,6 +84,7 @@ RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar. EXPOSE %EXPOSE% VOLUME /var/www/documents +VOLUME /var/www/html VOLUME /var/www/html/custom COPY docker-init.php /var/www/scripts/ diff --git a/docker-run.sh b/docker-run.sh index c2292cc..fc9ed33 100755 --- a/docker-run.sh +++ b/docker-run.sh @@ -54,6 +54,7 @@ EOF if [[ ! -f /var/www/html/conf/conf.php ]]; then echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf cat > /var/www/html/conf/conf.php << EOF /var/www/documents/vi + > /var/www/documents/vi versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql @@ -281,11 +289,13 @@ function run() mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 r=$? if [[ ${r} -ne 0 ]]; then + updateHtdocs initializeDatabase else INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` echo "Last installed Version is : ${INSTALLED_VERSION}" if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs migrateDatabase else echo "Schema update is not required ... Enjoy !!" From e4ab853a842af65892270ee0417ff5b071e19399 Mon Sep 17 00:00:00 2001 From: Florian Charlaix Date: Thu, 12 Sep 2024 12:12:50 +0200 Subject: [PATCH 3/5] Add FPM Nginx example --- examples/with-fpm-nginx/conf/nginx.conf | 65 +++++++++++++++++++ examples/with-fpm-nginx/docker-compose.yml | 53 +++++++++++++++ .../with-fpm-nginx/dolibarr-with-fpm-nginx.md | 3 + 3 files changed, 121 insertions(+) create mode 100644 examples/with-fpm-nginx/conf/nginx.conf create mode 100644 examples/with-fpm-nginx/docker-compose.yml create mode 100644 examples/with-fpm-nginx/dolibarr-with-fpm-nginx.md diff --git a/examples/with-fpm-nginx/conf/nginx.conf b/examples/with-fpm-nginx/conf/nginx.conf new file mode 100644 index 0000000..d2cd4fc --- /dev/null +++ b/examples/with-fpm-nginx/conf/nginx.conf @@ -0,0 +1,65 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + upstream dolibarr { + server dolibarr:9000; + } + + server { + listen 80; + keepalive_timeout 70; + + root /var/www/html/; + index index.php; + + try_files $uri $uri/ =404; + + location ~ [^/]\.php(/|$) { + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + + # Mitigate https://httpoxy.org/ vulnerabilities + fastcgi_param HTTP_PROXY ""; + + fastcgi_pass dolibarr; + fastcgi_index index.php; + + include fastcgi_params; + + fastcgi_intercept_errors on; + fastcgi_param SCRIPT_FILENAME $request_filename; + + # Dolibarr Rest API path support + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param PATH_TRANSLATED $request_filename; + fastcgi_param CONTEXT_DOCUMENT_ROOT $document_root; + } + + client_max_body_size 8m; + } +} diff --git a/examples/with-fpm-nginx/docker-compose.yml b/examples/with-fpm-nginx/docker-compose.yml new file mode 100644 index 0000000..8710bdc --- /dev/null +++ b/examples/with-fpm-nginx/docker-compose.yml @@ -0,0 +1,53 @@ +networks: + internal-pod: + internal: true + external-pod: + internal: false + +volumes: + dolibarr-htdocs: + dolibarr-custom: + dolibarr-docs: + mysql-data: + +services: + nginx: + image: nginx + ports: + - 80:80 + volumes: + - ./conf/nginx.conf:/etc/nginx/nginx.conf:ro + - dolibarr-htdocs:/var/www/html:ro + - dolibarr-custom:/var/www/html/custom:ro + networks: + - internal-pod + - external-pod + + dolibarr: + image: dolibarr/dolibarr:latest-fpm + environment: + DOLI_DB_HOST: "mysql" + DOLI_DB_HOST_PORT: "3306" + DOLI_DB_USER: "dolibarr" + DOLI_DB_PASSWORD: "mysupersecretpasswordfordatabase" + DOLI_DB_NAME: "dolibarr" + DOLI_ADMIN_LOGIN: "admin" + DOLI_ADMIN_PASSWORD: "mysuperhypersecretpasswordforadminacount" + volumes: + - dolibarr-docs:/var/www/documents + - dolibarr-htdocs:/var/www/html + - dolibarr-custom:/var/www/html/custom + networks: + - internal-pod + + mysql: + image: mysql:latest + environment: + MYSQL_DATABASE: "dolibarr" + MYSQL_USER: "dolibarr" + MYSQL_PASSWORD: "mysupersecretpasswordfordatabase" + MYSQL_ROOT_PASSWORD: "mysupersupersecretpasswordforrootuser" + volumes: + - mysql-data:/var/lib/mysql + networks: + - internal-pod diff --git a/examples/with-fpm-nginx/dolibarr-with-fpm-nginx.md b/examples/with-fpm-nginx/dolibarr-with-fpm-nginx.md new file mode 100644 index 0000000..78c310f --- /dev/null +++ b/examples/with-fpm-nginx/dolibarr-with-fpm-nginx.md @@ -0,0 +1,3 @@ +# Dolibarr with FPM and Nginx + +This example use the PHP-FPM image with Nginx instead of Apache2. From 4c53f86c051b6ee8670d0c2fa2107873a7945002 Mon Sep 17 00:00:00 2001 From: Florian Charlaix Date: Thu, 12 Sep 2024 12:19:43 +0200 Subject: [PATCH 4/5] Fix README tags and develop --- update.sh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/update.sh b/update.sh index 7b24d0a..52d2a36 100755 --- a/update.sh +++ b/update.sh @@ -69,6 +69,10 @@ for dolibarrVersion in "${DOLIBARR_VERSIONS[@]}"; do if [ "${dolibarrVersion}" = "develop" ]; then currentTag="${dolibarrVersion}" + + if [ "$imageVariant" != "$DEFAULT_VARIANT" ]; then + currentTag+="-$imageVariant" + fi else currentTag="${dolibarrVersion}-php${phpVersion}" @@ -127,12 +131,17 @@ for dolibarrVersion in "${DOLIBARR_VERSIONS[@]}"; do done if [ "${dolibarrVersion}" = "develop" ]; then - tags="${tags} develop" + tags="${tags} develop develop-fpm" else tags="${tags} ${dolibarrVersion} ${dolibarrMajor}" + for imageVariant in "${VARIANTS[@]}"; do + if [ "$imageVariant" != "$DEFAULT_VARIANT" ]; then + tags="${tags} ${dolibarrVersion}-${imageVariant} ${dolibarrMajor}-${imageVariant}" + fi + done fi if [ "${dolibarrVersion}" = "${DOLIBARR_LATEST_TAG}" ]; then - tags="${tags} latest" + tags="${tags} latest latest-fpm" fi done From e61f6e9a2bc53e817321d62ad76032b77f1b1fe0 Mon Sep 17 00:00:00 2001 From: Florian Charlaix Date: Thu, 12 Sep 2024 12:22:47 +0200 Subject: [PATCH 5/5] Updated images and README --- README.md | 12 +- .../apache-buster}/Dockerfile | 11 +- .../apache-buster}/docker-init.php | 0 .../apache-buster}/docker-run.sh | 12 +- images/15.0.3/fpm/Dockerfile | 94 +++++ .../fpm}/docker-init.php | 0 .../fpm}/docker-run.sh | 12 +- .../apache-buster}/Dockerfile | 11 +- .../apache-buster}/docker-init.php | 0 .../apache-buster}/docker-run.sh | 12 +- images/16.0.5/fpm/Dockerfile | 94 +++++ .../fpm}/docker-init.php | 0 .../fpm}/docker-run.sh | 12 +- .../apache-buster}/Dockerfile | 11 +- .../apache-buster}/docker-init.php | 0 images/17.0.4/apache-buster/docker-run.sh | 340 ++++++++++++++++++ images/17.0.4/fpm/Dockerfile | 94 +++++ .../{develop => 17.0.4/fpm}/docker-init.php | 0 images/17.0.4/fpm/docker-run.sh | 340 ++++++++++++++++++ .../apache-buster}/Dockerfile | 11 +- images/18.0.5/apache-buster/docker-init.php | 49 +++ images/18.0.5/apache-buster/docker-run.sh | 340 ++++++++++++++++++ images/18.0.5/fpm/Dockerfile | 94 +++++ images/18.0.5/fpm/docker-init.php | 49 +++ images/18.0.5/fpm/docker-run.sh | 340 ++++++++++++++++++ images/19.0.3-php8.2/docker-run.sh | 330 ----------------- .../apache-buster}/Dockerfile | 11 +- images/19.0.3/apache-buster/docker-init.php | 49 +++ images/19.0.3/apache-buster/docker-run.sh | 340 ++++++++++++++++++ images/19.0.3/fpm/Dockerfile | 94 +++++ images/19.0.3/fpm/docker-init.php | 49 +++ images/19.0.3/fpm/docker-run.sh | 340 ++++++++++++++++++ images/develop/{ => apache-buster}/Dockerfile | 11 +- images/develop/apache-buster/docker-init.php | 49 +++ images/develop/apache-buster/docker-run.sh | 340 ++++++++++++++++++ images/develop/docker-run.sh | 330 ----------------- images/develop/fpm/Dockerfile | 94 +++++ images/develop/fpm/docker-init.php | 49 +++ images/develop/fpm/docker-run.sh | 340 ++++++++++++++++++ 39 files changed, 3658 insertions(+), 706 deletions(-) rename images/{15.0.3-php7.4 => 15.0.3/apache-buster}/Dockerfile (88%) rename images/{15.0.3-php7.4 => 15.0.3/apache-buster}/docker-init.php (100%) rename images/{17.0.4-php8.1 => 15.0.3/apache-buster}/docker-run.sh (97%) create mode 100644 images/15.0.3/fpm/Dockerfile rename images/{16.0.5-php8.1 => 15.0.3/fpm}/docker-init.php (100%) rename images/{15.0.3-php7.4 => 15.0.3/fpm}/docker-run.sh (97%) rename images/{16.0.5-php8.1 => 16.0.5/apache-buster}/Dockerfile (88%) rename images/{17.0.4-php8.1 => 16.0.5/apache-buster}/docker-init.php (100%) rename images/{18.0.5-php8.1 => 16.0.5/apache-buster}/docker-run.sh (97%) create mode 100644 images/16.0.5/fpm/Dockerfile rename images/{18.0.5-php8.1 => 16.0.5/fpm}/docker-init.php (100%) rename images/{16.0.5-php8.1 => 16.0.5/fpm}/docker-run.sh (97%) rename images/{17.0.4-php8.1 => 17.0.4/apache-buster}/Dockerfile (88%) rename images/{19.0.3-php8.2 => 17.0.4/apache-buster}/docker-init.php (100%) create mode 100755 images/17.0.4/apache-buster/docker-run.sh create mode 100644 images/17.0.4/fpm/Dockerfile rename images/{develop => 17.0.4/fpm}/docker-init.php (100%) create mode 100755 images/17.0.4/fpm/docker-run.sh rename images/{18.0.5-php8.1 => 18.0.5/apache-buster}/Dockerfile (88%) create mode 100644 images/18.0.5/apache-buster/docker-init.php create mode 100755 images/18.0.5/apache-buster/docker-run.sh create mode 100644 images/18.0.5/fpm/Dockerfile create mode 100644 images/18.0.5/fpm/docker-init.php create mode 100755 images/18.0.5/fpm/docker-run.sh delete mode 100755 images/19.0.3-php8.2/docker-run.sh rename images/{19.0.3-php8.2 => 19.0.3/apache-buster}/Dockerfile (88%) create mode 100644 images/19.0.3/apache-buster/docker-init.php create mode 100755 images/19.0.3/apache-buster/docker-run.sh create mode 100644 images/19.0.3/fpm/Dockerfile create mode 100644 images/19.0.3/fpm/docker-init.php create mode 100755 images/19.0.3/fpm/docker-run.sh rename images/develop/{ => apache-buster}/Dockerfile (88%) create mode 100644 images/develop/apache-buster/docker-init.php create mode 100755 images/develop/apache-buster/docker-run.sh delete mode 100755 images/develop/docker-run.sh create mode 100644 images/develop/fpm/Dockerfile create mode 100644 images/develop/fpm/docker-init.php create mode 100755 images/develop/fpm/docker-run.sh diff --git a/README.md b/README.md index 54aac80..e930f94 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,12 @@ Dolibarr is a modern software package to manage your organization's activity (co ## Supported tags -* 15.0.3-php7.4 15.0.3 15 -* 16.0.5-php8.1 16.0.5 16 -* 17.0.4-php8.1 17.0.4 17 -* 18.0.5-php8.1 18.0.5 18 -* 19.0.3-php8.2 19.0.3 19 latest -* develop +* 15.0.3-php7.4 15.0.3-php7.4-fpm 15.0.3 15 15.0.3-fpm 15-fpm +* 16.0.5-php8.1 16.0.5-php8.1-fpm 16.0.5 16 16.0.5-fpm 16-fpm +* 17.0.4-php8.1 17.0.4-php8.1-fpm 17.0.4 17 17.0.4-fpm 17-fpm +* 18.0.5-php8.1 18.0.5-php8.1-fpm 18.0.5 18 18.0.5-fpm 18-fpm +* 19.0.3-php8.2 19.0.3-php8.2-fpm 19.0.3 19 19.0.3-fpm 19-fpm latest latest-fpm +* develop develop-fpm **End of support for PHP < 7.4** diff --git a/images/15.0.3-php7.4/Dockerfile b/images/15.0.3/apache-buster/Dockerfile similarity index 88% rename from images/15.0.3-php7.4/Dockerfile rename to images/15.0.3/apache-buster/Dockerfile index d06fa00..7722b3d 100644 --- a/images/15.0.3-php7.4/Dockerfile +++ b/images/15.0.3/apache-buster/Dockerfile @@ -40,11 +40,7 @@ ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M ENV PHP_INI_POST_MAX_SIZE 8M ENV PHP_INI_ALLOW_URL_FOPEN 0 -RUN sed -i \ - -e 's/^\(ServerSignature On\)$/#\1/g' \ - -e 's/^#\(ServerSignature Off\)$/\1/g' \ - -e 's/^\(ServerTokens\) OS$/\1 Prod/g' \ - /etc/apache2/conf-available/security.conf +RUN sed -i -e 's/^\(ServerSignature On\)$/#\1/g' -e 's/^#\(ServerSignature Off\)$/\1/g' -e 's/^\(ServerTokens\) OS$/\1 Prod/g' /etc/apache2/conf-available/security.conf RUN apt-get update -y \ && apt-get dist-upgrade -y \ @@ -61,6 +57,7 @@ RUN apt-get update -y \ default-mysql-client \ postgresql-client \ cron \ + rsync \ && apt-get autoremove -y \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ @@ -76,7 +73,8 @@ RUN apt-get update -y \ # Get Dolibarr RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ tar -C /tmp -xz && \ - cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /var/www/html/ && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ ln -s /var/www/html /var/www/htdocs && \ cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ rm -rf /tmp/* && \ @@ -86,6 +84,7 @@ RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar. EXPOSE 80 VOLUME /var/www/documents +VOLUME /var/www/html VOLUME /var/www/html/custom COPY docker-init.php /var/www/scripts/ diff --git a/images/15.0.3-php7.4/docker-init.php b/images/15.0.3/apache-buster/docker-init.php similarity index 100% rename from images/15.0.3-php7.4/docker-init.php rename to images/15.0.3/apache-buster/docker-init.php diff --git a/images/17.0.4-php8.1/docker-run.sh b/images/15.0.3/apache-buster/docker-run.sh similarity index 97% rename from images/17.0.4-php8.1/docker-run.sh rename to images/15.0.3/apache-buster/docker-run.sh index c2292cc..fc9ed33 100755 --- a/images/17.0.4-php8.1/docker-run.sh +++ b/images/15.0.3/apache-buster/docker-run.sh @@ -54,6 +54,7 @@ EOF if [[ ! -f /var/www/html/conf/conf.php ]]; then echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf cat > /var/www/html/conf/conf.php << EOF /var/www/documents/vi + > /var/www/documents/vi versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql @@ -281,11 +289,13 @@ function run() mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 r=$? if [[ ${r} -ne 0 ]]; then + updateHtdocs initializeDatabase else INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` echo "Last installed Version is : ${INSTALLED_VERSION}" if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs migrateDatabase else echo "Schema update is not required ... Enjoy !!" diff --git a/images/15.0.3/fpm/Dockerfile b/images/15.0.3/fpm/Dockerfile new file mode 100644 index 0000000..466dd7e --- /dev/null +++ b/images/15.0.3/fpm/Dockerfile @@ -0,0 +1,94 @@ +ARG ARCH= + +# Use an image like PHP_BASE_IMAGE=x.y-apache-buster +FROM ${ARCH}php:7.4-fpm + +LABEL maintainer="Garcia MICHEL " + +ENV DOLI_VERSION 15.0.3 +ENV DOLI_INSTALL_AUTO 1 +ENV DOLI_PROD 1 + +ENV DOLI_DB_TYPE mysqli +ENV DOLI_DB_HOST mysql +ENV DOLI_DB_HOST_PORT 3306 +ENV DOLI_DB_NAME dolidb + +ENV DOLI_URL_ROOT 'http://localhost' +ENV DOLI_NOCSRFCHECK 0 + +ENV DOLI_AUTH dolibarr +ENV DOLI_LDAP_HOST 127.0.0.1 +ENV DOLI_LDAP_PORT 389 +ENV DOLI_LDAP_VERSION 3 +ENV DOLI_LDAP_SERVER_TYPE openldap +ENV DOLI_LDAP_LOGIN_ATTRIBUTE uid +ENV DOLI_LDAP_DN 'ou=users,dc=my-domain,dc=com' +ENV DOLI_LDAP_FILTER '' +ENV DOLI_LDAP_BIND_DN '' +ENV DOLI_LDAP_BIND_PASS '' +ENV DOLI_LDAP_DEBUG false + +ENV DOLI_CRON 0 + +ENV WWW_USER_ID 33 +ENV WWW_GROUP_ID 33 + +ENV PHP_INI_DATE_TIMEZONE 'UTC' +ENV PHP_INI_MEMORY_LIMIT 256M +ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M +ENV PHP_INI_POST_MAX_SIZE 8M +ENV PHP_INI_ALLOW_URL_FOPEN 0 + + + +RUN apt-get update -y \ + && apt-get dist-upgrade -y \ + && apt-get install -y --no-install-recommends \ + libc-client-dev \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libkrb5-dev \ + libldap2-dev \ + libpng-dev \ + libpq-dev \ + libxml2-dev \ + libzip-dev \ + default-mysql-client \ + postgresql-client \ + cron \ + rsync \ + && apt-get autoremove -y \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ + && docker-php-ext-configure pgsql -with-pgsql \ + && docker-php-ext-install pdo_pgsql pgsql \ + && docker-php-ext-configure ldap --with-libdir=lib/$(gcc -dumpmachine)/ \ + && docker-php-ext-install -j$(nproc) ldap \ + && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ + && docker-php-ext-install imap \ + && mv ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini \ + && rm -rf /var/lib/apt/lists/* + +# Get Dolibarr +RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ + tar -C /tmp -xz && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ + ln -s /var/www/html /var/www/htdocs && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ + rm -rf /tmp/* && \ + mkdir -p /var/www/documents && \ + mkdir -p /var/www/html/custom && \ + chown -R www-data:www-data /var/www + +EXPOSE 9000 +VOLUME /var/www/documents +VOLUME /var/www/html +VOLUME /var/www/html/custom + +COPY docker-init.php /var/www/scripts/ +COPY docker-run.sh /usr/local/bin/ +ENTRYPOINT ["docker-run.sh"] + +CMD ["php-fpm"] diff --git a/images/16.0.5-php8.1/docker-init.php b/images/15.0.3/fpm/docker-init.php similarity index 100% rename from images/16.0.5-php8.1/docker-init.php rename to images/15.0.3/fpm/docker-init.php diff --git a/images/15.0.3-php7.4/docker-run.sh b/images/15.0.3/fpm/docker-run.sh similarity index 97% rename from images/15.0.3-php7.4/docker-run.sh rename to images/15.0.3/fpm/docker-run.sh index c2292cc..fc9ed33 100755 --- a/images/15.0.3-php7.4/docker-run.sh +++ b/images/15.0.3/fpm/docker-run.sh @@ -54,6 +54,7 @@ EOF if [[ ! -f /var/www/html/conf/conf.php ]]; then echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf cat > /var/www/html/conf/conf.php << EOF /var/www/documents/vi + > /var/www/documents/vi versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql @@ -281,11 +289,13 @@ function run() mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 r=$? if [[ ${r} -ne 0 ]]; then + updateHtdocs initializeDatabase else INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` echo "Last installed Version is : ${INSTALLED_VERSION}" if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs migrateDatabase else echo "Schema update is not required ... Enjoy !!" diff --git a/images/16.0.5-php8.1/Dockerfile b/images/16.0.5/apache-buster/Dockerfile similarity index 88% rename from images/16.0.5-php8.1/Dockerfile rename to images/16.0.5/apache-buster/Dockerfile index f354c82..7252223 100644 --- a/images/16.0.5-php8.1/Dockerfile +++ b/images/16.0.5/apache-buster/Dockerfile @@ -40,11 +40,7 @@ ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M ENV PHP_INI_POST_MAX_SIZE 8M ENV PHP_INI_ALLOW_URL_FOPEN 0 -RUN sed -i \ - -e 's/^\(ServerSignature On\)$/#\1/g' \ - -e 's/^#\(ServerSignature Off\)$/\1/g' \ - -e 's/^\(ServerTokens\) OS$/\1 Prod/g' \ - /etc/apache2/conf-available/security.conf +RUN sed -i -e 's/^\(ServerSignature On\)$/#\1/g' -e 's/^#\(ServerSignature Off\)$/\1/g' -e 's/^\(ServerTokens\) OS$/\1 Prod/g' /etc/apache2/conf-available/security.conf RUN apt-get update -y \ && apt-get dist-upgrade -y \ @@ -61,6 +57,7 @@ RUN apt-get update -y \ default-mysql-client \ postgresql-client \ cron \ + rsync \ && apt-get autoremove -y \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ @@ -76,7 +73,8 @@ RUN apt-get update -y \ # Get Dolibarr RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ tar -C /tmp -xz && \ - cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /var/www/html/ && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ ln -s /var/www/html /var/www/htdocs && \ cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ rm -rf /tmp/* && \ @@ -86,6 +84,7 @@ RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar. EXPOSE 80 VOLUME /var/www/documents +VOLUME /var/www/html VOLUME /var/www/html/custom COPY docker-init.php /var/www/scripts/ diff --git a/images/17.0.4-php8.1/docker-init.php b/images/16.0.5/apache-buster/docker-init.php similarity index 100% rename from images/17.0.4-php8.1/docker-init.php rename to images/16.0.5/apache-buster/docker-init.php diff --git a/images/18.0.5-php8.1/docker-run.sh b/images/16.0.5/apache-buster/docker-run.sh similarity index 97% rename from images/18.0.5-php8.1/docker-run.sh rename to images/16.0.5/apache-buster/docker-run.sh index c2292cc..fc9ed33 100755 --- a/images/18.0.5-php8.1/docker-run.sh +++ b/images/16.0.5/apache-buster/docker-run.sh @@ -54,6 +54,7 @@ EOF if [[ ! -f /var/www/html/conf/conf.php ]]; then echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf cat > /var/www/html/conf/conf.php << EOF /var/www/documents/vi + > /var/www/documents/vi versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql @@ -281,11 +289,13 @@ function run() mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 r=$? if [[ ${r} -ne 0 ]]; then + updateHtdocs initializeDatabase else INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` echo "Last installed Version is : ${INSTALLED_VERSION}" if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs migrateDatabase else echo "Schema update is not required ... Enjoy !!" diff --git a/images/16.0.5/fpm/Dockerfile b/images/16.0.5/fpm/Dockerfile new file mode 100644 index 0000000..1502d6b --- /dev/null +++ b/images/16.0.5/fpm/Dockerfile @@ -0,0 +1,94 @@ +ARG ARCH= + +# Use an image like PHP_BASE_IMAGE=x.y-apache-buster +FROM ${ARCH}php:8.1-fpm + +LABEL maintainer="Garcia MICHEL " + +ENV DOLI_VERSION 16.0.5 +ENV DOLI_INSTALL_AUTO 1 +ENV DOLI_PROD 1 + +ENV DOLI_DB_TYPE mysqli +ENV DOLI_DB_HOST mysql +ENV DOLI_DB_HOST_PORT 3306 +ENV DOLI_DB_NAME dolidb + +ENV DOLI_URL_ROOT 'http://localhost' +ENV DOLI_NOCSRFCHECK 0 + +ENV DOLI_AUTH dolibarr +ENV DOLI_LDAP_HOST 127.0.0.1 +ENV DOLI_LDAP_PORT 389 +ENV DOLI_LDAP_VERSION 3 +ENV DOLI_LDAP_SERVER_TYPE openldap +ENV DOLI_LDAP_LOGIN_ATTRIBUTE uid +ENV DOLI_LDAP_DN 'ou=users,dc=my-domain,dc=com' +ENV DOLI_LDAP_FILTER '' +ENV DOLI_LDAP_BIND_DN '' +ENV DOLI_LDAP_BIND_PASS '' +ENV DOLI_LDAP_DEBUG false + +ENV DOLI_CRON 0 + +ENV WWW_USER_ID 33 +ENV WWW_GROUP_ID 33 + +ENV PHP_INI_DATE_TIMEZONE 'UTC' +ENV PHP_INI_MEMORY_LIMIT 256M +ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M +ENV PHP_INI_POST_MAX_SIZE 8M +ENV PHP_INI_ALLOW_URL_FOPEN 0 + + + +RUN apt-get update -y \ + && apt-get dist-upgrade -y \ + && apt-get install -y --no-install-recommends \ + libc-client-dev \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libkrb5-dev \ + libldap2-dev \ + libpng-dev \ + libpq-dev \ + libxml2-dev \ + libzip-dev \ + default-mysql-client \ + postgresql-client \ + cron \ + rsync \ + && apt-get autoremove -y \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ + && docker-php-ext-configure pgsql -with-pgsql \ + && docker-php-ext-install pdo_pgsql pgsql \ + && docker-php-ext-configure ldap --with-libdir=lib/$(gcc -dumpmachine)/ \ + && docker-php-ext-install -j$(nproc) ldap \ + && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ + && docker-php-ext-install imap \ + && mv ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini \ + && rm -rf /var/lib/apt/lists/* + +# Get Dolibarr +RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ + tar -C /tmp -xz && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ + ln -s /var/www/html /var/www/htdocs && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ + rm -rf /tmp/* && \ + mkdir -p /var/www/documents && \ + mkdir -p /var/www/html/custom && \ + chown -R www-data:www-data /var/www + +EXPOSE 9000 +VOLUME /var/www/documents +VOLUME /var/www/html +VOLUME /var/www/html/custom + +COPY docker-init.php /var/www/scripts/ +COPY docker-run.sh /usr/local/bin/ +ENTRYPOINT ["docker-run.sh"] + +CMD ["php-fpm"] diff --git a/images/18.0.5-php8.1/docker-init.php b/images/16.0.5/fpm/docker-init.php similarity index 100% rename from images/18.0.5-php8.1/docker-init.php rename to images/16.0.5/fpm/docker-init.php diff --git a/images/16.0.5-php8.1/docker-run.sh b/images/16.0.5/fpm/docker-run.sh similarity index 97% rename from images/16.0.5-php8.1/docker-run.sh rename to images/16.0.5/fpm/docker-run.sh index c2292cc..fc9ed33 100755 --- a/images/16.0.5-php8.1/docker-run.sh +++ b/images/16.0.5/fpm/docker-run.sh @@ -54,6 +54,7 @@ EOF if [[ ! -f /var/www/html/conf/conf.php ]]; then echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf cat > /var/www/html/conf/conf.php << EOF /var/www/documents/vi + > /var/www/documents/vi versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql @@ -281,11 +289,13 @@ function run() mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 r=$? if [[ ${r} -ne 0 ]]; then + updateHtdocs initializeDatabase else INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` echo "Last installed Version is : ${INSTALLED_VERSION}" if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs migrateDatabase else echo "Schema update is not required ... Enjoy !!" diff --git a/images/17.0.4-php8.1/Dockerfile b/images/17.0.4/apache-buster/Dockerfile similarity index 88% rename from images/17.0.4-php8.1/Dockerfile rename to images/17.0.4/apache-buster/Dockerfile index 456f5db..cf4dcc4 100644 --- a/images/17.0.4-php8.1/Dockerfile +++ b/images/17.0.4/apache-buster/Dockerfile @@ -40,11 +40,7 @@ ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M ENV PHP_INI_POST_MAX_SIZE 8M ENV PHP_INI_ALLOW_URL_FOPEN 0 -RUN sed -i \ - -e 's/^\(ServerSignature On\)$/#\1/g' \ - -e 's/^#\(ServerSignature Off\)$/\1/g' \ - -e 's/^\(ServerTokens\) OS$/\1 Prod/g' \ - /etc/apache2/conf-available/security.conf +RUN sed -i -e 's/^\(ServerSignature On\)$/#\1/g' -e 's/^#\(ServerSignature Off\)$/\1/g' -e 's/^\(ServerTokens\) OS$/\1 Prod/g' /etc/apache2/conf-available/security.conf RUN apt-get update -y \ && apt-get dist-upgrade -y \ @@ -61,6 +57,7 @@ RUN apt-get update -y \ default-mysql-client \ postgresql-client \ cron \ + rsync \ && apt-get autoremove -y \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ @@ -76,7 +73,8 @@ RUN apt-get update -y \ # Get Dolibarr RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ tar -C /tmp -xz && \ - cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /var/www/html/ && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ ln -s /var/www/html /var/www/htdocs && \ cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ rm -rf /tmp/* && \ @@ -86,6 +84,7 @@ RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar. EXPOSE 80 VOLUME /var/www/documents +VOLUME /var/www/html VOLUME /var/www/html/custom COPY docker-init.php /var/www/scripts/ diff --git a/images/19.0.3-php8.2/docker-init.php b/images/17.0.4/apache-buster/docker-init.php similarity index 100% rename from images/19.0.3-php8.2/docker-init.php rename to images/17.0.4/apache-buster/docker-init.php diff --git a/images/17.0.4/apache-buster/docker-run.sh b/images/17.0.4/apache-buster/docker-run.sh new file mode 100755 index 0000000..fc9ed33 --- /dev/null +++ b/images/17.0.4/apache-buster/docker-run.sh @@ -0,0 +1,340 @@ +#!/bin/bash +# This script is run when the Docker web container is started. +# It is embedded into the Docker image of dolibarr/dolibarr. +# + +# usage: get_env_value VAR [DEFAULT] +# ie: get_env_value 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +function get_env_value() { + local varName="${1}" + local fileVarName="${varName}_FILE" + local defaultValue="${2:-}" + + if [ "${!varName:-}" ] && [ "${!fileVarName:-}" ]; then + echo >&2 "error: both ${varName} and ${fileVarName} are set (but are exclusive)" + exit 1 + fi + + local value="${defaultValue}" + if [ "${!varName:-}" ]; then + value="${!varName}" + elif [ "${!fileVarName:-}" ]; then + value="$(< "${!fileVarName}")" + fi + + echo ${value} + exit 0 +} + +function initDolibarr() +{ + local CURRENT_UID=$(id -u www-data) + local CURRENT_GID=$(id -g www-data) + usermod -u ${WWW_USER_ID} www-data + groupmod -g ${WWW_GROUP_ID} www-data + + if [[ ! -d /var/www/documents ]]; then + echo "[INIT] => create volume directory /var/www/documents ..." + mkdir -p /var/www/documents + fi + + echo "[INIT] => update PHP Config ..." + cat > ${PHP_INI_DIR}/conf.d/dolibarr-php.ini << EOF +date.timezone = ${PHP_INI_DATE_TIMEZONE} +sendmail_path = /usr/sbin/sendmail -t -i +memory_limit = ${PHP_INI_MEMORY_LIMIT} +upload_max_filesize = ${PHP_INI_UPLOAD_MAX_FILESIZE} +post_max_size = ${PHP_INI_POST_MAX_SIZE} +allow_url_fopen = ${PHP_INI_ALLOW_URL_FOPEN} +session.use_strict_mode = 1 +disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,passthru,shell_exec,system,proc_open,popen +EOF + +if [[ ! -f /var/www/html/conf/conf.php ]]; then + echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf + cat > /var/www/html/conf/conf.php << EOF + update Dolibarr Config with instance unique id ..." + echo "\$dolibarr_main_instance_unique_id='${DOLI_INSTANCE_UNIQUE_ID}';" >> /var/www/html/conf/conf.php + fi + if [[ ${DOLI_AUTH} =~ .*ldap.* ]]; then + echo "[INIT] => update Dolibarr Config with LDAP entries ..." + cat >> /var/www/html/conf/conf.php << EOF +\$dolibarr_main_auth_ldap_host='${DOLI_LDAP_HOST}'; +\$dolibarr_main_auth_ldap_port='${DOLI_LDAP_PORT}'; +\$dolibarr_main_auth_ldap_version='${DOLI_LDAP_VERSION}'; +\$dolibarr_main_auth_ldap_servertype='${DOLI_LDAP_SERVER_TYPE}'; +\$dolibarr_main_auth_ldap_login_attribute='${DOLI_LDAP_LOGIN_ATTRIBUTE}'; +\$dolibarr_main_auth_ldap_dn='${DOLI_LDAP_DN}'; +\$dolibarr_main_auth_ldap_filter='${DOLI_LDAP_FILTER}'; +\$dolibarr_main_auth_ldap_admin_login='${DOLI_LDAP_BIND_DN}'; +\$dolibarr_main_auth_ldap_admin_pass='${DOLI_LDAP_BIND_PASS}'; +\$dolibarr_main_auth_ldap_debug='${DOLI_LDAP_DEBUG}'; +EOF + fi + fi + + echo "[INIT] => update ownership for file in Dolibarr Config ..." + chown www-data:www-data /var/www/html/conf/conf.php + if [[ ${DOLI_DB_TYPE} == "pgsql" && ! -f /var/www/documents/install.lock ]]; then + chmod 600 /var/www/html/conf/conf.php + else + chmod 400 /var/www/html/conf/conf.php + fi + + if [[ ${CURRENT_UID} -ne ${WWW_USER_ID} || ${CURRENT_GID} -ne ${WWW_GROUP_ID} ]]; then + # Refresh file ownership cause it has changed + echo "[INIT] => As UID / GID have changed from default, update ownership for files in /var/ww ..." + chown -R www-data:www-data /var/www + else + # Reducing load on init : change ownership only for volumes declared in docker + echo "[INIT] => update ownership for files in /var/www/documents ..." + chown -R www-data:www-data /var/www/documents + fi +} + +function waitForDataBase() +{ + r=1 + + while [[ ${r} -ne 0 ]]; do + mysql -u ${DOLI_DB_USER} --protocol tcp -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} --connect-timeout=5 -e "status" > /dev/null 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + echo "Waiting that SQL database is up ..." + sleep 2 + fi + done +} + +function lockInstallation() +{ + touch /var/www/documents/install.lock + chown www-data:www-data /var/www/documents/install.lock + chmod 400 /var/www/documents/install.lock +} + +function runScripts() +{ + if [ -d /var/www/scripts/$1 ] ; then + for file in /var/www/scripts/$1/*; do + [ ! -f $file ] && continue + + # If extension is not in PHP SQL SH, we loop + isExec=$(echo "PHP SQL SH" | grep -wio ${file##*.}) + [ -z "$isExec" ] && continue + + echo "Importing custom ${isExec} from `basename ${file}` ..." + if [ "$isExec" == "SQL" ] ; then + sed -i 's/--.*//g;' ${file} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${file} > /dev/null 2>&1 + elif [ "$isExec" == "PHP" ] ; then + php $file + elif [ "$isExec" == "SH" ] ; then + /bin/bash $file + fi + done + fi +} + +# Function called to update the htdocs folde with the new code +function updateHtdocs() +{ + echo "Updating htdocs folder..." + rsync -rlD --chown www-data:www-data --delete --exclude custom --exclude conf/conf.php /usr/src/dolibarr/ /var/www/html/ +} + +# Function called to initialize the database (creation of tables and init data) +function initializeDatabase() +{ + for fileSQL in /var/www/html/install/mysql/tables/*.sql; do + if [[ ${fileSQL} != *.key.sql ]]; then + echo "Importing table from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} # remove all comment + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} + fi + done + + for fileSQL in /var/www/html/install/mysql/tables/*.key.sql; do + echo "Importing table key from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/functions/*.sql; do + echo "Importing `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/data/*.sql; do + if [[ $fileSQL =~ llx_accounting_account_ ]]; then + echo "Do not import data from `basename ${fileSQL}` ..." + continue + fi + echo "Importing data from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + echo "Create SuperAdmin account ..." + pass_crypted=`echo -n ${DOLI_ADMIN_PASSWORD} | md5sum | awk '{print $1}'` + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_user (entity, login, pass_crypted, lastname, admin, statut) VALUES (0, '${DOLI_ADMIN_LOGIN}', '${pass_crypted}', 'SuperAdmin', 1, 1);" > /dev/null 2>&1 + + echo "Set some default const ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_NOT_INSTALLED';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_LANG_DEFAULT';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) values('MAIN_VERSION_LAST_INSTALL', '${DOLI_VERSION}', 'chaine', 0, 'Dolibarr version when install', 0);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('MAIN_LANG_DEFAULT', 'auto', 'chaine', 0, 'Default language', 1);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('SYSTEMTOOLS_MYSQLDUMP', '/usr/bin/mysqldump', 'chaine', 0, '', 0);" > /dev/null 2>&1 + + if [[ ${DOLI_INIT_DEMO} -eq 1 ]]; then + mkdir -p /var/www/dev/initdemo/ + > /var/www/documents/vi + versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` + echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." + curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql + for fileSQL in /var/www/dev/initdemo/*.sql; do + echo "Found demo data file, so we first drop table llx_accounting_system ..." + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_account\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_account" >> /var/www/documents/initdemo.log 2>&1 + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_system\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_system" >> /var/www/documents/initdemo.log 2>&1 + echo "Then we load demo data ${fileSQL} ..." + #sed -i 's/--.*//g;' ${fileSQL} + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1 + done + else + echo "DOLI_NIT_DEMO is off. No demo data load to do." + fi + + echo "Enable user module ..." + php /var/www/scripts/docker-init.php + + # Run init scripts + runScripts "docker-init.d" + + # Update ownership after initialisation of modules + chown -R www-data:www-data /var/www/documents +} + +function migrateDatabase() +{ + TARGET_VERSION="$(echo ${DOLI_VERSION} | cut -d. -f1).$(echo ${DOLI_VERSION} | cut -d. -f2).0" + echo "Schema update is required ..." + echo "Dumping Database into /var/www/documents/dump.sql ..." + + mysqldump -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} > /var/www/documents/dump.sql + r=${?} + if [[ ${r} -ne 0 ]]; then + echo "Dump failed ... Aborting migration ..." + return ${r} + fi + echo "Dump done ... Starting Migration ..." + + echo "" > /var/www/documents/migration_error.html + pushd /var/www/htdocs/install > /dev/null + php upgrade.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php upgrade2.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php step5.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 + r=$? + popd > /dev/null + + if [[ ${r} -ne 0 ]]; then + echo "Migration failed ... Restoring DB ... check file /var/www/documents/migration_error.html for more info on error ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < /var/www/documents/dump.sql + echo "DB Restored ..." + return ${r} + else + echo "Migration successful ... Enjoy !!" + fi + + return 0 +} + +function run() +{ + initDolibarr + echo "Current Version is : ${DOLI_VERSION}" + + # If install of mysql database (and not install of cron) is requested + if [[ ${DOLI_INSTALL_AUTO} -eq 1 && ${DOLI_CRON} -ne 1 && ${DOLI_DB_TYPE} != "pgsql" ]]; then + echo "DOLI_INSTALL_AUTO is on, so we check to initialize or upgrade mariadb database" + + # If install.lock does not exists, we launch the initializeDataze + if [[ ! -f /var/www/documents/install.lock ]]; then + waitForDataBase + + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + updateHtdocs + initializeDatabase + else + INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` + echo "Last installed Version is : ${INSTALLED_VERSION}" + if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs + migrateDatabase + else + echo "Schema update is not required ... Enjoy !!" + fi + fi + + if [[ ${DOLI_VERSION} != "develop" ]]; then + lockInstallation + fi + else + echo "File /var/www/documents/install.lock exists so we cancel database init" + fi + fi + + # Run scripts before starting + runScripts "before-starting.d" +} + +DOLI_DB_USER=$(get_env_value 'DOLI_DB_USER' 'doli') +DOLI_DB_PASSWORD=$(get_env_value 'DOLI_DB_PASSWORD' 'doli_pass') +DOLI_ADMIN_LOGIN=$(get_env_value 'DOLI_ADMIN_LOGIN' 'admin') +DOLI_ADMIN_PASSWORD=$(get_env_value 'DOLI_ADMIN_PASSWORD' 'admin') +DOLI_CRON_KEY=$(get_env_value 'DOLI_CRON_KEY' '') +DOLI_CRON_USER=$(get_env_value 'DOLI_CRON_USER' '') +DOLI_INSTANCE_UNIQUE_ID=$(get_env_value 'DOLI_INSTANCE_UNIQUE_ID' '') + +run + +set -e + +if [[ ${DOLI_CRON} -eq 1 ]]; then + echo "PATH=\$PATH:/usr/local/bin" > /etc/cron.d/dolibarr + echo "*/5 * * * * root /bin/su www-data -s /bin/sh -c '/var/www/scripts/cron/cron_run_jobs.php ${DOLI_CRON_KEY} ${DOLI_CRON_USER}' > /proc/1/fd/1 2> /proc/1/fd/2" >> /etc/cron.d/dolibarr + cron -f + exit 0 +fi + +if [ "${1#-}" != "$1" ]; then + set -- apache2-foreground "$@" +fi + +exec "$@" diff --git a/images/17.0.4/fpm/Dockerfile b/images/17.0.4/fpm/Dockerfile new file mode 100644 index 0000000..5c6b245 --- /dev/null +++ b/images/17.0.4/fpm/Dockerfile @@ -0,0 +1,94 @@ +ARG ARCH= + +# Use an image like PHP_BASE_IMAGE=x.y-apache-buster +FROM ${ARCH}php:8.1-fpm + +LABEL maintainer="Garcia MICHEL " + +ENV DOLI_VERSION 17.0.4 +ENV DOLI_INSTALL_AUTO 1 +ENV DOLI_PROD 1 + +ENV DOLI_DB_TYPE mysqli +ENV DOLI_DB_HOST mysql +ENV DOLI_DB_HOST_PORT 3306 +ENV DOLI_DB_NAME dolidb + +ENV DOLI_URL_ROOT 'http://localhost' +ENV DOLI_NOCSRFCHECK 0 + +ENV DOLI_AUTH dolibarr +ENV DOLI_LDAP_HOST 127.0.0.1 +ENV DOLI_LDAP_PORT 389 +ENV DOLI_LDAP_VERSION 3 +ENV DOLI_LDAP_SERVER_TYPE openldap +ENV DOLI_LDAP_LOGIN_ATTRIBUTE uid +ENV DOLI_LDAP_DN 'ou=users,dc=my-domain,dc=com' +ENV DOLI_LDAP_FILTER '' +ENV DOLI_LDAP_BIND_DN '' +ENV DOLI_LDAP_BIND_PASS '' +ENV DOLI_LDAP_DEBUG false + +ENV DOLI_CRON 0 + +ENV WWW_USER_ID 33 +ENV WWW_GROUP_ID 33 + +ENV PHP_INI_DATE_TIMEZONE 'UTC' +ENV PHP_INI_MEMORY_LIMIT 256M +ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M +ENV PHP_INI_POST_MAX_SIZE 8M +ENV PHP_INI_ALLOW_URL_FOPEN 0 + + + +RUN apt-get update -y \ + && apt-get dist-upgrade -y \ + && apt-get install -y --no-install-recommends \ + libc-client-dev \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libkrb5-dev \ + libldap2-dev \ + libpng-dev \ + libpq-dev \ + libxml2-dev \ + libzip-dev \ + default-mysql-client \ + postgresql-client \ + cron \ + rsync \ + && apt-get autoremove -y \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ + && docker-php-ext-configure pgsql -with-pgsql \ + && docker-php-ext-install pdo_pgsql pgsql \ + && docker-php-ext-configure ldap --with-libdir=lib/$(gcc -dumpmachine)/ \ + && docker-php-ext-install -j$(nproc) ldap \ + && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ + && docker-php-ext-install imap \ + && mv ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini \ + && rm -rf /var/lib/apt/lists/* + +# Get Dolibarr +RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ + tar -C /tmp -xz && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ + ln -s /var/www/html /var/www/htdocs && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ + rm -rf /tmp/* && \ + mkdir -p /var/www/documents && \ + mkdir -p /var/www/html/custom && \ + chown -R www-data:www-data /var/www + +EXPOSE 9000 +VOLUME /var/www/documents +VOLUME /var/www/html +VOLUME /var/www/html/custom + +COPY docker-init.php /var/www/scripts/ +COPY docker-run.sh /usr/local/bin/ +ENTRYPOINT ["docker-run.sh"] + +CMD ["php-fpm"] diff --git a/images/develop/docker-init.php b/images/17.0.4/fpm/docker-init.php similarity index 100% rename from images/develop/docker-init.php rename to images/17.0.4/fpm/docker-init.php diff --git a/images/17.0.4/fpm/docker-run.sh b/images/17.0.4/fpm/docker-run.sh new file mode 100755 index 0000000..fc9ed33 --- /dev/null +++ b/images/17.0.4/fpm/docker-run.sh @@ -0,0 +1,340 @@ +#!/bin/bash +# This script is run when the Docker web container is started. +# It is embedded into the Docker image of dolibarr/dolibarr. +# + +# usage: get_env_value VAR [DEFAULT] +# ie: get_env_value 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +function get_env_value() { + local varName="${1}" + local fileVarName="${varName}_FILE" + local defaultValue="${2:-}" + + if [ "${!varName:-}" ] && [ "${!fileVarName:-}" ]; then + echo >&2 "error: both ${varName} and ${fileVarName} are set (but are exclusive)" + exit 1 + fi + + local value="${defaultValue}" + if [ "${!varName:-}" ]; then + value="${!varName}" + elif [ "${!fileVarName:-}" ]; then + value="$(< "${!fileVarName}")" + fi + + echo ${value} + exit 0 +} + +function initDolibarr() +{ + local CURRENT_UID=$(id -u www-data) + local CURRENT_GID=$(id -g www-data) + usermod -u ${WWW_USER_ID} www-data + groupmod -g ${WWW_GROUP_ID} www-data + + if [[ ! -d /var/www/documents ]]; then + echo "[INIT] => create volume directory /var/www/documents ..." + mkdir -p /var/www/documents + fi + + echo "[INIT] => update PHP Config ..." + cat > ${PHP_INI_DIR}/conf.d/dolibarr-php.ini << EOF +date.timezone = ${PHP_INI_DATE_TIMEZONE} +sendmail_path = /usr/sbin/sendmail -t -i +memory_limit = ${PHP_INI_MEMORY_LIMIT} +upload_max_filesize = ${PHP_INI_UPLOAD_MAX_FILESIZE} +post_max_size = ${PHP_INI_POST_MAX_SIZE} +allow_url_fopen = ${PHP_INI_ALLOW_URL_FOPEN} +session.use_strict_mode = 1 +disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,passthru,shell_exec,system,proc_open,popen +EOF + +if [[ ! -f /var/www/html/conf/conf.php ]]; then + echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf + cat > /var/www/html/conf/conf.php << EOF + update Dolibarr Config with instance unique id ..." + echo "\$dolibarr_main_instance_unique_id='${DOLI_INSTANCE_UNIQUE_ID}';" >> /var/www/html/conf/conf.php + fi + if [[ ${DOLI_AUTH} =~ .*ldap.* ]]; then + echo "[INIT] => update Dolibarr Config with LDAP entries ..." + cat >> /var/www/html/conf/conf.php << EOF +\$dolibarr_main_auth_ldap_host='${DOLI_LDAP_HOST}'; +\$dolibarr_main_auth_ldap_port='${DOLI_LDAP_PORT}'; +\$dolibarr_main_auth_ldap_version='${DOLI_LDAP_VERSION}'; +\$dolibarr_main_auth_ldap_servertype='${DOLI_LDAP_SERVER_TYPE}'; +\$dolibarr_main_auth_ldap_login_attribute='${DOLI_LDAP_LOGIN_ATTRIBUTE}'; +\$dolibarr_main_auth_ldap_dn='${DOLI_LDAP_DN}'; +\$dolibarr_main_auth_ldap_filter='${DOLI_LDAP_FILTER}'; +\$dolibarr_main_auth_ldap_admin_login='${DOLI_LDAP_BIND_DN}'; +\$dolibarr_main_auth_ldap_admin_pass='${DOLI_LDAP_BIND_PASS}'; +\$dolibarr_main_auth_ldap_debug='${DOLI_LDAP_DEBUG}'; +EOF + fi + fi + + echo "[INIT] => update ownership for file in Dolibarr Config ..." + chown www-data:www-data /var/www/html/conf/conf.php + if [[ ${DOLI_DB_TYPE} == "pgsql" && ! -f /var/www/documents/install.lock ]]; then + chmod 600 /var/www/html/conf/conf.php + else + chmod 400 /var/www/html/conf/conf.php + fi + + if [[ ${CURRENT_UID} -ne ${WWW_USER_ID} || ${CURRENT_GID} -ne ${WWW_GROUP_ID} ]]; then + # Refresh file ownership cause it has changed + echo "[INIT] => As UID / GID have changed from default, update ownership for files in /var/ww ..." + chown -R www-data:www-data /var/www + else + # Reducing load on init : change ownership only for volumes declared in docker + echo "[INIT] => update ownership for files in /var/www/documents ..." + chown -R www-data:www-data /var/www/documents + fi +} + +function waitForDataBase() +{ + r=1 + + while [[ ${r} -ne 0 ]]; do + mysql -u ${DOLI_DB_USER} --protocol tcp -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} --connect-timeout=5 -e "status" > /dev/null 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + echo "Waiting that SQL database is up ..." + sleep 2 + fi + done +} + +function lockInstallation() +{ + touch /var/www/documents/install.lock + chown www-data:www-data /var/www/documents/install.lock + chmod 400 /var/www/documents/install.lock +} + +function runScripts() +{ + if [ -d /var/www/scripts/$1 ] ; then + for file in /var/www/scripts/$1/*; do + [ ! -f $file ] && continue + + # If extension is not in PHP SQL SH, we loop + isExec=$(echo "PHP SQL SH" | grep -wio ${file##*.}) + [ -z "$isExec" ] && continue + + echo "Importing custom ${isExec} from `basename ${file}` ..." + if [ "$isExec" == "SQL" ] ; then + sed -i 's/--.*//g;' ${file} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${file} > /dev/null 2>&1 + elif [ "$isExec" == "PHP" ] ; then + php $file + elif [ "$isExec" == "SH" ] ; then + /bin/bash $file + fi + done + fi +} + +# Function called to update the htdocs folde with the new code +function updateHtdocs() +{ + echo "Updating htdocs folder..." + rsync -rlD --chown www-data:www-data --delete --exclude custom --exclude conf/conf.php /usr/src/dolibarr/ /var/www/html/ +} + +# Function called to initialize the database (creation of tables and init data) +function initializeDatabase() +{ + for fileSQL in /var/www/html/install/mysql/tables/*.sql; do + if [[ ${fileSQL} != *.key.sql ]]; then + echo "Importing table from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} # remove all comment + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} + fi + done + + for fileSQL in /var/www/html/install/mysql/tables/*.key.sql; do + echo "Importing table key from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/functions/*.sql; do + echo "Importing `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/data/*.sql; do + if [[ $fileSQL =~ llx_accounting_account_ ]]; then + echo "Do not import data from `basename ${fileSQL}` ..." + continue + fi + echo "Importing data from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + echo "Create SuperAdmin account ..." + pass_crypted=`echo -n ${DOLI_ADMIN_PASSWORD} | md5sum | awk '{print $1}'` + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_user (entity, login, pass_crypted, lastname, admin, statut) VALUES (0, '${DOLI_ADMIN_LOGIN}', '${pass_crypted}', 'SuperAdmin', 1, 1);" > /dev/null 2>&1 + + echo "Set some default const ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_NOT_INSTALLED';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_LANG_DEFAULT';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) values('MAIN_VERSION_LAST_INSTALL', '${DOLI_VERSION}', 'chaine', 0, 'Dolibarr version when install', 0);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('MAIN_LANG_DEFAULT', 'auto', 'chaine', 0, 'Default language', 1);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('SYSTEMTOOLS_MYSQLDUMP', '/usr/bin/mysqldump', 'chaine', 0, '', 0);" > /dev/null 2>&1 + + if [[ ${DOLI_INIT_DEMO} -eq 1 ]]; then + mkdir -p /var/www/dev/initdemo/ + > /var/www/documents/vi + versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` + echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." + curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql + for fileSQL in /var/www/dev/initdemo/*.sql; do + echo "Found demo data file, so we first drop table llx_accounting_system ..." + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_account\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_account" >> /var/www/documents/initdemo.log 2>&1 + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_system\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_system" >> /var/www/documents/initdemo.log 2>&1 + echo "Then we load demo data ${fileSQL} ..." + #sed -i 's/--.*//g;' ${fileSQL} + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1 + done + else + echo "DOLI_NIT_DEMO is off. No demo data load to do." + fi + + echo "Enable user module ..." + php /var/www/scripts/docker-init.php + + # Run init scripts + runScripts "docker-init.d" + + # Update ownership after initialisation of modules + chown -R www-data:www-data /var/www/documents +} + +function migrateDatabase() +{ + TARGET_VERSION="$(echo ${DOLI_VERSION} | cut -d. -f1).$(echo ${DOLI_VERSION} | cut -d. -f2).0" + echo "Schema update is required ..." + echo "Dumping Database into /var/www/documents/dump.sql ..." + + mysqldump -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} > /var/www/documents/dump.sql + r=${?} + if [[ ${r} -ne 0 ]]; then + echo "Dump failed ... Aborting migration ..." + return ${r} + fi + echo "Dump done ... Starting Migration ..." + + echo "" > /var/www/documents/migration_error.html + pushd /var/www/htdocs/install > /dev/null + php upgrade.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php upgrade2.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php step5.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 + r=$? + popd > /dev/null + + if [[ ${r} -ne 0 ]]; then + echo "Migration failed ... Restoring DB ... check file /var/www/documents/migration_error.html for more info on error ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < /var/www/documents/dump.sql + echo "DB Restored ..." + return ${r} + else + echo "Migration successful ... Enjoy !!" + fi + + return 0 +} + +function run() +{ + initDolibarr + echo "Current Version is : ${DOLI_VERSION}" + + # If install of mysql database (and not install of cron) is requested + if [[ ${DOLI_INSTALL_AUTO} -eq 1 && ${DOLI_CRON} -ne 1 && ${DOLI_DB_TYPE} != "pgsql" ]]; then + echo "DOLI_INSTALL_AUTO is on, so we check to initialize or upgrade mariadb database" + + # If install.lock does not exists, we launch the initializeDataze + if [[ ! -f /var/www/documents/install.lock ]]; then + waitForDataBase + + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + updateHtdocs + initializeDatabase + else + INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` + echo "Last installed Version is : ${INSTALLED_VERSION}" + if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs + migrateDatabase + else + echo "Schema update is not required ... Enjoy !!" + fi + fi + + if [[ ${DOLI_VERSION} != "develop" ]]; then + lockInstallation + fi + else + echo "File /var/www/documents/install.lock exists so we cancel database init" + fi + fi + + # Run scripts before starting + runScripts "before-starting.d" +} + +DOLI_DB_USER=$(get_env_value 'DOLI_DB_USER' 'doli') +DOLI_DB_PASSWORD=$(get_env_value 'DOLI_DB_PASSWORD' 'doli_pass') +DOLI_ADMIN_LOGIN=$(get_env_value 'DOLI_ADMIN_LOGIN' 'admin') +DOLI_ADMIN_PASSWORD=$(get_env_value 'DOLI_ADMIN_PASSWORD' 'admin') +DOLI_CRON_KEY=$(get_env_value 'DOLI_CRON_KEY' '') +DOLI_CRON_USER=$(get_env_value 'DOLI_CRON_USER' '') +DOLI_INSTANCE_UNIQUE_ID=$(get_env_value 'DOLI_INSTANCE_UNIQUE_ID' '') + +run + +set -e + +if [[ ${DOLI_CRON} -eq 1 ]]; then + echo "PATH=\$PATH:/usr/local/bin" > /etc/cron.d/dolibarr + echo "*/5 * * * * root /bin/su www-data -s /bin/sh -c '/var/www/scripts/cron/cron_run_jobs.php ${DOLI_CRON_KEY} ${DOLI_CRON_USER}' > /proc/1/fd/1 2> /proc/1/fd/2" >> /etc/cron.d/dolibarr + cron -f + exit 0 +fi + +if [ "${1#-}" != "$1" ]; then + set -- apache2-foreground "$@" +fi + +exec "$@" diff --git a/images/18.0.5-php8.1/Dockerfile b/images/18.0.5/apache-buster/Dockerfile similarity index 88% rename from images/18.0.5-php8.1/Dockerfile rename to images/18.0.5/apache-buster/Dockerfile index afaf3b0..64564e9 100644 --- a/images/18.0.5-php8.1/Dockerfile +++ b/images/18.0.5/apache-buster/Dockerfile @@ -40,11 +40,7 @@ ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M ENV PHP_INI_POST_MAX_SIZE 8M ENV PHP_INI_ALLOW_URL_FOPEN 0 -RUN sed -i \ - -e 's/^\(ServerSignature On\)$/#\1/g' \ - -e 's/^#\(ServerSignature Off\)$/\1/g' \ - -e 's/^\(ServerTokens\) OS$/\1 Prod/g' \ - /etc/apache2/conf-available/security.conf +RUN sed -i -e 's/^\(ServerSignature On\)$/#\1/g' -e 's/^#\(ServerSignature Off\)$/\1/g' -e 's/^\(ServerTokens\) OS$/\1 Prod/g' /etc/apache2/conf-available/security.conf RUN apt-get update -y \ && apt-get dist-upgrade -y \ @@ -61,6 +57,7 @@ RUN apt-get update -y \ default-mysql-client \ postgresql-client \ cron \ + rsync \ && apt-get autoremove -y \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ @@ -76,7 +73,8 @@ RUN apt-get update -y \ # Get Dolibarr RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ tar -C /tmp -xz && \ - cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /var/www/html/ && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ ln -s /var/www/html /var/www/htdocs && \ cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ rm -rf /tmp/* && \ @@ -86,6 +84,7 @@ RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar. EXPOSE 80 VOLUME /var/www/documents +VOLUME /var/www/html VOLUME /var/www/html/custom COPY docker-init.php /var/www/scripts/ diff --git a/images/18.0.5/apache-buster/docker-init.php b/images/18.0.5/apache-buster/docker-init.php new file mode 100644 index 0000000..5006905 --- /dev/null +++ b/images/18.0.5/apache-buster/docker-init.php @@ -0,0 +1,49 @@ +#!/usr/bin/env php +fetch(0,$countryCode); + if ($res > 0 ) { + $s = $country->id.':'.$country->code.':'.$country->label; + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_COUNTRY", $s, 'chaine', 0, '', $conf->entity); + printf('Configuring for country : '.$s."\n"); + activateModulesRequiredByCountry($country->code); + } else { + printf('Unable to find country '.$countryCode."\n"); + } +} + +if (!empty(getenv('DOLI_COMPANY_NAME'))) { + $compname = getenv('DOLI_COMPANY_NAME'); + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", $compname, 'chaine', 0, '', $conf->entity); +} + +if (!empty(getenv('DOLI_ENABLE_MODULES'))) { + $mods = explode(',', getenv('DOLI_ENABLE_MODULES')); + foreach ($mods as $mod) { + printf("Activating module ".$mod." ..."); + try { + $res = activateModule('mod' . $mod); + if ($res < 0) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } else { + printf(" OK\n"); + } + } catch (Throwable $t) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } + } +} diff --git a/images/18.0.5/apache-buster/docker-run.sh b/images/18.0.5/apache-buster/docker-run.sh new file mode 100755 index 0000000..fc9ed33 --- /dev/null +++ b/images/18.0.5/apache-buster/docker-run.sh @@ -0,0 +1,340 @@ +#!/bin/bash +# This script is run when the Docker web container is started. +# It is embedded into the Docker image of dolibarr/dolibarr. +# + +# usage: get_env_value VAR [DEFAULT] +# ie: get_env_value 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +function get_env_value() { + local varName="${1}" + local fileVarName="${varName}_FILE" + local defaultValue="${2:-}" + + if [ "${!varName:-}" ] && [ "${!fileVarName:-}" ]; then + echo >&2 "error: both ${varName} and ${fileVarName} are set (but are exclusive)" + exit 1 + fi + + local value="${defaultValue}" + if [ "${!varName:-}" ]; then + value="${!varName}" + elif [ "${!fileVarName:-}" ]; then + value="$(< "${!fileVarName}")" + fi + + echo ${value} + exit 0 +} + +function initDolibarr() +{ + local CURRENT_UID=$(id -u www-data) + local CURRENT_GID=$(id -g www-data) + usermod -u ${WWW_USER_ID} www-data + groupmod -g ${WWW_GROUP_ID} www-data + + if [[ ! -d /var/www/documents ]]; then + echo "[INIT] => create volume directory /var/www/documents ..." + mkdir -p /var/www/documents + fi + + echo "[INIT] => update PHP Config ..." + cat > ${PHP_INI_DIR}/conf.d/dolibarr-php.ini << EOF +date.timezone = ${PHP_INI_DATE_TIMEZONE} +sendmail_path = /usr/sbin/sendmail -t -i +memory_limit = ${PHP_INI_MEMORY_LIMIT} +upload_max_filesize = ${PHP_INI_UPLOAD_MAX_FILESIZE} +post_max_size = ${PHP_INI_POST_MAX_SIZE} +allow_url_fopen = ${PHP_INI_ALLOW_URL_FOPEN} +session.use_strict_mode = 1 +disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,passthru,shell_exec,system,proc_open,popen +EOF + +if [[ ! -f /var/www/html/conf/conf.php ]]; then + echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf + cat > /var/www/html/conf/conf.php << EOF + update Dolibarr Config with instance unique id ..." + echo "\$dolibarr_main_instance_unique_id='${DOLI_INSTANCE_UNIQUE_ID}';" >> /var/www/html/conf/conf.php + fi + if [[ ${DOLI_AUTH} =~ .*ldap.* ]]; then + echo "[INIT] => update Dolibarr Config with LDAP entries ..." + cat >> /var/www/html/conf/conf.php << EOF +\$dolibarr_main_auth_ldap_host='${DOLI_LDAP_HOST}'; +\$dolibarr_main_auth_ldap_port='${DOLI_LDAP_PORT}'; +\$dolibarr_main_auth_ldap_version='${DOLI_LDAP_VERSION}'; +\$dolibarr_main_auth_ldap_servertype='${DOLI_LDAP_SERVER_TYPE}'; +\$dolibarr_main_auth_ldap_login_attribute='${DOLI_LDAP_LOGIN_ATTRIBUTE}'; +\$dolibarr_main_auth_ldap_dn='${DOLI_LDAP_DN}'; +\$dolibarr_main_auth_ldap_filter='${DOLI_LDAP_FILTER}'; +\$dolibarr_main_auth_ldap_admin_login='${DOLI_LDAP_BIND_DN}'; +\$dolibarr_main_auth_ldap_admin_pass='${DOLI_LDAP_BIND_PASS}'; +\$dolibarr_main_auth_ldap_debug='${DOLI_LDAP_DEBUG}'; +EOF + fi + fi + + echo "[INIT] => update ownership for file in Dolibarr Config ..." + chown www-data:www-data /var/www/html/conf/conf.php + if [[ ${DOLI_DB_TYPE} == "pgsql" && ! -f /var/www/documents/install.lock ]]; then + chmod 600 /var/www/html/conf/conf.php + else + chmod 400 /var/www/html/conf/conf.php + fi + + if [[ ${CURRENT_UID} -ne ${WWW_USER_ID} || ${CURRENT_GID} -ne ${WWW_GROUP_ID} ]]; then + # Refresh file ownership cause it has changed + echo "[INIT] => As UID / GID have changed from default, update ownership for files in /var/ww ..." + chown -R www-data:www-data /var/www + else + # Reducing load on init : change ownership only for volumes declared in docker + echo "[INIT] => update ownership for files in /var/www/documents ..." + chown -R www-data:www-data /var/www/documents + fi +} + +function waitForDataBase() +{ + r=1 + + while [[ ${r} -ne 0 ]]; do + mysql -u ${DOLI_DB_USER} --protocol tcp -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} --connect-timeout=5 -e "status" > /dev/null 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + echo "Waiting that SQL database is up ..." + sleep 2 + fi + done +} + +function lockInstallation() +{ + touch /var/www/documents/install.lock + chown www-data:www-data /var/www/documents/install.lock + chmod 400 /var/www/documents/install.lock +} + +function runScripts() +{ + if [ -d /var/www/scripts/$1 ] ; then + for file in /var/www/scripts/$1/*; do + [ ! -f $file ] && continue + + # If extension is not in PHP SQL SH, we loop + isExec=$(echo "PHP SQL SH" | grep -wio ${file##*.}) + [ -z "$isExec" ] && continue + + echo "Importing custom ${isExec} from `basename ${file}` ..." + if [ "$isExec" == "SQL" ] ; then + sed -i 's/--.*//g;' ${file} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${file} > /dev/null 2>&1 + elif [ "$isExec" == "PHP" ] ; then + php $file + elif [ "$isExec" == "SH" ] ; then + /bin/bash $file + fi + done + fi +} + +# Function called to update the htdocs folde with the new code +function updateHtdocs() +{ + echo "Updating htdocs folder..." + rsync -rlD --chown www-data:www-data --delete --exclude custom --exclude conf/conf.php /usr/src/dolibarr/ /var/www/html/ +} + +# Function called to initialize the database (creation of tables and init data) +function initializeDatabase() +{ + for fileSQL in /var/www/html/install/mysql/tables/*.sql; do + if [[ ${fileSQL} != *.key.sql ]]; then + echo "Importing table from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} # remove all comment + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} + fi + done + + for fileSQL in /var/www/html/install/mysql/tables/*.key.sql; do + echo "Importing table key from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/functions/*.sql; do + echo "Importing `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/data/*.sql; do + if [[ $fileSQL =~ llx_accounting_account_ ]]; then + echo "Do not import data from `basename ${fileSQL}` ..." + continue + fi + echo "Importing data from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + echo "Create SuperAdmin account ..." + pass_crypted=`echo -n ${DOLI_ADMIN_PASSWORD} | md5sum | awk '{print $1}'` + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_user (entity, login, pass_crypted, lastname, admin, statut) VALUES (0, '${DOLI_ADMIN_LOGIN}', '${pass_crypted}', 'SuperAdmin', 1, 1);" > /dev/null 2>&1 + + echo "Set some default const ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_NOT_INSTALLED';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_LANG_DEFAULT';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) values('MAIN_VERSION_LAST_INSTALL', '${DOLI_VERSION}', 'chaine', 0, 'Dolibarr version when install', 0);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('MAIN_LANG_DEFAULT', 'auto', 'chaine', 0, 'Default language', 1);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('SYSTEMTOOLS_MYSQLDUMP', '/usr/bin/mysqldump', 'chaine', 0, '', 0);" > /dev/null 2>&1 + + if [[ ${DOLI_INIT_DEMO} -eq 1 ]]; then + mkdir -p /var/www/dev/initdemo/ + > /var/www/documents/vi + versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` + echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." + curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql + for fileSQL in /var/www/dev/initdemo/*.sql; do + echo "Found demo data file, so we first drop table llx_accounting_system ..." + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_account\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_account" >> /var/www/documents/initdemo.log 2>&1 + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_system\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_system" >> /var/www/documents/initdemo.log 2>&1 + echo "Then we load demo data ${fileSQL} ..." + #sed -i 's/--.*//g;' ${fileSQL} + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1 + done + else + echo "DOLI_NIT_DEMO is off. No demo data load to do." + fi + + echo "Enable user module ..." + php /var/www/scripts/docker-init.php + + # Run init scripts + runScripts "docker-init.d" + + # Update ownership after initialisation of modules + chown -R www-data:www-data /var/www/documents +} + +function migrateDatabase() +{ + TARGET_VERSION="$(echo ${DOLI_VERSION} | cut -d. -f1).$(echo ${DOLI_VERSION} | cut -d. -f2).0" + echo "Schema update is required ..." + echo "Dumping Database into /var/www/documents/dump.sql ..." + + mysqldump -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} > /var/www/documents/dump.sql + r=${?} + if [[ ${r} -ne 0 ]]; then + echo "Dump failed ... Aborting migration ..." + return ${r} + fi + echo "Dump done ... Starting Migration ..." + + echo "" > /var/www/documents/migration_error.html + pushd /var/www/htdocs/install > /dev/null + php upgrade.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php upgrade2.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php step5.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 + r=$? + popd > /dev/null + + if [[ ${r} -ne 0 ]]; then + echo "Migration failed ... Restoring DB ... check file /var/www/documents/migration_error.html for more info on error ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < /var/www/documents/dump.sql + echo "DB Restored ..." + return ${r} + else + echo "Migration successful ... Enjoy !!" + fi + + return 0 +} + +function run() +{ + initDolibarr + echo "Current Version is : ${DOLI_VERSION}" + + # If install of mysql database (and not install of cron) is requested + if [[ ${DOLI_INSTALL_AUTO} -eq 1 && ${DOLI_CRON} -ne 1 && ${DOLI_DB_TYPE} != "pgsql" ]]; then + echo "DOLI_INSTALL_AUTO is on, so we check to initialize or upgrade mariadb database" + + # If install.lock does not exists, we launch the initializeDataze + if [[ ! -f /var/www/documents/install.lock ]]; then + waitForDataBase + + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + updateHtdocs + initializeDatabase + else + INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` + echo "Last installed Version is : ${INSTALLED_VERSION}" + if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs + migrateDatabase + else + echo "Schema update is not required ... Enjoy !!" + fi + fi + + if [[ ${DOLI_VERSION} != "develop" ]]; then + lockInstallation + fi + else + echo "File /var/www/documents/install.lock exists so we cancel database init" + fi + fi + + # Run scripts before starting + runScripts "before-starting.d" +} + +DOLI_DB_USER=$(get_env_value 'DOLI_DB_USER' 'doli') +DOLI_DB_PASSWORD=$(get_env_value 'DOLI_DB_PASSWORD' 'doli_pass') +DOLI_ADMIN_LOGIN=$(get_env_value 'DOLI_ADMIN_LOGIN' 'admin') +DOLI_ADMIN_PASSWORD=$(get_env_value 'DOLI_ADMIN_PASSWORD' 'admin') +DOLI_CRON_KEY=$(get_env_value 'DOLI_CRON_KEY' '') +DOLI_CRON_USER=$(get_env_value 'DOLI_CRON_USER' '') +DOLI_INSTANCE_UNIQUE_ID=$(get_env_value 'DOLI_INSTANCE_UNIQUE_ID' '') + +run + +set -e + +if [[ ${DOLI_CRON} -eq 1 ]]; then + echo "PATH=\$PATH:/usr/local/bin" > /etc/cron.d/dolibarr + echo "*/5 * * * * root /bin/su www-data -s /bin/sh -c '/var/www/scripts/cron/cron_run_jobs.php ${DOLI_CRON_KEY} ${DOLI_CRON_USER}' > /proc/1/fd/1 2> /proc/1/fd/2" >> /etc/cron.d/dolibarr + cron -f + exit 0 +fi + +if [ "${1#-}" != "$1" ]; then + set -- apache2-foreground "$@" +fi + +exec "$@" diff --git a/images/18.0.5/fpm/Dockerfile b/images/18.0.5/fpm/Dockerfile new file mode 100644 index 0000000..1c9ac9b --- /dev/null +++ b/images/18.0.5/fpm/Dockerfile @@ -0,0 +1,94 @@ +ARG ARCH= + +# Use an image like PHP_BASE_IMAGE=x.y-apache-buster +FROM ${ARCH}php:8.1-fpm + +LABEL maintainer="Garcia MICHEL " + +ENV DOLI_VERSION 18.0.5 +ENV DOLI_INSTALL_AUTO 1 +ENV DOLI_PROD 1 + +ENV DOLI_DB_TYPE mysqli +ENV DOLI_DB_HOST mysql +ENV DOLI_DB_HOST_PORT 3306 +ENV DOLI_DB_NAME dolidb + +ENV DOLI_URL_ROOT 'http://localhost' +ENV DOLI_NOCSRFCHECK 0 + +ENV DOLI_AUTH dolibarr +ENV DOLI_LDAP_HOST 127.0.0.1 +ENV DOLI_LDAP_PORT 389 +ENV DOLI_LDAP_VERSION 3 +ENV DOLI_LDAP_SERVER_TYPE openldap +ENV DOLI_LDAP_LOGIN_ATTRIBUTE uid +ENV DOLI_LDAP_DN 'ou=users,dc=my-domain,dc=com' +ENV DOLI_LDAP_FILTER '' +ENV DOLI_LDAP_BIND_DN '' +ENV DOLI_LDAP_BIND_PASS '' +ENV DOLI_LDAP_DEBUG false + +ENV DOLI_CRON 0 + +ENV WWW_USER_ID 33 +ENV WWW_GROUP_ID 33 + +ENV PHP_INI_DATE_TIMEZONE 'UTC' +ENV PHP_INI_MEMORY_LIMIT 256M +ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M +ENV PHP_INI_POST_MAX_SIZE 8M +ENV PHP_INI_ALLOW_URL_FOPEN 0 + + + +RUN apt-get update -y \ + && apt-get dist-upgrade -y \ + && apt-get install -y --no-install-recommends \ + libc-client-dev \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libkrb5-dev \ + libldap2-dev \ + libpng-dev \ + libpq-dev \ + libxml2-dev \ + libzip-dev \ + default-mysql-client \ + postgresql-client \ + cron \ + rsync \ + && apt-get autoremove -y \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ + && docker-php-ext-configure pgsql -with-pgsql \ + && docker-php-ext-install pdo_pgsql pgsql \ + && docker-php-ext-configure ldap --with-libdir=lib/$(gcc -dumpmachine)/ \ + && docker-php-ext-install -j$(nproc) ldap \ + && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ + && docker-php-ext-install imap \ + && mv ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini \ + && rm -rf /var/lib/apt/lists/* + +# Get Dolibarr +RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ + tar -C /tmp -xz && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ + ln -s /var/www/html /var/www/htdocs && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ + rm -rf /tmp/* && \ + mkdir -p /var/www/documents && \ + mkdir -p /var/www/html/custom && \ + chown -R www-data:www-data /var/www + +EXPOSE 9000 +VOLUME /var/www/documents +VOLUME /var/www/html +VOLUME /var/www/html/custom + +COPY docker-init.php /var/www/scripts/ +COPY docker-run.sh /usr/local/bin/ +ENTRYPOINT ["docker-run.sh"] + +CMD ["php-fpm"] diff --git a/images/18.0.5/fpm/docker-init.php b/images/18.0.5/fpm/docker-init.php new file mode 100644 index 0000000..5006905 --- /dev/null +++ b/images/18.0.5/fpm/docker-init.php @@ -0,0 +1,49 @@ +#!/usr/bin/env php +fetch(0,$countryCode); + if ($res > 0 ) { + $s = $country->id.':'.$country->code.':'.$country->label; + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_COUNTRY", $s, 'chaine', 0, '', $conf->entity); + printf('Configuring for country : '.$s."\n"); + activateModulesRequiredByCountry($country->code); + } else { + printf('Unable to find country '.$countryCode."\n"); + } +} + +if (!empty(getenv('DOLI_COMPANY_NAME'))) { + $compname = getenv('DOLI_COMPANY_NAME'); + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", $compname, 'chaine', 0, '', $conf->entity); +} + +if (!empty(getenv('DOLI_ENABLE_MODULES'))) { + $mods = explode(',', getenv('DOLI_ENABLE_MODULES')); + foreach ($mods as $mod) { + printf("Activating module ".$mod." ..."); + try { + $res = activateModule('mod' . $mod); + if ($res < 0) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } else { + printf(" OK\n"); + } + } catch (Throwable $t) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } + } +} diff --git a/images/18.0.5/fpm/docker-run.sh b/images/18.0.5/fpm/docker-run.sh new file mode 100755 index 0000000..fc9ed33 --- /dev/null +++ b/images/18.0.5/fpm/docker-run.sh @@ -0,0 +1,340 @@ +#!/bin/bash +# This script is run when the Docker web container is started. +# It is embedded into the Docker image of dolibarr/dolibarr. +# + +# usage: get_env_value VAR [DEFAULT] +# ie: get_env_value 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +function get_env_value() { + local varName="${1}" + local fileVarName="${varName}_FILE" + local defaultValue="${2:-}" + + if [ "${!varName:-}" ] && [ "${!fileVarName:-}" ]; then + echo >&2 "error: both ${varName} and ${fileVarName} are set (but are exclusive)" + exit 1 + fi + + local value="${defaultValue}" + if [ "${!varName:-}" ]; then + value="${!varName}" + elif [ "${!fileVarName:-}" ]; then + value="$(< "${!fileVarName}")" + fi + + echo ${value} + exit 0 +} + +function initDolibarr() +{ + local CURRENT_UID=$(id -u www-data) + local CURRENT_GID=$(id -g www-data) + usermod -u ${WWW_USER_ID} www-data + groupmod -g ${WWW_GROUP_ID} www-data + + if [[ ! -d /var/www/documents ]]; then + echo "[INIT] => create volume directory /var/www/documents ..." + mkdir -p /var/www/documents + fi + + echo "[INIT] => update PHP Config ..." + cat > ${PHP_INI_DIR}/conf.d/dolibarr-php.ini << EOF +date.timezone = ${PHP_INI_DATE_TIMEZONE} +sendmail_path = /usr/sbin/sendmail -t -i +memory_limit = ${PHP_INI_MEMORY_LIMIT} +upload_max_filesize = ${PHP_INI_UPLOAD_MAX_FILESIZE} +post_max_size = ${PHP_INI_POST_MAX_SIZE} +allow_url_fopen = ${PHP_INI_ALLOW_URL_FOPEN} +session.use_strict_mode = 1 +disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,passthru,shell_exec,system,proc_open,popen +EOF + +if [[ ! -f /var/www/html/conf/conf.php ]]; then + echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf + cat > /var/www/html/conf/conf.php << EOF + update Dolibarr Config with instance unique id ..." + echo "\$dolibarr_main_instance_unique_id='${DOLI_INSTANCE_UNIQUE_ID}';" >> /var/www/html/conf/conf.php + fi + if [[ ${DOLI_AUTH} =~ .*ldap.* ]]; then + echo "[INIT] => update Dolibarr Config with LDAP entries ..." + cat >> /var/www/html/conf/conf.php << EOF +\$dolibarr_main_auth_ldap_host='${DOLI_LDAP_HOST}'; +\$dolibarr_main_auth_ldap_port='${DOLI_LDAP_PORT}'; +\$dolibarr_main_auth_ldap_version='${DOLI_LDAP_VERSION}'; +\$dolibarr_main_auth_ldap_servertype='${DOLI_LDAP_SERVER_TYPE}'; +\$dolibarr_main_auth_ldap_login_attribute='${DOLI_LDAP_LOGIN_ATTRIBUTE}'; +\$dolibarr_main_auth_ldap_dn='${DOLI_LDAP_DN}'; +\$dolibarr_main_auth_ldap_filter='${DOLI_LDAP_FILTER}'; +\$dolibarr_main_auth_ldap_admin_login='${DOLI_LDAP_BIND_DN}'; +\$dolibarr_main_auth_ldap_admin_pass='${DOLI_LDAP_BIND_PASS}'; +\$dolibarr_main_auth_ldap_debug='${DOLI_LDAP_DEBUG}'; +EOF + fi + fi + + echo "[INIT] => update ownership for file in Dolibarr Config ..." + chown www-data:www-data /var/www/html/conf/conf.php + if [[ ${DOLI_DB_TYPE} == "pgsql" && ! -f /var/www/documents/install.lock ]]; then + chmod 600 /var/www/html/conf/conf.php + else + chmod 400 /var/www/html/conf/conf.php + fi + + if [[ ${CURRENT_UID} -ne ${WWW_USER_ID} || ${CURRENT_GID} -ne ${WWW_GROUP_ID} ]]; then + # Refresh file ownership cause it has changed + echo "[INIT] => As UID / GID have changed from default, update ownership for files in /var/ww ..." + chown -R www-data:www-data /var/www + else + # Reducing load on init : change ownership only for volumes declared in docker + echo "[INIT] => update ownership for files in /var/www/documents ..." + chown -R www-data:www-data /var/www/documents + fi +} + +function waitForDataBase() +{ + r=1 + + while [[ ${r} -ne 0 ]]; do + mysql -u ${DOLI_DB_USER} --protocol tcp -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} --connect-timeout=5 -e "status" > /dev/null 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + echo "Waiting that SQL database is up ..." + sleep 2 + fi + done +} + +function lockInstallation() +{ + touch /var/www/documents/install.lock + chown www-data:www-data /var/www/documents/install.lock + chmod 400 /var/www/documents/install.lock +} + +function runScripts() +{ + if [ -d /var/www/scripts/$1 ] ; then + for file in /var/www/scripts/$1/*; do + [ ! -f $file ] && continue + + # If extension is not in PHP SQL SH, we loop + isExec=$(echo "PHP SQL SH" | grep -wio ${file##*.}) + [ -z "$isExec" ] && continue + + echo "Importing custom ${isExec} from `basename ${file}` ..." + if [ "$isExec" == "SQL" ] ; then + sed -i 's/--.*//g;' ${file} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${file} > /dev/null 2>&1 + elif [ "$isExec" == "PHP" ] ; then + php $file + elif [ "$isExec" == "SH" ] ; then + /bin/bash $file + fi + done + fi +} + +# Function called to update the htdocs folde with the new code +function updateHtdocs() +{ + echo "Updating htdocs folder..." + rsync -rlD --chown www-data:www-data --delete --exclude custom --exclude conf/conf.php /usr/src/dolibarr/ /var/www/html/ +} + +# Function called to initialize the database (creation of tables and init data) +function initializeDatabase() +{ + for fileSQL in /var/www/html/install/mysql/tables/*.sql; do + if [[ ${fileSQL} != *.key.sql ]]; then + echo "Importing table from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} # remove all comment + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} + fi + done + + for fileSQL in /var/www/html/install/mysql/tables/*.key.sql; do + echo "Importing table key from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/functions/*.sql; do + echo "Importing `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/data/*.sql; do + if [[ $fileSQL =~ llx_accounting_account_ ]]; then + echo "Do not import data from `basename ${fileSQL}` ..." + continue + fi + echo "Importing data from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + echo "Create SuperAdmin account ..." + pass_crypted=`echo -n ${DOLI_ADMIN_PASSWORD} | md5sum | awk '{print $1}'` + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_user (entity, login, pass_crypted, lastname, admin, statut) VALUES (0, '${DOLI_ADMIN_LOGIN}', '${pass_crypted}', 'SuperAdmin', 1, 1);" > /dev/null 2>&1 + + echo "Set some default const ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_NOT_INSTALLED';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_LANG_DEFAULT';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) values('MAIN_VERSION_LAST_INSTALL', '${DOLI_VERSION}', 'chaine', 0, 'Dolibarr version when install', 0);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('MAIN_LANG_DEFAULT', 'auto', 'chaine', 0, 'Default language', 1);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('SYSTEMTOOLS_MYSQLDUMP', '/usr/bin/mysqldump', 'chaine', 0, '', 0);" > /dev/null 2>&1 + + if [[ ${DOLI_INIT_DEMO} -eq 1 ]]; then + mkdir -p /var/www/dev/initdemo/ + > /var/www/documents/vi + versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` + echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." + curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql + for fileSQL in /var/www/dev/initdemo/*.sql; do + echo "Found demo data file, so we first drop table llx_accounting_system ..." + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_account\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_account" >> /var/www/documents/initdemo.log 2>&1 + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_system\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_system" >> /var/www/documents/initdemo.log 2>&1 + echo "Then we load demo data ${fileSQL} ..." + #sed -i 's/--.*//g;' ${fileSQL} + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1 + done + else + echo "DOLI_NIT_DEMO is off. No demo data load to do." + fi + + echo "Enable user module ..." + php /var/www/scripts/docker-init.php + + # Run init scripts + runScripts "docker-init.d" + + # Update ownership after initialisation of modules + chown -R www-data:www-data /var/www/documents +} + +function migrateDatabase() +{ + TARGET_VERSION="$(echo ${DOLI_VERSION} | cut -d. -f1).$(echo ${DOLI_VERSION} | cut -d. -f2).0" + echo "Schema update is required ..." + echo "Dumping Database into /var/www/documents/dump.sql ..." + + mysqldump -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} > /var/www/documents/dump.sql + r=${?} + if [[ ${r} -ne 0 ]]; then + echo "Dump failed ... Aborting migration ..." + return ${r} + fi + echo "Dump done ... Starting Migration ..." + + echo "" > /var/www/documents/migration_error.html + pushd /var/www/htdocs/install > /dev/null + php upgrade.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php upgrade2.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php step5.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 + r=$? + popd > /dev/null + + if [[ ${r} -ne 0 ]]; then + echo "Migration failed ... Restoring DB ... check file /var/www/documents/migration_error.html for more info on error ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < /var/www/documents/dump.sql + echo "DB Restored ..." + return ${r} + else + echo "Migration successful ... Enjoy !!" + fi + + return 0 +} + +function run() +{ + initDolibarr + echo "Current Version is : ${DOLI_VERSION}" + + # If install of mysql database (and not install of cron) is requested + if [[ ${DOLI_INSTALL_AUTO} -eq 1 && ${DOLI_CRON} -ne 1 && ${DOLI_DB_TYPE} != "pgsql" ]]; then + echo "DOLI_INSTALL_AUTO is on, so we check to initialize or upgrade mariadb database" + + # If install.lock does not exists, we launch the initializeDataze + if [[ ! -f /var/www/documents/install.lock ]]; then + waitForDataBase + + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + updateHtdocs + initializeDatabase + else + INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` + echo "Last installed Version is : ${INSTALLED_VERSION}" + if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs + migrateDatabase + else + echo "Schema update is not required ... Enjoy !!" + fi + fi + + if [[ ${DOLI_VERSION} != "develop" ]]; then + lockInstallation + fi + else + echo "File /var/www/documents/install.lock exists so we cancel database init" + fi + fi + + # Run scripts before starting + runScripts "before-starting.d" +} + +DOLI_DB_USER=$(get_env_value 'DOLI_DB_USER' 'doli') +DOLI_DB_PASSWORD=$(get_env_value 'DOLI_DB_PASSWORD' 'doli_pass') +DOLI_ADMIN_LOGIN=$(get_env_value 'DOLI_ADMIN_LOGIN' 'admin') +DOLI_ADMIN_PASSWORD=$(get_env_value 'DOLI_ADMIN_PASSWORD' 'admin') +DOLI_CRON_KEY=$(get_env_value 'DOLI_CRON_KEY' '') +DOLI_CRON_USER=$(get_env_value 'DOLI_CRON_USER' '') +DOLI_INSTANCE_UNIQUE_ID=$(get_env_value 'DOLI_INSTANCE_UNIQUE_ID' '') + +run + +set -e + +if [[ ${DOLI_CRON} -eq 1 ]]; then + echo "PATH=\$PATH:/usr/local/bin" > /etc/cron.d/dolibarr + echo "*/5 * * * * root /bin/su www-data -s /bin/sh -c '/var/www/scripts/cron/cron_run_jobs.php ${DOLI_CRON_KEY} ${DOLI_CRON_USER}' > /proc/1/fd/1 2> /proc/1/fd/2" >> /etc/cron.d/dolibarr + cron -f + exit 0 +fi + +if [ "${1#-}" != "$1" ]; then + set -- apache2-foreground "$@" +fi + +exec "$@" diff --git a/images/19.0.3-php8.2/docker-run.sh b/images/19.0.3-php8.2/docker-run.sh deleted file mode 100755 index c2292cc..0000000 --- a/images/19.0.3-php8.2/docker-run.sh +++ /dev/null @@ -1,330 +0,0 @@ -#!/bin/bash -# This script is run when the Docker web container is started. -# It is embedded into the Docker image of dolibarr/dolibarr. -# - -# usage: get_env_value VAR [DEFAULT] -# ie: get_env_value 'XYZ_DB_PASSWORD' 'example' -# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of -# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) -function get_env_value() { - local varName="${1}" - local fileVarName="${varName}_FILE" - local defaultValue="${2:-}" - - if [ "${!varName:-}" ] && [ "${!fileVarName:-}" ]; then - echo >&2 "error: both ${varName} and ${fileVarName} are set (but are exclusive)" - exit 1 - fi - - local value="${defaultValue}" - if [ "${!varName:-}" ]; then - value="${!varName}" - elif [ "${!fileVarName:-}" ]; then - value="$(< "${!fileVarName}")" - fi - - echo ${value} - exit 0 -} - -function initDolibarr() -{ - local CURRENT_UID=$(id -u www-data) - local CURRENT_GID=$(id -g www-data) - usermod -u ${WWW_USER_ID} www-data - groupmod -g ${WWW_GROUP_ID} www-data - - if [[ ! -d /var/www/documents ]]; then - echo "[INIT] => create volume directory /var/www/documents ..." - mkdir -p /var/www/documents - fi - - echo "[INIT] => update PHP Config ..." - cat > ${PHP_INI_DIR}/conf.d/dolibarr-php.ini << EOF -date.timezone = ${PHP_INI_DATE_TIMEZONE} -sendmail_path = /usr/sbin/sendmail -t -i -memory_limit = ${PHP_INI_MEMORY_LIMIT} -upload_max_filesize = ${PHP_INI_UPLOAD_MAX_FILESIZE} -post_max_size = ${PHP_INI_POST_MAX_SIZE} -allow_url_fopen = ${PHP_INI_ALLOW_URL_FOPEN} -session.use_strict_mode = 1 -disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,passthru,shell_exec,system,proc_open,popen -EOF - -if [[ ! -f /var/www/html/conf/conf.php ]]; then - echo "[INIT] => update Dolibarr Config ..." - cat > /var/www/html/conf/conf.php << EOF - update Dolibarr Config with instance unique id ..." - echo "\$dolibarr_main_instance_unique_id='${DOLI_INSTANCE_UNIQUE_ID}';" >> /var/www/html/conf/conf.php - fi - if [[ ${DOLI_AUTH} =~ .*ldap.* ]]; then - echo "[INIT] => update Dolibarr Config with LDAP entries ..." - cat >> /var/www/html/conf/conf.php << EOF -\$dolibarr_main_auth_ldap_host='${DOLI_LDAP_HOST}'; -\$dolibarr_main_auth_ldap_port='${DOLI_LDAP_PORT}'; -\$dolibarr_main_auth_ldap_version='${DOLI_LDAP_VERSION}'; -\$dolibarr_main_auth_ldap_servertype='${DOLI_LDAP_SERVER_TYPE}'; -\$dolibarr_main_auth_ldap_login_attribute='${DOLI_LDAP_LOGIN_ATTRIBUTE}'; -\$dolibarr_main_auth_ldap_dn='${DOLI_LDAP_DN}'; -\$dolibarr_main_auth_ldap_filter='${DOLI_LDAP_FILTER}'; -\$dolibarr_main_auth_ldap_admin_login='${DOLI_LDAP_BIND_DN}'; -\$dolibarr_main_auth_ldap_admin_pass='${DOLI_LDAP_BIND_PASS}'; -\$dolibarr_main_auth_ldap_debug='${DOLI_LDAP_DEBUG}'; -EOF - fi - fi - - echo "[INIT] => update ownership for file in Dolibarr Config ..." - chown www-data:www-data /var/www/html/conf/conf.php - if [[ ${DOLI_DB_TYPE} == "pgsql" && ! -f /var/www/documents/install.lock ]]; then - chmod 600 /var/www/html/conf/conf.php - else - chmod 400 /var/www/html/conf/conf.php - fi - - if [[ ${CURRENT_UID} -ne ${WWW_USER_ID} || ${CURRENT_GID} -ne ${WWW_GROUP_ID} ]]; then - # Refresh file ownership cause it has changed - echo "[INIT] => As UID / GID have changed from default, update ownership for files in /var/ww ..." - chown -R www-data:www-data /var/www - else - # Reducing load on init : change ownership only for volumes declared in docker - echo "[INIT] => update ownership for files in /var/www/documents ..." - chown -R www-data:www-data /var/www/documents - fi -} - -function waitForDataBase() -{ - r=1 - - while [[ ${r} -ne 0 ]]; do - mysql -u ${DOLI_DB_USER} --protocol tcp -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} --connect-timeout=5 -e "status" > /dev/null 2>&1 - r=$? - if [[ ${r} -ne 0 ]]; then - echo "Waiting that SQL database is up ..." - sleep 2 - fi - done -} - -function lockInstallation() -{ - touch /var/www/documents/install.lock - chown www-data:www-data /var/www/documents/install.lock - chmod 400 /var/www/documents/install.lock -} - -function runScripts() -{ - if [ -d /var/www/scripts/$1 ] ; then - for file in /var/www/scripts/$1/*; do - [ ! -f $file ] && continue - - # If extension is not in PHP SQL SH, we loop - isExec=$(echo "PHP SQL SH" | grep -wio ${file##*.}) - [ -z "$isExec" ] && continue - - echo "Importing custom ${isExec} from `basename ${file}` ..." - if [ "$isExec" == "SQL" ] ; then - sed -i 's/--.*//g;' ${file} - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${file} > /dev/null 2>&1 - elif [ "$isExec" == "PHP" ] ; then - php $file - elif [ "$isExec" == "SH" ] ; then - /bin/bash $file - fi - done - fi -} - -# Function called to initialize the database (creation of tables and init data) -function initializeDatabase() -{ - for fileSQL in /var/www/html/install/mysql/tables/*.sql; do - if [[ ${fileSQL} != *.key.sql ]]; then - echo "Importing table from `basename ${fileSQL}` ..." - sed -i 's/--.*//g;' ${fileSQL} # remove all comment - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} - fi - done - - for fileSQL in /var/www/html/install/mysql/tables/*.key.sql; do - echo "Importing table key from `basename ${fileSQL}` ..." - sed -i 's/--.*//g;' ${fileSQL} - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 - done - - for fileSQL in /var/www/html/install/mysql/functions/*.sql; do - echo "Importing `basename ${fileSQL}` ..." - sed -i 's/--.*//g;' ${fileSQL} - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 - done - - for fileSQL in /var/www/html/install/mysql/data/*.sql; do - if [[ $fileSQL =~ llx_accounting_account_ ]]; then - echo "Do not import data from `basename ${fileSQL}` ..." - continue - fi - echo "Importing data from `basename ${fileSQL}` ..." - sed -i 's/--.*//g;' ${fileSQL} - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 - done - - echo "Create SuperAdmin account ..." - pass_crypted=`echo -n ${DOLI_ADMIN_PASSWORD} | md5sum | awk '{print $1}'` - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_user (entity, login, pass_crypted, lastname, admin, statut) VALUES (0, '${DOLI_ADMIN_LOGIN}', '${pass_crypted}', 'SuperAdmin', 1, 1);" > /dev/null 2>&1 - - echo "Set some default const ..." - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL';" > /dev/null 2>&1 - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_NOT_INSTALLED';" > /dev/null 2>&1 - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_LANG_DEFAULT';" > /dev/null 2>&1 - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) values('MAIN_VERSION_LAST_INSTALL', '${DOLI_VERSION}', 'chaine', 0, 'Dolibarr version when install', 0);" > /dev/null 2>&1 - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('MAIN_LANG_DEFAULT', 'auto', 'chaine', 0, 'Default language', 1);" > /dev/null 2>&1 - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('SYSTEMTOOLS_MYSQLDUMP', '/usr/bin/mysqldump', 'chaine', 0, '', 0);" > /dev/null 2>&1 - - if [[ ${DOLI_INIT_DEMO} -eq 1 ]]; then - mkdir -p /var/www/dev/initdemo/ - > /var/www/documents/vi - versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` - echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." - curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql - for fileSQL in /var/www/dev/initdemo/*.sql; do - echo "Found demo data file, so we first drop table llx_accounting_system ..." - echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_account\" >> /var/www/documents/initdemo.log 2>&1" - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_account" >> /var/www/documents/initdemo.log 2>&1 - echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_system\" >> /var/www/documents/initdemo.log 2>&1" - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_system" >> /var/www/documents/initdemo.log 2>&1 - echo "Then we load demo data ${fileSQL} ..." - #sed -i 's/--.*//g;' ${fileSQL} - echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1" - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1 - done - else - echo "DOLI_NIT_DEMO is off. No demo data load to do." - fi - - echo "Enable user module ..." - php /var/www/scripts/docker-init.php - - # Run init scripts - runScripts "docker-init.d" - - # Update ownership after initialisation of modules - chown -R www-data:www-data /var/www/documents -} - -function migrateDatabase() -{ - TARGET_VERSION="$(echo ${DOLI_VERSION} | cut -d. -f1).$(echo ${DOLI_VERSION} | cut -d. -f2).0" - echo "Schema update is required ..." - echo "Dumping Database into /var/www/documents/dump.sql ..." - - mysqldump -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} > /var/www/documents/dump.sql - r=${?} - if [[ ${r} -ne 0 ]]; then - echo "Dump failed ... Aborting migration ..." - return ${r} - fi - echo "Dump done ... Starting Migration ..." - - echo "" > /var/www/documents/migration_error.html - pushd /var/www/htdocs/install > /dev/null - php upgrade.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ - php upgrade2.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ - php step5.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 - r=$? - popd > /dev/null - - if [[ ${r} -ne 0 ]]; then - echo "Migration failed ... Restoring DB ... check file /var/www/documents/migration_error.html for more info on error ..." - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < /var/www/documents/dump.sql - echo "DB Restored ..." - return ${r} - else - echo "Migration successful ... Enjoy !!" - fi - - return 0 -} - -function run() -{ - initDolibarr - echo "Current Version is : ${DOLI_VERSION}" - - # If install of mysql database (and not install of cron) is requested - if [[ ${DOLI_INSTALL_AUTO} -eq 1 && ${DOLI_CRON} -ne 1 && ${DOLI_DB_TYPE} != "pgsql" ]]; then - echo "DOLI_INSTALL_AUTO is on, so we check to initialize or upgrade mariadb database" - - # If install.lock does not exists, we launch the initializeDataze - if [[ ! -f /var/www/documents/install.lock ]]; then - waitForDataBase - - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 - r=$? - if [[ ${r} -ne 0 ]]; then - initializeDatabase - else - INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` - echo "Last installed Version is : ${INSTALLED_VERSION}" - if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then - migrateDatabase - else - echo "Schema update is not required ... Enjoy !!" - fi - fi - - if [[ ${DOLI_VERSION} != "develop" ]]; then - lockInstallation - fi - else - echo "File /var/www/documents/install.lock exists so we cancel database init" - fi - fi - - # Run scripts before starting - runScripts "before-starting.d" -} - -DOLI_DB_USER=$(get_env_value 'DOLI_DB_USER' 'doli') -DOLI_DB_PASSWORD=$(get_env_value 'DOLI_DB_PASSWORD' 'doli_pass') -DOLI_ADMIN_LOGIN=$(get_env_value 'DOLI_ADMIN_LOGIN' 'admin') -DOLI_ADMIN_PASSWORD=$(get_env_value 'DOLI_ADMIN_PASSWORD' 'admin') -DOLI_CRON_KEY=$(get_env_value 'DOLI_CRON_KEY' '') -DOLI_CRON_USER=$(get_env_value 'DOLI_CRON_USER' '') -DOLI_INSTANCE_UNIQUE_ID=$(get_env_value 'DOLI_INSTANCE_UNIQUE_ID' '') - -run - -set -e - -if [[ ${DOLI_CRON} -eq 1 ]]; then - echo "PATH=\$PATH:/usr/local/bin" > /etc/cron.d/dolibarr - echo "*/5 * * * * root /bin/su www-data -s /bin/sh -c '/var/www/scripts/cron/cron_run_jobs.php ${DOLI_CRON_KEY} ${DOLI_CRON_USER}' > /proc/1/fd/1 2> /proc/1/fd/2" >> /etc/cron.d/dolibarr - cron -f - exit 0 -fi - -if [ "${1#-}" != "$1" ]; then - set -- apache2-foreground "$@" -fi - -exec "$@" diff --git a/images/19.0.3-php8.2/Dockerfile b/images/19.0.3/apache-buster/Dockerfile similarity index 88% rename from images/19.0.3-php8.2/Dockerfile rename to images/19.0.3/apache-buster/Dockerfile index 3e0fb62..ec82044 100644 --- a/images/19.0.3-php8.2/Dockerfile +++ b/images/19.0.3/apache-buster/Dockerfile @@ -40,11 +40,7 @@ ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M ENV PHP_INI_POST_MAX_SIZE 8M ENV PHP_INI_ALLOW_URL_FOPEN 0 -RUN sed -i \ - -e 's/^\(ServerSignature On\)$/#\1/g' \ - -e 's/^#\(ServerSignature Off\)$/\1/g' \ - -e 's/^\(ServerTokens\) OS$/\1 Prod/g' \ - /etc/apache2/conf-available/security.conf +RUN sed -i -e 's/^\(ServerSignature On\)$/#\1/g' -e 's/^#\(ServerSignature Off\)$/\1/g' -e 's/^\(ServerTokens\) OS$/\1 Prod/g' /etc/apache2/conf-available/security.conf RUN apt-get update -y \ && apt-get dist-upgrade -y \ @@ -61,6 +57,7 @@ RUN apt-get update -y \ default-mysql-client \ postgresql-client \ cron \ + rsync \ && apt-get autoremove -y \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ @@ -76,7 +73,8 @@ RUN apt-get update -y \ # Get Dolibarr RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ tar -C /tmp -xz && \ - cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /var/www/html/ && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ ln -s /var/www/html /var/www/htdocs && \ cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ rm -rf /tmp/* && \ @@ -86,6 +84,7 @@ RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar. EXPOSE 80 VOLUME /var/www/documents +VOLUME /var/www/html VOLUME /var/www/html/custom COPY docker-init.php /var/www/scripts/ diff --git a/images/19.0.3/apache-buster/docker-init.php b/images/19.0.3/apache-buster/docker-init.php new file mode 100644 index 0000000..5006905 --- /dev/null +++ b/images/19.0.3/apache-buster/docker-init.php @@ -0,0 +1,49 @@ +#!/usr/bin/env php +fetch(0,$countryCode); + if ($res > 0 ) { + $s = $country->id.':'.$country->code.':'.$country->label; + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_COUNTRY", $s, 'chaine', 0, '', $conf->entity); + printf('Configuring for country : '.$s."\n"); + activateModulesRequiredByCountry($country->code); + } else { + printf('Unable to find country '.$countryCode."\n"); + } +} + +if (!empty(getenv('DOLI_COMPANY_NAME'))) { + $compname = getenv('DOLI_COMPANY_NAME'); + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", $compname, 'chaine', 0, '', $conf->entity); +} + +if (!empty(getenv('DOLI_ENABLE_MODULES'))) { + $mods = explode(',', getenv('DOLI_ENABLE_MODULES')); + foreach ($mods as $mod) { + printf("Activating module ".$mod." ..."); + try { + $res = activateModule('mod' . $mod); + if ($res < 0) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } else { + printf(" OK\n"); + } + } catch (Throwable $t) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } + } +} diff --git a/images/19.0.3/apache-buster/docker-run.sh b/images/19.0.3/apache-buster/docker-run.sh new file mode 100755 index 0000000..fc9ed33 --- /dev/null +++ b/images/19.0.3/apache-buster/docker-run.sh @@ -0,0 +1,340 @@ +#!/bin/bash +# This script is run when the Docker web container is started. +# It is embedded into the Docker image of dolibarr/dolibarr. +# + +# usage: get_env_value VAR [DEFAULT] +# ie: get_env_value 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +function get_env_value() { + local varName="${1}" + local fileVarName="${varName}_FILE" + local defaultValue="${2:-}" + + if [ "${!varName:-}" ] && [ "${!fileVarName:-}" ]; then + echo >&2 "error: both ${varName} and ${fileVarName} are set (but are exclusive)" + exit 1 + fi + + local value="${defaultValue}" + if [ "${!varName:-}" ]; then + value="${!varName}" + elif [ "${!fileVarName:-}" ]; then + value="$(< "${!fileVarName}")" + fi + + echo ${value} + exit 0 +} + +function initDolibarr() +{ + local CURRENT_UID=$(id -u www-data) + local CURRENT_GID=$(id -g www-data) + usermod -u ${WWW_USER_ID} www-data + groupmod -g ${WWW_GROUP_ID} www-data + + if [[ ! -d /var/www/documents ]]; then + echo "[INIT] => create volume directory /var/www/documents ..." + mkdir -p /var/www/documents + fi + + echo "[INIT] => update PHP Config ..." + cat > ${PHP_INI_DIR}/conf.d/dolibarr-php.ini << EOF +date.timezone = ${PHP_INI_DATE_TIMEZONE} +sendmail_path = /usr/sbin/sendmail -t -i +memory_limit = ${PHP_INI_MEMORY_LIMIT} +upload_max_filesize = ${PHP_INI_UPLOAD_MAX_FILESIZE} +post_max_size = ${PHP_INI_POST_MAX_SIZE} +allow_url_fopen = ${PHP_INI_ALLOW_URL_FOPEN} +session.use_strict_mode = 1 +disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,passthru,shell_exec,system,proc_open,popen +EOF + +if [[ ! -f /var/www/html/conf/conf.php ]]; then + echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf + cat > /var/www/html/conf/conf.php << EOF + update Dolibarr Config with instance unique id ..." + echo "\$dolibarr_main_instance_unique_id='${DOLI_INSTANCE_UNIQUE_ID}';" >> /var/www/html/conf/conf.php + fi + if [[ ${DOLI_AUTH} =~ .*ldap.* ]]; then + echo "[INIT] => update Dolibarr Config with LDAP entries ..." + cat >> /var/www/html/conf/conf.php << EOF +\$dolibarr_main_auth_ldap_host='${DOLI_LDAP_HOST}'; +\$dolibarr_main_auth_ldap_port='${DOLI_LDAP_PORT}'; +\$dolibarr_main_auth_ldap_version='${DOLI_LDAP_VERSION}'; +\$dolibarr_main_auth_ldap_servertype='${DOLI_LDAP_SERVER_TYPE}'; +\$dolibarr_main_auth_ldap_login_attribute='${DOLI_LDAP_LOGIN_ATTRIBUTE}'; +\$dolibarr_main_auth_ldap_dn='${DOLI_LDAP_DN}'; +\$dolibarr_main_auth_ldap_filter='${DOLI_LDAP_FILTER}'; +\$dolibarr_main_auth_ldap_admin_login='${DOLI_LDAP_BIND_DN}'; +\$dolibarr_main_auth_ldap_admin_pass='${DOLI_LDAP_BIND_PASS}'; +\$dolibarr_main_auth_ldap_debug='${DOLI_LDAP_DEBUG}'; +EOF + fi + fi + + echo "[INIT] => update ownership for file in Dolibarr Config ..." + chown www-data:www-data /var/www/html/conf/conf.php + if [[ ${DOLI_DB_TYPE} == "pgsql" && ! -f /var/www/documents/install.lock ]]; then + chmod 600 /var/www/html/conf/conf.php + else + chmod 400 /var/www/html/conf/conf.php + fi + + if [[ ${CURRENT_UID} -ne ${WWW_USER_ID} || ${CURRENT_GID} -ne ${WWW_GROUP_ID} ]]; then + # Refresh file ownership cause it has changed + echo "[INIT] => As UID / GID have changed from default, update ownership for files in /var/ww ..." + chown -R www-data:www-data /var/www + else + # Reducing load on init : change ownership only for volumes declared in docker + echo "[INIT] => update ownership for files in /var/www/documents ..." + chown -R www-data:www-data /var/www/documents + fi +} + +function waitForDataBase() +{ + r=1 + + while [[ ${r} -ne 0 ]]; do + mysql -u ${DOLI_DB_USER} --protocol tcp -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} --connect-timeout=5 -e "status" > /dev/null 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + echo "Waiting that SQL database is up ..." + sleep 2 + fi + done +} + +function lockInstallation() +{ + touch /var/www/documents/install.lock + chown www-data:www-data /var/www/documents/install.lock + chmod 400 /var/www/documents/install.lock +} + +function runScripts() +{ + if [ -d /var/www/scripts/$1 ] ; then + for file in /var/www/scripts/$1/*; do + [ ! -f $file ] && continue + + # If extension is not in PHP SQL SH, we loop + isExec=$(echo "PHP SQL SH" | grep -wio ${file##*.}) + [ -z "$isExec" ] && continue + + echo "Importing custom ${isExec} from `basename ${file}` ..." + if [ "$isExec" == "SQL" ] ; then + sed -i 's/--.*//g;' ${file} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${file} > /dev/null 2>&1 + elif [ "$isExec" == "PHP" ] ; then + php $file + elif [ "$isExec" == "SH" ] ; then + /bin/bash $file + fi + done + fi +} + +# Function called to update the htdocs folde with the new code +function updateHtdocs() +{ + echo "Updating htdocs folder..." + rsync -rlD --chown www-data:www-data --delete --exclude custom --exclude conf/conf.php /usr/src/dolibarr/ /var/www/html/ +} + +# Function called to initialize the database (creation of tables and init data) +function initializeDatabase() +{ + for fileSQL in /var/www/html/install/mysql/tables/*.sql; do + if [[ ${fileSQL} != *.key.sql ]]; then + echo "Importing table from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} # remove all comment + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} + fi + done + + for fileSQL in /var/www/html/install/mysql/tables/*.key.sql; do + echo "Importing table key from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/functions/*.sql; do + echo "Importing `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/data/*.sql; do + if [[ $fileSQL =~ llx_accounting_account_ ]]; then + echo "Do not import data from `basename ${fileSQL}` ..." + continue + fi + echo "Importing data from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + echo "Create SuperAdmin account ..." + pass_crypted=`echo -n ${DOLI_ADMIN_PASSWORD} | md5sum | awk '{print $1}'` + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_user (entity, login, pass_crypted, lastname, admin, statut) VALUES (0, '${DOLI_ADMIN_LOGIN}', '${pass_crypted}', 'SuperAdmin', 1, 1);" > /dev/null 2>&1 + + echo "Set some default const ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_NOT_INSTALLED';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_LANG_DEFAULT';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) values('MAIN_VERSION_LAST_INSTALL', '${DOLI_VERSION}', 'chaine', 0, 'Dolibarr version when install', 0);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('MAIN_LANG_DEFAULT', 'auto', 'chaine', 0, 'Default language', 1);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('SYSTEMTOOLS_MYSQLDUMP', '/usr/bin/mysqldump', 'chaine', 0, '', 0);" > /dev/null 2>&1 + + if [[ ${DOLI_INIT_DEMO} -eq 1 ]]; then + mkdir -p /var/www/dev/initdemo/ + > /var/www/documents/vi + versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` + echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." + curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql + for fileSQL in /var/www/dev/initdemo/*.sql; do + echo "Found demo data file, so we first drop table llx_accounting_system ..." + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_account\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_account" >> /var/www/documents/initdemo.log 2>&1 + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_system\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_system" >> /var/www/documents/initdemo.log 2>&1 + echo "Then we load demo data ${fileSQL} ..." + #sed -i 's/--.*//g;' ${fileSQL} + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1 + done + else + echo "DOLI_NIT_DEMO is off. No demo data load to do." + fi + + echo "Enable user module ..." + php /var/www/scripts/docker-init.php + + # Run init scripts + runScripts "docker-init.d" + + # Update ownership after initialisation of modules + chown -R www-data:www-data /var/www/documents +} + +function migrateDatabase() +{ + TARGET_VERSION="$(echo ${DOLI_VERSION} | cut -d. -f1).$(echo ${DOLI_VERSION} | cut -d. -f2).0" + echo "Schema update is required ..." + echo "Dumping Database into /var/www/documents/dump.sql ..." + + mysqldump -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} > /var/www/documents/dump.sql + r=${?} + if [[ ${r} -ne 0 ]]; then + echo "Dump failed ... Aborting migration ..." + return ${r} + fi + echo "Dump done ... Starting Migration ..." + + echo "" > /var/www/documents/migration_error.html + pushd /var/www/htdocs/install > /dev/null + php upgrade.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php upgrade2.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php step5.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 + r=$? + popd > /dev/null + + if [[ ${r} -ne 0 ]]; then + echo "Migration failed ... Restoring DB ... check file /var/www/documents/migration_error.html for more info on error ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < /var/www/documents/dump.sql + echo "DB Restored ..." + return ${r} + else + echo "Migration successful ... Enjoy !!" + fi + + return 0 +} + +function run() +{ + initDolibarr + echo "Current Version is : ${DOLI_VERSION}" + + # If install of mysql database (and not install of cron) is requested + if [[ ${DOLI_INSTALL_AUTO} -eq 1 && ${DOLI_CRON} -ne 1 && ${DOLI_DB_TYPE} != "pgsql" ]]; then + echo "DOLI_INSTALL_AUTO is on, so we check to initialize or upgrade mariadb database" + + # If install.lock does not exists, we launch the initializeDataze + if [[ ! -f /var/www/documents/install.lock ]]; then + waitForDataBase + + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + updateHtdocs + initializeDatabase + else + INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` + echo "Last installed Version is : ${INSTALLED_VERSION}" + if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs + migrateDatabase + else + echo "Schema update is not required ... Enjoy !!" + fi + fi + + if [[ ${DOLI_VERSION} != "develop" ]]; then + lockInstallation + fi + else + echo "File /var/www/documents/install.lock exists so we cancel database init" + fi + fi + + # Run scripts before starting + runScripts "before-starting.d" +} + +DOLI_DB_USER=$(get_env_value 'DOLI_DB_USER' 'doli') +DOLI_DB_PASSWORD=$(get_env_value 'DOLI_DB_PASSWORD' 'doli_pass') +DOLI_ADMIN_LOGIN=$(get_env_value 'DOLI_ADMIN_LOGIN' 'admin') +DOLI_ADMIN_PASSWORD=$(get_env_value 'DOLI_ADMIN_PASSWORD' 'admin') +DOLI_CRON_KEY=$(get_env_value 'DOLI_CRON_KEY' '') +DOLI_CRON_USER=$(get_env_value 'DOLI_CRON_USER' '') +DOLI_INSTANCE_UNIQUE_ID=$(get_env_value 'DOLI_INSTANCE_UNIQUE_ID' '') + +run + +set -e + +if [[ ${DOLI_CRON} -eq 1 ]]; then + echo "PATH=\$PATH:/usr/local/bin" > /etc/cron.d/dolibarr + echo "*/5 * * * * root /bin/su www-data -s /bin/sh -c '/var/www/scripts/cron/cron_run_jobs.php ${DOLI_CRON_KEY} ${DOLI_CRON_USER}' > /proc/1/fd/1 2> /proc/1/fd/2" >> /etc/cron.d/dolibarr + cron -f + exit 0 +fi + +if [ "${1#-}" != "$1" ]; then + set -- apache2-foreground "$@" +fi + +exec "$@" diff --git a/images/19.0.3/fpm/Dockerfile b/images/19.0.3/fpm/Dockerfile new file mode 100644 index 0000000..9dfe2b2 --- /dev/null +++ b/images/19.0.3/fpm/Dockerfile @@ -0,0 +1,94 @@ +ARG ARCH= + +# Use an image like PHP_BASE_IMAGE=x.y-apache-buster +FROM ${ARCH}php:8.2-fpm + +LABEL maintainer="Garcia MICHEL " + +ENV DOLI_VERSION 19.0.3 +ENV DOLI_INSTALL_AUTO 1 +ENV DOLI_PROD 1 + +ENV DOLI_DB_TYPE mysqli +ENV DOLI_DB_HOST mysql +ENV DOLI_DB_HOST_PORT 3306 +ENV DOLI_DB_NAME dolidb + +ENV DOLI_URL_ROOT 'http://localhost' +ENV DOLI_NOCSRFCHECK 0 + +ENV DOLI_AUTH dolibarr +ENV DOLI_LDAP_HOST 127.0.0.1 +ENV DOLI_LDAP_PORT 389 +ENV DOLI_LDAP_VERSION 3 +ENV DOLI_LDAP_SERVER_TYPE openldap +ENV DOLI_LDAP_LOGIN_ATTRIBUTE uid +ENV DOLI_LDAP_DN 'ou=users,dc=my-domain,dc=com' +ENV DOLI_LDAP_FILTER '' +ENV DOLI_LDAP_BIND_DN '' +ENV DOLI_LDAP_BIND_PASS '' +ENV DOLI_LDAP_DEBUG false + +ENV DOLI_CRON 0 + +ENV WWW_USER_ID 33 +ENV WWW_GROUP_ID 33 + +ENV PHP_INI_DATE_TIMEZONE 'UTC' +ENV PHP_INI_MEMORY_LIMIT 256M +ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M +ENV PHP_INI_POST_MAX_SIZE 8M +ENV PHP_INI_ALLOW_URL_FOPEN 0 + + + +RUN apt-get update -y \ + && apt-get dist-upgrade -y \ + && apt-get install -y --no-install-recommends \ + libc-client-dev \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libkrb5-dev \ + libldap2-dev \ + libpng-dev \ + libpq-dev \ + libxml2-dev \ + libzip-dev \ + default-mysql-client \ + postgresql-client \ + cron \ + rsync \ + && apt-get autoremove -y \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ + && docker-php-ext-configure pgsql -with-pgsql \ + && docker-php-ext-install pdo_pgsql pgsql \ + && docker-php-ext-configure ldap --with-libdir=lib/$(gcc -dumpmachine)/ \ + && docker-php-ext-install -j$(nproc) ldap \ + && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ + && docker-php-ext-install imap \ + && mv ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini \ + && rm -rf /var/lib/apt/lists/* + +# Get Dolibarr +RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ + tar -C /tmp -xz && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ + ln -s /var/www/html /var/www/htdocs && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ + rm -rf /tmp/* && \ + mkdir -p /var/www/documents && \ + mkdir -p /var/www/html/custom && \ + chown -R www-data:www-data /var/www + +EXPOSE 9000 +VOLUME /var/www/documents +VOLUME /var/www/html +VOLUME /var/www/html/custom + +COPY docker-init.php /var/www/scripts/ +COPY docker-run.sh /usr/local/bin/ +ENTRYPOINT ["docker-run.sh"] + +CMD ["php-fpm"] diff --git a/images/19.0.3/fpm/docker-init.php b/images/19.0.3/fpm/docker-init.php new file mode 100644 index 0000000..5006905 --- /dev/null +++ b/images/19.0.3/fpm/docker-init.php @@ -0,0 +1,49 @@ +#!/usr/bin/env php +fetch(0,$countryCode); + if ($res > 0 ) { + $s = $country->id.':'.$country->code.':'.$country->label; + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_COUNTRY", $s, 'chaine', 0, '', $conf->entity); + printf('Configuring for country : '.$s."\n"); + activateModulesRequiredByCountry($country->code); + } else { + printf('Unable to find country '.$countryCode."\n"); + } +} + +if (!empty(getenv('DOLI_COMPANY_NAME'))) { + $compname = getenv('DOLI_COMPANY_NAME'); + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", $compname, 'chaine', 0, '', $conf->entity); +} + +if (!empty(getenv('DOLI_ENABLE_MODULES'))) { + $mods = explode(',', getenv('DOLI_ENABLE_MODULES')); + foreach ($mods as $mod) { + printf("Activating module ".$mod." ..."); + try { + $res = activateModule('mod' . $mod); + if ($res < 0) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } else { + printf(" OK\n"); + } + } catch (Throwable $t) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } + } +} diff --git a/images/19.0.3/fpm/docker-run.sh b/images/19.0.3/fpm/docker-run.sh new file mode 100755 index 0000000..fc9ed33 --- /dev/null +++ b/images/19.0.3/fpm/docker-run.sh @@ -0,0 +1,340 @@ +#!/bin/bash +# This script is run when the Docker web container is started. +# It is embedded into the Docker image of dolibarr/dolibarr. +# + +# usage: get_env_value VAR [DEFAULT] +# ie: get_env_value 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +function get_env_value() { + local varName="${1}" + local fileVarName="${varName}_FILE" + local defaultValue="${2:-}" + + if [ "${!varName:-}" ] && [ "${!fileVarName:-}" ]; then + echo >&2 "error: both ${varName} and ${fileVarName} are set (but are exclusive)" + exit 1 + fi + + local value="${defaultValue}" + if [ "${!varName:-}" ]; then + value="${!varName}" + elif [ "${!fileVarName:-}" ]; then + value="$(< "${!fileVarName}")" + fi + + echo ${value} + exit 0 +} + +function initDolibarr() +{ + local CURRENT_UID=$(id -u www-data) + local CURRENT_GID=$(id -g www-data) + usermod -u ${WWW_USER_ID} www-data + groupmod -g ${WWW_GROUP_ID} www-data + + if [[ ! -d /var/www/documents ]]; then + echo "[INIT] => create volume directory /var/www/documents ..." + mkdir -p /var/www/documents + fi + + echo "[INIT] => update PHP Config ..." + cat > ${PHP_INI_DIR}/conf.d/dolibarr-php.ini << EOF +date.timezone = ${PHP_INI_DATE_TIMEZONE} +sendmail_path = /usr/sbin/sendmail -t -i +memory_limit = ${PHP_INI_MEMORY_LIMIT} +upload_max_filesize = ${PHP_INI_UPLOAD_MAX_FILESIZE} +post_max_size = ${PHP_INI_POST_MAX_SIZE} +allow_url_fopen = ${PHP_INI_ALLOW_URL_FOPEN} +session.use_strict_mode = 1 +disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,passthru,shell_exec,system,proc_open,popen +EOF + +if [[ ! -f /var/www/html/conf/conf.php ]]; then + echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf + cat > /var/www/html/conf/conf.php << EOF + update Dolibarr Config with instance unique id ..." + echo "\$dolibarr_main_instance_unique_id='${DOLI_INSTANCE_UNIQUE_ID}';" >> /var/www/html/conf/conf.php + fi + if [[ ${DOLI_AUTH} =~ .*ldap.* ]]; then + echo "[INIT] => update Dolibarr Config with LDAP entries ..." + cat >> /var/www/html/conf/conf.php << EOF +\$dolibarr_main_auth_ldap_host='${DOLI_LDAP_HOST}'; +\$dolibarr_main_auth_ldap_port='${DOLI_LDAP_PORT}'; +\$dolibarr_main_auth_ldap_version='${DOLI_LDAP_VERSION}'; +\$dolibarr_main_auth_ldap_servertype='${DOLI_LDAP_SERVER_TYPE}'; +\$dolibarr_main_auth_ldap_login_attribute='${DOLI_LDAP_LOGIN_ATTRIBUTE}'; +\$dolibarr_main_auth_ldap_dn='${DOLI_LDAP_DN}'; +\$dolibarr_main_auth_ldap_filter='${DOLI_LDAP_FILTER}'; +\$dolibarr_main_auth_ldap_admin_login='${DOLI_LDAP_BIND_DN}'; +\$dolibarr_main_auth_ldap_admin_pass='${DOLI_LDAP_BIND_PASS}'; +\$dolibarr_main_auth_ldap_debug='${DOLI_LDAP_DEBUG}'; +EOF + fi + fi + + echo "[INIT] => update ownership for file in Dolibarr Config ..." + chown www-data:www-data /var/www/html/conf/conf.php + if [[ ${DOLI_DB_TYPE} == "pgsql" && ! -f /var/www/documents/install.lock ]]; then + chmod 600 /var/www/html/conf/conf.php + else + chmod 400 /var/www/html/conf/conf.php + fi + + if [[ ${CURRENT_UID} -ne ${WWW_USER_ID} || ${CURRENT_GID} -ne ${WWW_GROUP_ID} ]]; then + # Refresh file ownership cause it has changed + echo "[INIT] => As UID / GID have changed from default, update ownership for files in /var/ww ..." + chown -R www-data:www-data /var/www + else + # Reducing load on init : change ownership only for volumes declared in docker + echo "[INIT] => update ownership for files in /var/www/documents ..." + chown -R www-data:www-data /var/www/documents + fi +} + +function waitForDataBase() +{ + r=1 + + while [[ ${r} -ne 0 ]]; do + mysql -u ${DOLI_DB_USER} --protocol tcp -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} --connect-timeout=5 -e "status" > /dev/null 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + echo "Waiting that SQL database is up ..." + sleep 2 + fi + done +} + +function lockInstallation() +{ + touch /var/www/documents/install.lock + chown www-data:www-data /var/www/documents/install.lock + chmod 400 /var/www/documents/install.lock +} + +function runScripts() +{ + if [ -d /var/www/scripts/$1 ] ; then + for file in /var/www/scripts/$1/*; do + [ ! -f $file ] && continue + + # If extension is not in PHP SQL SH, we loop + isExec=$(echo "PHP SQL SH" | grep -wio ${file##*.}) + [ -z "$isExec" ] && continue + + echo "Importing custom ${isExec} from `basename ${file}` ..." + if [ "$isExec" == "SQL" ] ; then + sed -i 's/--.*//g;' ${file} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${file} > /dev/null 2>&1 + elif [ "$isExec" == "PHP" ] ; then + php $file + elif [ "$isExec" == "SH" ] ; then + /bin/bash $file + fi + done + fi +} + +# Function called to update the htdocs folde with the new code +function updateHtdocs() +{ + echo "Updating htdocs folder..." + rsync -rlD --chown www-data:www-data --delete --exclude custom --exclude conf/conf.php /usr/src/dolibarr/ /var/www/html/ +} + +# Function called to initialize the database (creation of tables and init data) +function initializeDatabase() +{ + for fileSQL in /var/www/html/install/mysql/tables/*.sql; do + if [[ ${fileSQL} != *.key.sql ]]; then + echo "Importing table from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} # remove all comment + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} + fi + done + + for fileSQL in /var/www/html/install/mysql/tables/*.key.sql; do + echo "Importing table key from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/functions/*.sql; do + echo "Importing `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/data/*.sql; do + if [[ $fileSQL =~ llx_accounting_account_ ]]; then + echo "Do not import data from `basename ${fileSQL}` ..." + continue + fi + echo "Importing data from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + echo "Create SuperAdmin account ..." + pass_crypted=`echo -n ${DOLI_ADMIN_PASSWORD} | md5sum | awk '{print $1}'` + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_user (entity, login, pass_crypted, lastname, admin, statut) VALUES (0, '${DOLI_ADMIN_LOGIN}', '${pass_crypted}', 'SuperAdmin', 1, 1);" > /dev/null 2>&1 + + echo "Set some default const ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_NOT_INSTALLED';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_LANG_DEFAULT';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) values('MAIN_VERSION_LAST_INSTALL', '${DOLI_VERSION}', 'chaine', 0, 'Dolibarr version when install', 0);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('MAIN_LANG_DEFAULT', 'auto', 'chaine', 0, 'Default language', 1);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('SYSTEMTOOLS_MYSQLDUMP', '/usr/bin/mysqldump', 'chaine', 0, '', 0);" > /dev/null 2>&1 + + if [[ ${DOLI_INIT_DEMO} -eq 1 ]]; then + mkdir -p /var/www/dev/initdemo/ + > /var/www/documents/vi + versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` + echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." + curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql + for fileSQL in /var/www/dev/initdemo/*.sql; do + echo "Found demo data file, so we first drop table llx_accounting_system ..." + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_account\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_account" >> /var/www/documents/initdemo.log 2>&1 + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_system\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_system" >> /var/www/documents/initdemo.log 2>&1 + echo "Then we load demo data ${fileSQL} ..." + #sed -i 's/--.*//g;' ${fileSQL} + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1 + done + else + echo "DOLI_NIT_DEMO is off. No demo data load to do." + fi + + echo "Enable user module ..." + php /var/www/scripts/docker-init.php + + # Run init scripts + runScripts "docker-init.d" + + # Update ownership after initialisation of modules + chown -R www-data:www-data /var/www/documents +} + +function migrateDatabase() +{ + TARGET_VERSION="$(echo ${DOLI_VERSION} | cut -d. -f1).$(echo ${DOLI_VERSION} | cut -d. -f2).0" + echo "Schema update is required ..." + echo "Dumping Database into /var/www/documents/dump.sql ..." + + mysqldump -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} > /var/www/documents/dump.sql + r=${?} + if [[ ${r} -ne 0 ]]; then + echo "Dump failed ... Aborting migration ..." + return ${r} + fi + echo "Dump done ... Starting Migration ..." + + echo "" > /var/www/documents/migration_error.html + pushd /var/www/htdocs/install > /dev/null + php upgrade.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php upgrade2.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php step5.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 + r=$? + popd > /dev/null + + if [[ ${r} -ne 0 ]]; then + echo "Migration failed ... Restoring DB ... check file /var/www/documents/migration_error.html for more info on error ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < /var/www/documents/dump.sql + echo "DB Restored ..." + return ${r} + else + echo "Migration successful ... Enjoy !!" + fi + + return 0 +} + +function run() +{ + initDolibarr + echo "Current Version is : ${DOLI_VERSION}" + + # If install of mysql database (and not install of cron) is requested + if [[ ${DOLI_INSTALL_AUTO} -eq 1 && ${DOLI_CRON} -ne 1 && ${DOLI_DB_TYPE} != "pgsql" ]]; then + echo "DOLI_INSTALL_AUTO is on, so we check to initialize or upgrade mariadb database" + + # If install.lock does not exists, we launch the initializeDataze + if [[ ! -f /var/www/documents/install.lock ]]; then + waitForDataBase + + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + updateHtdocs + initializeDatabase + else + INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` + echo "Last installed Version is : ${INSTALLED_VERSION}" + if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs + migrateDatabase + else + echo "Schema update is not required ... Enjoy !!" + fi + fi + + if [[ ${DOLI_VERSION} != "develop" ]]; then + lockInstallation + fi + else + echo "File /var/www/documents/install.lock exists so we cancel database init" + fi + fi + + # Run scripts before starting + runScripts "before-starting.d" +} + +DOLI_DB_USER=$(get_env_value 'DOLI_DB_USER' 'doli') +DOLI_DB_PASSWORD=$(get_env_value 'DOLI_DB_PASSWORD' 'doli_pass') +DOLI_ADMIN_LOGIN=$(get_env_value 'DOLI_ADMIN_LOGIN' 'admin') +DOLI_ADMIN_PASSWORD=$(get_env_value 'DOLI_ADMIN_PASSWORD' 'admin') +DOLI_CRON_KEY=$(get_env_value 'DOLI_CRON_KEY' '') +DOLI_CRON_USER=$(get_env_value 'DOLI_CRON_USER' '') +DOLI_INSTANCE_UNIQUE_ID=$(get_env_value 'DOLI_INSTANCE_UNIQUE_ID' '') + +run + +set -e + +if [[ ${DOLI_CRON} -eq 1 ]]; then + echo "PATH=\$PATH:/usr/local/bin" > /etc/cron.d/dolibarr + echo "*/5 * * * * root /bin/su www-data -s /bin/sh -c '/var/www/scripts/cron/cron_run_jobs.php ${DOLI_CRON_KEY} ${DOLI_CRON_USER}' > /proc/1/fd/1 2> /proc/1/fd/2" >> /etc/cron.d/dolibarr + cron -f + exit 0 +fi + +if [ "${1#-}" != "$1" ]; then + set -- apache2-foreground "$@" +fi + +exec "$@" diff --git a/images/develop/Dockerfile b/images/develop/apache-buster/Dockerfile similarity index 88% rename from images/develop/Dockerfile rename to images/develop/apache-buster/Dockerfile index 8be6404..bf190d8 100644 --- a/images/develop/Dockerfile +++ b/images/develop/apache-buster/Dockerfile @@ -40,11 +40,7 @@ ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M ENV PHP_INI_POST_MAX_SIZE 8M ENV PHP_INI_ALLOW_URL_FOPEN 0 -RUN sed -i \ - -e 's/^\(ServerSignature On\)$/#\1/g' \ - -e 's/^#\(ServerSignature Off\)$/\1/g' \ - -e 's/^\(ServerTokens\) OS$/\1 Prod/g' \ - /etc/apache2/conf-available/security.conf +RUN sed -i -e 's/^\(ServerSignature On\)$/#\1/g' -e 's/^#\(ServerSignature Off\)$/\1/g' -e 's/^\(ServerTokens\) OS$/\1 Prod/g' /etc/apache2/conf-available/security.conf RUN apt-get update -y \ && apt-get dist-upgrade -y \ @@ -61,6 +57,7 @@ RUN apt-get update -y \ default-mysql-client \ postgresql-client \ cron \ + rsync \ && apt-get autoremove -y \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ @@ -76,7 +73,8 @@ RUN apt-get update -y \ # Get Dolibarr RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ tar -C /tmp -xz && \ - cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /var/www/html/ && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ ln -s /var/www/html /var/www/htdocs && \ cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ rm -rf /tmp/* && \ @@ -86,6 +84,7 @@ RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar. EXPOSE 80 VOLUME /var/www/documents +VOLUME /var/www/html VOLUME /var/www/html/custom COPY docker-init.php /var/www/scripts/ diff --git a/images/develop/apache-buster/docker-init.php b/images/develop/apache-buster/docker-init.php new file mode 100644 index 0000000..5006905 --- /dev/null +++ b/images/develop/apache-buster/docker-init.php @@ -0,0 +1,49 @@ +#!/usr/bin/env php +fetch(0,$countryCode); + if ($res > 0 ) { + $s = $country->id.':'.$country->code.':'.$country->label; + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_COUNTRY", $s, 'chaine', 0, '', $conf->entity); + printf('Configuring for country : '.$s."\n"); + activateModulesRequiredByCountry($country->code); + } else { + printf('Unable to find country '.$countryCode."\n"); + } +} + +if (!empty(getenv('DOLI_COMPANY_NAME'))) { + $compname = getenv('DOLI_COMPANY_NAME'); + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", $compname, 'chaine', 0, '', $conf->entity); +} + +if (!empty(getenv('DOLI_ENABLE_MODULES'))) { + $mods = explode(',', getenv('DOLI_ENABLE_MODULES')); + foreach ($mods as $mod) { + printf("Activating module ".$mod." ..."); + try { + $res = activateModule('mod' . $mod); + if ($res < 0) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } else { + printf(" OK\n"); + } + } catch (Throwable $t) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } + } +} diff --git a/images/develop/apache-buster/docker-run.sh b/images/develop/apache-buster/docker-run.sh new file mode 100755 index 0000000..fc9ed33 --- /dev/null +++ b/images/develop/apache-buster/docker-run.sh @@ -0,0 +1,340 @@ +#!/bin/bash +# This script is run when the Docker web container is started. +# It is embedded into the Docker image of dolibarr/dolibarr. +# + +# usage: get_env_value VAR [DEFAULT] +# ie: get_env_value 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +function get_env_value() { + local varName="${1}" + local fileVarName="${varName}_FILE" + local defaultValue="${2:-}" + + if [ "${!varName:-}" ] && [ "${!fileVarName:-}" ]; then + echo >&2 "error: both ${varName} and ${fileVarName} are set (but are exclusive)" + exit 1 + fi + + local value="${defaultValue}" + if [ "${!varName:-}" ]; then + value="${!varName}" + elif [ "${!fileVarName:-}" ]; then + value="$(< "${!fileVarName}")" + fi + + echo ${value} + exit 0 +} + +function initDolibarr() +{ + local CURRENT_UID=$(id -u www-data) + local CURRENT_GID=$(id -g www-data) + usermod -u ${WWW_USER_ID} www-data + groupmod -g ${WWW_GROUP_ID} www-data + + if [[ ! -d /var/www/documents ]]; then + echo "[INIT] => create volume directory /var/www/documents ..." + mkdir -p /var/www/documents + fi + + echo "[INIT] => update PHP Config ..." + cat > ${PHP_INI_DIR}/conf.d/dolibarr-php.ini << EOF +date.timezone = ${PHP_INI_DATE_TIMEZONE} +sendmail_path = /usr/sbin/sendmail -t -i +memory_limit = ${PHP_INI_MEMORY_LIMIT} +upload_max_filesize = ${PHP_INI_UPLOAD_MAX_FILESIZE} +post_max_size = ${PHP_INI_POST_MAX_SIZE} +allow_url_fopen = ${PHP_INI_ALLOW_URL_FOPEN} +session.use_strict_mode = 1 +disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,passthru,shell_exec,system,proc_open,popen +EOF + +if [[ ! -f /var/www/html/conf/conf.php ]]; then + echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf + cat > /var/www/html/conf/conf.php << EOF + update Dolibarr Config with instance unique id ..." + echo "\$dolibarr_main_instance_unique_id='${DOLI_INSTANCE_UNIQUE_ID}';" >> /var/www/html/conf/conf.php + fi + if [[ ${DOLI_AUTH} =~ .*ldap.* ]]; then + echo "[INIT] => update Dolibarr Config with LDAP entries ..." + cat >> /var/www/html/conf/conf.php << EOF +\$dolibarr_main_auth_ldap_host='${DOLI_LDAP_HOST}'; +\$dolibarr_main_auth_ldap_port='${DOLI_LDAP_PORT}'; +\$dolibarr_main_auth_ldap_version='${DOLI_LDAP_VERSION}'; +\$dolibarr_main_auth_ldap_servertype='${DOLI_LDAP_SERVER_TYPE}'; +\$dolibarr_main_auth_ldap_login_attribute='${DOLI_LDAP_LOGIN_ATTRIBUTE}'; +\$dolibarr_main_auth_ldap_dn='${DOLI_LDAP_DN}'; +\$dolibarr_main_auth_ldap_filter='${DOLI_LDAP_FILTER}'; +\$dolibarr_main_auth_ldap_admin_login='${DOLI_LDAP_BIND_DN}'; +\$dolibarr_main_auth_ldap_admin_pass='${DOLI_LDAP_BIND_PASS}'; +\$dolibarr_main_auth_ldap_debug='${DOLI_LDAP_DEBUG}'; +EOF + fi + fi + + echo "[INIT] => update ownership for file in Dolibarr Config ..." + chown www-data:www-data /var/www/html/conf/conf.php + if [[ ${DOLI_DB_TYPE} == "pgsql" && ! -f /var/www/documents/install.lock ]]; then + chmod 600 /var/www/html/conf/conf.php + else + chmod 400 /var/www/html/conf/conf.php + fi + + if [[ ${CURRENT_UID} -ne ${WWW_USER_ID} || ${CURRENT_GID} -ne ${WWW_GROUP_ID} ]]; then + # Refresh file ownership cause it has changed + echo "[INIT] => As UID / GID have changed from default, update ownership for files in /var/ww ..." + chown -R www-data:www-data /var/www + else + # Reducing load on init : change ownership only for volumes declared in docker + echo "[INIT] => update ownership for files in /var/www/documents ..." + chown -R www-data:www-data /var/www/documents + fi +} + +function waitForDataBase() +{ + r=1 + + while [[ ${r} -ne 0 ]]; do + mysql -u ${DOLI_DB_USER} --protocol tcp -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} --connect-timeout=5 -e "status" > /dev/null 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + echo "Waiting that SQL database is up ..." + sleep 2 + fi + done +} + +function lockInstallation() +{ + touch /var/www/documents/install.lock + chown www-data:www-data /var/www/documents/install.lock + chmod 400 /var/www/documents/install.lock +} + +function runScripts() +{ + if [ -d /var/www/scripts/$1 ] ; then + for file in /var/www/scripts/$1/*; do + [ ! -f $file ] && continue + + # If extension is not in PHP SQL SH, we loop + isExec=$(echo "PHP SQL SH" | grep -wio ${file##*.}) + [ -z "$isExec" ] && continue + + echo "Importing custom ${isExec} from `basename ${file}` ..." + if [ "$isExec" == "SQL" ] ; then + sed -i 's/--.*//g;' ${file} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${file} > /dev/null 2>&1 + elif [ "$isExec" == "PHP" ] ; then + php $file + elif [ "$isExec" == "SH" ] ; then + /bin/bash $file + fi + done + fi +} + +# Function called to update the htdocs folde with the new code +function updateHtdocs() +{ + echo "Updating htdocs folder..." + rsync -rlD --chown www-data:www-data --delete --exclude custom --exclude conf/conf.php /usr/src/dolibarr/ /var/www/html/ +} + +# Function called to initialize the database (creation of tables and init data) +function initializeDatabase() +{ + for fileSQL in /var/www/html/install/mysql/tables/*.sql; do + if [[ ${fileSQL} != *.key.sql ]]; then + echo "Importing table from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} # remove all comment + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} + fi + done + + for fileSQL in /var/www/html/install/mysql/tables/*.key.sql; do + echo "Importing table key from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/functions/*.sql; do + echo "Importing `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/data/*.sql; do + if [[ $fileSQL =~ llx_accounting_account_ ]]; then + echo "Do not import data from `basename ${fileSQL}` ..." + continue + fi + echo "Importing data from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + echo "Create SuperAdmin account ..." + pass_crypted=`echo -n ${DOLI_ADMIN_PASSWORD} | md5sum | awk '{print $1}'` + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_user (entity, login, pass_crypted, lastname, admin, statut) VALUES (0, '${DOLI_ADMIN_LOGIN}', '${pass_crypted}', 'SuperAdmin', 1, 1);" > /dev/null 2>&1 + + echo "Set some default const ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_NOT_INSTALLED';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_LANG_DEFAULT';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) values('MAIN_VERSION_LAST_INSTALL', '${DOLI_VERSION}', 'chaine', 0, 'Dolibarr version when install', 0);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('MAIN_LANG_DEFAULT', 'auto', 'chaine', 0, 'Default language', 1);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('SYSTEMTOOLS_MYSQLDUMP', '/usr/bin/mysqldump', 'chaine', 0, '', 0);" > /dev/null 2>&1 + + if [[ ${DOLI_INIT_DEMO} -eq 1 ]]; then + mkdir -p /var/www/dev/initdemo/ + > /var/www/documents/vi + versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` + echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." + curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql + for fileSQL in /var/www/dev/initdemo/*.sql; do + echo "Found demo data file, so we first drop table llx_accounting_system ..." + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_account\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_account" >> /var/www/documents/initdemo.log 2>&1 + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_system\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_system" >> /var/www/documents/initdemo.log 2>&1 + echo "Then we load demo data ${fileSQL} ..." + #sed -i 's/--.*//g;' ${fileSQL} + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1 + done + else + echo "DOLI_NIT_DEMO is off. No demo data load to do." + fi + + echo "Enable user module ..." + php /var/www/scripts/docker-init.php + + # Run init scripts + runScripts "docker-init.d" + + # Update ownership after initialisation of modules + chown -R www-data:www-data /var/www/documents +} + +function migrateDatabase() +{ + TARGET_VERSION="$(echo ${DOLI_VERSION} | cut -d. -f1).$(echo ${DOLI_VERSION} | cut -d. -f2).0" + echo "Schema update is required ..." + echo "Dumping Database into /var/www/documents/dump.sql ..." + + mysqldump -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} > /var/www/documents/dump.sql + r=${?} + if [[ ${r} -ne 0 ]]; then + echo "Dump failed ... Aborting migration ..." + return ${r} + fi + echo "Dump done ... Starting Migration ..." + + echo "" > /var/www/documents/migration_error.html + pushd /var/www/htdocs/install > /dev/null + php upgrade.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php upgrade2.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php step5.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 + r=$? + popd > /dev/null + + if [[ ${r} -ne 0 ]]; then + echo "Migration failed ... Restoring DB ... check file /var/www/documents/migration_error.html for more info on error ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < /var/www/documents/dump.sql + echo "DB Restored ..." + return ${r} + else + echo "Migration successful ... Enjoy !!" + fi + + return 0 +} + +function run() +{ + initDolibarr + echo "Current Version is : ${DOLI_VERSION}" + + # If install of mysql database (and not install of cron) is requested + if [[ ${DOLI_INSTALL_AUTO} -eq 1 && ${DOLI_CRON} -ne 1 && ${DOLI_DB_TYPE} != "pgsql" ]]; then + echo "DOLI_INSTALL_AUTO is on, so we check to initialize or upgrade mariadb database" + + # If install.lock does not exists, we launch the initializeDataze + if [[ ! -f /var/www/documents/install.lock ]]; then + waitForDataBase + + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + updateHtdocs + initializeDatabase + else + INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` + echo "Last installed Version is : ${INSTALLED_VERSION}" + if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs + migrateDatabase + else + echo "Schema update is not required ... Enjoy !!" + fi + fi + + if [[ ${DOLI_VERSION} != "develop" ]]; then + lockInstallation + fi + else + echo "File /var/www/documents/install.lock exists so we cancel database init" + fi + fi + + # Run scripts before starting + runScripts "before-starting.d" +} + +DOLI_DB_USER=$(get_env_value 'DOLI_DB_USER' 'doli') +DOLI_DB_PASSWORD=$(get_env_value 'DOLI_DB_PASSWORD' 'doli_pass') +DOLI_ADMIN_LOGIN=$(get_env_value 'DOLI_ADMIN_LOGIN' 'admin') +DOLI_ADMIN_PASSWORD=$(get_env_value 'DOLI_ADMIN_PASSWORD' 'admin') +DOLI_CRON_KEY=$(get_env_value 'DOLI_CRON_KEY' '') +DOLI_CRON_USER=$(get_env_value 'DOLI_CRON_USER' '') +DOLI_INSTANCE_UNIQUE_ID=$(get_env_value 'DOLI_INSTANCE_UNIQUE_ID' '') + +run + +set -e + +if [[ ${DOLI_CRON} -eq 1 ]]; then + echo "PATH=\$PATH:/usr/local/bin" > /etc/cron.d/dolibarr + echo "*/5 * * * * root /bin/su www-data -s /bin/sh -c '/var/www/scripts/cron/cron_run_jobs.php ${DOLI_CRON_KEY} ${DOLI_CRON_USER}' > /proc/1/fd/1 2> /proc/1/fd/2" >> /etc/cron.d/dolibarr + cron -f + exit 0 +fi + +if [ "${1#-}" != "$1" ]; then + set -- apache2-foreground "$@" +fi + +exec "$@" diff --git a/images/develop/docker-run.sh b/images/develop/docker-run.sh deleted file mode 100755 index c2292cc..0000000 --- a/images/develop/docker-run.sh +++ /dev/null @@ -1,330 +0,0 @@ -#!/bin/bash -# This script is run when the Docker web container is started. -# It is embedded into the Docker image of dolibarr/dolibarr. -# - -# usage: get_env_value VAR [DEFAULT] -# ie: get_env_value 'XYZ_DB_PASSWORD' 'example' -# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of -# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) -function get_env_value() { - local varName="${1}" - local fileVarName="${varName}_FILE" - local defaultValue="${2:-}" - - if [ "${!varName:-}" ] && [ "${!fileVarName:-}" ]; then - echo >&2 "error: both ${varName} and ${fileVarName} are set (but are exclusive)" - exit 1 - fi - - local value="${defaultValue}" - if [ "${!varName:-}" ]; then - value="${!varName}" - elif [ "${!fileVarName:-}" ]; then - value="$(< "${!fileVarName}")" - fi - - echo ${value} - exit 0 -} - -function initDolibarr() -{ - local CURRENT_UID=$(id -u www-data) - local CURRENT_GID=$(id -g www-data) - usermod -u ${WWW_USER_ID} www-data - groupmod -g ${WWW_GROUP_ID} www-data - - if [[ ! -d /var/www/documents ]]; then - echo "[INIT] => create volume directory /var/www/documents ..." - mkdir -p /var/www/documents - fi - - echo "[INIT] => update PHP Config ..." - cat > ${PHP_INI_DIR}/conf.d/dolibarr-php.ini << EOF -date.timezone = ${PHP_INI_DATE_TIMEZONE} -sendmail_path = /usr/sbin/sendmail -t -i -memory_limit = ${PHP_INI_MEMORY_LIMIT} -upload_max_filesize = ${PHP_INI_UPLOAD_MAX_FILESIZE} -post_max_size = ${PHP_INI_POST_MAX_SIZE} -allow_url_fopen = ${PHP_INI_ALLOW_URL_FOPEN} -session.use_strict_mode = 1 -disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,passthru,shell_exec,system,proc_open,popen -EOF - -if [[ ! -f /var/www/html/conf/conf.php ]]; then - echo "[INIT] => update Dolibarr Config ..." - cat > /var/www/html/conf/conf.php << EOF - update Dolibarr Config with instance unique id ..." - echo "\$dolibarr_main_instance_unique_id='${DOLI_INSTANCE_UNIQUE_ID}';" >> /var/www/html/conf/conf.php - fi - if [[ ${DOLI_AUTH} =~ .*ldap.* ]]; then - echo "[INIT] => update Dolibarr Config with LDAP entries ..." - cat >> /var/www/html/conf/conf.php << EOF -\$dolibarr_main_auth_ldap_host='${DOLI_LDAP_HOST}'; -\$dolibarr_main_auth_ldap_port='${DOLI_LDAP_PORT}'; -\$dolibarr_main_auth_ldap_version='${DOLI_LDAP_VERSION}'; -\$dolibarr_main_auth_ldap_servertype='${DOLI_LDAP_SERVER_TYPE}'; -\$dolibarr_main_auth_ldap_login_attribute='${DOLI_LDAP_LOGIN_ATTRIBUTE}'; -\$dolibarr_main_auth_ldap_dn='${DOLI_LDAP_DN}'; -\$dolibarr_main_auth_ldap_filter='${DOLI_LDAP_FILTER}'; -\$dolibarr_main_auth_ldap_admin_login='${DOLI_LDAP_BIND_DN}'; -\$dolibarr_main_auth_ldap_admin_pass='${DOLI_LDAP_BIND_PASS}'; -\$dolibarr_main_auth_ldap_debug='${DOLI_LDAP_DEBUG}'; -EOF - fi - fi - - echo "[INIT] => update ownership for file in Dolibarr Config ..." - chown www-data:www-data /var/www/html/conf/conf.php - if [[ ${DOLI_DB_TYPE} == "pgsql" && ! -f /var/www/documents/install.lock ]]; then - chmod 600 /var/www/html/conf/conf.php - else - chmod 400 /var/www/html/conf/conf.php - fi - - if [[ ${CURRENT_UID} -ne ${WWW_USER_ID} || ${CURRENT_GID} -ne ${WWW_GROUP_ID} ]]; then - # Refresh file ownership cause it has changed - echo "[INIT] => As UID / GID have changed from default, update ownership for files in /var/ww ..." - chown -R www-data:www-data /var/www - else - # Reducing load on init : change ownership only for volumes declared in docker - echo "[INIT] => update ownership for files in /var/www/documents ..." - chown -R www-data:www-data /var/www/documents - fi -} - -function waitForDataBase() -{ - r=1 - - while [[ ${r} -ne 0 ]]; do - mysql -u ${DOLI_DB_USER} --protocol tcp -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} --connect-timeout=5 -e "status" > /dev/null 2>&1 - r=$? - if [[ ${r} -ne 0 ]]; then - echo "Waiting that SQL database is up ..." - sleep 2 - fi - done -} - -function lockInstallation() -{ - touch /var/www/documents/install.lock - chown www-data:www-data /var/www/documents/install.lock - chmod 400 /var/www/documents/install.lock -} - -function runScripts() -{ - if [ -d /var/www/scripts/$1 ] ; then - for file in /var/www/scripts/$1/*; do - [ ! -f $file ] && continue - - # If extension is not in PHP SQL SH, we loop - isExec=$(echo "PHP SQL SH" | grep -wio ${file##*.}) - [ -z "$isExec" ] && continue - - echo "Importing custom ${isExec} from `basename ${file}` ..." - if [ "$isExec" == "SQL" ] ; then - sed -i 's/--.*//g;' ${file} - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${file} > /dev/null 2>&1 - elif [ "$isExec" == "PHP" ] ; then - php $file - elif [ "$isExec" == "SH" ] ; then - /bin/bash $file - fi - done - fi -} - -# Function called to initialize the database (creation of tables and init data) -function initializeDatabase() -{ - for fileSQL in /var/www/html/install/mysql/tables/*.sql; do - if [[ ${fileSQL} != *.key.sql ]]; then - echo "Importing table from `basename ${fileSQL}` ..." - sed -i 's/--.*//g;' ${fileSQL} # remove all comment - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} - fi - done - - for fileSQL in /var/www/html/install/mysql/tables/*.key.sql; do - echo "Importing table key from `basename ${fileSQL}` ..." - sed -i 's/--.*//g;' ${fileSQL} - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 - done - - for fileSQL in /var/www/html/install/mysql/functions/*.sql; do - echo "Importing `basename ${fileSQL}` ..." - sed -i 's/--.*//g;' ${fileSQL} - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 - done - - for fileSQL in /var/www/html/install/mysql/data/*.sql; do - if [[ $fileSQL =~ llx_accounting_account_ ]]; then - echo "Do not import data from `basename ${fileSQL}` ..." - continue - fi - echo "Importing data from `basename ${fileSQL}` ..." - sed -i 's/--.*//g;' ${fileSQL} - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 - done - - echo "Create SuperAdmin account ..." - pass_crypted=`echo -n ${DOLI_ADMIN_PASSWORD} | md5sum | awk '{print $1}'` - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_user (entity, login, pass_crypted, lastname, admin, statut) VALUES (0, '${DOLI_ADMIN_LOGIN}', '${pass_crypted}', 'SuperAdmin', 1, 1);" > /dev/null 2>&1 - - echo "Set some default const ..." - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL';" > /dev/null 2>&1 - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_NOT_INSTALLED';" > /dev/null 2>&1 - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_LANG_DEFAULT';" > /dev/null 2>&1 - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) values('MAIN_VERSION_LAST_INSTALL', '${DOLI_VERSION}', 'chaine', 0, 'Dolibarr version when install', 0);" > /dev/null 2>&1 - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('MAIN_LANG_DEFAULT', 'auto', 'chaine', 0, 'Default language', 1);" > /dev/null 2>&1 - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('SYSTEMTOOLS_MYSQLDUMP', '/usr/bin/mysqldump', 'chaine', 0, '', 0);" > /dev/null 2>&1 - - if [[ ${DOLI_INIT_DEMO} -eq 1 ]]; then - mkdir -p /var/www/dev/initdemo/ - > /var/www/documents/vi - versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` - echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." - curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql - for fileSQL in /var/www/dev/initdemo/*.sql; do - echo "Found demo data file, so we first drop table llx_accounting_system ..." - echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_account\" >> /var/www/documents/initdemo.log 2>&1" - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_account" >> /var/www/documents/initdemo.log 2>&1 - echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_system\" >> /var/www/documents/initdemo.log 2>&1" - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_system" >> /var/www/documents/initdemo.log 2>&1 - echo "Then we load demo data ${fileSQL} ..." - #sed -i 's/--.*//g;' ${fileSQL} - echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1" - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1 - done - else - echo "DOLI_NIT_DEMO is off. No demo data load to do." - fi - - echo "Enable user module ..." - php /var/www/scripts/docker-init.php - - # Run init scripts - runScripts "docker-init.d" - - # Update ownership after initialisation of modules - chown -R www-data:www-data /var/www/documents -} - -function migrateDatabase() -{ - TARGET_VERSION="$(echo ${DOLI_VERSION} | cut -d. -f1).$(echo ${DOLI_VERSION} | cut -d. -f2).0" - echo "Schema update is required ..." - echo "Dumping Database into /var/www/documents/dump.sql ..." - - mysqldump -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} > /var/www/documents/dump.sql - r=${?} - if [[ ${r} -ne 0 ]]; then - echo "Dump failed ... Aborting migration ..." - return ${r} - fi - echo "Dump done ... Starting Migration ..." - - echo "" > /var/www/documents/migration_error.html - pushd /var/www/htdocs/install > /dev/null - php upgrade.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ - php upgrade2.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ - php step5.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 - r=$? - popd > /dev/null - - if [[ ${r} -ne 0 ]]; then - echo "Migration failed ... Restoring DB ... check file /var/www/documents/migration_error.html for more info on error ..." - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < /var/www/documents/dump.sql - echo "DB Restored ..." - return ${r} - else - echo "Migration successful ... Enjoy !!" - fi - - return 0 -} - -function run() -{ - initDolibarr - echo "Current Version is : ${DOLI_VERSION}" - - # If install of mysql database (and not install of cron) is requested - if [[ ${DOLI_INSTALL_AUTO} -eq 1 && ${DOLI_CRON} -ne 1 && ${DOLI_DB_TYPE} != "pgsql" ]]; then - echo "DOLI_INSTALL_AUTO is on, so we check to initialize or upgrade mariadb database" - - # If install.lock does not exists, we launch the initializeDataze - if [[ ! -f /var/www/documents/install.lock ]]; then - waitForDataBase - - mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 - r=$? - if [[ ${r} -ne 0 ]]; then - initializeDatabase - else - INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` - echo "Last installed Version is : ${INSTALLED_VERSION}" - if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then - migrateDatabase - else - echo "Schema update is not required ... Enjoy !!" - fi - fi - - if [[ ${DOLI_VERSION} != "develop" ]]; then - lockInstallation - fi - else - echo "File /var/www/documents/install.lock exists so we cancel database init" - fi - fi - - # Run scripts before starting - runScripts "before-starting.d" -} - -DOLI_DB_USER=$(get_env_value 'DOLI_DB_USER' 'doli') -DOLI_DB_PASSWORD=$(get_env_value 'DOLI_DB_PASSWORD' 'doli_pass') -DOLI_ADMIN_LOGIN=$(get_env_value 'DOLI_ADMIN_LOGIN' 'admin') -DOLI_ADMIN_PASSWORD=$(get_env_value 'DOLI_ADMIN_PASSWORD' 'admin') -DOLI_CRON_KEY=$(get_env_value 'DOLI_CRON_KEY' '') -DOLI_CRON_USER=$(get_env_value 'DOLI_CRON_USER' '') -DOLI_INSTANCE_UNIQUE_ID=$(get_env_value 'DOLI_INSTANCE_UNIQUE_ID' '') - -run - -set -e - -if [[ ${DOLI_CRON} -eq 1 ]]; then - echo "PATH=\$PATH:/usr/local/bin" > /etc/cron.d/dolibarr - echo "*/5 * * * * root /bin/su www-data -s /bin/sh -c '/var/www/scripts/cron/cron_run_jobs.php ${DOLI_CRON_KEY} ${DOLI_CRON_USER}' > /proc/1/fd/1 2> /proc/1/fd/2" >> /etc/cron.d/dolibarr - cron -f - exit 0 -fi - -if [ "${1#-}" != "$1" ]; then - set -- apache2-foreground "$@" -fi - -exec "$@" diff --git a/images/develop/fpm/Dockerfile b/images/develop/fpm/Dockerfile new file mode 100644 index 0000000..283433c --- /dev/null +++ b/images/develop/fpm/Dockerfile @@ -0,0 +1,94 @@ +ARG ARCH= + +# Use an image like PHP_BASE_IMAGE=x.y-apache-buster +FROM ${ARCH}php:8.2-fpm + +LABEL maintainer="Garcia MICHEL " + +ENV DOLI_VERSION develop +ENV DOLI_INSTALL_AUTO 1 +ENV DOLI_PROD 1 + +ENV DOLI_DB_TYPE mysqli +ENV DOLI_DB_HOST mysql +ENV DOLI_DB_HOST_PORT 3306 +ENV DOLI_DB_NAME dolidb + +ENV DOLI_URL_ROOT 'http://localhost' +ENV DOLI_NOCSRFCHECK 0 + +ENV DOLI_AUTH dolibarr +ENV DOLI_LDAP_HOST 127.0.0.1 +ENV DOLI_LDAP_PORT 389 +ENV DOLI_LDAP_VERSION 3 +ENV DOLI_LDAP_SERVER_TYPE openldap +ENV DOLI_LDAP_LOGIN_ATTRIBUTE uid +ENV DOLI_LDAP_DN 'ou=users,dc=my-domain,dc=com' +ENV DOLI_LDAP_FILTER '' +ENV DOLI_LDAP_BIND_DN '' +ENV DOLI_LDAP_BIND_PASS '' +ENV DOLI_LDAP_DEBUG false + +ENV DOLI_CRON 0 + +ENV WWW_USER_ID 33 +ENV WWW_GROUP_ID 33 + +ENV PHP_INI_DATE_TIMEZONE 'UTC' +ENV PHP_INI_MEMORY_LIMIT 256M +ENV PHP_INI_UPLOAD_MAX_FILESIZE 2M +ENV PHP_INI_POST_MAX_SIZE 8M +ENV PHP_INI_ALLOW_URL_FOPEN 0 + + + +RUN apt-get update -y \ + && apt-get dist-upgrade -y \ + && apt-get install -y --no-install-recommends \ + libc-client-dev \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libkrb5-dev \ + libldap2-dev \ + libpng-dev \ + libpq-dev \ + libxml2-dev \ + libzip-dev \ + default-mysql-client \ + postgresql-client \ + cron \ + rsync \ + && apt-get autoremove -y \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j$(nproc) calendar intl mysqli pdo_mysql gd soap zip \ + && docker-php-ext-configure pgsql -with-pgsql \ + && docker-php-ext-install pdo_pgsql pgsql \ + && docker-php-ext-configure ldap --with-libdir=lib/$(gcc -dumpmachine)/ \ + && docker-php-ext-install -j$(nproc) ldap \ + && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ + && docker-php-ext-install imap \ + && mv ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini \ + && rm -rf /var/lib/apt/lists/* + +# Get Dolibarr +RUN curl -fLSs https://github.com/Dolibarr/dolibarr/archive/${DOLI_VERSION}.tar.gz |\ + tar -C /tmp -xz && \ + mkdir -p /usr/src/dolibarr && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/htdocs/* /usr/src/dolibarr/ && \ + ln -s /var/www/html /var/www/htdocs && \ + cp -r /tmp/dolibarr-${DOLI_VERSION}/scripts /var/www/ && \ + rm -rf /tmp/* && \ + mkdir -p /var/www/documents && \ + mkdir -p /var/www/html/custom && \ + chown -R www-data:www-data /var/www + +EXPOSE 9000 +VOLUME /var/www/documents +VOLUME /var/www/html +VOLUME /var/www/html/custom + +COPY docker-init.php /var/www/scripts/ +COPY docker-run.sh /usr/local/bin/ +ENTRYPOINT ["docker-run.sh"] + +CMD ["php-fpm"] diff --git a/images/develop/fpm/docker-init.php b/images/develop/fpm/docker-init.php new file mode 100644 index 0000000..5006905 --- /dev/null +++ b/images/develop/fpm/docker-init.php @@ -0,0 +1,49 @@ +#!/usr/bin/env php +fetch(0,$countryCode); + if ($res > 0 ) { + $s = $country->id.':'.$country->code.':'.$country->label; + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_COUNTRY", $s, 'chaine', 0, '', $conf->entity); + printf('Configuring for country : '.$s."\n"); + activateModulesRequiredByCountry($country->code); + } else { + printf('Unable to find country '.$countryCode."\n"); + } +} + +if (!empty(getenv('DOLI_COMPANY_NAME'))) { + $compname = getenv('DOLI_COMPANY_NAME'); + dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", $compname, 'chaine', 0, '', $conf->entity); +} + +if (!empty(getenv('DOLI_ENABLE_MODULES'))) { + $mods = explode(',', getenv('DOLI_ENABLE_MODULES')); + foreach ($mods as $mod) { + printf("Activating module ".$mod." ..."); + try { + $res = activateModule('mod' . $mod); + if ($res < 0) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } else { + printf(" OK\n"); + } + } catch (Throwable $t) { + print(" FAILED. Unable to load module. Be sure to check the case\n"); + } + } +} diff --git a/images/develop/fpm/docker-run.sh b/images/develop/fpm/docker-run.sh new file mode 100755 index 0000000..fc9ed33 --- /dev/null +++ b/images/develop/fpm/docker-run.sh @@ -0,0 +1,340 @@ +#!/bin/bash +# This script is run when the Docker web container is started. +# It is embedded into the Docker image of dolibarr/dolibarr. +# + +# usage: get_env_value VAR [DEFAULT] +# ie: get_env_value 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +function get_env_value() { + local varName="${1}" + local fileVarName="${varName}_FILE" + local defaultValue="${2:-}" + + if [ "${!varName:-}" ] && [ "${!fileVarName:-}" ]; then + echo >&2 "error: both ${varName} and ${fileVarName} are set (but are exclusive)" + exit 1 + fi + + local value="${defaultValue}" + if [ "${!varName:-}" ]; then + value="${!varName}" + elif [ "${!fileVarName:-}" ]; then + value="$(< "${!fileVarName}")" + fi + + echo ${value} + exit 0 +} + +function initDolibarr() +{ + local CURRENT_UID=$(id -u www-data) + local CURRENT_GID=$(id -g www-data) + usermod -u ${WWW_USER_ID} www-data + groupmod -g ${WWW_GROUP_ID} www-data + + if [[ ! -d /var/www/documents ]]; then + echo "[INIT] => create volume directory /var/www/documents ..." + mkdir -p /var/www/documents + fi + + echo "[INIT] => update PHP Config ..." + cat > ${PHP_INI_DIR}/conf.d/dolibarr-php.ini << EOF +date.timezone = ${PHP_INI_DATE_TIMEZONE} +sendmail_path = /usr/sbin/sendmail -t -i +memory_limit = ${PHP_INI_MEMORY_LIMIT} +upload_max_filesize = ${PHP_INI_UPLOAD_MAX_FILESIZE} +post_max_size = ${PHP_INI_POST_MAX_SIZE} +allow_url_fopen = ${PHP_INI_ALLOW_URL_FOPEN} +session.use_strict_mode = 1 +disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,passthru,shell_exec,system,proc_open,popen +EOF + +if [[ ! -f /var/www/html/conf/conf.php ]]; then + echo "[INIT] => update Dolibarr Config ..." + mkdir /var/www/html/conf + cat > /var/www/html/conf/conf.php << EOF + update Dolibarr Config with instance unique id ..." + echo "\$dolibarr_main_instance_unique_id='${DOLI_INSTANCE_UNIQUE_ID}';" >> /var/www/html/conf/conf.php + fi + if [[ ${DOLI_AUTH} =~ .*ldap.* ]]; then + echo "[INIT] => update Dolibarr Config with LDAP entries ..." + cat >> /var/www/html/conf/conf.php << EOF +\$dolibarr_main_auth_ldap_host='${DOLI_LDAP_HOST}'; +\$dolibarr_main_auth_ldap_port='${DOLI_LDAP_PORT}'; +\$dolibarr_main_auth_ldap_version='${DOLI_LDAP_VERSION}'; +\$dolibarr_main_auth_ldap_servertype='${DOLI_LDAP_SERVER_TYPE}'; +\$dolibarr_main_auth_ldap_login_attribute='${DOLI_LDAP_LOGIN_ATTRIBUTE}'; +\$dolibarr_main_auth_ldap_dn='${DOLI_LDAP_DN}'; +\$dolibarr_main_auth_ldap_filter='${DOLI_LDAP_FILTER}'; +\$dolibarr_main_auth_ldap_admin_login='${DOLI_LDAP_BIND_DN}'; +\$dolibarr_main_auth_ldap_admin_pass='${DOLI_LDAP_BIND_PASS}'; +\$dolibarr_main_auth_ldap_debug='${DOLI_LDAP_DEBUG}'; +EOF + fi + fi + + echo "[INIT] => update ownership for file in Dolibarr Config ..." + chown www-data:www-data /var/www/html/conf/conf.php + if [[ ${DOLI_DB_TYPE} == "pgsql" && ! -f /var/www/documents/install.lock ]]; then + chmod 600 /var/www/html/conf/conf.php + else + chmod 400 /var/www/html/conf/conf.php + fi + + if [[ ${CURRENT_UID} -ne ${WWW_USER_ID} || ${CURRENT_GID} -ne ${WWW_GROUP_ID} ]]; then + # Refresh file ownership cause it has changed + echo "[INIT] => As UID / GID have changed from default, update ownership for files in /var/ww ..." + chown -R www-data:www-data /var/www + else + # Reducing load on init : change ownership only for volumes declared in docker + echo "[INIT] => update ownership for files in /var/www/documents ..." + chown -R www-data:www-data /var/www/documents + fi +} + +function waitForDataBase() +{ + r=1 + + while [[ ${r} -ne 0 ]]; do + mysql -u ${DOLI_DB_USER} --protocol tcp -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} --connect-timeout=5 -e "status" > /dev/null 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + echo "Waiting that SQL database is up ..." + sleep 2 + fi + done +} + +function lockInstallation() +{ + touch /var/www/documents/install.lock + chown www-data:www-data /var/www/documents/install.lock + chmod 400 /var/www/documents/install.lock +} + +function runScripts() +{ + if [ -d /var/www/scripts/$1 ] ; then + for file in /var/www/scripts/$1/*; do + [ ! -f $file ] && continue + + # If extension is not in PHP SQL SH, we loop + isExec=$(echo "PHP SQL SH" | grep -wio ${file##*.}) + [ -z "$isExec" ] && continue + + echo "Importing custom ${isExec} from `basename ${file}` ..." + if [ "$isExec" == "SQL" ] ; then + sed -i 's/--.*//g;' ${file} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${file} > /dev/null 2>&1 + elif [ "$isExec" == "PHP" ] ; then + php $file + elif [ "$isExec" == "SH" ] ; then + /bin/bash $file + fi + done + fi +} + +# Function called to update the htdocs folde with the new code +function updateHtdocs() +{ + echo "Updating htdocs folder..." + rsync -rlD --chown www-data:www-data --delete --exclude custom --exclude conf/conf.php /usr/src/dolibarr/ /var/www/html/ +} + +# Function called to initialize the database (creation of tables and init data) +function initializeDatabase() +{ + for fileSQL in /var/www/html/install/mysql/tables/*.sql; do + if [[ ${fileSQL} != *.key.sql ]]; then + echo "Importing table from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} # remove all comment + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} + fi + done + + for fileSQL in /var/www/html/install/mysql/tables/*.key.sql; do + echo "Importing table key from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/functions/*.sql; do + echo "Importing `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + for fileSQL in /var/www/html/install/mysql/data/*.sql; do + if [[ $fileSQL =~ llx_accounting_account_ ]]; then + echo "Do not import data from `basename ${fileSQL}` ..." + continue + fi + echo "Importing data from `basename ${fileSQL}` ..." + sed -i 's/--.*//g;' ${fileSQL} + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} > /dev/null 2>&1 + done + + echo "Create SuperAdmin account ..." + pass_crypted=`echo -n ${DOLI_ADMIN_PASSWORD} | md5sum | awk '{print $1}'` + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_user (entity, login, pass_crypted, lastname, admin, statut) VALUES (0, '${DOLI_ADMIN_LOGIN}', '${pass_crypted}', 'SuperAdmin', 1, 1);" > /dev/null 2>&1 + + echo "Set some default const ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_NOT_INSTALLED';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DELETE FROM llx_const WHERE name='MAIN_LANG_DEFAULT';" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) values('MAIN_VERSION_LAST_INSTALL', '${DOLI_VERSION}', 'chaine', 0, 'Dolibarr version when install', 0);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('MAIN_LANG_DEFAULT', 'auto', 'chaine', 0, 'Default language', 1);" > /dev/null 2>&1 + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "INSERT INTO llx_const(name,value,type,visible,note,entity) VALUES ('SYSTEMTOOLS_MYSQLDUMP', '/usr/bin/mysqldump', 'chaine', 0, '', 0);" > /dev/null 2>&1 + + if [[ ${DOLI_INIT_DEMO} -eq 1 ]]; then + mkdir -p /var/www/dev/initdemo/ + > /var/www/documents/vi + versiondemo=`echo "${DOLI_VERSION}" | sed "s/^\([0-9]*\.[0-9]*\).*/\1.0/"` + echo "Get demo data from file https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql ..." + curl -fLSs -o /var/www/dev/initdemo/initdemo.sql https://raw.githubusercontent.com/Dolibarr/dolibarr/${DOLI_VERSION}/dev/initdemo/mysqldump_dolibarr_$versiondemo.sql + for fileSQL in /var/www/dev/initdemo/*.sql; do + echo "Found demo data file, so we first drop table llx_accounting_system ..." + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_account\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_account" >> /var/www/documents/initdemo.log 2>&1 + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e \"DROP TABLE llx_accounting_system\" >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "DROP TABLE llx_accounting_system" >> /var/www/documents/initdemo.log 2>&1 + echo "Then we load demo data ${fileSQL} ..." + #sed -i 's/--.*//g;' ${fileSQL} + echo "mysql -u ${DOLI_DB_USER} -pxxxxxxx -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1" + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < ${fileSQL} >> /var/www/documents/initdemo.log 2>&1 + done + else + echo "DOLI_NIT_DEMO is off. No demo data load to do." + fi + + echo "Enable user module ..." + php /var/www/scripts/docker-init.php + + # Run init scripts + runScripts "docker-init.d" + + # Update ownership after initialisation of modules + chown -R www-data:www-data /var/www/documents +} + +function migrateDatabase() +{ + TARGET_VERSION="$(echo ${DOLI_VERSION} | cut -d. -f1).$(echo ${DOLI_VERSION} | cut -d. -f2).0" + echo "Schema update is required ..." + echo "Dumping Database into /var/www/documents/dump.sql ..." + + mysqldump -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} > /var/www/documents/dump.sql + r=${?} + if [[ ${r} -ne 0 ]]; then + echo "Dump failed ... Aborting migration ..." + return ${r} + fi + echo "Dump done ... Starting Migration ..." + + echo "" > /var/www/documents/migration_error.html + pushd /var/www/htdocs/install > /dev/null + php upgrade.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php upgrade2.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 && \ + php step5.php ${INSTALLED_VERSION} ${TARGET_VERSION} >> /var/www/documents/migration_error.html 2>&1 + r=$? + popd > /dev/null + + if [[ ${r} -ne 0 ]]; then + echo "Migration failed ... Restoring DB ... check file /var/www/documents/migration_error.html for more info on error ..." + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} < /var/www/documents/dump.sql + echo "DB Restored ..." + return ${r} + else + echo "Migration successful ... Enjoy !!" + fi + + return 0 +} + +function run() +{ + initDolibarr + echo "Current Version is : ${DOLI_VERSION}" + + # If install of mysql database (and not install of cron) is requested + if [[ ${DOLI_INSTALL_AUTO} -eq 1 && ${DOLI_CRON} -ne 1 && ${DOLI_DB_TYPE} != "pgsql" ]]; then + echo "DOLI_INSTALL_AUTO is on, so we check to initialize or upgrade mariadb database" + + # If install.lock does not exists, we launch the initializeDataze + if [[ ! -f /var/www/documents/install.lock ]]; then + waitForDataBase + + mysql -u ${DOLI_DB_USER} -p${DOLI_DB_PASSWORD} -h ${DOLI_DB_HOST} -P ${DOLI_DB_HOST_PORT} ${DOLI_DB_NAME} -e "SELECT Q.LAST_INSTALLED_VERSION FROM (SELECT INET_ATON(CONCAT(value, REPEAT('.0', 3 - CHAR_LENGTH(value) + CHAR_LENGTH(REPLACE(value, '.', ''))))) as VERSION_ATON, value as LAST_INSTALLED_VERSION FROM llx_const WHERE name IN ('MAIN_VERSION_LAST_INSTALL', 'MAIN_VERSION_LAST_UPGRADE') and entity=0) Q ORDER BY VERSION_ATON DESC LIMIT 1" > /tmp/lastinstall.result 2>&1 + r=$? + if [[ ${r} -ne 0 ]]; then + updateHtdocs + initializeDatabase + else + INSTALLED_VERSION=`grep -v LAST_INSTALLED_VERSION /tmp/lastinstall.result` + echo "Last installed Version is : ${INSTALLED_VERSION}" + if [[ "$(echo ${INSTALLED_VERSION} | cut -d. -f1)" -lt "$(echo ${DOLI_VERSION} | cut -d. -f1)" ]]; then + updateHtdocs + migrateDatabase + else + echo "Schema update is not required ... Enjoy !!" + fi + fi + + if [[ ${DOLI_VERSION} != "develop" ]]; then + lockInstallation + fi + else + echo "File /var/www/documents/install.lock exists so we cancel database init" + fi + fi + + # Run scripts before starting + runScripts "before-starting.d" +} + +DOLI_DB_USER=$(get_env_value 'DOLI_DB_USER' 'doli') +DOLI_DB_PASSWORD=$(get_env_value 'DOLI_DB_PASSWORD' 'doli_pass') +DOLI_ADMIN_LOGIN=$(get_env_value 'DOLI_ADMIN_LOGIN' 'admin') +DOLI_ADMIN_PASSWORD=$(get_env_value 'DOLI_ADMIN_PASSWORD' 'admin') +DOLI_CRON_KEY=$(get_env_value 'DOLI_CRON_KEY' '') +DOLI_CRON_USER=$(get_env_value 'DOLI_CRON_USER' '') +DOLI_INSTANCE_UNIQUE_ID=$(get_env_value 'DOLI_INSTANCE_UNIQUE_ID' '') + +run + +set -e + +if [[ ${DOLI_CRON} -eq 1 ]]; then + echo "PATH=\$PATH:/usr/local/bin" > /etc/cron.d/dolibarr + echo "*/5 * * * * root /bin/su www-data -s /bin/sh -c '/var/www/scripts/cron/cron_run_jobs.php ${DOLI_CRON_KEY} ${DOLI_CRON_USER}' > /proc/1/fd/1 2> /proc/1/fd/2" >> /etc/cron.d/dolibarr + cron -f + exit 0 +fi + +if [ "${1#-}" != "$1" ]; then + set -- apache2-foreground "$@" +fi + +exec "$@"