mirror of
https://github.com/ether/etherpad-lite.git
synced 2026-07-17 16:47:05 +00:00
* feat!: replace Abiword with LibreOffice and add DOCX export (#4805)
The Abiword converter is dropped. Abiword's DOCX export is weak and the
project is niche on modern platforms; LibreOffice (soffice) is the
common deployment path and now serves as the sole converter backend.
DOCX is added as an export format and becomes the new target for the
"Microsoft Word" UI button. The /export/doc URL still works for legacy
API consumers.
BREAKING CHANGE: The 'abiword' setting, the INSTALL_ABIWORD Dockerfile
build arg, the abiwordAvailable clientVar, and the
#importmessageabiword UI element (with locale key
pad.importExport.abiword.innerHTML) are removed. Deployments relying on
Abiword must configure 'soffice' instead.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: add docxExport feature flag and abiword deprecation WARN
- Add `docxExport: true` setting to opt out of DOCX (use legacy DOC)
- Pass `docxExport` to client via clientVars
- Use `docxExport` flag in pad_impexp.ts for Word button format
- Emit a specific WARN when deprecated `abiword` config is detected
- Update settings.json.template and settings.json.docker with docxExport
- Add docxExport to ClientVarPayload type in SocketIOMessage.ts
Agent-Logs-Url: https://github.com/ether/etherpad/sessions/9afc5291-73b2-4b66-b028-feed39e7056f
Co-authored-by: JohnMcLear <220864+JohnMcLear@users.noreply.github.com>
* refactor: extract wordFormat variable and improve docxExport comment
Agent-Logs-Url: https://github.com/ether/etherpad/sessions/9afc5291-73b2-4b66-b028-feed39e7056f
Co-authored-by: JohnMcLear <220864+JohnMcLear@users.noreply.github.com>
* fix: restore import-limitation message when no converter is configured
The abiword removal dropped both the #importmessageabiword DOM element
and its locale key, but Copilot's refactor still expected the show()
call to surface a message when exportAvailable === 'no'. Result: users
with no soffice binary got silent failure instead of an explanation.
Add #importmessagenoconverter back with updated, LibreOffice-focused
copy (new locale key pad.importExport.noConverter.innerHTML) and flip
the hidden prop when the client knows no converter is available.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* i18n: inline English fallback for noConverter import message
The original abiword message existed in ~70 locale files and was
removed from all of them by this PR. The replacement key was only
added to en.json, so non-English users had an empty div until
translators localize. Follow the project's usual pad.html pattern
(e.g. line 146's "Font type:") and include the English text inside
the div as the fallback content; html10n replaces it when a
translation is available.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Revert "i18n: inline English fallback for noConverter import message"
This reverts commit f336f24d. Follow the project convention: add the
new locale key to en.json only and let translations catch up via the
translation system, rather than putting inline fallback in the template.
* i18n: leave non-English locale files untouched
The PR had removed pad.importExport.abiword.innerHTML from ~82 locale
files alongside its removal from en.json. The replacement message uses
a new key (pad.importExport.noConverter.innerHTML) in en.json only, so
churning every localisation file for a key that is no longer referenced
produces useless translation diffs. Restore every non-en locale file to
its pre-PR state.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JohnMcLear <220864+JohnMcLear@users.noreply.github.com>
197 lines
6.2 KiB
Docker
197 lines
6.2 KiB
Docker
# Etherpad Lite Dockerfile
|
|
#
|
|
# https://github.com/ether/etherpad-lite
|
|
#
|
|
# Author: muxator
|
|
# Set to "copy" for builds without git metadata (source tarballs, some CI):
|
|
# docker build --build-arg BUILD_ENV=copy .
|
|
ARG BUILD_ENV=git
|
|
|
|
ARG PnpmVersion=10.28.2
|
|
|
|
FROM node:lts-alpine AS adminbuild
|
|
RUN npm install -g pnpm@${PnpmVersion}
|
|
WORKDIR /opt/etherpad-lite
|
|
COPY . .
|
|
RUN pnpm install
|
|
RUN pnpm run build:ui
|
|
|
|
|
|
FROM node:lts-alpine AS build
|
|
LABEL maintainer="Etherpad team, https://github.com/ether/etherpad-lite"
|
|
|
|
# Set these arguments when building the image from behind a proxy
|
|
ARG http_proxy=
|
|
ARG https_proxy=
|
|
ARG no_proxy=
|
|
|
|
ARG TIMEZONE=
|
|
|
|
RUN \
|
|
[ -z "${TIMEZONE}" ] || { \
|
|
apk add --no-cache tzdata && \
|
|
cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && \
|
|
echo "${TIMEZONE}" > /etc/timezone; \
|
|
}
|
|
ENV TIMEZONE=${TIMEZONE}
|
|
|
|
# Control the configuration file to be copied into the container.
|
|
ARG SETTINGS=./settings.json.docker
|
|
|
|
# plugins to install while building the container. By default no plugins are
|
|
# installed.
|
|
# If given a value, it has to be a space-separated, quoted list of plugin names.
|
|
#
|
|
# EXAMPLE:
|
|
# ETHERPAD_PLUGINS="ep_codepad ep_author_neat"
|
|
ARG ETHERPAD_PLUGINS=
|
|
|
|
# local plugins to install while building the container. By default no plugins are
|
|
# installed.
|
|
# If given a value, it has to be a space-separated, quoted list of plugin names.
|
|
#
|
|
# EXAMPLE:
|
|
# ETHERPAD_LOCAL_PLUGINS="../ep_my_plugin ../ep_another_plugin"
|
|
ARG ETHERPAD_LOCAL_PLUGINS=
|
|
|
|
# github plugins to install while building the container. By default no plugins are
|
|
# installed.
|
|
# If given a value, it has to be a space-separated, quoted list of plugin names.
|
|
#
|
|
# EXAMPLE:
|
|
# ETHERPAD_GITHUB_PLUGINS="ether/ep_plugin"
|
|
ARG ETHERPAD_GITHUB_PLUGINS=
|
|
|
|
# Control whether libreoffice will be installed, enabling exports to DOC/DOCX/PDF/ODT formats.
|
|
# By default, it is not installed.
|
|
# If given any value, libreoffice will be installed.
|
|
#
|
|
# EXAMPLE:
|
|
# INSTALL_LIBREOFFICE=true
|
|
ARG INSTALL_SOFFICE=
|
|
|
|
# Install dependencies required for modifying access.
|
|
RUN apk add --no-cache shadow bash
|
|
# Follow the principle of least privilege: run as unprivileged user.
|
|
#
|
|
# Running as non-root enables running this image in platforms like OpenShift
|
|
# that do not allow images running as root.
|
|
#
|
|
# If any of the following args are set to the empty string, default
|
|
# values will be chosen.
|
|
ARG EP_HOME=
|
|
ARG EP_UID=5001
|
|
ARG EP_GID=0
|
|
ARG EP_SHELL=
|
|
|
|
RUN groupadd --system ${EP_GID:+--gid "${EP_GID}" --non-unique} etherpad && \
|
|
useradd --system ${EP_UID:+--uid "${EP_UID}" --non-unique} --gid etherpad \
|
|
${EP_HOME:+--home-dir "${EP_HOME}"} --create-home \
|
|
${EP_SHELL:+--shell "${EP_SHELL}"} etherpad
|
|
|
|
ARG EP_DIR=/opt/etherpad-lite
|
|
RUN mkdir -p "${EP_DIR}" && chown etherpad:etherpad "${EP_DIR}"
|
|
|
|
# the mkdir is needed for configuration of openjdk-11-jre-headless, see
|
|
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=863199
|
|
RUN \
|
|
mkdir -p /usr/share/man/man1 && \
|
|
npm install pnpm@${PnpmVersion} -g && \
|
|
apk update && apk upgrade && \
|
|
apk add --no-cache \
|
|
ca-certificates \
|
|
curl \
|
|
git \
|
|
${INSTALL_SOFFICE:+libreoffice openjdk8-jre libreoffice-common} && \
|
|
rm -rf /var/cache/apk/*
|
|
|
|
USER etherpad
|
|
|
|
WORKDIR "${EP_DIR}"
|
|
|
|
# etherpads version feature requires this. Only copy what is really needed
|
|
COPY --chown=etherpad:etherpad ${SETTINGS} ./settings.json
|
|
COPY --chown=etherpad:etherpad ./var ./var
|
|
COPY --chown=etherpad:etherpad ./bin ./bin
|
|
COPY --chown=etherpad:etherpad ./pnpm-workspace.yaml ./package.json ./
|
|
|
|
|
|
|
|
FROM build AS build_git
|
|
# When checked out as a git submodule, .git is a file (gitlink) instead of a
|
|
# directory, so .git/HEAD and .git/refs do not exist. Copy the whole .git
|
|
# entry (the .dockerignore already strips the heavy objects) and normalise it
|
|
# with a shell step so the build succeeds in both cases and across builders
|
|
# (Docker, buildah, podman). See #6663 and containers/buildah#5742.
|
|
ONBUILD COPY --chown=etherpad:etherpad ./.git ./.git
|
|
ONBUILD RUN if [ -f .git ]; then rm .git; fi
|
|
|
|
FROM build AS build_copy
|
|
|
|
|
|
|
|
|
|
FROM build_${BUILD_ENV} AS development
|
|
|
|
ARG ETHERPAD_PLUGINS=
|
|
ARG ETHERPAD_LOCAL_PLUGINS=
|
|
ARG ETHERPAD_LOCAL_PLUGINS_ENV=
|
|
ARG ETHERPAD_GITHUB_PLUGINS=
|
|
|
|
COPY --chown=etherpad:etherpad ./src/ ./src/
|
|
COPY --chown=etherpad:etherpad --from=adminbuild /opt/etherpad-lite/src/templates/admin ./src/templates/admin
|
|
COPY --chown=etherpad:etherpad --from=adminbuild /opt/etherpad-lite/src/static/oidc ./src/static/oidc
|
|
|
|
COPY --chown=etherpad:etherpad ./local_plugin[s] ./local_plugins/
|
|
|
|
RUN bash -c ./bin/installLocalPlugins.sh
|
|
|
|
RUN bin/installDeps.sh && \
|
|
if [ ! -z "${ETHERPAD_PLUGINS}" ] || [ ! -z "${ETHERPAD_GITHUB_PLUGINS}" ]; then \
|
|
pnpm run plugins i ${ETHERPAD_PLUGINS} ${ETHERPAD_GITHUB_PLUGINS:+--github ${ETHERPAD_GITHUB_PLUGINS}}; \
|
|
fi
|
|
|
|
|
|
FROM build_${BUILD_ENV} AS production
|
|
|
|
ARG ETHERPAD_PLUGINS=
|
|
ARG ETHERPAD_LOCAL_PLUGINS=
|
|
ARG ETHERPAD_LOCAL_PLUGINS_ENV=
|
|
ARG ETHERPAD_GITHUB_PLUGINS=
|
|
|
|
ENV NODE_ENV=production
|
|
ENV ETHERPAD_PRODUCTION=true
|
|
|
|
# The full pnpm-workspace.yaml references admin, doc, ui which are not
|
|
# needed at runtime. Overwrite it with a production-only version so
|
|
# pnpm install doesn't warn about missing workspace directories.
|
|
RUN printf 'packages:\n - src\n - bin\n' > pnpm-workspace.yaml
|
|
|
|
COPY --chown=etherpad:etherpad ./src ./src
|
|
COPY --chown=etherpad:etherpad --from=adminbuild /opt/etherpad-lite/src/templates/admin ./src/templates/admin
|
|
COPY --chown=etherpad:etherpad --from=adminbuild /opt/etherpad-lite/src/static/oidc ./src/static/oidc
|
|
|
|
COPY --chown=etherpad:etherpad ./local_plugin[s] ./local_plugins/
|
|
|
|
RUN bash -c ./bin/installLocalPlugins.sh
|
|
|
|
RUN bin/installDeps.sh && \
|
|
if [ ! -z "${ETHERPAD_PLUGINS}" ] || [ ! -z "${ETHERPAD_GITHUB_PLUGINS}" ]; then \
|
|
pnpm run plugins i ${ETHERPAD_PLUGINS} ${ETHERPAD_GITHUB_PLUGINS:+--github ${ETHERPAD_GITHUB_PLUGINS}}; \
|
|
fi && \
|
|
pnpm store prune
|
|
|
|
# Copy the configuration file.
|
|
COPY --chown=etherpad:etherpad ${SETTINGS} "${EP_DIR}"/settings.json
|
|
|
|
# Fix group permissions
|
|
# Note: For some reason increases image size from 257 to 334.
|
|
# RUN chmod -R g=u .
|
|
|
|
USER etherpad
|
|
|
|
HEALTHCHECK --interval=5s --timeout=3s \
|
|
CMD curl --silent http://localhost:9001/health | grep -E "pass|ok|up" > /dev/null || exit 1
|
|
|
|
EXPOSE 9001
|
|
CMD ["pnpm", "run", "prod"]
|