diff options
author | Christian Segundo | 2022-03-07 20:58:31 +0100 |
---|---|---|
committer | Christian Segundo | 2022-03-07 20:58:31 +0100 |
commit | 66ae9ab6eb3751ae7507156e696e3215cab0a496 (patch) | |
tree | 4b9a9cb190a725a15f62446dfd6aea84012ae59c | |
parent | c3b760f58b1b548a2435fda1f52dbaa26b190a88 (diff) | |
download | languagetool-66ae9ab6eb3751ae7507156e696e3215cab0a496.tar.gz |
Full refactor
-rw-r--r-- | .dockerignore | 9 | ||||
-rw-r--r-- | .github/workflows/main.yml | 69 | ||||
-rw-r--r-- | .github/workflows/test.yml | 32 | ||||
-rw-r--r-- | .github/workflows/trivy.yml | 38 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Dockerfile | 23 | ||||
-rw-r--r-- | Makefile | 114 | ||||
-rw-r--r-- | Makefile.version | 4 | ||||
-rw-r--r-- | misc/init.sh | 13 | ||||
-rwxr-xr-x | misc/ngram.sh | 59 | ||||
-rw-r--r-- | misc/start.sh | 6 | ||||
-rw-r--r-- | readme.md | 52 |
12 files changed, 255 insertions, 165 deletions
diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 40a87fe..0000000 --- a/.dockerignore +++ /dev/null @@ -1,9 +0,0 @@ -*.swp -*.zip -.dockerignore -.git -.gitignore -.travis.yml -Makefile -ngrams -readme.md diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3fddc7e..a8a47ef 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,51 +1,40 @@ -name: Release for silvio/docker-languagetool - +name: Build on: push: - tags: - - '[0-9]+.[0-9]+' - - '[0-9]+.[0-9]+.[0-9]+' - - '[0-9]+.[0-9]+-update[0-9]+' - - '[0-9]+.[0-9]+.[0-9]+-update[0-9]+' + branches: [ master ] + schedule: + - cron: '5 4 * * *' + workflow_dispatch: jobs: - docker: + build: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v1 - - - name: Set environment variables - run: | - make envout >> ${GITHUB_ENV} - - - name: Prepare system - run: | - make prepare - - - name: Build Docker image - run: | - make build + - uses: actions/checkout@v2 + - run: | + make docker-test - - name: Run tests - run: | - make test - - - name: Login Docker - uses: docker/login-action@v1 + push: + runs-on: ubuntu-latest + needs: [ build ] + permissions: + packages: write + contents: read + steps: + - uses: actions/checkout@v2 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} + fetch-depth: 0 - - name: Push tag - run: | - make tag + - uses: docker/login-action@v1 + env: + GITHUB_USER: ${{ github.actor }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + registry: ghcr.io + username: $GITHUB_USER + password: ${{ secrets.GITHUB_TOKEN }} + - run: | + make docker-push \ + DOCKER_EXTRA_ARGS="-v ${HOME}/.docker:/root/.docker" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index de95a7f..63c8c1b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,36 +1,18 @@ -name: Test for silviof/docker-languagetool +name: Test on: + push: + branches: [ master ] pull_request: + branches: [ master ] workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v2 + - uses: actions/checkout@v2 - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v1 - - - name: Set environment variables - run: | - make envout >> ${GITHUB_ENV} - - - name: Prepare system - run: | - make prepare - - - name: Build Docker image - run: | - make build - - - name: Run tests - run: | - make test + - run: | + make docker-test diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml new file mode 100644 index 0000000..ce25513 --- /dev/null +++ b/.github/workflows/trivy.yml @@ -0,0 +1,38 @@ +name: Trivy + +on: + workflow_dispatch: + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + - cron: '28 15 * * 3' + +permissions: + contents: read + +jobs: + build: + permissions: + contents: read + security-events: write + runs-on: "ubuntu-18.04" + steps: + - uses: actions/checkout@v2 + + - run: | + docker build -t docker.io/my-organization/my-app:${{ github.sha }} . + + - uses: aquasecurity/trivy-action@2a2157eb22c08c9a1fac99263430307b8d1bc7a2 + with: + image-ref: 'docker.io/my-organization/my-app:${{ github.sha }}' + format: 'template' + template: '@/contrib/sarif.tpl' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + ignore-unfixed: true + + - uses: github/codeql-action/upload-sarif@v1 + with: + sarif_file: 'trivy-results.sarif' diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 32b1038..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -ngrams @@ -1,19 +1,20 @@ -FROM openjdk:16-slim-buster +FROM openjdk:slim -# see Makefile.version -ARG VERSION +ARG VERSION=5.6 -MAINTAINER Silvio Fricke <silvio.fricke@gmail.com> +RUN apt-get update && \ + apt-get install -y \ + curl \ + libarchive-tools && \ + rm -rf /var/lib/apt/lists/* -RUN apt-get update && apt-get install -y wget unzip && rm -rf /var/lib/apt/lists/* +RUN curl --progress-bar "https://languagetool.org/download/LanguageTool-$VERSION.zip" |\ + bsdtar -x -f - -RUN wget https://www.languagetool.org/download/LanguageTool-$VERSION.zip && \ - unzip LanguageTool-$VERSION.zip && \ - rm LanguageTool-$VERSION.zip +ADD misc/init.sh /init.sh +ADD misc/ngram.sh /ngram.sh WORKDIR /LanguageTool-$VERSION - -ADD misc/start.sh /start.sh -CMD [ "sh", "/start.sh" ] +CMD [ "sh", "/init.sh" ] USER nobody EXPOSE 8010 @@ -1,65 +1,91 @@ -include Makefile.version +LANGUAGETOOL_VERSION := 5.6 +TRIVY_VERSION := 0.24.2 -envout: - @echo "VERSION=$(VERSION)" - @echo "BUILDARG_VERSION=$(BUILDARG_VERSION)" - @echo "IMAGENAME=$(IMAGENAME)" - @echo "BUILDARG_PLATFORM=$(BUILDARG_PLATFORM)" +BUILDARG_VERSION := --build-arg VERSION=$(LANGUAGETOOL_VERSION) +IMAGENAME := ghcr.io/someone-stole-my-name/docker-languagetool +BUILDARG_PLATFORM := --platform linux/amd64,linux/arm64/v8 +DOCKER_EXTRA_ARGS := -prepare: - sudo apt-get -qq -y install curl +ci-deps: + apt-get -qq -y install \ + binfmt-support \ + ca-certificates \ + curl \ + git \ + gnupg \ + lsb-release \ + qemu-user-static \ + wget \ + jq -build: +ci-deps-docker: + curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \ + echo "deb [arch=$(shell dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(shell lsb_release -cs) stable" |\ + tee /etc/apt/sources.list.d/docker.list > /dev/null && \ + cat /etc/apt/sources.list.d/docker.list && \ + apt-get update && \ + apt-get -qq -y install \ + docker-ce \ + docker-ce-cli \ + containerd.io + +ci-deps-trivy: + wget https://github.com/aquasecurity/trivy/releases/download/v$(TRIVY_VERSION)/trivy_$(TRIVY_VERSION)_Linux-64bit.deb && \ + dpkg -i trivy_$(TRIVY_VERSION)_Linux-64bit.deb + +ci-setup-buildx: + docker run --privileged --rm tonistiigi/binfmt --install all + docker buildx create --name mybuilder + docker buildx use mybuilder + +ci-prepare: ci-deps ci-deps-docker ci-deps-trivy ci-setup-buildx + +build: ci-prepare docker buildx build $(BUILDARG_VERSION) $(BUILDARG_PLATFORM) -t $(IMAGENAME):latest . docker buildx build $(BUILDARG_VERSION) --load -t $(IMAGENAME):latest . -test: test-cleanup.1 -test: TESTIPADDRESS=$(subst ",,$(shell docker inspect languagetool | jq '.[0].NetworkSettings.IPAddress')) -test: test-print-ip-address -test: test-start -test: test-run-test-lang -test: test-run-test-en -test: test-run-test-fr -test: test-cleanup.2 +push: ci-prepare + docker buildx build $(BUILDARG_VERSION) $(BUILDARG_PLATFORM) -t $(IMAGENAME):latest . --push + docker buildx build $(BUILDARG_VERSION) $(BUILDARG_PLATFORM) -t $(IMAGENAME):$(shell git describe --tags --abbrev=0) . --push + +trivy: + trivy i \ + --ignore-unfixed \ + --exit-code 1 \ + $(IMAGENAME):latest -test-start: - docker run -d --name languagetool -p 8010:8010 $(IMAGENAME):latest - sleep 3 +test: build trivy test-int -test-print-ip-address: - @echo "IP address of languagetools docker container: $(TESTIPADDRESS)" +test-int-start: + docker kill languagetool || true + docker rm languagetool || true + docker run --rm -d --name languagetool -p 8010:8010 $(IMAGENAME):latest -test-run-test-lang: +test-int-run: IP=$(subst ",,$(shell docker inspect languagetool | jq '.[0].NetworkSettings.IPAddress')) +test-int-run: + timeout 60 sh -c 'until (curl -i $(IP):8010/v2/info | grep "200 OK") do sleep 1; done' curl \ -X GET \ --header 'Accept: application/json' \ - 'http://$(TESTIPADDRESS):8010/v2/languages' - -test-run-test-en: + --fail \ + 'http://$(IP):8010/v2/languages' curl \ -X POST \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'Accept: application/json' \ + --fail \ -d 'text=hello%20woorld&language=en-US&motherTongue=de-DE&enabledOnly=false' \ - 'http://$(TESTIPADDRESS):8010/v2/check' + 'http://$(IP):8010/v2/check' -test-run-test-fr: - curl -X POST \ - --header 'Content-Type: application/x-www-form-urlencoded' \ - --header 'Accept: application/json' \ - -d 'text=hello%20woorld&language=fr&motherTongue=de-DE&enabledOnly=false' \ - 'http://$(TESTIPADDRESS):8010/v2/check' -.PHONY: test-cleanup -test-cleanup.%: - -docker stop languagetool - -docker rm languagetool +test-int: test-int-start test-int-run -.PHONY: tag -tag: tag-push - -.PHONY: tag-push -tag-push: - docker buildx build $(BUILDARG_VERSION) $(BUILDARG_PLATFORM) -t $(IMAGENAME):latest . --push - docker buildx build $(BUILDARG_VERSION) $(BUILDARG_PLATFORM) -t $(IMAGENAME):$(VERSION) . --push +docker-%: + docker run \ + --rm \ + --privileged \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v $(shell pwd):/data \ + -w /data $(DOCKER_EXTRA_ARGS) \ + debian:stable sh -c "apt-get update && apt-get install make && make $*" diff --git a/Makefile.version b/Makefile.version deleted file mode 100644 index 2d4cbb0..0000000 --- a/Makefile.version +++ /dev/null @@ -1,4 +0,0 @@ -VERSION := 5.6 -BUILDARG_VERSION := --build-arg VERSION=$(VERSION) -IMAGENAME := docker.io/silviof/docker-languagetool -BUILDARG_PLATFORM := --platform linux/amd64,linux/arm64/v8 diff --git a/misc/init.sh b/misc/init.sh new file mode 100644 index 0000000..5681037 --- /dev/null +++ b/misc/init.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +EXTRAOPTIONS=${EXTRAOPTIONS:-} +JAVAOPTIONS=${JAVAOPTIONS:-} + +if [ -d "/ngrams" ]; then + EXTRAOPTIONS="${EXTRAOPTIONS} --languageModel /ngrams" + if [ ! -z ${NGRAM_LANGUAGES+x} ]; then + bash /ngram.sh "${NGRAM_LANGUAGES}" "/ngrams" + fi +fi + +java ${JAVAOPTIONS} -cp languagetool-server.jar org.languagetool.server.HTTPServer --port 8010 --public --allow-origin '*' ${EXTRAOPTIONS} diff --git a/misc/ngram.sh b/misc/ngram.sh new file mode 100755 index 0000000..ce25a49 --- /dev/null +++ b/misc/ngram.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +set -euo pipefail + +NGRAM_DATA_URL="https://languagetool.org/download/ngram-data/" +NGRAM_ARCHIVES=$(curl -sS "${NGRAM_DATA_URL}" | grep "\.zip" | grep -oP 'ngrams-\w\w-\d+\.zip' | sort | uniq) + +TARGET_LANGS="${1}" +TARGET_DIR="${2}" + +download_ngram() { + local lang=$1 + local version=$2 + local directory=$3 + + echo "Downloading: ${lang} - ${version}" + rm -rf "${directory}/${lang}" + curl --progress-bar "${NGRAM_DATA_URL}ngrams-${lang}-${version}.zip" |\ + bsdtar -x -f - -C "${directory}" +} + + +VERSION_FILE_CONTENT= + +if test -f "${TARGET_DIR}/version"; then + VERSION_FILE_CONTENT=$(cat "${TARGET_DIR}/version") + >"${TARGET_DIR}/version" +fi + +while read -r ngram_archive; do + for lang in ${TARGET_LANGS/,/ }; do + if echo "$(echo ${ngram_archive} | cut -d'-' -f2)" | grep -q $lang; then + version=$(echo ${ngram_archive} | cut -d'-' -f3 | cut -d'.' -f1) + if echo "${VERSION_FILE_CONTENT}" | grep -q "$lang"; then + existing_version=$(echo "${VERSION_FILE_CONTENT}" | grep "${lang}" | cut -d':' -f2) + current_version=$(echo "${ngram_archive}" | cut -d'-' -f3 | cut -d'.' -f1) + if [[ "${existing_version}" -lt "${current_version}" ]]; then + download_ngram "${lang}" "${version}" "${TARGET_DIR}" + fi + else + download_ngram "${lang}" "${version}" "${TARGET_DIR}" + fi + echo "${lang}:${version}" >> "${TARGET_DIR}/version" + fi + done +done <<< "${NGRAM_ARCHIVES}" + +for i in $(ls -d "${TARGET_DIR}"/*/); do + realdir="$(basename ${i})" + delete=yes + for lang in ${TARGET_LANGS/,/ }; do + if echo "${realdir}" | grep -q "${lang}"; then + delete=no + fi + done + if [ "${delete}" == "yes" ]; then + rm -rf "${TARGET_DIR}/${realdir}" + fi +done diff --git a/misc/start.sh b/misc/start.sh deleted file mode 100644 index f550f08..0000000 --- a/misc/start.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -EXTRAOPTIONS="" -[ -d "/ngrams" ] && EXTRAOPTIONS=" --languageModel /ngrams " - -java -cp languagetool-server.jar org.languagetool.server.HTTPServer --port 8010 --public --allow-origin '*' ${EXTRAOPTIONS} @@ -1,59 +1,61 @@ +[](https://github.com/someone-stole-my-name/docker-languagetool/actions/workflows/main.yml) [](https://github.com/someone-stole-my-name/docker-languagetool/actions/workflows/test.yml) [](https://github.com/someone-stole-my-name/docker-languagetool/actions/workflows/trivy.yml) # Introduction [LanguageTool] is an Open Source proofÂreading software for English, French, German, Polish, and more than 20 other languages. -You can use the LanguageTools with a [firefox-plugin]. +You can use LanguageTool with a [Firefox extension]. -This is a Dockerfile to get the languagetools running on a system without java. +This is a container to get the LanguageTool running on a system without java. [LanguageTool]: https://www.languagetool.org/ -[firefox-plugin]: https://addons.mozilla.org/firefox/addon/languagetool +[Firefox extension]: https://addons.mozilla.org/firefox/addon/languagetool # Usage The Server is running on port 8010, this port should exposed. - $ docker pull silviof/docker-languagetool + docker pull ghcr.io/someone-stole-my-name/docker-languagetool [...] - $ docker run --rm -p 8010:8010 silviof/docker-languagetool + docker run --rm -p 8010:8010 ghcr.io/someone-stole-my-name/docker-languagetool -Or you run it in background via `-d`-option. +Or you run it in background via `-d` option. Run with no minimum rights and RAM -``` -docker run --name languagetool \ - --cap-drop=ALL \ - --user=65534:65534 \ - --read-only \ - --mount type=bind,src=/tmp/languagetool/tmp,dst=/tmp \ - -p 127.0.0.1:8010:8010 \ - --memory 412m --memory-swap 500m \ - -e EXTRAOPTIONS="-Xmx382M" \ - silviof/docker-languagetool:latest -``` + + docker run --name languagetool \ + --cap-drop=ALL \ + --user=65534:65534 \ + --read-only \ + --mount type=bind,src=/tmp/languagetool/tmp,dst=/tmp \ + -p 127.0.0.1:8010:8010 \ + --memory 412m --memory-swap 500m \ + -e JAVAOPTIONS="-Xmx382M" \ + ghcr.io/someone-stole-my-name/docker-languagetool:latest + Route information can be found at https://languagetool.org/http-api/swagger-ui/#/default, an easy route to test that it's running is `/v2/languages`. ## ngram support To support [ngrams] you need an additional volume or directory mounted to the -`/ngrams` directory. For that add a `-v` to the `docker run`-command. +`/ngrams` directory. For that add a `-v` to the `docker run` command. - docker run ... -v /path/to/ngrams:/ngrams ... + docker run ... -v /foo:/ngrams ... [ngrams]: http://wiki.languagetool.org/finding-errors-using-n-gram-data - +### Manual Download English ngrams with the commands: mkdir ngrams - wget https://languagetool.org/download/ngram-data/ngrams-en-20150817.zip - (cd ngrams && unzip ../ngrams-en-20150817.zip) - rm -f ngrams-en-20150817.zip + wget https://languagetool.org/download/ngram-data/ngrams-en-YYYYMMDD.zip + (cd ngrams && unzip ../ngrams-en-YYYYMMDD.zip) + rm -f ngrams-en-YYYYMMDD.zip +### Automatically -One can use them using web browser plugin "Local server (localhost)" setting by running: +Mount a directory or volume to `/ngrams` and use the `NGRAM_LANGUAGES` variable to pass a comma separated string with languages: - docker run -d --name languagetool -p 127.0.0.1:8081:8010 -v `pwd`/ngrams:/ngrams:ro --restart=unless-stopped silviof/docker-languagetool + docker run ... -v /path/to/ngrams:/ngrams -e NGRAM_LANGUAGES="en,es" ... |