Zammad-init can't find mysql2.so when it exists where it is looking for it

Infos:

  • Used Zammad version: stable
  • Used Zammad installation source: (source, package, …)
    source: zammad/zammad-docker-compose:master
  • Operating system: Docker 18.06.1-ce (Ubuntu 18.04 host, docker-compose 1.15.0)
  • Browser + version: n/a

I made very minor changes that should allow Zammad to use an external MySQL (MariaDB) database, which I will detail below. I was hoping to submit them for inclusion in the repository if they worked. Essentially, it boils down to setting the database adapter=mysql2 and installing the mysql Gem group rather than postgres during the build process. After that everything happens in docker-compose by dropping postgres-related containers and tweaking the environment.

Expected behavior:

  • zammad-init container should install the database on the MariaDB server

Actual behavior:

  • I get two load errors from the zammad-init container during init, and the database does not install:

    LoadError: Error loading the 'mysql2' Active Record adapter. Missing a gem it depends on? libmariadb.so.3: cannot open shared object file: No such file or directory - /usr/local/bundle/gems/mysql2-0.4.10/lib/mysql2/mysql2.so
    

    followed by:

    Caused by:
    LoadError: libmariadb.so.3: cannot open shared object file: No such file or directory - /usr/local/bundle/gems/mysql2-0.4.10/lib/mysql2/mysql2.so
    
  • The indicated file is present and accessible when I run ls -l in the container:

    $ docker-compose exec zammad-init ls -l /usr/local/bundle/gems/mysql2-0.4.10/lib/mysql2/mysql2.so
    -rwxr-xr-x 1 root root 280856 Feb 18 16:53 /usr/local/bundle/gems/mysql2-0.4.10/lib/mysql2/mysql2.so
    

Steps to reproduce the behavior:

  • Here is the diff of my changes to the zammad containers. I also made changes to the .env and docker-compose.* files, but those changes simply configure the options made accessible by the changes below. Building the container must use the --build-arg SQL_ADAPTER=mysql2 argument to build for MySQL. Note that I installed the libmariadb-dev and libmariadbclient-dev packages so that the mysql2 gem would install:
diff --git a/containers/zammad/Dockerfile b/containers/zammad/Dockerfile
index 64d1e7e..a2cea9c 100644
--- a/containers/zammad/Dockerfile
+++ b/containers/zammad/Dockerfile
@@ -5,6 +5,7 @@ FROM ruby:2.5.5-slim AS builder
 MAINTAINER Zammad <info@zammad.org>
 ARG BUILD_DATE
 ARG DEBIAN_FRONTEND=noninteractive
+ARG SQL_ADAPTER=postgres

 ENV GIT_BRANCH stable
 ENV GIT_URL ${PROJECT_URL}.git
diff --git a/containers/zammad/docker-entrypoint.sh b/containers/zammad/docker-entrypoint.sh
index b37344f..4b594e1 100755
--- a/containers/zammad/docker-entrypoint.sh
+++ b/containers/zammad/docker-entrypoint.sh
@@ -9,12 +9,13 @@ set -e
 : "${ELASTICSEARCH_SSL_VERIFY:=true}"
 : "${MEMCACHED_HOST:=zammad-memcached}"
 : "${MEMCACHED_PORT:=11211}"
-: "${POSTGRESQL_HOST:=zammad-postgresql}"
-: "${POSTGRESQL_PORT:=5432}"
-: "${POSTGRESQL_USER:=postgres}"
-: "${POSTGRESQL_PASS:=}"
-: "${POSTGRESQL_DB:=zammad_production}"
-: "${POSTGRESQL_DB_CREATE:=true}"
+: "${SQL_ADAPTER:=}"
+: "${SQL_HOST:=zammad-postgresql}"
+: "${SQL_PORT:=5432}"
+: "${SQL_USER:=postgres}"
+: "${SQL_PASS:=}"
+: "${SQL_DB:=zammad_production}"
+: "${SQL_DB_CREATE:=true}"
 : "${ZAMMAD_RAILSSERVER_HOST:=zammad-railsserver}"
 : "${ZAMMAD_RAILSSERVER_PORT:=3000}"
 : "${ZAMMAD_WEBSOCKET_HOST:=zammad-websocket}"
@@ -36,7 +37,7 @@ if [ "$1" = 'zammad-init' ]; then
   rsync -a --delete --exclude 'public/assets/images/*' --exclude 'storage/fs/*' "${ZAMMAD_TMP_DIR}/" "${ZAMMAD_DIR}"
   rsync -a "${ZAMMAD_TMP_DIR}"/public/assets/images/ "${ZAMMAD_DIR}"/public/assets/images

