Dockerfile for PureScript 0.14.2

I had a little chat with @paluh yesterday, and he encouraged me to share with you the results of my work.

I’ve been using PureScript for a couple of months, and I always used it with Docker containers. Recently, with the new 0.14.2 release, a different version of GLIBC was used to compile PureScript tools, and the standard Node.js images, available on hub.docker.com, no longer worked with them.

I managed to build a working image, based on Ubuntu 20.04, with node, npm, yarn, PureScript tools (compiler + spago), and terser (an npm package to compress JavaScript source files). The Dockerfile is based on the Node.js ones, from hub.docker.com, with my slight modifications. I tested it only for my one (and only) PureScript project, and it worked (at least tests were run).

For all those, who are not familiar with Docker, a short user’s guide:

(1) To build the image, in the directory, where the Dockerfile is stored:

$ docker build -t image/name:0.14.2 -f Dockerfile.name .

(2a) To start a container (and use it later to run both PS- and Node-related commands):

$ docker run --rm -it -v "$(pwd):/home/node/project" -w /home/node/project -u $UID:$GID image/name:0.14.2 /bin/bash

This command should be executed in the directory, where your Node/PS-based project is kept.

(2b) Or, as an alternative for (2a), you can also run only one command in Docker container:

$ docker run --rm -it -v "$(pwd):/home/node/project" -w /home/node/project -u $UID:$GID image/name:0.14.2 spago init

Here’s the Dockerfile. Feel free to use it, or to modify it to suit your needs better.

FROM ubuntu:20.04

RUN groupadd --gid 1000 node \
  && useradd --uid 1000 --gid node --shell /bin/bash --create-home node

ENV NODE_VERSION 14.17.0
ENV YARN_VERSION 1.22.5
ENV PURESCRIPT_VERSION 0.14.2
ENV SPAGO_VERSION 0.20.3
ENV TERSER_VERSION 5.7.0

RUN ARCH= && dpkgArch="$(dpkg --print-architecture)" \
    && case "${dpkgArch##*-}" in \
      amd64) ARCH='x64';; \
      ppc64el) ARCH='ppc64le';; \
      s390x) ARCH='s390x';; \
      arm64) ARCH='arm64';; \
      armhf) ARCH='armv7l';; \
      i386) ARCH='x86';; \
      *) echo "unsupported architecture"; exit 1 ;; \
    esac \
    && set -ex \
    # libatomic1 for arm
    && apt-get update && apt-get install -y ca-certificates curl wget gnupg dirmngr xz-utils libatomic1 --no-install-recommends \
    && rm -rf /var/lib/apt/lists/* \
    && for key in \
      4ED778F539E3634C779C87C6D7062848A1AB005C \
      94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
      74F12602B6F1C4E913FAA37AD3A89613643B6201 \
      71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
      8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \
      C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
      C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \
      DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
      A48C2BEE680E841632CD4E44F07496B3EB3C1762 \
      108F52B48DB57BB0CC439B2997B01419BD92F80A \
      B9E2F5981AA6E0CD28160D9FF13993A75599653C \
    ; do \
      gpg --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys "$key" || \
      gpg --batch --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys "$key" || \
      gpg --batch --keyserver hkp://pgp.mit.edu:80 --recv-keys "$key" ; \
    done \
    && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH.tar.xz" \
    && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
    && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
    && grep " node-v$NODE_VERSION-linux-$ARCH.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
    && tar -xJf "node-v$NODE_VERSION-linux-$ARCH.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
    && rm "node-v$NODE_VERSION-linux-$ARCH.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
    && for key in \
    6A010C5166006599AA17F08146C2130DFD2497F5 \
  ; do \
    gpg --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys "$key" || \
    gpg --batch --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys "$key" || \
    gpg --batch --keyserver hkp://pgp.mit.edu:80 --recv-keys "$key" ; \
  done \
    && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
    && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc" \
    && gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \
    && mkdir -p /opt \
    && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \
    && ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \
    && ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \
    && rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \
    && apt-mark auto '.*' > /dev/null \
    && find /usr/local -type f -executable -exec ldd '{}' ';' \
      | awk '/=>/ { print $(NF-1) }' \
      | sort -u \
      | xargs -r dpkg-query --search \
      | cut -d: -f1 \
      | sort -u \
      | xargs -r apt-mark manual \
    && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
    && ln -s /usr/local/bin/node /usr/local/bin/nodejs \
    # smoke tests
    && node --version \
    && npm --version \
    && yarn --version \
    # PureScript stuff
    && apt update \
    && apt install -y git \
    && npm install -g purescript@$PURESCRIPT_VERSION --unsafe-perm \
    && npm install -g spago@$SPAGO_VERSION --unsafe-perm \
    && npm install -g terser@$TERSER_VERSION \
    # smoke tests
    && purs --version \
    && spago --version \
    && terser --version

CMD [ "node" ]
5 Likes

Thanks for writing this up. I think this probably shouldn’t have happened, at least not without some kind of warning, so I’ve written up https://github.com/purescript/purescript/issues/4107.

1 Like