From 893c25d73f518b53373c3d724bb806dc19f79fe6 Mon Sep 17 00:00:00 2001
From: Gilles Filippini <pini@debian.org>
Date: Mon, 10 May 2021 10:47:52 +0200
Subject: [PATCH 1/5] build(docker): WORKDIR = Duniter home

And force option '--home /var/lib/duniter' in the wrapper when not given.

It should help when running an interactive shell into the instance.
---
 release/docker/Dockerfile           | 6 +++---
 release/docker/docker-entrypoint.sh | 3 ---
 release/docker/duniter.sh           | 7 +++++++
 3 files changed, 10 insertions(+), 6 deletions(-)
 create mode 100755 release/docker/duniter.sh

diff --git a/release/docker/Dockerfile b/release/docker/Dockerfile
index 10e3a137f..fefac8c94 100644
--- a/release/docker/Dockerfile
+++ b/release/docker/Dockerfile
@@ -46,8 +46,8 @@ RUN mkdir -p /var/lib/duniter /etc/duniter && chown duniter:duniter /var/lib/dun
 # copy the build artifact from the build stage
 COPY --from=build --chown=duniter:duniter /duniter/work /duniter
 
-# install duniter executable symlink
-RUN ln -s /duniter/bin/duniter /usr/bin/duniter
+# copy duniter wrapper
+COPY release/docker/duniter.sh /usr/bin/duniter
 
 # copy entrypoint
 COPY release/docker/docker-entrypoint.sh /
@@ -61,7 +61,7 @@ EXPOSE 9220 10901 20901 30901
 
 # use duniter user
 USER duniter
-WORKDIR /duniter
+WORKDIR /var/lib/duniter
 
 ENTRYPOINT ["/docker-entrypoint.sh"]
 CMD []
