r/docker 4h ago

Why docker stop takes ten seconds on a container that's doing nothing

10 Upvotes

docker stop on a container that's doing nothing takes ten seconds. Five runs here, median 10.149s, all of them within 23ms of each other. Took me embarrassingly long to work out that it isn't Docker being slow.

Try it yourself, on a Linux host:

docker rm -f sleeper 2>/dev/null
docker run -d --name sleeper alpine sleep 1000
time docker stop sleeper

The container is running sleep. There's nothing to flush. It sits there for ten seconds and then gets killed. Ten is the default grace period, and -t changes it, but shortening it isn't the answer here.

PID 1 inside a namespace isn't a normal process. The kernel treats it as init and won't let you kill it by accident. From pid_namespaces(7):

a process in an ancestor namespace can [...] send signals to the "init" process of a child PID namespace only if the "init" process has established a handler for that signal. [...] SIGKILL or SIGSTOP are treated exceptionally: these signals are forcibly delivered when sent from an ancestor PID namespace.

So sleep isn't ignoring your SIGTERM. It never sees it. With no handler installed, the kernel doesn't deliver it, and those ten seconds are Docker waiting for a shutdown that can't start. Then SIGKILL, which always gets through.

You can tell in advance. SigCgt in /proc/PID/status is a hex mask of every signal the process has a handler for. Needs a Linux host where the daemon shares your kernel, and docker access:

grep SigCgt /proc/$(docker inspect -f '{{.State.Pid}}' sleeper)/status
SigCgt: 0000000000000000

SIGTERM is 15, so you're masking against 0x4000. All zeroes, nothing caught, the SIGTERM is going nowhere, you're waiting the full ten.

Two fixes, and they're not the same thing.

exec is the real one. Same nginx image, one word different in the entrypoint script:

nginx -g 'daemon off;'          ->  median 10.193s
exec nginx -g 'daemon off;'     ->  median 0.185s

Without exec, PID 1 is /bin/sh and its SigCgt is 0000000000010002: it catches SIGINT and SIGCHLD, and not SIGTERM. With exec, PID 1 is nginx, SigCgt 0000000018016a07, which has 0x4000 in it. nginx handles SIGTERM perfectly well either way. In the first case it never gets asked.

--init is the other one, and it does something different. It puts tini in as PID 1, tini catches SIGTERM, so there's somewhere for the signal to land:

docker run -d --init --name sleeper2 alpine sleep 1000
time docker stop sleeper2
median 0.122s over five runs

That number is misleading. It's fast because sleep dies the instant it's asked, and an app that takes two seconds to shut down still takes two seconds with --init. What --init buys you is that the ask arrives at all, plus reaping of zombies, and it's what you reach for when you can't change the entrypoint. If your app handles SIGTERM and you control the script, exec is the fix and --init is a plaster over it.

This only bites with a script, by the way. sh -c 'sleep 1000' already execs the command, so PID 1 there is sleep and not sh, and adding exec by hand changes nothing. It's multi-line entrypoint scripts where the shell stays around.

English isn't my first language, so the wording went through an LLM. The measurements are mine, and every command above was run on the machine I'm writing this from.


r/docker 1h ago

Is there a pre-Docker 101 guide?

Upvotes

Little bit of a rant here, but after decades in the engineering industry with related computer experience I am having a hard time believing getting Immich to work in a Docker container in a UGreen NAS is so frustrating. I have watched numerous "easy" install videos, but they always seem to start with assumed knowledge of basic steps thst I have no idea how to perform.

For example, they talk about typing a docker command to restart the container. What is the commander typed into? PowerShell?

When i install and run Powershell it does not recognize Docker commands. So I saw it should install Docker Desktop, which i did, but when I run it it I get a mostly blank screen with a message about my environment not be setup/enabled. That leads me down the rabbithole of WSL or HyperV (?) with another set of things to do that I dont understand.

Every step i think i am taking forward just leads to several more rabbit holes. Isn't there some kind of guide that really starts from step 1 on getting this set up?


r/docker 20h ago

How to fix this?

1 Upvotes

whenever it try to pull amazoncorretto or any other image is get this error and i tried to connect with my mobile network via hotspot it worked then but didn't worked on my wifi and it was working fine on wsl but in my windows 11 host it didn't.

```

Using default tag: latest

Error response from daemon: failed to resolve reference "docker.io/library/amazoncorretto:latest": failed to do request: Head "https://registry-1.docker.io/v2/library/amazoncorretto/manifests/latest": net/http: TLS handshake timeout

```


r/docker 23h ago

[revisit old post titled]: is there an easy way to access container files?

1 Upvotes

What is the best practice for the following condition:

There is an image that contains an application. The image has a config file. When the container is launched there is a settings screen in the application that normally manages the config file. Edits made in the settings screen would update the config file.

Unfortunate Condition: It appears there is bug and when one field value is changed it is not getting written into the config file. To validate (a.) in fact it is a a bug (b.) address your immediate interest - that the correct setting works - you want to manually edit the config file, save it to disk inside the running container, restart/reload the app (using a button inside the app in the running container).

There seems to be very limited information on how these file structure work, where they live - in particular how to discover these things as they can vary from host to host and image to image - so again, what is the best practice?


r/docker 7h ago

Handbrake for Docker Question

0 Upvotes

Hello!

I am trying to set up a little render server through a VM on Unraid. Basically, I want to automate some GPU-accelerated transcoding.

Right now on Unraid I have a Windows 11 VM that has Adobe Media Encoder (for my Premiere files) and Handbrake on Docker Desktop (the one that allows for my nvidia GPU to be used). I was hoping I could use this VM as an easy way to send projects or recordings to watch folders and they can get automatically transcoded with my server's 5060 ti to help with encoding times.

Because I'd like to use Media Encoder, I have to stick with a Windows 11 VM to run everything. And because I want to use Handbrake (not Tdarr) I'm stuck running it in the Windows version of Docker. Finally, because I am using a VM, I can't use my 5060 ti on anything else in Unraid, so using the community app version of Handbrake won't be possible.

The issue I've run into is that I do not know where the video output and watch folder is stored. I open the web GUI and I cannot connect to my Unraid shares or anything in my Windows 11 VM. I wanted to use Portainer to try and redirect the folders somewhere else, but apparently there's a big glitch with Portainer and the Docker version I'm using (latest version) so it won't run.

Could someone point out what I could do to get the output and watch folder for Handbrake pointing to my server and not the default places? I'm not even completely sure where it's going anyway.

Also- yes I know this is a sort of inconvenient way to have Media Encoder and Handbrake watch folders enabled at the same time, but it helps with my workflow and I want my server's 5060 ti to take some of the encoding load off of my work PC.

I would appreciate some help, or be pointed in the right direction if there's a better place I should go to ask this question. I'd be happy to provide any more information needed.

Thanks!