diff --git a/doc/use/docker.md b/doc/use/docker.md index 1b660f5f2d3f4bfb08f3de046405ce1ef78840bf..49df4a6dfcc8f3705b51fc995d6034673cc7092b 100644 --- a/doc/use/docker.md +++ b/doc/use/docker.md @@ -4,7 +4,7 @@ Build this image: - docker build . -t duniter/duniter + docker build . -t duniter/duniter -f release/docker/Dockerfile ## Usage @@ -59,6 +59,41 @@ When no parameters are given, `duniter` is called with the command `direct_webst Note that you should not call duniter with daemon command (`webstart` or `start`) if you run docker with `-d` parameter, because the docker image will then immediately stop. +## Environment variables + +To ease the deployment automation, three environment variables are available: + +* DUNITER_MANUAL_CONFIG (boolean, default = false) + + When set to 'true' (or 'yes', or '1'), the entrypoint script waits until the file + '/etc/duniter/conf.json.orig' is present before starting the duniter + service. Here is the workflow when enabled: + 1. wait for '/etc/duniter/conf.json.orig' + 2. if this file was changed since the previous startup: + 1. Save 'conf.json' to 'conf.json.old' + 2. Replace 'conf.json' with 'conf.json.orig' + 3. Save the new file's checksum to compare with at next startup + 3. continue the startup sequence + + When set to false, the startup sequence continues. + +* DUNITER_AUTO_SYNC (boolean, default = false) + Requires 'DUNITER_SYNC_HOST'. + + When set to 'true' (or 'yes', or '1') and the folder + '/var/lib/duniter/duniter_default/data' doesn't exist, a 'duniter sync' + command will be issued before starting the service. + + When set to false, the service is started directly. + +* DUNITER_SYNC_HOST (hostname, default = "") + + This is the 'host:port' parameter to use with 'duniter sync' when + 'DUNITER_AUTO_SYNC' is enabled. + + The synchronization won't be launched when the variable is not defined + or empty. + ## Test develop version To test develop version on G1-test network: diff --git a/release/docker/Dockerfile b/release/docker/Dockerfile index f45486c7582e526d8c0137867b12d077c9b95c0e..e609085bdf171488099a780b29091169b9a9c2f9 100644 --- a/release/docker/Dockerfile +++ b/release/docker/Dockerfile @@ -36,6 +36,9 @@ RUN PATH=${HOME}/.cargo/bin:${PATH} \ FROM node:10-alpine +# install jq +RUN apk add jq + # create group and user duniter RUN addgroup -S -g 1111 duniter && \ adduser -SD -h /duniter -G duniter -u 1111 duniter @@ -49,6 +52,9 @@ RUN cp /duniter/duniter/docker.sh /usr/bin/duniter && \ chmod +x /usr/bin/duniter && \ chown duniter:duniter /usr/bin/duniter +# copy entrypoint +COPY release/docker/docker-entrypoint.sh / + # create volumes VOLUME /var/lib/duniter VOLUME /etc/duniter @@ -60,5 +66,5 @@ EXPOSE 9220 10901 20901 USER duniter WORKDIR /duniter -ENTRYPOINT ["/usr/bin/duniter"] +ENTRYPOINT ["/docker-entrypoint.sh"] CMD [] diff --git a/release/docker/docker-entrypoint.sh b/release/docker/docker-entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..ed93a0c0ca5e10270f4ca909660b992ab7597fe3 --- /dev/null +++ b/release/docker/docker-entrypoint.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +home=/var/lib/duniter +config=/etc/duniter +home_default=$home/duniter_default + +function boolean () { + echo "$1" | sed -E 's/^(true|yes|1)$/true/i' +} + +manual_config="$(boolean "${DUNITER_MANUAL_CONFIG:-false}")" +auto_sync="$(boolean "${DUNITER_AUTO_SYNC:-false}")" + +# Use path /etc/duniter/conf.json +if ! [ -f "$config/conf.json" ] && [ -f "$home_default/conf.json" ]; then + mv "$home_default/conf.json" "$conf/conf.json" +fi +mkdir -p "$home/duniter_default" +ln -fs "$config/conf.json" "$home_default/conf.json" + +# Manual config when enabled +if [ "$manual_config" = true ]; then + # Do not start until a configuration file was initialized + while ! [ -f "$config/conf.json.orig" ]; do + echo "Waiting for initial configuration file... Please copy your configuration file to '$config/conf.json.orig'" + sleep 10 + done + echo "Configuration file found. Continuing..." + # Use new conf.json.orig when changed + md5_file="$config/conf.json.orig.md5" + if ! md5sum -c "$md5_file"; then + if [ -f "$config/conf.json" ]; then + echo "Backing up old configuration file to '$config/conf.json.old'..." + mv $config/conf.json $config/conf.json.old + fi + echo "Installing new configuration file..." + cp "$config/conf.json.orig" "$config/conf.json" + md5sum "$config/conf.json.orig" >"$md5_file" + fi + # Log differences between initial, old and current conf file + jq --sort-keys -r . "$config/conf.json.orig" >"$config/conf.json.orig.sorted" + jq --sort-keys -r . "$config/conf.json" >"$config/conf.json.sorted" + if [ -f "$config/conf.json.old" ]; then + jq --sort-keys -r . "$config/conf.json.old" >"$config/conf.json.old.sorted" + if ! diff -q "$config/conf.json.old.sorted" "$config/conf.json.orig.sorted"; then + diff -u "$config/conf.json.old.sorted" "$config/conf.json.orig.sorted" + fi + fi + if ! diff -q "$config/conf.json.orig.sorted" "$config/conf.json.sorted"; then + diff -u "$config/conf.json.orig.sorted" "$config/conf.json.sorted" + fi +fi + +# Auto start synchronization when enabled and starting from scratch +if [ "$auto_sync" = true ]; then + if ! [ -d "$home_default/data" ]; then + echo "No 'data' folder. " + if [ -z "$DUNITER_SYNC_HOST" ]; then + echo "DUNITER_SYNC_HOST undefined. Can't start synchronization!" + else + echo "Starting synchronization..." + /usr/bin/duniter sync --home "$home" "$DUNITER_SYNC_HOST" + fi + fi +fi + +# Start duniter +echo Starting duniter with: +echo /usr/bin/duniter "$@" +/usr/bin/duniter "$@"