diff --git a/.dockerignore b/.dockerignore index ed0571a988..c7c9b76f0d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,8 +4,7 @@ HISTORY.md mayan/media db.sqlite* docker -!docker/etc -!docker/entrypoint.sh -!docker/version +!docker/rootfs ./.* docs + diff --git a/contrib/scripts/docker/run-tests.sh b/contrib/scripts/docker/run-tests.sh index 11b4a327ef..89c77edee3 100755 --- a/contrib/scripts/docker/run-tests.sh +++ b/contrib/scripts/docker/run-tests.sh @@ -1,8 +1,10 @@ #!/bin/sh +export DEBIAN_FRONTEND=noninteractive + apt-get update apt-get install -y --no-install-recommends tesseract-ocr-deu -$MAYAN_PIP_BIN install -r $DOCKER_ROOT/requirements-testing.txt +$MAYAN_PIP_BIN install -r ${MAYAN_INSTALL_DIR}/requirements-testing.txt $MAYAN_BIN test --mayan-apps --settings=mayan.settings.testing diff --git a/docker/Dockerfile b/docker/Dockerfile index 85c1399716..7b340394de 100755 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,167 +1,150 @@ # vim:set ft=dockerfile: -#################### -# Base image start # -#################### +#### +# BASE_IMAGE - Bare bones image with the base packages needed to run Mayan EDMS +#### -FROM debian:9.4-slim as BASE_IMAGE +FROM debian:9.8-slim as BASE_IMAGE -MAINTAINER Roberto Rosario "roberto.rosario@mayan-edms.com" +LABEL maintainer="Roberto Rosario roberto.rosario@mayan-edms.com" -ENV DEBIAN_FRONTEND noninteractive -ENV PYTHONUNBUFFERED 1 -ENV LC_ALL C.UTF-8 -ENV PROJECT_INSTALL_DIR=/opt/mayan-edms -ENV PYTHON_PIP=${PROJECT_INSTALL_DIR}/bin/pip +ENV PYTHONUNBUFFERED=1 \ + LC_ALL=C.UTF-8 \ + PROJECT_INSTALL_DIR=/opt/mayan-edms +# Debian package caching ARG APT_PROXY -# Package caching -RUN if [ "${APT_PROXY}" ]; then echo "Acquire::http { Proxy \"http://${APT_PROXY}\"; };" > /etc/apt/apt.conf.d/01proxy; fi - -# Install base Ubuntu libraries -RUN apt-get update && \ -apt-get install -y --no-install-recommends \ - g++ \ - gcc \ - ghostscript \ - gpgv \ - gnupg1 \ - graphviz \ - libffi-dev \ - libfuse2 \ - libjpeg-dev \ - libmagic1 \ - default-libmysqlclient-dev \ - libpng-dev \ - libpq-dev \ - libreoffice \ - libtiff-dev \ - poppler-utils \ - python-dev \ - python-setuptools \ - python-virtualenv \ - python-wheel \ - redis-server \ - sane-utils \ - sudo \ - supervisor \ - tesseract-ocr \ - zlib1g-dev \ - libssl-dev \ -&& \ -apt-get clean autoclean && \ -apt-get autoremove --purge -y && \ -rm -rf /var/lib/apt/lists/* && \ -rm -f /var/cache/apt/archives/*.deb - -# Install apt-get-install -ADD https://raw.githubusercontent.com/guilhem/apt-get-install/master/apt-get-install /usr/bin/ -RUN chmod +x /usr/bin/apt-get-install - -RUN adduser mayan --disabled-password --disabled-login --no-create-home --gecos "" - +RUN set -x \ +&& if [ "${APT_PROXY}" ]; \ + then echo "Acquire::http { Proxy \"http://${APT_PROXY}\"; };" > /etc/apt/apt.conf.d/01proxy \ +; fi \ +# Install base OS packages to run Mayan EDMS +&& DEBIAN_FRONTEND=noninteractive \ +apt-get update \ +&& apt-get install -y --no-install-recommends \ + exiftool \ + ghostscript \ + gpgv \ + gnupg1 \ + graphviz \ + libfuse2 \ + libmagic1 \ + libmariadbclient18 \ + libreoffice \ + libpq5 \ + poppler-utils \ + redis-server \ + sane-utils \ + sudo \ + supervisor \ + tesseract-ocr \ +# Add mayan user +&& adduser mayan --disabled-password --disabled-login --no-create-home --gecos "" \ # Pillow can't find zlib or libjpeg on aarch64 (ODROID C2) -RUN if [ "$(uname -m)" = "aarch64" ]; then \ -ln -s /usr/lib/aarch64-linux-gnu/libz.so /usr/lib/ && \ -ln -s /usr/lib/aarch64-linux-gnu/libjpeg.so /usr/lib/ \ -; fi - +&& if [ "$(uname -m)" = "aarch64" ]; then \ + ln -s /usr/lib/aarch64-linux-gnu/libz.so /usr/lib/ \ + && ln -s /usr/lib/aarch64-linux-gnu/libjpeg.so /usr/lib/ \ +; fi \ # Pillow can't find zlib or libjpeg on armv7l (ODROID HC1) -RUN if [ "$(uname -m)" = "armv7l" ]; then \ -ln -s /usr/lib/arm-linux-gnueabihf/libz.so /usr/lib/ && \ -ln -s /usr/lib/arm-linux-gnueabihf/libjpeg.so /usr/lib/ \ -; fi - +&& if [ "$(uname -m)" = "armv7l" ]; then \ + ln -s /usr/lib/arm-linux-gnueabihf/libz.so /usr/lib/ \ + && ln -s /usr/lib/arm-linux-gnueabihf/libjpeg.so /usr/lib/ \ +; fi \ # Discard data when Redis runs out of memory -RUN echo "maxmemory-policy allkeys-lru" >> /etc/redis/redis.conf - +&& echo "maxmemory-policy allkeys-lru" >> /etc/redis/redis.conf \ # Disable saving the Redis database -RUN echo "save \"\"" >> /etc/redis/redis.conf - +echo "save \"\"" >> /etc/redis/redis.conf \ # Only provision 1 database -RUN echo "databases 1" >> /etc/redis/redis.conf +&& echo "databases 1" >> /etc/redis/redis.conf -##################### -# Build image start # -##################### -FROM debian:9.4-slim as BUILDER_IMAGE +#### +# BUILDER_IMAGE - This image buildS the Python package and is discarded afterwards +#### -ARG APT_PROXY -# Package caching -RUN if [ "${APT_PROXY}" ]; then echo "Acquire::http { Proxy \"http://${APT_PROXY}\"; };" > /etc/apt/apt.conf.d/01proxy; fi +# Reuse image +FROM BASE_IMAGE as BUILDER_IMAGE -WORKDIR /code +WORKDIR /src -COPY . /code +# Copy the source files needed to build the Python package +COPY --chown=mayan:mayan requirements /src/requirements +COPY --chown=mayan:mayan \ + HISTORY.rst \ + LICENSE \ + MANIFEST.in \ + README.md \ + README.rst \ + setup.py \ + Makefile \ + /src/ -RUN apt-get update && apt-get install make python-dev python-pip -y +COPY --chown=mayan:mayan mayan /src/mayan -RUN pip install -r requirements/build.txt +# Install development packages needed to build the Python packages +RUN DEBIAN_FRONTEND=noninteractive \ +apt-get install -y --no-install-recommends \ + default-libmysqlclient-dev \ + libffi-dev \ + libjpeg-dev \ + libpng-dev \ + libpq-dev \ + libtiff-dev \ + make \ + python-wheel \ + zlib1g-dev \ + libssl-dev \ + g++ \ + gcc \ + python-dev \ + python-setuptools \ + python-virtualenv \ +&& mkdir -p "${PROJECT_INSTALL_DIR}" \ +&& chown -R mayan:mayan "${PROJECT_INSTALL_DIR}" \ +&& chown -R mayan:mayan /src -ENV LC_ALL C.UTF-8 +USER mayan +RUN python -m virtualenv "${PROJECT_INSTALL_DIR}" \ +&& . "${PROJECT_INSTALL_DIR}/bin/activate" \ +&& pip install --no-cache-dir --no-use-pep517 \ + librabbitmq==1.6.1 \ + mysql-python==1.2.5 \ + psycopg2==2.7.3.2 \ + redis==2.10.6 \ +# Install the Python packages needed to build Mayan EDMS +&& pip install --no-cache-dir --no-use-pep517 -r /src/requirements/build.txt \ +# Build Mayan EDMS +&& make python-wheel \ +# Install the built Mayan EDMS package +&& pip install --no-cache-dir --no-use-pep517 dist/*.whl \ +# Install the static content +&& mayan-edms.py installjavascript \ +&& MAYAN_STATIC_ROOT=${PROJECT_INSTALL_DIR}/static mayan-edms.py preparestatic --link --noinput -RUN touch docker/Makefile +COPY --chown=mayan:mayan requirements/testing-base.txt "${PROJECT_INSTALL_DIR}" -RUN make python-wheel - -RUN chmod 777 dist -R - -##################### -# Final image start # -##################### +#### +# Final image - BASE_IMAGE + Mayan install directory from the builder image +#### FROM BASE_IMAGE -RUN mkdir -p /opt +COPY --from=BUILDER_IMAGE --chown=mayan:mayan "${PROJECT_INSTALL_DIR}/" "${PROJECT_INSTALL_DIR}/" -RUN python /usr/lib/python2.7/dist-packages/virtualenv.py $PROJECT_INSTALL_DIR +USER root -WORKDIR $PROJECT_INSTALL_DIR +COPY docker/rootfs / -COPY --from=BUILDER_IMAGE /code/dist/*.whl . - -COPY --from=BUILDER_IMAGE /code/contrib/scripts/docker/run-tests.sh . - -COPY --from=BUILDER_IMAGE /code/requirements/testing-base.txt requirements-testing.txt - -COPY --from=BUILDER_IMAGE /code/docker/version . - -# Fix ownership -RUN chown -R mayan:mayan $PROJECT_INSTALL_DIR - -# Install build Mayan EDMS -RUN sudo -u mayan $PYTHON_PIP install --no-cache-dir --no-use-pep517 *.whl && \ -rm *.whl && \ -mayan-edms.py installjavascript && \ -MAYAN_STATIC_ROOT=${PROJECT_INSTALL_DIR}/static mayan-edms.py preparestatic --link --noinput - - -# Install Python clients for librabbitmq, MySQL, PostgreSQL, REDIS -RUN sudo -u mayan $PYTHON_PIP install --no-cache-dir --no-use-pep517 librabbitmq==1.6.1 mysql-python==1.2.5 psycopg2==2.7.3.2 redis==2.10.6 - -# Setup supervisor -COPY docker/etc/supervisor/mayan.conf /etc/supervisor/conf.d - -RUN mkdir /var/lib/mayan VOLUME ["/var/lib/mayan"] -COPY docker/entrypoint.sh /usr/local/bin/ -RUN ln -s usr/local/bin/entrypoint.sh / # backwards compat ENTRYPOINT ["entrypoint.sh"] EXPOSE 8000 CMD ["mayan"] -RUN rm /root/.cache -R -RUN rm -rf /tmp/* - -RUN apt-get -y autoremove --purge && apt-get -y autoclean && apt-get -y clean - -RUN rm -rf /usr/share/man/* -RUN rm -rf /usr/share/doc/* - -RUN find /var/lib/apt -type f | xargs rm -f -RUN find /var/cache -type f -exec rm -rf {} \; - -RUN find /var/log -type f | while read f; do echo -ne '' > $f; done; +RUN apt-get clean autoclean \ +&& apt-get autoremove --purge -y \ +&& rm -rf /var/lib/apt/lists/* \ +&& rm -f /var/cache/apt/archives/*.deb \ +# Keep displaying log messages to stdout +&& find /var/log -type f | while read f; do echo -ne '' > $f; done; diff --git a/docker/Makefile b/docker/Makefile index 9b89a955dc..1dd7e42d13 100755 --- a/docker/Makefile +++ b/docker/Makefile @@ -1,5 +1,5 @@ APT_PROXY ?= `/sbin/ip route|awk '/docker0/ { print $$9 }'`:3142 -IMAGE_VERSION ?= `cat docker/version` +IMAGE_VERSION ?= `cat docker/rootfs/version` CONSOLE_COLUMNS ?= `echo $$(tput cols)` CONSOLE_LINES ?= `echo $$(tput lines)` diff --git a/docker/etc/supervisor/mayan.conf b/docker/rootfs/etc/supervisor/conf.d/mayan.conf similarity index 100% rename from docker/etc/supervisor/mayan.conf rename to docker/rootfs/etc/supervisor/conf.d/mayan.conf diff --git a/docker/entrypoint.sh b/docker/rootfs/usr/local/bin/entrypoint.sh similarity index 90% rename from docker/entrypoint.sh rename to docker/rootfs/usr/local/bin/entrypoint.sh index 38256e8c1f..6a9d8d0d5b 100755 --- a/docker/entrypoint.sh +++ b/docker/rootfs/usr/local/bin/entrypoint.sh @@ -4,7 +4,6 @@ set -e echo "mayan: starting entrypoint.sh" INSTALL_FLAG=/var/lib/mayan/system/SECRET_KEY CONCURRENCY_ARGUMENT=--concurrency= -export DOCKER_ROOT=/opt/mayan-edms export MAYAN_DEFAULT_BROKER_URL=redis://127.0.0.1:6379/0 export MAYAN_DEFAULT_CELERY_RESULT_BACKEND=redis://127.0.0.1:6379/0 @@ -53,14 +52,30 @@ export PYTHONPATH=$PYTHONPATH:$MAYAN_MEDIA_ROOT chown mayan:mayan /var/lib/mayan -R +apt_get_install() { + apt-get -q update + apt-get install -y --force-yes --no-install-recommends --auto-remove "$@" + apt-get -q clean + rm -rf /var/lib/apt/lists/* +} + initialize() { echo "mayan: initialize()" su mayan -c "${MAYAN_BIN} initialsetup --force --no-javascript" } -upgrade() { - echo "mayan: upgrade()" - su mayan -c "${MAYAN_BIN} performupgrade --no-javascript" +os_package_installs() { + echo "mayan: os_package_installs()" + if [ "${MAYAN_APT_INSTALLS}" ]; then + DEBIAN_FRONTEND=noninteractive apt_get_install $MAYAN_APT_INSTALLS + fi +} + +pip_installs() { + echo "mayan: pip_installs()" + if [ "${MAYAN_PIP_INSTALLS}" ]; then + su mayan -c "${MAYAN_PIP_BIN} install $MAYAN_PIP_INSTALLS" + fi } start() { @@ -69,18 +84,9 @@ start() { exec /usr/bin/supervisord -nc /etc/supervisor/supervisord.conf } -os_package_installs() { - echo "mayan: os_package_installs()" - if [ "${MAYAN_APT_INSTALLS}" ]; then - apt-get-install $MAYAN_APT_INSTALLS - fi -} - -pip_installs() { - echo "mayan: pip_installs()" - if [ "${MAYAN_PIP_INSTALLS}" ]; then - $MAYAN_PIP_BIN install $MAYAN_PIP_INSTALLS - fi +upgrade() { + echo "mayan: upgrade()" + su mayan -c "${MAYAN_BIN} performupgrade --no-javascript" } os_package_installs || true @@ -105,7 +111,7 @@ run-tests) # Check if this is a new install, otherwise try to upgrade the existi else upgrade fi - $DOCKER_ROOT/run-tests.sh + run-tests.sh ;; *) su mayan -c "$@"; diff --git a/docker/rootfs/usr/local/bin/run-tests.sh b/docker/rootfs/usr/local/bin/run-tests.sh new file mode 100755 index 0000000000..f2baf135f8 --- /dev/null +++ b/docker/rootfs/usr/local/bin/run-tests.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +export DEBIAN_FRONTEND=noninteractive + +apt-get update +apt-get install -y --no-install-recommends tesseract-ocr-deu + +$MAYAN_PIP_BIN install -r ${MAYAN_INSTALL_DIR}/testing-base.txt + +$MAYAN_BIN test --mayan-apps --settings=mayan.settings.testing diff --git a/docker/version b/docker/rootfs/version similarity index 100% rename from docker/version rename to docker/rootfs/version