1

I have a Dockerfile which was originally pulling from ubuntu and I recently came across alpine which is more lightweight so would like to pull from that instead. Part of the code I'm trying to build is called Healpix which depends on cfitsio. When I originally built the ubuntu version I found this Dockerfile https://github.com/MilesCranmer/dockers/blob/master/dockerfiles/healpix.

Essentially the problem is the following works in ubuntu but not with alpine:

RUN echo "3\ngfortran\n\nY\n\n\ngcc\n\n\n\n\nN\n1\nY\nN\nN\n0\n" |
    ./configure && make

The error I get is

Something went wrong ...
Quitting configuration script !

./configure: exit: line 162: Illegal number: -1
The command '/bin/sh -c echo     "3\ngfortran\n\nY\n\n\ngcc\n\n\n\n\nN\n1\nY\nN\nN\n0\n" | ./configure     && make' returned a non-zero code: 2

somewhat confusingly the configure script in question isn't 162 lines long https://sourceforge.net/p/healpix/code/HEAD/tree/branches/branch_v350r1006/configure. I have tried installing bash and changing script to that but that didn't work.

ubuntu Dockerfile

FROM ubuntu
RUN apt-get update && apt-get install -y gcc g++ gfortran make wget
WORKDIR /home
RUN wget \ 
   http://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/cfitsio_latest.tar.gz \
   && tar xzf cfitsio_latest.tar.gz
WORKDIR cfitsio
RUN ./configure --prefix=/usr && make && make install
WORKDIR /home
RUN wget \
   https://sourceforge.net/projects/healpix/files/Healpix_3.50/Healpix_3.50_2018Dec10.tar.gz \
   && tar xzf Healpix*.tar.gz
WORKDIR Healpix_3.50
RUN echo \
    "3\ngfortran\n\nY\n\n\ngcc\n\n\n\n\nN\n1\nY\nN\nN\n0\n" | ./configure \
    && make

alpine Dockerfile

FROM alpine
RUN apk --no-cache add gcc g++ gfortran make wget
WORKDIR /home
RUN wget \ 
   http://heasarc.gsfc.nasa.gov/FTP/software/fitsio/c/cfitsio_latest.tar.gz \
   && tar xzf cfitsio_latest.tar.gz
WORKDIR cfitsio
RUN ./configure --prefix=/usr && make && make install
WORKDIR /home
RUN wget \
   https://sourceforge.net/projects/healpix/files/Healpix_3.50/Healpix_3.50_2018Dec10.tar.gz \
   && tar xzf Healpix*.tar.gz
WORKDIR Healpix_3.50
RUN echo \
    "3\ngfortran\n\nY\n\n\ngcc\n\n\n\n\nN\n1\nY\nN\nN\n0\n" | ./configure \
    && make
Paddy Roddy
  • 135
  • 2
  • 10
  • 1
    Have you checked the `./configure` script line 162 (where the error comes from)? Could you edit your question and post this script (at least the part returning the error)? – norbjd Mar 30 '19 at 14:17
  • @norbjd have edited the question – Paddy Roddy Mar 30 '19 at 14:43
  • I think the main problem here is the way you are passing arguments to your `./configure` script. You should use one of the solutions presented in that answer : https://stackoverflow.com/a/14397049 instead. – norbjd Mar 30 '19 at 15:00
  • will try but just curious why it works on ubuntu/macos like how I have it above though ^ – Paddy Roddy Mar 30 '19 at 15:03
  • 1
    The only difference I see is the shell used : to execute the script (see the shebang at the top of `./configure`), alpine uses `/bin/sh` -> `/bin/busybox`, while ubuntu uses `/bin/sh` -> `/bin/dash`. – norbjd Mar 30 '19 at 15:06

1 Answers1

5

TL;DR

In your Dockerfile, use :

RUN /bin/echo -e "3\ngfortran\n[...]" | ./configure && make

to have the same behavior on Ubuntu and Alpine.

Explanations

The ./configure script is executed with /bin/sh (see the shebang). On Ubuntu, /bin/sh is a link to /bin/dash, while on Alpine, /bin/sh is a link to /bin/busybox.

The following small example reproduces your problem.

Consider the following ./configure script :

#!/bin/sh

read -p "1st prompt : " first
read -p "2nd prompt : " second

echo "$first-$second"

On Ubuntu :

docker run --rm -v $PWD/configure:/configure ubuntu:18.04 \
    /bin/sh -c 'echo "a\nb" | ./configure'

prints :

a-b

While, on Alpine :

docker run --rm -v $PWD/configure:/configure alpine:3.8 \
    /bin/sh -c 'echo "a\nb" | ./configure'

prints :

anb-

On Alpine (busybox), the echoed string (a\nb) is interpreted as a single argument, while on Ubuntu (dash), the \n is used to separate both arguments.

To have the same behavior as Ubuntu on Alpine, you can run :

docker run --rm -v $PWD/configure:/configure alpine:3.8 /bin/sh -c 'echo "a                   
b                                                 
" | ./configure'

or :

docker run --rm -v $PWD/configure:/configure alpine:3.8 /bin/sh -c \
    'echo -e "a\nb" | ./configure'

(see the -e parameter of echo)

These 2 commands print :

a-b

As for your Dockerfile, you should write something like :

RUN /bin/echo -e "3\ngfortran\n[...]" | ./configure && make

/bin/echo is used instead of echo because on Ubuntu, echo -e "3\ngfortran\n[...]" will print -e 3\nngfortran\n[...].

This is because echo is parsed a shell built-in, while /bin/echo is explicitly not (source : https://github.com/moby/moby/issues/8949#issuecomment-61682684).

norbjd
  • 10,166
  • 4
  • 45
  • 80