diff --git a/.gitignore b/.gitignore index 0f7fe87..9fc184e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ tmp/* spec/output.log .byebug_history storage/ + +# Docker +docker/colore/variables.env diff --git a/README.md b/README.md index 0069580..e014215 100644 --- a/README.md +++ b/README.md @@ -381,6 +381,35 @@ ARGS="$@" exec java -jar /usr/share/java/tika-app.jar $ARGS ``` +## Docker + +Developing applications integrated with Colore locally may not be easy, because +of the dependencies Colore requires. + +We provide a Docker implementation to speed up local development. + +1. Copy `docker/colore/variables.env.example` to `docker/colore/variables.env` +2. Run `docker compose up` +3. Have fun with Colore up and running on `http://localhost:9240/` + +Note that some features of Colore, like synchronous HTML to PDF conversion, may +need remote access to stylesheets and JavaScripts on the host machine. In such +cases, please make sure that: + +1. The web application server allows for concurrent HTTP connections; +2. The web application generates absolute urls to stylesheets and JavaScripts + (`config.asset_host` on a Rails application) +3. The container is capable of reaching assets on the host machine (it is + possible to use `host.docker.internal` on macOS) + +### Run tests in the container + +It is possible to run specs in the container by executing: + +``` +$ docker-compose run colore bundle exec rspec +``` + ## Security notes Colore does not implement any authentication mechanism. It is up to you to @@ -403,7 +432,7 @@ Want to contribute? Great! * Joe Blackman * Marcello Barnaba * Geremia Taglialatela -* Luca Spiller +* Luca Spiller ## License diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..868fc88 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,58 @@ +version: '3.7' + +services: + colore: + build: + context: . + dockerfile: ./docker/colore/Dockerfile + args: + RACK_ENV: development + container_name: colore + depends_on: + - redis + - sidekiq + env_file: + - ./docker/colore/variables.env + environment: + RACK_ENV: development + networks: + - colore + ports: + - 9240:9240 + restart: on-failure + volumes: + - storage:/colore/storage + redis: + container_name: redis + image: redis:5.0.8-alpine + networks: + - colore + restart: on-failure + volumes: + - redis:/data + sidekiq: + build: + context: . + dockerfile: ./docker/colore/Dockerfile + args: + RACK_ENV: development + command: bundle exec sidekiq -C config/sidekiq.yml -r ./lib/sidekiq_app.rb + container_name: sidekiq + depends_on: + - redis + env_file: + - ./docker/colore/variables.env + environment: + RACK_ENV: development + networks: + - colore + restart: on-failure + volumes: + - storage:/colore/storage + +volumes: + storage: + redis: + +networks: + colore: diff --git a/docker/colore/Dockerfile b/docker/colore/Dockerfile new file mode 100644 index 0000000..81dbd77 --- /dev/null +++ b/docker/colore/Dockerfile @@ -0,0 +1,82 @@ +FROM ruby:2.6.5 + +RUN apt-get update && apt-get install -y \ + build-essential \ + imagemagick \ + libmagic-dev \ + libreoffice \ + tesseract-ocr + +ARG WKHTMLTOPDF_VERSION=0.12.5 +ARG WKHTMLTOPDF_SUBVERSION=-1 +ARG WKHTMLTOPDF_MD5=f4f3e0779d46579c63a76875e25e6b3d + +RUN wget --quiet https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/${WKHTMLTOPDF_VERSION}/wkhtmltox_${WKHTMLTOPDF_VERSION}${WKHTMLTOPDF_SUBVERSION}.buster_amd64.deb -O wkhtmltopdf.deb && \ + echo "${WKHTMLTOPDF_MD5} wkhtmltopdf.deb" > MD5SUMS && \ + md5sum -c MD5SUMS && \ + apt-get -qy install ./wkhtmltopdf.deb && \ + rm -f wkhtmltopdf.deb MD5SUMS + +ARG TIKA_VERSION=1.26 + +RUN gpg --keyserver hkp://keys.gnupg.net --recv-key 184454FAD8697760F3E00D2E4A51A45B944FFD51 && \ + wget --quiet https://archive.apache.org/dist/tika/tika-app-${TIKA_VERSION}.jar.asc -O tika-app.jar.asc && \ + wget --quiet https://archive.apache.org/dist/tika/tika-app-${TIKA_VERSION}.jar -O tika-app.jar && \ + gpg --verify tika-app.jar.asc tika-app.jar && \ + rm -f tika-app.jar.asc && \ + mv tika-app.jar /usr/share/java/tika-app.jar && \ + echo '#!/bin/sh\n\nARGS="$@"\n\n[ $# -eq 0 ] && ARGS="--help"\n\nexec java -jar /usr/share/java/tika-app.jar $ARGS\n' > /usr/local/bin/tika && \ + chmod +x /usr/local/bin/tika + +ENV APP_DIR /colore + +EXPOSE 9240 + +WORKDIR $APP_DIR + +# Create application user and add permissions +RUN groupadd --gid 1000 colore && \ + useradd --uid 1000 --gid colore --shell /bin/bash --create-home colore && \ + chown -R colore:colore $APP_DIR && \ + chmod -R 755 $APP_DIR + +# Switch to application user +USER colore + +RUN mkdir -p log +RUN mkdir -p tmp/pids + +ARG RACK_ENV +ENV RACK_ENV=${RACK_ENV:-production} + +RUN gem install bundler + +# Copy command always runs as root +COPY --chown=colore:colore Gemfile . +COPY --chown=colore:colore Gemfile.lock . + +RUN echo $RACK_ENV +RUN \ + if [ "$RACK_ENV" = "development" ] || [ "$RACK_ENV" = "test" ]; then \ + bundle install --retry 10; \ + else \ + bundle config set deployment 'true' && bundle --retry 10; \ + fi + +COPY --chown=colore:colore bin ./bin +COPY --chown=colore:colore config ./config +COPY --chown=colore:colore lib ./lib +COPY --chown=colore:colore spec ./spec +COPY --chown=colore:colore config.ru . +COPY --chown=colore:colore Rakefile . +COPY --chown=colore:colore unicorn.rb . + +# Create the shared volume so it will be owned by the application user +RUN mkdir -p storage + +COPY --chown=colore:colore docker/colore/docker-entrypoint.sh ./bin +RUN chmod +x ./bin/docker-entrypoint.sh + +ENTRYPOINT ["/colore/bin/docker-entrypoint.sh"] + +CMD ["bundle", "exec", "unicorn"] diff --git a/docker/colore/docker-entrypoint.sh b/docker/colore/docker-entrypoint.sh new file mode 100755 index 0000000..721727a --- /dev/null +++ b/docker/colore/docker-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +pwd + +rm -f tmp/pids/*.pid + +exec "$@" diff --git a/docker/colore/variables.env.example b/docker/colore/variables.env.example new file mode 100644 index 0000000..39689e1 --- /dev/null +++ b/docker/colore/variables.env.example @@ -0,0 +1,4 @@ +LANG=en_US.UTF-8 +LANGUAGE=en_US.UTF-8 +LC_ALL=C.UTF-8 +REDIS_URL=redis://redis:6379/4