valentjn / ltex-ls

LTeX Language Server: LSP language server for LanguageTool :mag::heavy_check_mark: with support for LaTeX :mortar_board:, Markdown :pencil:, and others
https://valentjn.github.io/ltex
Mozilla Public License 2.0
772 stars 35 forks source link

Docker image #140

Open folliehiyuki opened 2 years ago

folliehiyuki commented 2 years ago

Describe the problems you are having I just want to avoid Java tool chain in my system, since I don't know anything about Java. Yes it sounds really stupid :)

Describe the solution you'd like It would be nice to have a Docker image alongside the release. Some linting tools (which are hard to build from source) support this alternative method like hadolint. You don't need to publish it to DockerHub though. Just a Dockerfile file is helpful enough. Publishing it through GitHub container registry is also an option.

Additional context I have a working image, simply by just spinning up an Alpine base, copying the release over and installing opendjdk11-jdk on it. It works but not ideal. A Dockerfile file with detailed build instruction would be nice (I can't seem to find the build from source instruction anywhere).

valentjn commented 2 years ago

This is a great suggestion.

The build instructions are here: https://valentjn.github.io/ltex/ltex-ls/contributing.html#how-to-set-up-the-project

Could your paste your Dockerfile here? I'm quite new to Docker, but I'm learning it for my job anyway, so this should be a good opportunity.

folliehiyuki commented 2 years ago

Here is my Dockerfile (quite simple). It works pretty well in my Neovim setup. I launch the server in a wrapper script like this podman run --rm -i localhost/ltex-ls "$@".

FROM alpine:3.15

ENV version=15.2.0

RUN apk add --no-cache openjdk11-jre-headless \
    && wget https://github.com/valentjn/ltex-ls/releases/download/${version}/ltex-ls-${version}.tar.gz \
    && tar -xzf ltex-ls-${version}.tar.gz \
    && mv ltex-ls-${version} ltex-ls \
    && rm -rf ltex-ls-${version}.tar.gz

ENTRYPOINT ["/ltex-ls/bin/ltex-ls"]

I will try messing with java in the next few days, and maybe can come up with a PR :) but note that I'm not really advanced with container (I mostly build local images for personal usage and have never used public registries).

folliehiyuki commented 2 years ago

Sorry for the late response. It's just a draft right now, but I've come up with this Dockerfile:

FROM alpine:latest AS builder
ENV version=15.2.0
# Install build dependencies
RUN apk add --no-cache openjdk11-jdk maven python3 \
    && ln -sf /usr/bin/python3 /usr/bin/python
# Download the release
RUN wget -q https://github.com/valentjn/ltex-ls/archive/refs/tags/${version}.tar.gz \
    && tar x -zf ${version}.tar.gz \
    && mv ltex-ls-${version} ltex-ls-src
# Build
WORKDIR /ltex-ls-src
RUN mvn verify -DskipTests \
    && tar x -zf target/ltex-ls-${version}.tar.gz \
    && mv ltex-ls-${version} /ltex-ls

FROM alpine:latest
# Install only runtime dependencies and add a normal user
RUN apk add --no-cache openjdk11-jre-headless \
    && adduser -D -s /sbin/nologin -h /ltex-ls ltex
USER ltex
# Copy artifacts from builder
WORKDIR /ltex-ls
COPY --from=builder /ltex-ls/ ./
# Entrypoint
ENTRYPOINT ["/ltex-ls/bin/ltex-ls"]

Build: docker build -f Dockerfile -t ltex-ls . Launch with wrapper script: docker run --rm -i localhost/ltex-ls "$@"

Some brief testing (with org, markdown, latex):

Some improvements I can think of:

Putting it here for some comments.

har7an commented 2 years ago

Hi, I'd like to add to this discussion. Personally I use podman instead of docker, and here's a shell script that can build a container using buildah:

#!/usr/bin/env bash
set -o errexit

LTEX_VERSION=15.2.0
LTEX_ARCHIVE="ltex-ls-$LTEX_VERSION-linux-x64.tar.gz"
BASE_IMAGE="registry.fedoraproject.org/fedora-minimal:36"

# Create a container
CONTAINER=$(buildah from "$BASE_IMAGE")
MOUNTPOINT=$(buildah mount $CONTAINER)

