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.
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?