I try to have an auto rebuild & rexecute setup for my haskell RPC server code within a docker-compose service. The command is a bash script with stack build --file-watch
(and another command to start the binary when it changes but this works). The problem is that, no matter what I try, the stack build --file-watch
command fails with a cryptic error <stdin>: hGetLine: end of file
.
I do not understand why I get this error, especially because if I run the same command using docker-compose run bd-service bash -l -c "./bd-service/compile_hs_and_run.sh"
, it works as expected. I believe it's a problem of how bash is handled when docker-compose up is executed rather than a problem of stack itself, but I'll admit I'm clueless.
Also note that:
This is the service definition:
# this is my service definition in docker-compose.yml
bd-service:
build:
context: '.'
dockerfile: 'dockerfiles/bd_heroku_service.Dockerfile'
args:
UID: "$UID"
command: bash -l -c "./bd-service/compile_hs_and_run.sh"
user: "$UID"
volumes:
- .:/app/user
This is the relevant dockerfile:
# Inherit from bd_heroku_node image
FROM bd_heroku_node
ENV LANG en_US.UTF-8
# Stack stores binaries in /root/.local/bin
ENV PATH /root/.local/bin:$PATH
# Heroku assumes we'll put everything in /app/user
RUN mkdir -p /app/user/bd-service
WORKDIR /app/user
USER root
ARG STACK_VERSION=2.1.3
RUN wget -qO- https://github.com/commercialhaskell/stack/releases/download/v$STACK_VERSION/stack-$STACK_VERSION-linux-x86_64.tar.gz | tar xz --wildcards --strip-components=1 -C /usr/local/bin '*/stack'
USER appuser
# . here means the entire bd-bootstrap repo, context should be set accordingly (to bd-bootstrap)
RUN stack setup --resolver lts-14.10;
USER appuser
RUN mkdir -p /app/user/bd-common
RUN mkdir -p /app/user/bd-service
COPY bd-common/*.yaml /app/user/bd-common/
RUN cd /app/user/bd-common; stack build --only-dependencies;
RUN stack install fswatcher;
And then my bash file compile_hs_and_run:
#! /bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
echo "We are at "
pwd
echo "start";
stack build --verbose --file-watch
# The next command is commented because it works :
# /app/.local/bin/fswatcher --path /app/user/bd-service/.stack-work/install stack run bd-service-exe &
echo "it's over"
When starting with docker-compose up bd-service
it fails with these logs:
bd-service_1 | We are at
bd-service_1 | /app/user/bd-service
bd-service_1 | start
bd-service_1 | Version 2.1.3, Git revision 0fa51b9925decd937e4a993ad90cb686f88fa282 (7739 commits) x86_64 hpack-0.31.2
bd-service_1 | 2019-10-21 07:23:02.631167: [debug] Checking for project config at: /app/user/bd-service/stack.yaml
bd-service_1 | 2019-10-21 07:23:02.634794: [debug] Loading project config file stack.yaml
bd-service_1 | 2019-10-21 07:23:02.641395: [error] <stdin>: hGetLine: end of file
bd-service_1 | it's over
A simple workaround for my issue is to pipe cat to the stack build --file-watch.
I got inspired by this thread on stack exchange: https://unix.stackexchange.com/a/103893.
Thus replacing stack build --verbose --file-watch
by cat | stack build --verbose --file-watch
works like a charm. I do feel like this is not "normal" to some extent but whatever...
The thing that made it work is actually the stdin_open: true option in the docker-compose.yml, piping the cat
command didn't do anything...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With