cp "$LTEX_ARCHIVE" "$MOUNTPOINT/"
pushd "$MOUNTPOINT"
tar -xf "$LTEX_ARCHIVE"
rm "$LTEX_ARCHIVE"
#rsync -vua --delete-after "ltex-ls-$LTEX_VERSION/" . 1>/dev/null
#ls -lR
popd

buildah unmount $CONTAINER

# Run ltex-ls
#ENTRYPOINT=$(printf "'[ \"/ltex-ls-%s/bin/ltex-ls\" ]'" "$LTEX_VERSION")
#buildah config --entrypoint "$ENTRYPOINT" $CONTAINER
buildah config --entrypoint '[ "/ltex-ls-15.2.0/bin/ltex-ls" ]' $CONTAINER
buildah config --cmd "" $CONTAINER

# Save the container to an image
buildah commit --squash $CONTAINER "localhost/ltex:$LTEX_VERSION"

You build the container with:

$ buildah unshare bash container.sh

Then you need a small wrapper around it, like so:

#!/usr/bin/env bash
podman run --rm -i localhost/ltex:15.2.0 "$@"

It assumes that you have the ltex archive for version 15.2 (as .tar.gz) in the same directory as the script. Unfortunately the container is based off of fedora-minimal:36. I tried to build an empty container from scratch that contains only the contents of the released archive, but that didn't work due to not being able to find some dynamic library (?). You can have a look at that yourself if you set the BASE_IMAGE=scratch.

I tested it in conjunction with nvim-lsp on plain text, a git commit, Markdown and Latex files. Works really well, thanks for writing this tool!

folliehiyuki commented 2 years ago

Thanks for the feedback @har7an. Sadly what I want to achieve from this request is a Dockerfile with build instruction from source (to make a reproducible build) and not a container image for the sake of having one.

I already got a working container image with the Github release. See comment https://github.com/valentjn/ltex-ls/issues/140#issuecomment-1049058764.

folliehiyuki commented 2 years ago

@valentjn I checked the CI configuration and realized that I forgot to generate the completion lists. This is my new Dockerfile, which seems to work fine for Markdown and LaTEX files (I still can't get things to work in Org file).

FROM maven:3-eclipse-temurin-11-alpine AS builder
ARG LTEX_VERSION=15.2.0
# Install build dependencies
RUN apk add --no-cache python3 \
    && ln -sf /usr/bin/python3 /usr/bin/python
# Download the release
RUN wget -q https://github.com/valentjn/ltex-ls/archive/refs/tags/${LTEX_VERSION}.tar.gz \
    && tar -xzf ${LTEX_VERSION}.tar.gz \
    && rm -vf ${LTEX_VERSION}.tar.gz \
    && mv -v ltex-ls-${LTEX_VERSION} ltex-ls-src
WORKDIR /ltex-ls-src
# Generate completion lists
RUN python -u tools/createCompletionLists.py
# Build
RUN mvn --quiet --errors package -DskipTests
# Package binary
RUN tar -xzf target/ltex-ls-${LTEX_VERSION}.tar.gz \
    && mv -v ltex-ls-${LTEX_VERSION} /ltex-ls

FROM eclipse-temurin:11-jre-alpine
# Add a normal user to run the program
RUN adduser -D -s /sbin/nologin -h /ltex-ls ltex
USER ltex
# Copy artifacts from builder
WORKDIR /ltex-ls
COPY --from=builder /ltex-ls/ ./
# Entrypoint
ENTRYPOINT ["/ltex-ls/bin/ltex-ls"]

Build: podman build -f Dockerfile -t ltex-ls . Run using a wrapper script:

#!/bin/sh

podman run \
    --cap-drop ALL \
    --security-opt no-new-privileges \
    --read-only \
    --rm --interactive \
    localhost/ltex-ls "$@"

The container image is built from the Github release. I can send a PR getting this into the repo (with some changes to fit your workflow).

sanmai-NL commented 1 year ago

@FollieHiyuki: Please do! Being able to reuse this container image saves a lot of electricity and time for all those using dev containers with ltex-ls.

BaptisteRoseau commented 1 month ago

I know this issue is quite old, but I made a Dockerfile a few months ago if that helps: https://github.com/valentjn/ltex-ls/pull/254