# A container for PyBitmessage daemon FROM ubuntu:bionic SHELL ["/bin/bash", "-exo", "pipefail", "-c"] # Install dependencies. update and install share a layer on purpose: split # across two, a cached update feeds install package lists that may be months # stale, and the install then fails or pulls something unintended. RUN apt-get update \ && apt-get install -yq --no-install-suggests --no-install-recommends \ build-essential libcap-dev libssl-dev \ python-all-dev python-msgpack python-pip python-setuptools \ git ## Do not use cache when building next layers of the image. ARG NOCACHE=0 WORKDIR /root/PyBitmessage RUN git clone https://github.com/Bitmessage/PyBitmessage . # Install RUN pip2 install jsonrpclib . # Raise the SQL-thread startup timeout from the stock 60 s. # # PyBitmessage kills the daemon outright if the SQL thread is not ready within # sql_timeout seconds (class_objectProcessor.py -> os._exit(1)). The startup # VACUUM of a messages.dat that has grown to a few hundred MB does not fit in # 60 s, and since the process dies mid-VACUUM lastvacuumtime is never updated, # so every later start retries the same doomed VACUUM and the node never comes # back. Measured: 26 s for a 264 MB database on an idle host, and the last # start that did survive used 36 s of the 60. # # The greps are load-bearing: the clone above is unpinned, so if upstream ever # moves or renames the constant, a silent no-op sed would ship an image that # looks fixed and is not. Fail the build instead. The .pyc is refreshed because # at runtime /usr/local is root-owned while the daemon runs as bitmessage, so a # stale one can only be recompiled to memory on every start. RUN f=/usr/local/lib/python2.7/dist-packages/pybitmessage/helper_sql.py \ && grep -q '^sql_timeout = 60$' "$f" \ && sed -i 's/^sql_timeout = 60$/sql_timeout = 600/' "$f" \ && grep -q '^sql_timeout = 600$' "$f" \ && rm -f "${f}c" \ && python -c "import py_compile; py_compile.compile('$f')" FROM ubuntu:bionic # 8442 is the XML-RPC API (keep it on loopback), 8444 the Bitmessage P2P port. # The daemon listens on both regardless; publishing 8444 is what makes the node # reachable for inbound peers. EXPOSE 8442/tcp EXPOSE 8444/tcp ENV USER_UID=2000 ENV USER_GID=2000 ENV HOME=/home/bitmessage ENV BITMESSAGE_HOME=${HOME} COPY --from=0 /usr/local/ /usr/local/ COPY ./docker/healthy_check.py /usr/local/bin/ COPY ./docker/seed_addr_gen.py /usr/local/bin/ COPY ./docker/run.sh /usr/local/bin/ # Install dependencies RUN apt-get update \ && apt-get install -yq --no-install-suggests --no-install-recommends python-setuptools moreutils gosu \ && rm -rf /var/lib/apt/lists/* # Create a user RUN addgroup --gid $USER_GID bitmessage ;\ useradd --uid $USER_UID --gid $USER_GID --skel /dev/null --create-home --home-dir $HOME bitmessage WORKDIR ${HOME} # Generate default config RUN su bitmessage -c "pybitmessage -t" CMD ["sh", "/usr/local/bin/run.sh"] ## Check PyBitmessage active network connections. ## The start period covers the startup VACUUM of messages.dat, which takes tens ## of seconds once the database reaches a few hundred MB; without it the ## container reports unhealthy for that whole window on every restart. HEALTHCHECK --retries=0 --interval=15s --start-period=180s \ CMD ["python", "/usr/local/bin/healthy_check.py"]