aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Segundo2022-03-07 20:58:31 +0100
committerChristian Segundo2022-03-07 20:58:31 +0100
commit66ae9ab6eb3751ae7507156e696e3215cab0a496 (patch)
tree4b9a9cb190a725a15f62446dfd6aea84012ae59c
parentc3b760f58b1b548a2435fda1f52dbaa26b190a88 (diff)
downloadlanguagetool-66ae9ab6eb3751ae7507156e696e3215cab0a496.tar.gz
Full refactor
-rw-r--r--.dockerignore9
-rw-r--r--.github/workflows/main.yml69
-rw-r--r--.github/workflows/test.yml32
-rw-r--r--.github/workflows/trivy.yml38
-rw-r--r--.gitignore1
-rw-r--r--Dockerfile23
-rw-r--r--Makefile114
-rw-r--r--Makefile.version4
-rw-r--r--misc/init.sh13
-rwxr-xr-xmisc/ngram.sh59
-rw-r--r--misc/start.sh6
-rw-r--r--readme.md52
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
diff --git a/Dockerfile b/Dockerfile
index 98473cf..58f5b7a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -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
diff --git a/Makefile b/Makefile
index e8c9d31..51613f4 100644
--- a/Makefile
+++ b/Makefile
@@ -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}
diff --git a/readme.md b/readme.md
index 843159f..60885f0 100644
--- a/readme.md
+++ b/readme.md
@@ -1,59 +1,61 @@
+[![Publish](https://github.com/someone-stole-my-name/docker-languagetool/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/someone-stole-my-name/docker-languagetool/actions/workflows/main.yml) [![Test](https://github.com/someone-stole-my-name/docker-languagetool/actions/workflows/test.yml/badge.svg)](https://github.com/someone-stole-my-name/docker-languagetool/actions/workflows/test.yml) [![trivy](https://github.com/someone-stole-my-name/docker-languagetool/actions/workflows/trivy.yml/badge.svg?branch=master)](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" ...