Logcat bad default path?

user@hostname:/volume1/docker/photostructure$ sudo docker exec -u photostructure -it photostructure bash
photostructure@68a5ef16b4a5:/opt/photostructure$ ./photostructure logcat --recent
LogTail(): Tailing /tmp/.photostructure-cache-1032/logs/**/*.log...

Two things:

  1. I am calling logcat, but the log says LogTail() was called. Is this right?
  2. What is /tmp/.photostructure-cache-1032/logs/**/*.log? The logs are being written to .photostructure/library/logs as per default. How come logcat tried to load that tmp/ stuff?

Thanks for reporting!

The last alpha build moved

ENV PS_IS_DOCKER=1

from the Dockerfile to the docker-entrypoint.sh because some docker container managers were exposing the ENV to the user, and I thought that would be equivalent.

Spoiler alert:

it isn’t. If you shell into the container, the docker-entrypoint.sh isn’t run:

$ docker exec -u photostructure -it 48dcf33ed4d3 bash
node@48dcf33ed4d3:/opt/photostructure$ env | grep DOCKER

So PhotoStructure thinks it’s on a normal server running Debian.

What is /tmp/.photostructure-cache-1032/logs/**/*.log?

It’s the default log directory on non-docker linux, if there isn’t a ~/.config dir.

I originally implemented one of the tests in this horrible set of heuristics, and finally threw up my hands and went with the explicit env approach, but I think checking /proc/1/comm for tini should should be simple enough and more reliable.

Until I get out a fix, be sure to run export PS_IS_DOCKER=1 after shelling into your PhotoStructure docker container, and things should work properly.

I’ll get this fix out today.

So… I didn’t release that day because I found other (several unrelated) issue(s), but here’s the final algorithm that is implemented in this upcoming build:


// NOTE TO THE FUTURE: we used to parse out the owner from /proc/1/cgroup but
// that is missing from UnRAID docker containers, and doesn't work for podman
// or other container managers.

// An alternative would be to see that `/proc/1/comm === "tini"`, but it'll be
// "sh" if someone starts the container with `docker run -it
// photostructure/server sh`. I could check for `/proc/1/comm !== "systemd"`,
// but that might not be valid for some random linux distribution.

// The Dockerfile (and Dockerfile-alpine) copy
// /etc/profile.d/photostructure-docker.sh into their respective Docker
// images, so this should be safe and sufficiently explicit.

// See
// https://stackoverflow.com/questions/20010199/
// for madness.

export const isDocker = lazy(
  () =>
    isLinux &&
    (toBoolean(process.env[PS_IS_DOCKER]) ??
      existsSync("/.running-in-container"))
)

So, in English, that means:

  1. if the PS_IS_DOCKER environment variable is set to a boolean-esque value (like “true” or “false”), use that.

  2. If not, use the presence of /.running-in-container to determine if we’re in a container. This is just an empty file dropped into the image by the Dockerfile.

Note that this filename doesn’t comply with any standard–because I couldn’t find one. If someone knows of an Actual Standard, I’m happy to switch to that, but I don’t want to use /.dockerenv (given that it’s Docker-specific, and they love to change stuff continuously).

Thank you @mrm I love that you share code snippets :slight_smile:

Dropping a file is the way to go – pragmatic, predictable.

What sets isLinux?

I get that from Node.js: Process | Node.js v20.10.0 Documentation