You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

15 KiB

Build Custom Node Images

Polar v1.0.0 supports using custom docker images for nodes in your networks. The instructions below will walk you through the process of creating custom images using the master branch of each implementation. There are some limitations, such as running as a non-root user to be compatible across multiple platforms. Feel free to customize these Dockerfiles to you specific needs.

Note: The Dockerfiles for each implementation will likely change in the future. Please be mindful to make updates as needed when necessary.

LND

  1. git clone https://github.com/lightningnetwork/lnd

  2. cd lnd

  3. Overwrite Dockerfile with the following:

    FROM golang:1.13-alpine as builder
    
    # Force Go to use the cgo based DNS resolver. This is required to ensure DNS
    # queries required to connect to linked containers succeed.
    ENV GODEBUG netdns=cgo
    
    # Pass a tag, branch or a commit using build-arg.  This allows a docker
    # image to be built from a specified Git state.  The default image
    # will use the Git tip of master by default.
    ARG checkout="master"
    
    # Install dependencies and build the binaries.
    RUN apk add --no-cache --update alpine-sdk \
        git \
        make \
        gcc \
    &&  git clone https://github.com/lightningnetwork/lnd /go/src/github.com/lightningnetwork/lnd \
    &&  cd /go/src/github.com/lightningnetwork/lnd \
    &&  git checkout $checkout \
    &&  make \
    &&  make install tags="signrpc walletrpc chainrpc invoicesrpc routerrpc"
    
    # Start a new, final image.
    FROM alpine as final
    
    # Define a root volume for data persistence.
    VOLUME /root/.lnd
    
    # Add bash and ca-certs, for quality of life and SSL-related reasons.
    RUN apk --no-cache add \
        bash \
        su-exec \
        ca-certificates
    
    # Copy the binaries from the builder image.
    COPY --from=builder /go/bin/lncli /bin/
    COPY --from=builder /go/bin/lnd /bin/
    
    COPY docker-entrypoint.sh /entrypoint.sh
    
    RUN chmod a+x /entrypoint.sh
    # Expose lnd ports (p2p, rpc).
    VOLUME ["/home/lnd/.lnd"]
    
    EXPOSE 9735 8080 10000
    
    # Specify the start command and entrypoint as the lnd daemon.
    ENTRYPOINT ["/entrypoint.sh"]
    
    CMD ["lnd"]
    
  4. Create a new file named docker-entrypoint.sh with the following contents

    #!/bin/sh
    set -e
    
    # containers on linux share file permissions with hosts.
    # assigning the same uid/gid from the host user
    # ensures that the files can be read/write from both sides
    if ! id lnd > /dev/null 2>&1; then
      USERID=${USERID:-1000}
      GROUPID=${GROUPID:-1000}
    
      echo "adding user lnd ($USERID:$GROUPID)"
      addgroup -g $GROUPID lnd
      adduser -D -u $USERID -G lnd lnd
    fi
    
    if [ $(echo "$1" | cut -c1) = "-" ]; then
      echo "$0: assuming arguments for lnd"
    
      set -- lnd "$@"
    fi
    
    if [ "$1" = "lnd" ] || [ "$1" = "lncli" ]; then
      echo "Running as lnd user: $@"
      exec su-exec lnd "$@"
    fi
    
    echo "$@"
    exec "$@"
    
    
  5. docker build -t lnd-master .

