replace dockerfile (#1410)

* replaces Dockerfile using bazel-based build system

This commit updates the Dockerfile to work with anki's bazel-based build
system.

The anki Dockerfile was originally added in
https://github.com/ankitects/anki/pull/753 back in September 2020. The
file was moved to `docs/Dockerfile` in
0d354da93a, with a note that the file had
to be updated to work with anki's updated build system. The file
`docs/Dockerfile` was removed in
7cd2e9618f.

* install setuptools and wheel + xkb libraries

* install anki virtual env in fresh base image

* move Dockerfile out of root directory

* add readme file for dockerized anki
This commit is contained in:
Jakub Kaczmarzyk 2021-10-14 20:41:15 -04:00 committed by GitHub
parent 5f19d39f15
commit 183e45c698
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 179 additions and 0 deletions

67
docs/docker/Dockerfile Normal file
View file

@ -0,0 +1,67 @@
# This Dockerfile uses three stages.
# 1. Compile anki (and dependencies) and build python wheels.
# 2. Create a virtual environment containing anki and its dependencies.
# 3. Create a final image that only includes anki's virtual environment and required
# system packages.
ARG PYTHON_VERSION="3.9"
ARG DEBIAN_FRONTEND="noninteractive"
# Build anki.
FROM python:$PYTHON_VERSION AS build
RUN curl -fsSL https://github.com/bazelbuild/bazelisk/releases/download/v1.7.4/bazelisk-linux-amd64 \
> /usr/local/bin/bazel \
&& chmod +x /usr/local/bin/bazel \
# Bazel expects /usr/bin/python
&& ln -s /usr/local/bin/python /usr/bin/python
WORKDIR /opt/anki
COPY . .
# Build python wheels.
RUN ./scripts/build
# Install pre-compiled Anki.
FROM python:${PYTHON_VERSION}-slim as installer
WORKDIR /opt/anki/
COPY --from=build /opt/anki/bazel-dist/ wheels/
# Use virtual environment.
RUN python -m venv venv \
&& ./venv/bin/python -m pip install --no-cache-dir setuptools wheel \
&& ./venv/bin/python -m pip install --no-cache-dir /opt/anki/wheels/*.whl
# We use another build stage here so we don't include the wheels in the final image.
FROM python:${PYTHON_VERSION}-slim as final
COPY --from=installer /opt/anki/venv /opt/anki/venv
ENV PATH=/opt/anki/venv/bin:$PATH
# Install run-time dependencies.
RUN apt-get update \
&& apt-get install --yes --no-install-recommends \
libasound2 \
libdbus-1-3 \
libfontconfig1 \
libfreetype6 \
libgl1 \
libglib2.0-0 \
libnss3 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-randr0 \
libxcb-render-util0 \
libxcb-shape0 \
libxcb-xinerama0 \
libxcb-xkb1 \
libxcomposite1 \
libxcursor1 \
libxi6 \
libxkbcommon0 \
libxkbcommon-x11-0 \
libxrandr2 \
libxrender1 \
libxtst6 \
&& rm -rf /var/lib/apt/lists/*
# Add non-root user.
RUN useradd --create-home anki
USER anki
WORKDIR /work
ENTRYPOINT ["/opt/anki/venv/bin/anki"]
LABEL maintainer="Jakub Kaczmarzyk <jakub.kaczmarzyk@gmail.com>"

112
docs/docker/README.md Normal file
View file

@ -0,0 +1,112 @@
# Anki in Docker
This README contains the instructions for building and running the Anki Docker image.
Docker provides a standard for installing software on many systems
(Windows, macOS, Linux), and it allows one to build software without cluttering a system
with dependencies. The Dockerfile contains the instructions for building the Docker image,
and it also serves as instructions for how to build Anki from source on Linux.
# Build the Docker image
For best results, enable BuildKit (`export DOCKER_BUILDKIT=1`).
When in this current directory, one can build the Docker image like this:
```bash
docker build --tag anki --file Dockerfile ../../
```
When this is done, run `docker image ls` to see that the image has been created.
If one wants to build from the project's root directory, use this command:
```bash
docker build --tag anki --file docs/docker/Dockerfile .
```
# Run the Docker image
Anki starts a graphical user interface, and this requires some extra setup on the user's
end. These instructions were tested on Linux (Debian 11) and will have to be adapted for
other operating systems.
To allow the Docker container to pull up a graphical user interface, we need to run the
following:
```bash
xhost +local:root
```
Once done using Anki, undo this with
```bash
xhost -local:root
```
Then, we will construct our `docker run` command:
```bash
docker run --rm -it \
--name anki \
--volume $HOME/.local/share:$HOME/.local/share:rw \
--volume /etc/passwd:/etc/passwd:ro \
--user $(id -u):$(id -g) \
--volume /tmp/.X11-unix:/tmp/.X11-unix:rw \
--env DISPLAY=$DISPLAY \
anki
```
Here is a breakdown of some of the arguments:
- Mount the current user's `~/.local/share` directory onto the container. Anki saves things
into this directory, and if we don't mount it, we will lose any changes once the
container exits. We mount this as read-write (`rw`) because we want to make changes here.
```bash
--volume $HOME/.local/share:$HOME/.local/share:rw
```
- Mount `/etc/passwd` so we can enter the container as ourselves. We mount this as
read-only because we definitely do not want to modify this.
```bash
--volume /etc/passwd:/etc/passwd:ro
```
- Enter the container with our user ID and group ID, so we stay as ourselves.
```bash
--user $(id -u):$(id -g)
```
- Mount the X11 directory that allows us to open displays.
```bash
--volume /tmp/.X11-unix:/tmp/.X11-unix:rw
```
- Pass the `DISPLAY` variable to the container, so it knows where to display graphics.
```bash
--env DISPLAY=$DISPLAY
```
# Running Dockerized Anki easily from the command line
One can create a shell function that executes the `docker run` command. Then one can
simply run `anki` on the command line, and Anki will open in Docker. Make sure to change
the image name to whatever you used when building Anki.
```bash
anki() {
docker run --rm -it \
--name anki \
--volume $HOME/.local/share:$HOME/.local/share:rw \
--volume /etc/passwd:/etc/passwd:ro \
--user $(id -u):$(id -g) \
--volume /tmp/.X11-unix:/tmp/.X11-unix:rw \
--env DISPLAY=$DISPLAY \
anki "$@"
}
```