ARG ZAMMAD_VERSION=6.5.2 FROM node:22-slim AS node FROM zammad/zammad-docker-compose:${ZAMMAD_VERSION} AS builder USER root # Copy Node.js from node image COPY --from=node /opt /opt 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 RUN pnpm install --frozen-lockfile # CRITICAL: Install addons BEFORE asset compilation # This extracts addon files including Vue components, TypeScript, and CSS RUN ruby contrib/link/install.rb # Recompile assets with our addon components # The base image has assets precompiled, but we need to recompile with our additions # SKIP asset compilation during build - it will happen at runtime via entrypoint # This is because asset compilation requires Redis which isn't available during build # RUN bundle exec rake assets:precompile RAILS_SKIP_ASSET_COMPILATION=false || echo "Skipped" # Run additional setup for addons RUN bundle exec rails runner /opt/zammad/contrib/link/setup.rb || true # 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 " proxy_pass ${LINK_HOST};" >> /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 sed -i '/^[[:space:]]*# es config/a\ echo "about to reinstall..."\n\ bundle exec rails runner /opt/zammad/contrib/link/setup.rb\n\ bundle exec rake zammad:package:migrate\n\ echo "Recompiling assets with addon CoffeeScript files..."\n\ bundle exec rake assets:precompile RAILS_SKIP_ASSET_COMPILATION=false\n\ echo "Asset recompilation complete"\n\ ' /docker-entrypoint.sh FROM zammad/zammad-docker-compose:${ZAMMAD_VERSION} AS runner USER root # 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 # Copy only the modified/added files from builder # Copy addon files that were installed COPY --from=builder --chown=zammad:zammad /opt/zammad/app/frontend/apps/desktop/pages/ticket/components/TicketDetailView/ /opt/zammad/app/frontend/apps/desktop/pages/ticket/components/TicketDetailView/ COPY --from=builder --chown=zammad:zammad /opt/zammad/app/frontend/shared/entities/ticket-article/action/plugins/ /opt/zammad/app/frontend/shared/entities/ticket-article/action/plugins/ COPY --from=builder --chown=zammad:zammad /opt/zammad/db/addon/ /opt/zammad/db/addon/ COPY --from=builder --chown=zammad:zammad /opt/zammad/app/assets/ /opt/zammad/app/assets/ COPY --from=builder --chown=zammad:zammad /opt/zammad/app/controllers/*cdr* /opt/zammad/app/controllers/ COPY --from=builder --chown=zammad:zammad /opt/zammad/app/jobs/*cdr* /opt/zammad/app/jobs/ COPY --from=builder --chown=zammad:zammad /opt/zammad/app/models/channel/driver/*cdr* /opt/zammad/app/models/channel/driver/ COPY --from=builder --chown=zammad:zammad /opt/zammad/app/models/ticket/article/*cdr* /opt/zammad/app/models/ticket/article/ COPY --from=builder --chown=zammad:zammad /opt/zammad/app/policies/controllers/*cdr* /opt/zammad/app/policies/controllers/ COPY --from=builder --chown=zammad:zammad /opt/zammad/config/initializers/*cdr* /opt/zammad/config/initializers/ COPY --from=builder --chown=zammad:zammad /opt/zammad/config/routes/*cdr* /opt/zammad/config/routes/ COPY --from=builder --chown=zammad:zammad /opt/zammad/lib/cdr* /opt/zammad/lib/ COPY --from=builder --chown=zammad:zammad /opt/zammad/public/assets/images/icons/*cdr* /opt/zammad/public/assets/images/icons/ COPY --from=builder --chown=zammad:zammad /opt/zammad/app/views/mailer/ticket_create/ /opt/zammad/app/views/mailer/ticket_create/ COPY --from=builder --chown=zammad:zammad /opt/zammad/public/assets/images/logo* /opt/zammad/public/assets/images/ # Copy the nginx config if embedded mode was used COPY --from=builder --chown=zammad:zammad /opt/zammad/contrib/nginx/zammad.conf /opt/zammad/contrib/nginx/zammad.conf # Copy the link setup scripts and addons COPY --from=builder --chown=zammad:zammad /opt/zammad/contrib/link/ /opt/zammad/contrib/link/ # CRITICAL: Copy compiled assets that include our CoffeeScript changes # The builder stage compiles assets at line 47, we must copy them to runner COPY --from=builder --chown=zammad:zammad /opt/zammad/public/assets/ /opt/zammad/public/assets/ # Copy the modified entrypoint script COPY --from=builder /docker-entrypoint.sh /docker-entrypoint.sh USER zammad