-  until (echo > /dev/tcp/"${POSTGRESQL_HOST}"/"${POSTGRESQL_PORT}") &> /dev/null; do
+  until (echo > /dev/tcp/"${SQL_HOST}"/"${SQL_PORT}") &> /dev/null; do
     echo "zammad railsserver waiting for postgresql server to be ready..."
     sleep 5
   done
@@ -44,7 +45,7 @@ if [ "$1" = 'zammad-init' ]; then
   cd "${ZAMMAD_DIR}"

   # configure database
-  sed -e "s#.*adapter:.*#  adapter: postgresql#g" -e "s#.*database:.*#  database: ${POSTGRESQL_DB}#g" -e "s#.*username:.*#  username: ${POSTGRESQL_USER}#g" -e "s#.*password:.*#  password: ${POSTGRESQL_PASS}\\n  host: ${POSTGRESQL_HOST}\\n  port: ${POSTGRESQL_PORT}#g" < contrib/packager.io/database.yml.pkgr > config/database.yml
+  sed -e "s#.*adapter:.*#  adapter: ${SQL_ADAPTER}#g" -e "s#.*database:.*#  database: ${SQL_DB}#g" -e "s#.*username:.*#  username: ${SQL_USER}#g" -e "s#.*password:.*#  password: ${SQL_PASS}\\n  host: ${SQL_HOST}\\n  port: ${SQL_PORT}#g" < contrib/packager.io/database.yml.pkgr > config/database.yml

   # configure memcache
   sed -i -e "s/.*config.cache_store.*file_store.*cache_file_store.*/    config.cache_store = :dalli_store, '${MEMCACHED_HOST}:${MEMCACHED_PORT}'\\n    config.session_store = :dalli_store, '${MEMCACHED_HOST}:${MEMCACHED_PORT}'/" config/application.rb
@@ -64,7 +65,7 @@ if [ "$1" = 'zammad-init' ]; then
   set -e

   # create database if not exists
-  if [ "${DB_MIGRATE}" != "0" ] && [ "${POSTGRESQL_DB_CREATE}" == "true" ]; then
+  if [ "${DB_MIGRATE}" != "0" ] && [ "${SQL_DB_CREATE}" == "true" ]; then
       echo "creating database..."
       bundle exec rake db:create
   fi
diff --git a/containers/zammad/setup.sh b/containers/zammad/setup.sh
index ee1f939..7813f7c 100644
--- a/containers/zammad/setup.sh
+++ b/containers/zammad/setup.sh
@@ -1,11 +1,21 @@
  # install dependencies
 if [ "$1" = 'install' ]; then
   PACKAGES="build-essential curl git libimlib2-dev libpq-dev"
+  if [ "${SQL_ADAPTER}" = 'mysql2' ]; then
+    PACKAGES="${PACKAGES} libmariadb-dev libmariadbclient-dev"
+  fi
 elif [ "$1" = 'run' ]; then
   PACKAGES="curl libimlib2 libimlib2-dev libpq5 nginx rsync"
 fi

 apt-get update
@@ -30,7 +40,11 @@ if [ "$1" = 'install' ]; then
   tar -xzf zammad-"${GIT_BRANCH}".tar.gz
   rm zammad-"${GIT_BRANCH}".tar.gz
   cd "${ZAMMAD_TMP_DIR}"
-  bundle install --without test development mysql
+  if [ "${SQL_ADAPTER}" = 'mysql2' ]; then
+    bundle install --without test development postgres
+  else
+    bundle install --without test development mysql
+  fi
   contrib/packager.io/fetch_locales.rb
   sed -e 's#.*adapter: postgresql#  adapter: nulldb#g' -e 's#.*username:.*#  username: postgres#g' -e 's#.*password:.*#  password: \n  host: zammad-postgresql\n#g' < contrib/packager.io/database.yml.pkgr > config/database.yml
   sed -i "/require 'rails\/all'/a require\ 'nulldb'" config/application.rb

I doubt mysql2.so lives in the container, as the docker-compose is built to run with postgresql - it wouldn’t make any sense to have mysql packages inside it, it would just require more space.

It did live in the container as indicated by the output of ls in my original post. I did finally figure out what the problem was, however.

When I changed the packages the system installed, I only added the mariadb libraries during the setup.sh install step. That step runs under the build container setup of the dockerfile. The production container also uses the same file with the run option: setup.sh run. Once I added the mariadb library under that step, the container created the database without a hitch.

From what I understand, this was a library issue. I’m not familiar with dynamic/static libraries, so my best guess is that the error message was misleading.

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.