xvfb-run hangs in container
Asked Answered
C

1

9

I'm trying to containerize a Node application that creates snapshots of .STL files. This application is started through xvfb-run to provide it a mock GUI in which it can generate said snapshots, and it works if I just run the application without a container, but when I try to containerize it, xvfb-run simply hangs. Nothing is printed in the container console, there are no logs, and adding -e /dev/stdout to xvfb-run doesn't output anything.

This is my dockerfile:

FROM debian:latest AS build-env
WORKDIR /app
COPY src ./src
COPY tsconfig.json ./
COPY package.json ./
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -my wget gnupg
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash
RUN apt-get install -y nodejs build-essential libxi-dev xvfb libgl1-mesa-dev libglu1-mesa-dev libglew-dev
RUN npm install .
RUN npm install -g typescript
RUN tsc
EXPOSE 3000
CMD ["xvfb-run", "node", "dist/examples/server.js"]

Example run (the cursor hangs there forever, nothing is ever printed)

example run

Edit: Just wanted to clarify that it IS supposed to print something - the Express server prints something when it starts, so I can tell it's not starting and something is wrong. I can also confirm that the xvfb-run command is present, as running it without any other arguments displays a help message.

Caritacaritas answered 1/6, 2018 at 1:18 Comment(1)
5 years later, get the same issue on raspberry pi as docker server. I try to run a java gui application inside the container. It works perfectly on raspberry it self but inside container cursor stops right after application start. Was you able to solve the issue? (init: true do not help for me) – Verditer
M
20

maybe late, but just saw your post. You probably need something like tini, so use --init flag when you do docker run. This will load init system as the ENTRYPOINT

Wine is a good example about how to use it

And to use it in docker-compose, just add init: true (inside the service).

I also found something similar, maybe it's useful for you too: stl-thumb

Hope it helps!

Edit to add more information, answering why

  • Containers are designed to run a single primary process. However, when running complex applications or scripts like xvfb-run, which might spawn child processes, managing these processes can become challenging. In a standard Linux environment, the init system (like systemd or SysVinit) is responsible for process management. In containers, this system isn't present by default.

  • Without an init system, terminated child processes might become zombie processes. These are processes that have completed execution but still have an entry in the process table. This occurs because the parent process has not read the status of its terminated child process. Over time, these zombie processes can accumulate, consuming system resources.

  • Tini (--init or init: true) acts as a minimal init system. It's a tiny utility that handles the reaping of zombie processes and performs signal forwarding. By using --init in docker run or setting init: true in Docker Compose, Tini is automatically added to your container and set as the entrypoint. This means it will handle process management, ensuring that when child processes exit, they don't turn into zombie processes.

As best practice, with Docker we should keep containers as simple as possible. However, when multi-process management is necessary, tools like Tini become essential for proper operation and resource management. πŸ˜‰

Magneto answered 19/1, 2020 at 18:35 Comment(3)
As of v1.13 Docker integrates tini when you use docker run --init – Figone
Can you explain the why? – Novitiate
Yes! Just added more information to my answer. Hope it helps! – Magneto

© 2022 - 2024 β€” McMap. All rights reserved.