Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a docker image #973

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

Conversation

dairiki
Copy link
Contributor

@dairiki dairiki commented Dec 17, 2021

Here is a first crack at creating a docker image.

I am no docker guru. There are probably improvements to be made.

Currently, it is pushing an image into the package registry of my fork of the project.

Notes

The container expects the Lektor project source (the top-level directory which contains the .lektorproject file) to be mounted at /project. If no volume is explicitly mounted there, the container defaults to working on the example project.

Build output is written to /output.

If no command-line is passed to the container, it will run the lektor server on port 5000. To do something else, specify a full Lektor command line, e.g., lektor build when running the container.

As things are now, rsync, imagemagick and ffmpeg are installed, so thumbnailing and rsync publishing should work. (I have not tested these, however.)

As things stand, Node is not installed. This means that lektor-webpack will probably not work. (Perhaps this should be reconsidered.)

Currently, no local cache of PyPI packages is included in the image. That may be worth doing — not sure. (Lektor and it's dependencies are all installed, obviously, but it might be worth including a local wheel cache of common plugins and plugin dependencies.)

Examples

Edit the example project

If it all works as intended, you can edit the example site by doing something like

docker run -i --rm -p 5000:5000 ghcr.io/dairiki/lektor:feature.docker

Once it appears (from console output) that the server has fired up, browse to http://localhost:5000/.

Edit your own project

To edit your own project, mount your project directory at the container’s /project:

docker run -i --rm -p 5000:5000 -v /path/to/lektor/project:/project ghcr.io/dairiki/lektor:feature.docker

Build your project

To collect the built HTML, mount the directory you’d like the output written to to the container’s /output:

docker run -i --rm -v /path/to/project:/project -v /path/to/htdocs:/output ghcr.io/dairiki/lektor:feature.docker lektor build

Note that the build process will prune the output directory. It's probably best to start with an empty output directory.

Issue(s) Resolved

Fixes #970

Related Issues / Links

Description of Changes

  • Wrote at least one-line docstrings (for any new functions)
  • Added unit test(s) covering the changes (if testable)
  • Included a screenshot or animation (if affecting the UI, see Licecap)
  • Link to corresponding documentation pull request for getlektor.com

@dairiki dairiki added ci related to Lektor's continous integration deploy enhancement labels Dec 17, 2021
@dwt
Copy link

dwt commented Mar 29, 2022

Some comments after having a look at the image. I really like the distinction into builder and final image.

  • I would recommend adding a step that updates installed packages. While this makes the image larger, base images are updated very infrequently (about monthly or rarer) and it's the only way to build a local image that does not contain security problems the distribution has already fixed.
  • Normally I would recommend switching to a different user to actually run the custom code for security. I'm not quite sure this applies here to the same extent, as this is a tool image, not one that gets run as a server (for now). I would still apply the benefit of the doubt and switch to a custom user to actually install and run all code. Reasoning
  • I would really like to see a docker-compose.yml file added, as that makes it much easier to use docker files in everyday practice. I imagine the docker-compose file to be used as a template to deploy this image and feed it all the parameters (volumes mostly) that it requires. Then a simple docker compose up or docker compose run --rm lektor-build or docker compose up could be all that's needed to build or serve the website locally.

Those are my first thoughts - please feel free to ask if I should provide more example / more thourough reasoning.

@peterwwillis
Copy link

peterwwillis commented Jun 12, 2022

Couple comments:

  • Using COPY . . will blow away your Docker cache every time it runs. You only want to copy in files that have changes that are material to / will end up in your container. COPY . . will pull in your .git directory and other files that aren't code or data.
  • This doesn't build for me, NPM errors out with npm ERR! enoent ENOENT: no such file or directory, open '/build/lektor/admin/package.json'
  • I would not keep a default lektor version in there. You want this to fail early if for some reason a version wasn't passed; you don't want to accidentally push a new release with this default.
  • Do you really need the npm, ffmpeg, imagemagick, etc for the first container? I'd stick to something simple first, then look at how other vendors package their containers. Most end up with a janky templating thing so they can cut multiple containers with different bundled dependencies or base images.
  • I built your container and it came in at ~300MB; I then stripped it down to the essentials and it came in at 100MB. This is a great size for an initial image I think.
  • If you want to switch between using docker-compose and docker run, you have to take an environment variable as both a build argument and an environment variable and set the latter based on the former. It's a weird docker-compose thing.

Based on my tweaking, I came up with this:

ARG PYTHON_TAG=3.10-alpine3.15
FROM python:${PYTHON_TAG} AS base

WORKDIR /project
COPY example /project

WORKDIR /build
COPY frontend lektor tests pyproject.toml setup.cfg tox.ini ./

ARG LEKTOR_VERSION
ENV LEKTOR_VERSION=$LEKTOR_VERSION
ENV SETUPTOOLS_SCM_PRETEND_VERSION=$LEKTOR_VERSION
RUN pip install --no-cache-dir .

VOLUME /project
VOLUME /output
ARG LEKTOR_OUTPUT_PATH=/output
ENV LEKTOR_OUTPUT_PATH=$LEKTOR_OUTPUT_PATH

ARG LEKTOR_DEPLOY_USERNAME
ENV LEKTOR_DEPLOY_USERNAME=$LEKTOR_DEPLOY_USERNAME
ARG LEKTOR_DEPLOY_PASSWORD
ENV LEKTOR_DEPLOY_PASSWORD=$LEKTOR_DEPLOY_PASSWORD
ARG LEKTOR_DEPLOY_KEY_FILE
ENV LEKTOR_DEPLOY_KEY_FILE=$LEKTOR_DEPLOY_KEY_FILE
ARG LEKTOR_DEPLOY_KEY
ENV LEKTOR_DEPLOY_KEY=LEKTOR_DEPLOY_KEY

EXPOSE 5000

CMD ["lektor", "server", "--host", "0.0.0.0"]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ci related to Lektor's continous integration deploy enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create a Docker Image
3 participants