Search code examples
dockerhaskellhaskell-stack

Why is Stack complaining about the parent directory being owned by someone else?


Background: I want to develop a website with the back-end being an Haskell API (using the Yesod library) and I'm using Docker with three different services: one for the database, one for the API and one for the front-end.

Problem: I keep having permission issues with Stack and the Haskell Docker container.

Here's what my Dockerfile for the API looks like:

FROM haskell:9

WORKDIR /app

COPY . .

RUN stack setup
RUN stack install yesod-bin --install-ghc
RUN stack build

EXPOSE 8000

CMD ["stack", "exec", "--", "yesod", "devel"]

and the docker-compose file:

  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    user: 1000:1000
    stdin_open: true
    tty: true
    volumes:
      - ./api:/app
      - .stack-work
      - .stack-root
    ports:
      # host <-> container
      - 8000:3000
    env_file: ./env/yesod.env
    depends_on:
      - database

and here's the error I get when I try running docker-compose up --build api:

Preventing creation of stack root '/.stack/'. Parent directory '/' is owned by someone else.

I tried many different approaches, including all of those listed in there: https://vsupalov.com/docker-shared-permissions/

I also tried running the stack commands with the --allow-different-user option but none of those have resulted.


Solution

  • Stack normally creates it's main state directory at $HOME/.stack. So the parent directory is normally the user's home directory.

    Checking that the parent directory isn't owned by another user would be an important security feature in case it is run on a multi-user system, because Stack caches code and binaries under that path. If the .stack folder is inside a folder owned by a different user, then that other user could at any time swap out the .stack folder for a different one, tricking you into running whatever code they want. Even systems that are only ever used by a single human often have multiple user accounts for managing capabilities of various processes, and it could easily be important for security not to let one of them be capable of replacing code to be run by another, via control of the .stack folder.

    It looks like $HOME isn't set in your docker container, so it's ending up trying to create .stack in the root folder. You could set $HOME, or Stack probably has an environment variable or command line flag that will override the default location of the main state directory. Or are you supposed to have mounted the .stack-work or .stack-root folders in some particular place?