Latest zammad compatibility

This commit is contained in:
Darren Clarke 2026-02-13 21:04:36 +01:00
parent 99b92fe4ce
commit 40c14ece94
13 changed files with 157 additions and 121 deletions

View file

@ -1,103 +1,140 @@
ARG ZAMMAD_VERSION=6.5.2
# Build Zammad with CDR Link addon
# Based on Zammad's upstream Dockerfile with addon injection steps.
# Zammad source is expected at .aidocs/zammad/ relative to the repo root.
FROM node:22-slim AS node
ARG RUBY_VERSION=3.4.8
ARG NODE_VERSION=22
FROM zammad/zammad-docker-compose:${ZAMMAD_VERSION} AS builder
USER root
# --- Base stage: runtime dependencies ---
FROM docker.io/library/ruby:$RUBY_VERSION-slim-trixie AS base
# Copy Node.js from node image
COPY --from=node /opt /opt
WORKDIR /opt/zammad
ENV RAILS_ENV="production" \
BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="test development" \
RAILS_LOG_TO_STDOUT="true"
RUN apt-get update -qq && \
apt-get install -y postgresql-common && \
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \
apt-get install --no-install-recommends -y curl libimlib2 libpq5 nginx gnupg postgresql-client-17 && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# --- Node binary ---
FROM node:${NODE_VERSION}-trixie-slim AS node
RUN npm -g install corepack && corepack enable pnpm && \
rm /usr/local/bin/yarn /usr/local/bin/yarnpkg
# --- Build stage ---
FROM base AS build
SHELL ["/bin/bash", "-o", "errexit", "-o", "pipefail", "-c"]
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential git libimlib2-dev libpq-dev libyaml-dev && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# Install Ruby gems
COPY .aidocs/zammad/Gemfile .aidocs/zammad/Gemfile.lock ./
COPY .aidocs/zammad/vendor/ vendor/
RUN bundle install && \
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git
# Install Node.js
COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules
COPY --from=node /usr/local/bin /usr/local/bin
COPY --from=node /usr/local/lib /usr/local/lib
COPY --from=node /usr/lib /usr/lib
SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]
# Install pnpm for package management
RUN npm install -g pnpm
RUN pnpm --version
ENV ZAMMAD_DIR=/opt/zammad
WORKDIR ${ZAMMAD_DIR}
# Copy addons and installation scripts
RUN mkdir -p /opt/zammad/contrib/link/addons
COPY addons contrib/link/addons
COPY setup.rb contrib/link/setup.rb
COPY install.rb contrib/link/install.rb
# Install system dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
git \
&& rm -rf /var/lib/apt/lists/*
# Install Ruby gems (they should already be installed in the base image)
RUN bundle check || bundle install --jobs 8
# Install Node packages
# Install node modules
COPY .aidocs/zammad/package.json .aidocs/zammad/pnpm-lock.yaml ./
COPY .aidocs/zammad/.eslint-plugin-zammad/ .eslint-plugin-zammad/
RUN pnpm install --frozen-lockfile
# CRITICAL: Install addons
# This extracts addon files including CoffeeScript, Vue components, TypeScript, and CSS
# Copy Zammad source
COPY .aidocs/zammad/ .
# --- CDR Link Addon ---
RUN mkdir -p contrib/link/addons
COPY docker/zammad/addons/ contrib/link/addons/
COPY docker/zammad/setup.rb contrib/link/setup.rb
COPY docker/zammad/install.rb contrib/link/install.rb
RUN ruby contrib/link/install.rb
# Rebuild Vite frontend to include addon Vue components
# The base image has pre-built Vite assets, but addon Vue files need to be compiled
RUN RAILS_ENV=production bundle exec vite build --clobber
# OpenSearch compatibility: 'flattened' -> 'flat_object'
RUN sed -i "s/'flattened'/'flat_object'/g" lib/search_index_backend.rb
# Fix OpenSearch compatibility: Replace 'flattened' with 'flat_object'
# Elasticsearch uses 'flattened' but OpenSearch uses 'flat_object'
# Without this fix, search index creation fails with:
# [o.o.c.m.MetadataCreateIndexService] failed on parsing mappings on index creation
# org.opensearch.index.mapper.MapperParsingException: Failed to parse mapping [_doc]:
# No handler for type [flattened] declared on field [preferences]
# See: https://github.com/zammad/zammad/blob/bfd2f5befc3aec3fe607a5b6146788ec9af461e4/lib/search_index_backend.rb#L896
RUN sed -i "s/'flattened'/'flat_object'/g" /opt/zammad/lib/search_index_backend.rb
# Build version info
ARG COMMIT_SHA=""
RUN COMMIT_SHA="${COMMIT_SHA:-$(git rev-parse HEAD 2>/dev/null || echo unknown)}"; \
COMMIT_SHA_SHORT=$(echo "${COMMIT_SHA}" | cut -c 1-8); \
echo "$(tr -d '\n' < VERSION)-${COMMIT_SHA_SHORT}.docker" > VERSION; \
cat VERSION
# Precompile assets with addon CoffeeScript files included
# Use ZAMMAD_SAFE_MODE=1 and dummy DATABASE_URL to avoid needing real database
# Precompile all assets (Vite + Sprockets, including addon Vue/CoffeeScript)
RUN touch db/schema.rb && \
ZAMMAD_SAFE_MODE=1 DATABASE_URL=postgresql://zammad:/zammad bundle exec rake assets:precompile
# Clean up build artifacts
RUN rm -rf tmp/cache node_modules/.cache
ARG EMBEDDED=false
ARG LINK_HOST=http://link:3000
# Add nginx proxy configuration for embedded mode
# Insert location block before the final closing brace
RUN if [ "$EMBEDDED" = "true" ] ; then \
sed -i '$ d' /opt/zammad/contrib/nginx/zammad.conf && \
echo "" >> /opt/zammad/contrib/nginx/zammad.conf && \
echo " location /link {" >> /opt/zammad/contrib/nginx/zammad.conf && \
echo " set \$link_url ${LINK_HOST}; proxy_pass \$link_url;" >> /opt/zammad/contrib/nginx/zammad.conf && \
echo " proxy_set_header Host \$host;" >> /opt/zammad/contrib/nginx/zammad.conf && \
echo " proxy_set_header X-Real-IP \$remote_addr;" >> /opt/zammad/contrib/nginx/zammad.conf && \
echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;" >> /opt/zammad/contrib/nginx/zammad.conf && \
echo " proxy_set_header X-Forwarded-Proto https;" >> /opt/zammad/contrib/nginx/zammad.conf && \
echo " }" >> /opt/zammad/contrib/nginx/zammad.conf && \
echo "}" >> /opt/zammad/contrib/nginx/zammad.conf; \
fi
RUN script/build/cleanup.sh
# Precompile bootsnap for faster boot times
RUN bundle exec bootsnap precompile --gemfile app/ lib/
# Modify entrypoint to install packages and run migrations at runtime
# Inject addon registration into the entrypoint (runs during zammad-init)
RUN sed -i '/^[[:space:]]*# es config/a\
echo "Installing addon packages..."\n\
bundle exec rails runner /opt/zammad/contrib/link/setup.rb\n\
bundle exec rake zammad:package:migrate\n\
' /docker-entrypoint.sh
' bin/docker-entrypoint
FROM zammad/zammad-docker-compose:${ZAMMAD_VERSION} AS runner
USER root
# Nginx embedded mode: add /link proxy location
ARG EMBEDDED=false
ARG LINK_HOST=http://link:3000
RUN if [ "$EMBEDDED" = "true" ] ; then \
sed -i '$ d' contrib/nginx/zammad.conf && \
echo "" >> contrib/nginx/zammad.conf && \
echo " location /link {" >> contrib/nginx/zammad.conf && \
echo " set \$link_url ${LINK_HOST}; proxy_pass \$link_url;" >> contrib/nginx/zammad.conf && \
echo " proxy_set_header Host \$host;" >> contrib/nginx/zammad.conf && \
echo " proxy_set_header X-Real-IP \$remote_addr;" >> contrib/nginx/zammad.conf && \
echo " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;" >> contrib/nginx/zammad.conf && \
echo " proxy_set_header X-Forwarded-Proto https;" >> contrib/nginx/zammad.conf && \
echo " }" >> contrib/nginx/zammad.conf && \
echo "}" >> contrib/nginx/zammad.conf; \
fi
# Install Node.js and npm in runner for asset compilation at runtime
# Using Node from Debian repository for simplicity
RUN apt-get update && \
apt-get install -y --no-install-recommends nodejs npm && \
rm -rf /var/lib/apt/lists/* && \
npm install -g pnpm
# --- Final stage ---
FROM base
USER zammad
COPY --from=builder --chown=zammad:zammad ${ZAMMAD_DIR} ${ZAMMAD_DIR}
COPY --from=builder /usr/local/bundle /usr/local/bundle
COPY --from=builder /docker-entrypoint.sh /docker-entrypoint.sh
RUN apt-get update -qq && \
apt-get upgrade -y && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
ENV POSTGRESQL_DB=zammad_production \
POSTGRESQL_HOST=postgresql \
POSTGRESQL_PORT=5432 \
POSTGRESQL_USER=zammad \
POSTGRESQL_PASS=zammad \
POSTGRESQL_OPTIONS=?pool=50 \
RAILS_TRUSTED_PROXIES=127.0.0.1,::1
RUN groupadd --system --gid 1000 zammad && \
useradd --create-home --home /opt/zammad --shell /bin/bash --uid 1000 --gid 1000 zammad
RUN sed -i -e "s#user www-data;##g" \
-e 's#/var/log/nginx/\(access\|error\).log#/dev/stdout#g' \
-e 's#pid /run/nginx.pid;#pid /tmp/nginx.pid;#g' /etc/nginx/nginx.conf && \
mkdir -p /opt/zammad /var/log/nginx
RUN mkdir -p "/opt/zammad/storage" "/opt/zammad/tmp" && \
chown -R 1000:1000 /etc/nginx /var/lib/nginx /var/log/nginx /opt/zammad
COPY --chown=1000:1000 --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --chown=1000:1000 --from=build /opt/zammad /opt/zammad
# Backwards compatibility
RUN ln -s "/opt/zammad/bin/docker-entrypoint" /docker-entrypoint.sh
USER 1000:1000
ENTRYPOINT ["/opt/zammad/bin/docker-entrypoint"]
LABEL io.portainer.commands.rails-console="bundle exec rails c"