c-lightning

  1. git clone https://github.com/ElementsProject/lightning.git

  2. cd lightning

  3. Overwrite Dockerfile with the following:

    # This dockerfile is meant to compile a c-lightning x64 image
    # It is using multi stage build:
    # * downloader: Download litecoin/bitcoin and qemu binaries needed for c-lightning
    # * builder: Compile c-lightning dependencies, then c-lightning itself with static linking
    # * final: Copy the binaries required at runtime
    # The resulting image uploaded to dockerhub will only contain what is needed for runtime.
    # From the root of the repository, run "docker build -t yourimage:yourtag ."
    FROM debian:stretch-slim as downloader
    
    RUN set -ex \
      && apt-get update \
      && apt-get install -qq --no-install-recommends ca-certificates dirmngr wget
    
    WORKDIR /opt
    
    RUN wget -qO /opt/tini "https://github.com/krallin/tini/releases/download/v0.18.0/tini" \
        && echo "12d20136605531b09a2c2dac02ccee85e1b874eb322ef6baf7561cd93f93c855 /opt/tini" | sha256sum -c - \
        && chmod +x /opt/tini
    
    ARG BITCOIN_VERSION=0.17.0
    ENV BITCOIN_TARBALL bitcoin-${BITCOIN_VERSION}-x86_64-linux-gnu.tar.gz
    ENV BITCOIN_URL https://bitcoincore.org/bin/bitcoin-core-$BITCOIN_VERSION/$BITCOIN_TARBALL
    ENV BITCOIN_ASC_URL https://bitcoincore.org/bin/bitcoin-core-$BITCOIN_VERSION/SHA256SUMS.asc
    
    RUN mkdir /opt/bitcoin && cd /opt/bitcoin \
        && wget -qO $BITCOIN_TARBALL "$BITCOIN_URL" \
        && wget -qO bitcoin.asc "$BITCOIN_ASC_URL" \
        && grep $BITCOIN_TARBALL bitcoin.asc | tee SHA256SUMS.asc \
        && sha256sum -c SHA256SUMS.asc \
        && BD=bitcoin-$BITCOIN_VERSION/bin \
        && tar -xzvf $BITCOIN_TARBALL $BD/bitcoin-cli --strip-components=1 \
        && rm $BITCOIN_TARBALL
    
    ENV LITECOIN_VERSION 0.16.3
    ENV LITECOIN_PGP_KEY FE3348877809386C
    ENV LITECOIN_URL https://download.litecoin.org/litecoin-${LITECOIN_VERSION}/linux/litecoin-${LITECOIN_VERSION}-x86_64-linux-gnu.tar.gz
    ENV LITECOIN_ASC_URL https://download.litecoin.org/litecoin-${LITECOIN_VERSION}/linux/litecoin-${LITECOIN_VERSION}-linux-signatures.asc
    ENV LITECOIN_SHA256 686d99d1746528648c2c54a1363d046436fd172beadaceea80bdc93043805994
    
    # install litecoin binaries
    RUN mkdir /opt/litecoin && cd /opt/litecoin \
        && wget -qO litecoin.tar.gz "$LITECOIN_URL" \
        && echo "$LITECOIN_SHA256  litecoin.tar.gz" | sha256sum -c - \
        && BD=litecoin-$LITECOIN_VERSION/bin \
        && tar -xzvf litecoin.tar.gz $BD/litecoin-cli --strip-components=1 --exclude=*-qt \
        && rm litecoin.tar.gz
    
    FROM debian:stretch-slim as builder
    
    ENV LIGHTNINGD_VERSION=master
    RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates autoconf automake build-essential git libtool python python3 python3-mako wget gnupg dirmngr git gettext
    
    RUN wget -q https://zlib.net/zlib-1.2.11.tar.gz \
    && tar xvf zlib-1.2.11.tar.gz \
    && cd zlib-1.2.11 \
    && ./configure \
    && make \
    && make install && cd .. && rm zlib-1.2.11.tar.gz && rm -rf zlib-1.2.11
    
    RUN apt-get install -y --no-install-recommends unzip tclsh \
    && wget -q https://www.sqlite.org/2018/sqlite-src-3260000.zip \
    && unzip sqlite-src-3260000.zip \
    && cd sqlite-src-3260000 \
    && ./configure --enable-static --disable-readline --disable-threadsafe --disable-load-extension \
    && make \
    && make install && cd .. && rm sqlite-src-3260000.zip && rm -rf sqlite-src-3260000
    
    RUN wget -q https://gmplib.org/download/gmp/gmp-6.1.2.tar.xz \
    && tar xvf gmp-6.1.2.tar.xz \
    && cd gmp-6.1.2 \
    && ./configure --disable-assembly \
    && make \
    && make install && cd .. && rm gmp-6.1.2.tar.xz && rm -rf gmp-6.1.2
    
    WORKDIR /opt/lightningd
    COPY . /tmp/lightning
    RUN git clone --recursive /tmp/lightning . && \
        git checkout $(git --work-tree=/tmp/lightning --git-dir=/tmp/lightning/.git rev-parse HEAD)
    
    #################### Polar Modification
    # This line is modified to enable developer command line flags
    # Original line: ARG DEVELOPER=0
    ARG DEVELOPER=1
    ####################
    RUN ./configure --prefix=/tmp/lightning_install --enable-static && make -j3 DEVELOPER=${DEVELOPER} && make install
    
    FROM debian:stretch-slim as final
    COPY --from=downloader /opt/tini /usr/bin/tini
    RUN apt-get update && apt-get install -y --no-install-recommends socat inotify-tools \
        && rm -rf /var/lib/apt/lists/*
    
    ENV LIGHTNINGD_DATA=/root/.lightning
    ENV LIGHTNINGD_RPC_PORT=9835
    ENV LIGHTNINGD_PORT=9735
    
    RUN mkdir $LIGHTNINGD_DATA && \
        touch $LIGHTNINGD_DATA/config
    VOLUME [ "/root/.lightning" ]
    COPY --from=builder /tmp/lightning_install/ /usr/local/
    COPY --from=downloader /opt/bitcoin/bin /usr/bin
    COPY --from=downloader /opt/litecoin/bin /usr/bin
    #################### Polar Modification
    # This line is removed as we have our own entrypoint file
    # Original line: COPY tools/docker-entrypoint.sh entrypoint.sh
    ####################
    
    #########################
    # END ElementsProject/lightning/Dockerfile
    #########################
    
    # install nodejs
    RUN apt-get update -y \
      && apt-get install -y curl gosu git \
      && curl -sL https://deb.nodesource.com/setup_12.x | bash - \
      && apt-get install -y nodejs \
      && apt-get clean \
      && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    
    # install c-lightning-REST API plugin
    RUN git clone https://github.com/Ride-The-Lightning/c-lightning-REST.git /opt/c-lightning-rest/ \
      && cd /opt/c-lightning-rest \
      && npm install \
      && chmod -R a+rw /opt/c-lightning-rest
    
    COPY docker-entrypoint.sh /entrypoint.sh
    
    RUN chmod a+x /entrypoint.sh
    
    VOLUME ["/home/clightning"]
    VOLUME ["/opt/c-lightning-rest/certs"]
    
    EXPOSE 9735 8080 10000
    
    ENTRYPOINT ["/entrypoint.sh"]
    
    CMD ["lightningd"]
    
    
  4. Create a new file named docker-entrypoint.sh with the following contents

    #!/bin/sh
    set -e
    
    # give bitcoind a second to bootup
    sleep 1
    
    # containers on linux share file permissions with hosts.
    # assigning the same uid/gid from the host user
    # ensures that the files can be read/write from both sides
    if ! id clightning > /dev/null 2>&1; then
      USERID=${USERID:-1000}
      GROUPID=${GROUPID:-1000}
    
      echo "adding user clightning ($USERID:$GROUPID)"
      groupadd -f -g $GROUPID clightning
      useradd -r -u $USERID -g $GROUPID clightning
      # ensure correct ownership of user home dir
      mkdir -p /home/clightning
      chown clightning:clightning /home/clightning
    fi
    
    if [ $(echo "$1" | cut -c1) = "-" ]; then
      echo "$0: assuming arguments for lightningd"
    
      set -- lightningd "$@"
    fi
    
    # TODO: investigate hsmd error on Windows
    # https://gist.github.com/jamaljsr/404c20f99be2f77fff2d834e2449158b
    
    if [ "$1" = "lightningd" ] || [ "$1" = "lightning-cli" ]; then
      echo "Running as clightning user: $@"
      exec gosu clightning "$@"
    fi
    
    echo "$@"
    exec "$@"
    
  5. docker build -t c-lightning-master .

Eclair

  1. git clone https://github.com/ACINQ/eclair.git

  2. cd eclair

  3. Overwrite Dockerfile with the following:

    FROM adoptopenjdk/openjdk11:jdk-11.0.3_7-alpine as BUILD
    
    # Setup maven, we don't use https://hub.docker.com/_/maven/ as it declare .m2 as volume, we loose all mvn cache
    # We can alternatively do as proposed by https://github.com/carlossg/docker-maven#packaging-a-local-repository-with-the-image
    # this was meant to make the image smaller, but we use multi-stage build so we don't care
    RUN apk add --no-cache curl tar bash
    
    ARG MAVEN_VERSION=3.6.3
    ARG USER_HOME_DIR="/root"
    ARG SHA=c35a1803a6e70a126e80b2b3ae33eed961f83ed74d18fcd16909b2d44d7dada3203f1ffe726c17ef8dcca2dcaa9fca676987befeadc9b9f759967a8cb77181c0
    ARG BASE_URL=https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries
    
    RUN mkdir -p /usr/share/maven /usr/share/maven/ref \
      && curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
      && echo "${SHA}  /tmp/apache-maven.tar.gz" | sha512sum -c - \
      && tar -xzf /tmp/apache-maven.tar.gz -C /usr/share/maven --strip-components=1 \
      && rm -f /tmp/apache-maven.tar.gz \
      && ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
    
    ENV MAVEN_HOME /usr/share/maven
    ENV MAVEN_CONFIG "$USER_HOME_DIR/.m2"
    
    # Let's fetch eclair dependencies, so that Docker can cache them
    # This way we won't have to fetch dependencies again if only the source code changes
    # The easiest way to reliably get dependencies is to build the project with no sources
    WORKDIR /usr/src
    COPY pom.xml pom.xml
    COPY eclair-core/pom.xml eclair-core/pom.xml
    COPY eclair-node/pom.xml eclair-node/pom.xml
    COPY eclair-node-gui/pom.xml eclair-node-gui/pom.xml
    COPY eclair-node/modules/assembly.xml eclair-node/modules/assembly.xml
    COPY eclair-node-gui/modules/assembly.xml eclair-node-gui/modules/assembly.xml
    RUN mkdir -p eclair-core/src/main/scala && touch eclair-core/src/main/scala/empty.scala
    # Blank build. We only care about eclair-node, and we use install because eclair-node depends on eclair-core
    RUN mvn install -pl eclair-node -am
    RUN mvn clean
    
    # Only then do we copy the sources
    COPY . .
    
    # And this time we can build in offline mode, specifying 'notag' instead of git commit
    RUN mvn package -pl eclair-node -am -DskipTests -Dgit.commit.id=notag -Dgit.commit.id.abbrev=notag -o
    # It might be good idea to run the tests here, so that the docker build fail if the code is bugged
    
    # We currently use a debian image for runtime because of some jni-related issue with sqlite
    FROM openjdk:11.0.4-jre-slim
    WORKDIR /app
    
    # install jq for eclair-cli
    RUN apt-get update && apt-get install -y bash jq curl unzip gosu
    
    # copy and install eclair-cli executable
    COPY --from=BUILD /usr/src/eclair-core/eclair-cli .
    RUN chmod +x eclair-cli && mv eclair-cli /sbin/eclair-cli
    
    # we only need the eclair-node.zip to run
    COPY --from=BUILD /usr/src/eclair-node/target/eclair-node-*.zip ./eclair-node.zip
    RUN unzip eclair-node.zip && mv eclair-node-* eclair-node
    
    #################### Polar Modification
    # Original lines:
    # ENV ECLAIR_DATADIR=/data
    # ENV JAVA_OPTS=
    # RUN mkdir -p "$ECLAIR_DATADIR"
    # VOLUME [ "/data" ]
    # ENTRYPOINT java $JAVA_OPTS -Declair.datadir=$ECLAIR_DATADIR -jar eclair-node.jar
    ENV ECLAIR_DATADIR=/home/eclair/
    RUN chmod -R a+x eclair-node/*
    RUN ls -al eclair-node/bin
    
    COPY docker-entrypoint.sh /entrypoint.sh
    
    RUN chmod a+x /entrypoint.sh
    
    VOLUME ["/home/eclair"]
    
    EXPOSE 9735 8080
    
    ENTRYPOINT ["/entrypoint.sh"]
    
    CMD $JAVA_OPTS bash eclair-node/bin/eclair-node.sh -Declair.datadir=$ECLAIR_DATADIR
    ####################
    
    
  4. Create a new file named docker-entrypoint.sh with the following contents

    #!/usr/bin/env bash
    set -e
    
    # give bitcoind a second to bootup
    sleep 1
    
    # containers on linux share file permissions with hosts.
    # assigning the same uid/gid from the host user
    # ensures that the files can be read/write from both sides
    if ! id eclair > /dev/null 2>&1; then
      USERID=${USERID:-1000}
      GROUPID=${GROUPID:-1000}
    
      echo "adding user eclair ($USERID:$GROUPID)"
      groupadd -f -g $GROUPID eclair
      useradd -r -u $USERID -g $GROUPID eclair
      # ensure correct ownership of user home dir
      mkdir -p /home/eclair
      chown eclair:eclair /home/eclair
    fi
    
    if [ "$1" = "polar-eclair" ]; then
      # convert command line args to JAVA_OPTS
      JAVA_OPTS=""
      for arg in "$@"
      do
        if [ "${arg:0:2}" = "--" ]; then
          JAVA_OPTS="$JAVA_OPTS -Declair.${arg:2}"
        fi
      done
      # trim leading/trailing whitespace
      JAVA_OPTS="$(sed -e 's/[[:space:]]*$//' <<<${JAVA_OPTS})"
    
      echo "Running as eclair user:"
      echo "bash eclair-node/bin/eclair-node.sh $JAVA_OPTS"
      exec gosu eclair bash eclair-node/bin/eclair-node.sh $JAVA_OPTS
    fi
    
    echo "Running: $@"
    exec "$@"
    
  5. docker build -t eclair-master .