diff --git a/release/docker/docker-entrypoint.sh b/release/docker/docker-entrypoint.sh
index 33fea165a..9b22adcc7 100755
--- a/release/docker/docker-entrypoint.sh
+++ b/release/docker/docker-entrypoint.sh
@@ -78,9 +78,6 @@ if [ $# = 0 ]; then
   set -- direct_webstart
 fi
 
-# Set --home option
-set -- --home "$home" "$@"
-
 # Start duniter
 echo Starting duniter with:
 echo /usr/bin/duniter "$@"
diff --git a/release/docker/duniter.sh b/release/docker/duniter.sh
new file mode 100755
index 000000000..d224e4524
--- /dev/null
+++ b/release/docker/duniter.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+cd /duniter
+if [ "$1" != --home ]; then
+  set -- --home /var/lib/duniter "$@"
+fi
+exec bin/duniter "$@"
+
-- 
GitLab


From 6169dffb305fe76b211ac298e74ed2b8dcca47af Mon Sep 17 00:00:00 2001
From: Gilles Filippini <pini@debian.org>
Date: Wed, 12 May 2021 16:37:24 +0200
Subject: [PATCH 2/5] feat(docker): entrypoint: use 'set -uo pipefail'

---
 release/docker/docker-entrypoint.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/release/docker/docker-entrypoint.sh b/release/docker/docker-entrypoint.sh
index 9b22adcc7..f32367309 100755
--- a/release/docker/docker-entrypoint.sh
+++ b/release/docker/docker-entrypoint.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-set -u
+set -uo pipefail
 
 function boolean () {
   echo "$1" | sed -E 's/^(true|yes|1)$/true/i'
-- 
GitLab


From 2587a56ecf1af1f4a93061de9ab4a724c456a56a Mon Sep 17 00:00:00 2001
From: Gilles Filippini <pini@debian.org>
Date: Wed, 12 May 2021 16:37:46 +0200
Subject: [PATCH 3/5] feat(docker): bootstrap conf.json and peers.db

Add new Docker environment variable: `DUNITER_PEER_HOST` (default to
`DUNITER_SYNC_HOST`).

When `conf.json` doesn't exist and `DUNITER_PEER_HOST` designs a remote
node, bootstrap currency parameters from this node into the configuration
file.

When `peers.db` doesn't exist and `DUNITER_PEER_HOST` designs a remote node,
use `sync $DUNITER_SYNC_HOST --only-peers` to have its endpoints into
`peers.db`.
---
 release/docker/docker-entrypoint.sh | 42 ++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/release/docker/docker-entrypoint.sh b/release/docker/docker-entrypoint.sh
index f32367309..7529dfcad 100755
--- a/release/docker/docker-entrypoint.sh
+++ b/release/docker/docker-entrypoint.sh
@@ -11,12 +11,14 @@ if [ "$DEBUG_ENTRYPOINT" = true ]; then
   set -x
 fi
 
+# Initialize vars
 home=/var/lib/duniter
 home_default=$home/duniter_default
-
 manual_config="$(boolean "${DUNITER_MANUAL_CONFIG:-false}")"
 auto_sync="$(boolean "${DUNITER_AUTO_SYNC:-false}")"
+DUNITER_PEER_HOST="${DUNITER_PEER_HOST:-${DUNITER_SYNC_HOST:-}}"
 
+# Create default profile path
 mkdir -p "$home/duniter_default"
 
 # Manual config when enabled
@@ -52,6 +54,44 @@ if [ "$manual_config" = true ]; then
   fi
 fi
 
+# If conf.json doesn't exist and we have DUNITER_PEER_HOST, then initialise it with
+# the currency parameters
+host_regex='[a-zA-Z0-9](([a-zA-Z0-9]|-)*[a-zA-Z0-9]+)?(\.[a-zA-Z0-9](([a-zA-Z0-9]|-)*[a-zA-Z0-9]+)?)*'
+ipv6_regex='((([0–9A-Fa-f]{1,4}:){7}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){6}:[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){5}:([0–9A-Fa-f]{1,4}:)?[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){4}:([0–9A-Fa-f]{1,4}:){0,2}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){3}:([0–9A-Fa-f]{1,4}:){0,3}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){2}:([0–9A-Fa-f]{1,4}:){0,4}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){6}((b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b).){3}(b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b))|(([0–9A-Fa-f]{1,4}:){0,5}:((b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b).){3}(b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b))|(::([0–9A-Fa-f]{1,4}:){0,5}((b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b).){3}(b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b))|([0–9A-Fa-f]{1,4}::([0–9A-Fa-f]{1,4}:){0,5}[0–9A-Fa-f]{1,4})|(::([0–9A-Fa-f]{1,4}:){0,6}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){1,7}:))'
+
+if ! [ -f "$home_default/conf.json" ] && echo "${DUNITER_PEER_HOST}" | grep -E "^($host_regex|$ipv6_regex)(:[0-9]+)?$"; then
+  echo "No config file - Initializing currency from '$DUNITER_PEER_HOST'..."
+  port="${DUNITER_PEER_HOST#*:}"
+  if [ "${port:-443}" = 443 ]; then
+    scheme=https://
+  else
+    scheme=http://
+  fi
+  if wget -q -O- "$scheme$DUNITER_PEER_HOST/blockchain/parameters" >"$home_default/conf.json.new"; then
+    mv "$home_default/conf.json.new" "$home_default/conf.json"
+  else
+    echo -e "$big_fat_warning Failed."
+  fi
+fi
+
+# If peers.db is missing and DUNITER_PEER_HOST is set, bootstrap it using
+# 'sync --only-peers'
+# Working into a temporary Duniter home to avoid side effects on the current
+# database
+if ! [ -f "$home_default/peers.db" ] && [ -n "${DUNITER_PEER_HOST:-}" ]; then
+  echo "No peers database - Initializing from '$DUNITER_PEER_HOST'..."
+  rm -fr /tmp/duniter-bootstrap
+  (
+    cd /duniter
+    if bin/duniter --home /tmp/duniter-bootstrap sync "$DUNITER_PEER_HOST" --no-interactive --only-peers; then
+      mv /tmp/duniter-bootstrap/duniter_default/peers.db "$home_default/"
+    else
+      echo -e "$big_fat_warning Failed."
+    fi
+  )
+  rm -fr /tmp/duniter-bootstrap
+fi
+
 # Auto start synchronization when enabled and starting from scratch
 if [ "$auto_sync" = true ]; then
   if ! [ -d "$home_default/data" ]; then
-- 
GitLab


From bd21845322e02d55c04fda3cfe721d90e6eca432 Mon Sep 17 00:00:00 2001
From: Gilles Filippini <pini@debian.org>
Date: Wed, 12 May 2021 19:52:13 +0200
Subject: [PATCH 4/5] ref(docker) home_default -> profile_default

---
 release/docker/docker-entrypoint.sh | 46 ++++++++++++++---------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/release/docker/docker-entrypoint.sh b/release/docker/docker-entrypoint.sh
index 7529dfcad..f3e6e4847 100755
--- a/release/docker/docker-entrypoint.sh
+++ b/release/docker/docker-entrypoint.sh
@@ -13,7 +13,7 @@ fi
 
 # Initialize vars
 home=/var/lib/duniter
-home_default=$home/duniter_default
+profile_default=$home/duniter_default
 manual_config="$(boolean "${DUNITER_MANUAL_CONFIG:-false}")"
 auto_sync="$(boolean "${DUNITER_AUTO_SYNC:-false}")"
 DUNITER_PEER_HOST="${DUNITER_PEER_HOST:-${DUNITER_SYNC_HOST:-}}"
@@ -24,33 +24,33 @@ mkdir -p "$home/duniter_default"
 # Manual config when enabled
 if [ "$manual_config" = true ]; then
   # Do not start until a configuration file was initialized
-  while ! [ -f "$home_default/conf.json.orig" ]; do
-    echo "Waiting for initial configuration file... Please copy your configuration file to '$home_default/conf.json.orig'"
+  while ! [ -f "$profile_default/conf.json.orig" ]; do
+    echo "Waiting for initial configuration file... Please copy your configuration file to '$profile_default/conf.json.orig'"
     sleep 10
   done
   echo "Configuration file found. Continuing..."
   # Use new conf.json.orig when changed
-  md5_file="$home_default/conf.json.orig.md5"
+  md5_file="$profile_default/conf.json.orig.md5"
   if ! md5sum -c "$md5_file"; then
-    if [ -f "$home_default/conf.json" ]; then
-      echo "Backing up old configuration file to '$home_default/conf.json.old'..."
-      mv $home_default/conf.json $home_default/conf.json.old
+    if [ -f "$profile_default/conf.json" ]; then
+      echo "Backing up old configuration file to '$profile_default/conf.json.old'..."
+      mv $profile_default/conf.json $profile_default/conf.json.old
     fi
     echo "Installing new configuration file..."
-    cp "$home_default/conf.json.orig" "$home_default/conf.json"
-    md5sum "$home_default/conf.json.orig" >"$md5_file"
+    cp "$profile_default/conf.json.orig" "$profile_default/conf.json"
+    md5sum "$profile_default/conf.json.orig" >"$md5_file"
   fi
   # Log differences between initial, old and current conf file
-  jq --sort-keys -r . "$home_default/conf.json.orig" >"$home_default/conf.json.orig.sorted"
-  jq --sort-keys -r . "$home_default/conf.json" >"$home_default/conf.json.sorted"
-  if [ -f "$home_default/conf.json.old" ]; then
-    jq --sort-keys -r . "$home_default/conf.json.old" >"$home_default/conf.json.old.sorted"
-    if ! diff -q "$home_default/conf.json.old.sorted" "$home_default/conf.json.orig.sorted"; then
-      diff -u "$home_default/conf.json.old.sorted" "$home_default/conf.json.orig.sorted"
+  jq --sort-keys -r . "$profile_default/conf.json.orig" >"$profile_default/conf.json.orig.sorted"
+  jq --sort-keys -r . "$profile_default/conf.json" >"$profile_default/conf.json.sorted"
+  if [ -f "$profile_default/conf.json.old" ]; then
+    jq --sort-keys -r . "$profile_default/conf.json.old" >"$profile_default/conf.json.old.sorted"
+    if ! diff -q "$profile_default/conf.json.old.sorted" "$profile_default/conf.json.orig.sorted"; then
+      diff -u "$profile_default/conf.json.old.sorted" "$profile_default/conf.json.orig.sorted"
     fi
   fi
-  if ! diff -q "$home_default/conf.json.orig.sorted" "$home_default/conf.json.sorted"; then
-    diff -u "$home_default/conf.json.orig.sorted" "$home_default/conf.json.sorted"
+  if ! diff -q "$profile_default/conf.json.orig.sorted" "$profile_default/conf.json.sorted"; then
+    diff -u "$profile_default/conf.json.orig.sorted" "$profile_default/conf.json.sorted"
   fi
 fi
 
@@ -59,7 +59,7 @@ fi
 host_regex='[a-zA-Z0-9](([a-zA-Z0-9]|-)*[a-zA-Z0-9]+)?(\.[a-zA-Z0-9](([a-zA-Z0-9]|-)*[a-zA-Z0-9]+)?)*'
 ipv6_regex='((([0–9A-Fa-f]{1,4}:){7}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){6}:[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){5}:([0–9A-Fa-f]{1,4}:)?[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){4}:([0–9A-Fa-f]{1,4}:){0,2}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){3}:([0–9A-Fa-f]{1,4}:){0,3}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){2}:([0–9A-Fa-f]{1,4}:){0,4}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){6}((b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b).){3}(b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b))|(([0–9A-Fa-f]{1,4}:){0,5}:((b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b).){3}(b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b))|(::([0–9A-Fa-f]{1,4}:){0,5}((b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b).){3}(b((25[0–5])|(1d{2})|(2[0–4]d)|(d{1,2}))b))|([0–9A-Fa-f]{1,4}::([0–9A-Fa-f]{1,4}:){0,5}[0–9A-Fa-f]{1,4})|(::([0–9A-Fa-f]{1,4}:){0,6}[0–9A-Fa-f]{1,4})|(([0–9A-Fa-f]{1,4}:){1,7}:))'
 
-if ! [ -f "$home_default/conf.json" ] && echo "${DUNITER_PEER_HOST}" | grep -E "^($host_regex|$ipv6_regex)(:[0-9]+)?$"; then
+if ! [ -f "$profile_default/conf.json" ] && echo "${DUNITER_PEER_HOST}" | grep -E "^($host_regex|$ipv6_regex)(:[0-9]+)?$"; then
   echo "No config file - Initializing currency from '$DUNITER_PEER_HOST'..."
   port="${DUNITER_PEER_HOST#*:}"
   if [ "${port:-443}" = 443 ]; then
@@ -67,8 +67,8 @@ if ! [ -f "$home_default/conf.json" ] && echo "${DUNITER_PEER_HOST}" | grep -E "
   else
     scheme=http://
   fi
-  if wget -q -O- "$scheme$DUNITER_PEER_HOST/blockchain/parameters" >"$home_default/conf.json.new"; then
-    mv "$home_default/conf.json.new" "$home_default/conf.json"
+  if wget -q -O- "$scheme$DUNITER_PEER_HOST/blockchain/parameters" >"$profile_default/conf.json.new"; then
+    mv "$profile_default/conf.json.new" "$profile_default/conf.json"
   else
     echo -e "$big_fat_warning Failed."
   fi
@@ -78,13 +78,13 @@ fi
 # 'sync --only-peers'
 # Working into a temporary Duniter home to avoid side effects on the current
 # database
-if ! [ -f "$home_default/peers.db" ] && [ -n "${DUNITER_PEER_HOST:-}" ]; then
+if ! [ -f "$profile_default/peers.db" ] && [ -n "${DUNITER_PEER_HOST:-}" ]; then
   echo "No peers database - Initializing from '$DUNITER_PEER_HOST'..."
   rm -fr /tmp/duniter-bootstrap
   (
     cd /duniter
     if bin/duniter --home /tmp/duniter-bootstrap sync "$DUNITER_PEER_HOST" --no-interactive --only-peers; then
-      mv /tmp/duniter-bootstrap/duniter_default/peers.db "$home_default/"
+      mv /tmp/duniter-bootstrap/duniter_default/peers.db "$profile_default/"
     else
       echo -e "$big_fat_warning Failed."
     fi
@@ -94,7 +94,7 @@ fi
 
 # Auto start synchronization when enabled and starting from scratch
 if [ "$auto_sync" = true ]; then
-  if ! [ -d "$home_default/data" ]; then
+  if ! [ -d "$profile_default/data" ]; then
     echo "No 'data' folder. "
     if [ -z "$DUNITER_SYNC_HOST:-" ]; then
       echo "DUNITER_SYNC_HOST undefined. Can't start synchronization!"
-- 
GitLab


From 1ed8dc9871650a101c54e1402add06c6a9b2ee96 Mon Sep 17 00:00:00 2001
From: Gilles Filippini <pini@debian.org>
Date: Sun, 9 May 2021 21:50:31 +0200
Subject: [PATCH 5/5] doc(docker): fix volume /etc/duniter description

---
 doc/use/docker.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/use/docker.md b/doc/use/docker.md
index 3cb43386c..be3e79529 100644
--- a/doc/use/docker.md
+++ b/doc/use/docker.md
@@ -35,7 +35,7 @@ Restart the stopped node:
 
 ### Volumes
 
-The container creates 2 docker volumes. The first one is mounted under `/etc/duniter` and contains the Duniter configuration. The other one is mounted under the Duniter home directory, i.e. `/var/lib/duniter`. This is the place the Duniter database will be stored.
+The container creates 2 docker volumes. The first one is mounted under the Duniter home directory, i.e. `/var/lib/duniter`. This is the place the Duniter configuration files and database will be stored. The other one is mounted under `/etc/duniter` which is where it is recommended to store the keyfile when the instance is a member node, so that the keyfile is kept separated from the - potentially - volatile data.
 
 See more about managing volumes with docker in the [docker documentation](https://docs.docker.com/storage/volumes/).
 
-- 
GitLab