2

I'm attempting to run lektor within a docker container and have hit a problem.

If I 'ADD' (or 'COPY') my source code folder within my Dockerfile, everything works perfectly but, of course, the container is then not dynamic and doesn't respond to changes in the code.

If, instead, I use a volume, the container becomes dynamic and lektor successfully rebuilds and serves my site as I make changes.

However, when I come to publish the site, an error appears in the container's log and it enters a never-ending loop:

Started build Debugging middleware caught exception in streamed response at a point where response headers were already sent. Traceback (most recent call last): File "/usr/local/lib/lektor/lib/python2.7/site-packages/lektor/admin/utils.py", line 18, in generate for event in chain(f(*args, **kwargs), (None,)): File "/usr/local/lib/lektor/lib/python2.7/site-packages/lektor/admin/modules/api.py", line 309, in generator for event in event_iter: File "/usr/local/lib/lektor/lib/python2.7/site-packages/lektor/publisher.py", line 639, in publish self.link_artifacts(path) File "/usr/local/lib/lektor/lib/python2.7/site-packages/lektor/publisher.py", line 602, in link_artifacts link(full_path, dst) OSError: [Errno 18] Invalid cross-device link

Minimal Dockerfile:

FROM python:2.7.11

RUN curl -sf https://www.getlektor.com/install.sh | \
  sed '/stdin/d;s/input = .*/return/' | \
  sh

I'm actually using docker-compose.

Minimal docker-compose.yml: version: '2' services: web: build: . ports: - "5000:5000" volumes: - .:/project working_dir: /project/source command: ['lektor', 'server', '--host', '0.0.0.0.']

(My project folder is structured such that the lektor project file and all the expected lektor folders are in the 'source' sub-folder).

meatballs
  • 3,917
  • 1
  • 15
  • 19
  • A quick google of 'invalid cross-device link' shows something with symbolic links. What does Lektor do when publishing (I've heard of it but not used it)? Is it possible it's trying to create symbolic links between volumes and something in the container? Maybe an issue there? Maybe permissions. Seems like the place to start. – johnharris85 Nov 09 '16 at 15:55
  • Yes, lektor is attempting to use links and it doesn't like the way the volume is mounted. – meatballs Nov 09 '16 at 16:03
  • It appears to be that the build process used hard links and the output folder is not in the source code path. Since the source code is a mounted volume and the build folder is elsewhere in the container, the two filesystems are different and the hard link fails. – meatballs Nov 09 '16 at 16:24
  • Assuming the output path is configurable? Guess you solved it? – johnharris85 Nov 09 '16 at 16:53
  • 1
    It's configurable via the command line, so yes, sort of! – meatballs Nov 09 '16 at 16:54
  • 2
    I raised an issue on lektor here: https://github.com/lektor/lektor/issues/315 – meatballs Nov 09 '16 at 16:54
  • I reckon that might sort it properly so that the wysiwig publishing would work too. – meatballs Nov 09 '16 at 16:55

1 Answers1

2

The lektor build process uses hard links and a temporary folder for the built files. If the source code is on a mounted volume (which it is in a docker volume), then the two filesystems are different and the linking fails as above.

Deploying and building via the command line and specifying the output path can get around the problem (described here: https://www.getlektor.com/docs/deployment/), but it's not a great solution within a Docker container where the aim is to make life as simple as possible.

The method that does the linking within lektor actually falls back to copying instead in some circumstances. I've created an issue (https://github.com/lektor/lektor/issues/315) suggesting that the fall back also occurs if the project and output folders are on different volumes. I suspect that would solve the problem properly.

das-g
  • 9,718
  • 4
  • 38
  • 80
meatballs
  • 3,917
  • 1
  • 15
  • 19