From 561803c0a75a73abe3a392c080d6678b84a31891 Mon Sep 17 00:00:00 2001
From: neilpang <neil@neilpang.com>
Date: Sat, 1 Jun 2019 22:30:25 +0800
Subject: [PATCH 1/8] add deploy hook to docker containers

---
 Dockerfile       |   1 +
 deploy/docker.sh | 264 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 265 insertions(+)
 create mode 100755 deploy/docker.sh

diff --git a/Dockerfile b/Dockerfile
index 0e8b58d0..8a7fd039 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,6 +8,7 @@ RUN apk update -f \
   curl \
   socat \
   tzdata \
+  tar \
   && rm -rf /var/cache/apk/*
 
 ENV LE_CONFIG_HOME /acme.sh
diff --git a/deploy/docker.sh b/deploy/docker.sh
new file mode 100755
index 00000000..57081cc1
--- /dev/null
+++ b/deploy/docker.sh
@@ -0,0 +1,264 @@
+#!/usr/bin/env sh
+
+#DEPLOY_DOCKER_CONTAINER_LABEL="xxxxxxx"
+#DOCKER_HOST=/var/run/docker.sock | tcp://localhost:8888
+
+
+#DEPLOY_DOCKER_CONTAINER_KEY_FILE="/path/to/key.pem"
+#DEPLOY_DOCKER_CONTAINER_CERT_FILE="/path/to/cert.pem"
+#DEPLOY_DOCKER_CONTAINER_CA_FILE="/path/to/ca.pem"
+#DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/path/to/fullchain.pem"
+#DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload"
+
+_DEPLOY_DOCKER_WIKI="http://xxxxxx"
+
+_DOCKER_HOST_DEFAULT="/var/run/docker.sock"
+
+docker_deploy() {
+  _cdomain="$1"
+  _ckey="$2"
+  _ccert="$3"
+  _cca="$4"
+  _cfullchain="$5"
+
+  if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then
+    _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container."
+    _err "See: $_DEPLOY_DOCKER_WIKI"
+  fi
+
+  _savedomainconf DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
+
+  if [ "$DOCKER_HOST" ]; then
+    _saveaccountconf DOCKER_HOST "$DOCKER_HOST"
+  fi
+
+  if _exists docker && docker version | grep -i docker >/dev/null; then
+    _info "Using docker command"
+    export _USE_DOCKER_COMMAND=1
+  else
+    export _USE_DOCKER_COMMAND=
+  fi
+
+  export _USE_UNIX_SOCKET=
+  if [ -z "$_USE_DOCKER_COMMAND" ]; then
+    export _USE_REST=
+    if [ "$DOCKER_HOST" ]; then
+      _debug "Try use docker host: $DOCKER_HOST"
+      export _USE_REST=1
+    else
+      export _DOCKER_SOCK="$_DOCKER_HOST_DEFAULT"
+      _debug "Try use $_DOCKER_SOCK"
+      if [ ! -e "$_DOCKER_SOCK" ] || [ ! -w "$_DOCKER_SOCK" ]; then
+        _err "$_DOCKER_SOCK is not available"
+        return 1
+      fi
+      export _USE_UNIX_SOCKET=1
+      if ! _exists "curl"; then
+        _err "Please install curl first."
+        _err "We need curl to work."
+        return 1
+      fi
+      if ! _check_curl_version; then
+        return 1
+      fi
+    fi
+  fi
+
+  if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
+    _savedomainconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
+  fi
+
+  if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
+    _savedomainconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
+  fi
+
+  if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
+    _savedomainconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
+  fi
+
+  if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
+    _savedomainconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
+  fi
+
+  if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
+    _savedomainconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
+  fi
+
+  _cid="$(_get_id "$DEPLOY_DOCKER_CONTAINER_LABEL")"
+  _info "Container id: $_cid"
+  if [ -z "$_cid" ]; then
+    _err "can not find container id"
+    return 1
+  fi
+
+  if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
+    if ! _docker_cp "$_cid" "$_ckey" "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"; then
+      return 1
+    fi
+  fi
+
+  if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
+    if ! _docker_cp "$_cid" "$_ccert" "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"; then
+      return 1
+    fi
+  fi
+
+  if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
+    if ! _docker_cp "$_cid" "$_cca" "$DEPLOY_DOCKER_CONTAINER_CA_FILE"; then
+      return 1
+    fi
+  fi
+
+  if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
+    if ! _docker_cp "$_cid" "$_cfullchain" "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"; then
+      return 1
+    fi
+  fi
+
+  if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
+    if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then
+      return 1
+    fi
+  fi
+  return 0
+}
+
+#label
+_get_id() {
+  _label="$1"
+  if [ "$_USE_DOCKER_COMMAND" ]; then
+    docker ps -f label="$_label" --format "{{.ID}}"
+  elif [ "$_USE_REST" ]; then
+    _err "Not implemented yet."
+    return 1
+  elif [ "$_USE_UNIX_SOCKET" ]; then
+    _req="{\"label\":[\"$_label\"]}"
+    _debug2 _req "$_req"
+    _req="$(printf "%s" "$_req" | _url_encode)"
+    _debug2 _req "$_req"
+    listjson="$(_curl_unix_sock "${_DOCKER_SOCK:-$_DOCKER_HOST_DEFAULT}" GET "/containers/json?filters=$_req")" 
+    _debug2 "listjson" "$listjson"
+    echo "$listjson" | tr '{,' '\n' | grep -i '"id":' | _head_n 1 | cut -d '"' -f 4
+  else
+    _err "Not implemented yet."
+    return 1
+  fi
+}
+
+#id  cmd
+_docker_exec() {
+  _eargs="$@"
+  _debug2 "_docker_exec $_eargs"
+  _dcid="$1"
+  shift
+  if [ "$_USE_DOCKER_COMMAND" ]; then
+    docker exec -i "$_dcid" $@
+  elif [ "$_USE_REST" ]; then
+    _err "Not implemented yet."
+    return 1
+  elif [ "$_USE_UNIX_SOCKET" ]; then
+    _cmd="$@"
+    _cmd="$(printf "$_cmd" | sed 's/ /","/g')"
+    _debug2 _cmd "$_cmd"
+    #create exec instance:
+    cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"$_cmd\"]}")";
+    _debug2 cjson "$cjson"
+    execid="$(echo "$cjson" | cut -d '"' -f 4)"
+    _debug execid "$execid"
+    ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")";
+    _debug2 ejson "$ejson"
+  else
+    _err "Not implemented yet."
+    return 1
+  fi
+}
+
+#id from  to
+_docker_cp() {
+  _dcid="$1"
+  _from="$2"
+  _to="$3"
+  _info "Copying file from $_from to $_to"
+  _dir="$(dirname "$_to")"
+  _docker_exec "$_dcid" mkdir -p "$_dir"
+  if [ "$_USE_DOCKER_COMMAND" ]; then
+    cat "$_from" | _docker_exec "$_dcid" tee "$_to" >/dev/null
+    if [ "$?" = "0" ]; then
+      _info "Success"
+      return 0
+    else
+      _info "Error"
+      return 1
+    fi
+  elif [ "$_USE_REST" ]; then
+    _err "Not implemented yet."
+    return 1
+  elif [ "$_USE_UNIX_SOCKET" ]; then
+    _frompath="$_from"
+    if _startswith "$_frompath" '/'; then
+      _frompath="$(echo "$_from" | cut -b 2- )" #remove the first '/' char
+    fi
+    _debug2 "_frompath" "$_frompath"
+    _toname="$(basename "$_to")"
+    _debug2 "_toname" "$_toname"
+    if ! tar --transform="s,$_frompath,$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then
+      _err "copy error"
+      return 1
+    fi
+    return 0
+  else
+    _err "Not implemented yet."
+    return 1
+  fi
+
+}
+
+#sock method  endpoint data content-type
+_curl_unix_sock() {
+  _socket="$1"
+  _method="$2"
+  _endpoint="$3"
+  _data="$4"
+  _ctype="$5"
+  if [ -z "$_ctype" ]; then
+    _ctype="Content-Type: application/json"
+  fi
+  _debug _data "$_data"
+  _debug2 "url" "http://localhost$_endpoint"
+  if [ "$_CURL_NO_HOST" ]; then
+    _cux_url="http:$_endpoint"
+  else
+    _cux_url="http://localhost$_endpoint"
+  fi
+
+  if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
+    curl -vvv --silent --unix-socket "$_socket" -X $_method --data-binary "$_data" --header "$_ctype" "$_cux_url"
+  else
+    curl      --silent --unix-socket "$_socket" -X $_method --data-binary "$_data" --header "$_ctype" "$_cux_url"
+  fi
+
+}
+
+_check_curl_version() {
+  _cversion="$(curl -V | grep '^curl ' | cut -d ' ' -f 2)"
+  _debug2 "_cversion" "$_cversion"
+
+  _major="$(_getfield "$_cversion" 1 '.')"
+  _debug2 "_major" "$_major"
+
+  _minor="$(_getfield "$_cversion" 2 '.')"
+  _debug2 "_minor" "$_minor"
+
+  if [ "$_major$_minor" -lt "740" ]; then
+    _err "curl v$_cversion doesn't support unit socket"
+    return 1
+  fi
+  if [ "$_major$_minor" -lt "750" ]; then
+    _debug "Use short host name"
+    export _CURL_NO_HOST=1
+  else
+    export _CURL_NO_HOST=
+  fi
+  return 0
+}
+

From 0bbaa51945f882c1197f64ccb8c4522cd4d3b304 Mon Sep 17 00:00:00 2001
From: neilpang <neil@neilpang.com>
Date: Sun, 2 Jun 2019 10:05:24 +0800
Subject: [PATCH 2/8] fix format

---
 deploy/docker.sh | 33 +++++++++++++++++----------------
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/deploy/docker.sh b/deploy/docker.sh
index 57081cc1..0e22ddc8 100755
--- a/deploy/docker.sh
+++ b/deploy/docker.sh
@@ -1,8 +1,6 @@
 #!/usr/bin/env sh
 
 #DEPLOY_DOCKER_CONTAINER_LABEL="xxxxxxx"
-#DOCKER_HOST=/var/run/docker.sock | tcp://localhost:8888
-
 
 #DEPLOY_DOCKER_CONTAINER_KEY_FILE="/path/to/key.pem"
 #DEPLOY_DOCKER_CONTAINER_CERT_FILE="/path/to/cert.pem"
@@ -10,7 +8,7 @@
 #DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/path/to/fullchain.pem"
 #DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload"
 
-_DEPLOY_DOCKER_WIKI="http://xxxxxx"
+_DEPLOY_DOCKER_WIKI="https://github.com/Neilpang/acme.sh/wiki/deploy-to-docker-containers"
 
 _DOCKER_HOST_DEFAULT="/var/run/docker.sock"
 
@@ -20,7 +18,7 @@ docker_deploy() {
   _ccert="$3"
   _cca="$4"
   _cfullchain="$5"
-
+  _debug _cdomain "$_cdomain"
   if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then
     _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container."
     _err "See: $_DEPLOY_DOCKER_WIKI"
@@ -136,7 +134,7 @@ _get_id() {
     _debug2 _req "$_req"
     _req="$(printf "%s" "$_req" | _url_encode)"
     _debug2 _req "$_req"
-    listjson="$(_curl_unix_sock "${_DOCKER_SOCK:-$_DOCKER_HOST_DEFAULT}" GET "/containers/json?filters=$_req")" 
+    listjson="$(_curl_unix_sock "${_DOCKER_SOCK:-$_DOCKER_HOST_DEFAULT}" GET "/containers/json?filters=$_req")"
     _debug2 "listjson" "$listjson"
     echo "$listjson" | tr '{,' '\n' | grep -i '"id":' | _head_n 1 | cut -d '"' -f 4
   else
@@ -147,25 +145,25 @@ _get_id() {
 
 #id  cmd
 _docker_exec() {
-  _eargs="$@"
+  _eargs="$*"
   _debug2 "_docker_exec $_eargs"
   _dcid="$1"
   shift
   if [ "$_USE_DOCKER_COMMAND" ]; then
-    docker exec -i "$_dcid" $@
+    docker exec -i "$_dcid" "$@"
   elif [ "$_USE_REST" ]; then
     _err "Not implemented yet."
     return 1
   elif [ "$_USE_UNIX_SOCKET" ]; then
-    _cmd="$@"
-    _cmd="$(printf "$_cmd" | sed 's/ /","/g')"
+    _cmd="$*"
+    _cmd="$(printf "%s" "$_cmd" | sed 's/ /","/g')"
     _debug2 _cmd "$_cmd"
     #create exec instance:
-    cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"$_cmd\"]}")";
+    cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"$_cmd\"]}")"
     _debug2 cjson "$cjson"
     execid="$(echo "$cjson" | cut -d '"' -f 4)"
     _debug execid "$execid"
-    ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")";
+    ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")"
     _debug2 ejson "$ejson"
   else
     _err "Not implemented yet."
@@ -182,7 +180,11 @@ _docker_cp() {
   _dir="$(dirname "$_to")"
   _docker_exec "$_dcid" mkdir -p "$_dir"
   if [ "$_USE_DOCKER_COMMAND" ]; then
-    cat "$_from" | _docker_exec "$_dcid" tee "$_to" >/dev/null
+    if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
+      _docker_exec "$_dcid" tee "$_to" <"$_from"
+    else
+      _docker_exec "$_dcid" tee "$_to" <"$_from" >/dev/null
+    fi
     if [ "$?" = "0" ]; then
       _info "Success"
       return 0
@@ -196,7 +198,7 @@ _docker_cp() {
   elif [ "$_USE_UNIX_SOCKET" ]; then
     _frompath="$_from"
     if _startswith "$_frompath" '/'; then
-      _frompath="$(echo "$_from" | cut -b 2- )" #remove the first '/' char
+      _frompath="$(echo "$_from" | cut -b 2-)" #remove the first '/' char
     fi
     _debug2 "_frompath" "$_frompath"
     _toname="$(basename "$_to")"
@@ -232,9 +234,9 @@ _curl_unix_sock() {
   fi
 
   if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
-    curl -vvv --silent --unix-socket "$_socket" -X $_method --data-binary "$_data" --header "$_ctype" "$_cux_url"
+    curl -vvv --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url"
   else
-    curl      --silent --unix-socket "$_socket" -X $_method --data-binary "$_data" --header "$_ctype" "$_cux_url"
+    curl --silent --unix-socket "$_socket" -X "$_method" --data-binary "$_data" --header "$_ctype" "$_cux_url"
   fi
 
 }
@@ -261,4 +263,3 @@ _check_curl_version() {
   fi
   return 0
 }
-

From 64928b28bcb77165e9630355b37e85574da3fe65 Mon Sep 17 00:00:00 2001
From: neilpang <neil@neilpang.com>
Date: Sun, 2 Jun 2019 11:11:34 +0800
Subject: [PATCH 3/8] trim quotation marks

---
 deploy/docker.sh | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/deploy/docker.sh b/deploy/docker.sh
index 0e22ddc8..18a9d429 100755
--- a/deploy/docker.sh
+++ b/deploy/docker.sh
@@ -19,6 +19,7 @@ docker_deploy() {
   _cca="$4"
   _cfullchain="$5"
   _debug _cdomain "$_cdomain"
+  DEPLOY_DOCKER_CONTAINER_LABEL="$(echo "$DEPLOY_DOCKER_CONTAINER_LABEL" | tr -d '"')"
   if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then
     _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container."
     _err "See: $_DEPLOY_DOCKER_WIKI"
@@ -62,22 +63,27 @@ docker_deploy() {
     fi
   fi
 
+  DEPLOY_DOCKER_CONTAINER_KEY_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" | tr -d '"')"
   if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
     _savedomainconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
   fi
 
+  DEPLOY_DOCKER_CONTAINER_CERT_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" | tr -d '"')"
   if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
     _savedomainconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
   fi
 
+  DEPLOY_DOCKER_CONTAINER_CA_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_CA_FILE" | tr -d '"')"
   if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
     _savedomainconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
   fi
 
+  DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" | tr -d '"')"
   if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
     _savedomainconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
   fi
 
+  DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="$(echo "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" | tr -d '"')"
   if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
     _savedomainconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
   fi

From a18c3ff07d83a28dad3bf4391633a3e86cf6721d Mon Sep 17 00:00:00 2001
From: neilpang <neil@neilpang.com>
Date: Sun, 2 Jun 2019 15:21:08 +0800
Subject: [PATCH 4/8] use `sh -c`

---
 deploy/docker.sh | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/deploy/docker.sh b/deploy/docker.sh
index 18a9d429..d2dc70bc 100755
--- a/deploy/docker.sh
+++ b/deploy/docker.sh
@@ -156,21 +156,25 @@ _docker_exec() {
   _dcid="$1"
   shift
   if [ "$_USE_DOCKER_COMMAND" ]; then
-    docker exec -i "$_dcid" "$@"
+    docker exec -i "$_dcid" sh -c "$*"
   elif [ "$_USE_REST" ]; then
     _err "Not implemented yet."
     return 1
   elif [ "$_USE_UNIX_SOCKET" ]; then
     _cmd="$*"
-    _cmd="$(printf "%s" "$_cmd" | sed 's/ /","/g')"
+    #_cmd="$(printf "%s" "$_cmd" | sed 's/ /","/g')"
     _debug2 _cmd "$_cmd"
     #create exec instance:
-    cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"$_cmd\"]}")"
+    cjson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/containers/$_dcid/exec" "{\"Cmd\": [\"sh\", \"-c\", \"$_cmd\"]}")"
     _debug2 cjson "$cjson"
     execid="$(echo "$cjson" | cut -d '"' -f 4)"
     _debug execid "$execid"
     ejson="$(_curl_unix_sock "$_DOCKER_SOCK" POST "/exec/$execid/start" "{\"Detach\": false,\"Tty\": false}")"
     _debug2 ejson "$ejson"
+    if [ "$ejson" ]; then
+      _err "$ejson"
+      return 1
+    fi
   else
     _err "Not implemented yet."
     return 1

From aec6636205d539eae83f54b4fa4f868f5079d55b Mon Sep 17 00:00:00 2001
From: neilpang <neil@neilpang.com>
Date: Sun, 2 Jun 2019 19:36:11 +0800
Subject: [PATCH 5/8] add _getdeployconf

---
 acme.sh          | 17 +++++++++++++++++
 deploy/docker.sh | 24 ++++++++++++------------
 2 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/acme.sh b/acme.sh
index eb2194aa..45f0ea86 100755
--- a/acme.sh
+++ b/acme.sh
@@ -2078,6 +2078,23 @@ _readdomainconf() {
   _read_conf "$DOMAIN_CONF" "$1"
 }
 
+#key  value  base64encode
+_savedeployconf() {
+  _savedomainconf "SAVED_$1" "$2" "$3"
+  #remove later
+  _clearaccountconf "$1"
+}
+
+#key
+_getdeployconf() {
+  _rac_key="$1"
+  if [ "$(eval echo \$"$_rac_key")" ]; then
+    return 0 # do nothing
+  fi
+  _saved=$(_readdomainconf "SAVED_$_rac_key")
+  eval "export $_rac_key=$_saved"
+}
+
 #_saveaccountconf  key  value  base64encode
 _saveaccountconf() {
   _save_conf "$ACCOUNT_CONF_PATH" "$@"
diff --git a/deploy/docker.sh b/deploy/docker.sh
index d2dc70bc..6f3a2718 100755
--- a/deploy/docker.sh
+++ b/deploy/docker.sh
@@ -19,13 +19,13 @@ docker_deploy() {
   _cca="$4"
   _cfullchain="$5"
   _debug _cdomain "$_cdomain"
-  DEPLOY_DOCKER_CONTAINER_LABEL="$(echo "$DEPLOY_DOCKER_CONTAINER_LABEL" | tr -d '"')"
+  _getdeployconf DEPLOY_DOCKER_CONTAINER_LABEL
   if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then
     _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container."
     _err "See: $_DEPLOY_DOCKER_WIKI"
   fi
 
-  _savedomainconf DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
+  _savedeployconf DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
 
   if [ "$DOCKER_HOST" ]; then
     _saveaccountconf DOCKER_HOST "$DOCKER_HOST"
@@ -63,29 +63,29 @@ docker_deploy() {
     fi
   fi
 
-  DEPLOY_DOCKER_CONTAINER_KEY_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" | tr -d '"')"
+  _getdeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE
   if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
-    _savedomainconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
+    _savedeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
   fi
 
-  DEPLOY_DOCKER_CONTAINER_CERT_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" | tr -d '"')"
+  _getdeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE
   if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
-    _savedomainconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
+    _savedeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
   fi
 
-  DEPLOY_DOCKER_CONTAINER_CA_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_CA_FILE" | tr -d '"')"
+  _getdeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE
   if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
-    _savedomainconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
+    _savedeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
   fi
 
-  DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="$(echo "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" | tr -d '"')"
+  _getdeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE
   if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
-    _savedomainconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
+    _savedeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
   fi
 
-  DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="$(echo "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" | tr -d '"')"
+  _getdeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD
   if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
-    _savedomainconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
+    _savedeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
   fi
 
   _cid="$(_get_id "$DEPLOY_DOCKER_CONTAINER_LABEL")"

From dc5eda7ebb53ba9dadb631d703829b37a3879be7 Mon Sep 17 00:00:00 2001
From: neilpang <neil@neilpang.com>
Date: Sun, 2 Jun 2019 20:04:36 +0800
Subject: [PATCH 6/8] fix savedeployconf

---
 acme.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/acme.sh b/acme.sh
index 45f0ea86..4c856dbd 100755
--- a/acme.sh
+++ b/acme.sh
@@ -2082,7 +2082,7 @@ _readdomainconf() {
 _savedeployconf() {
   _savedomainconf "SAVED_$1" "$2" "$3"
   #remove later
-  _clearaccountconf "$1"
+  _cleardomainconf "$1"
 }
 
 #key

From 2e3ddd3a61da8a412d0926520e9a0006bd48857f Mon Sep 17 00:00:00 2001
From: neilpang <neil@neilpang.com>
Date: Mon, 3 Jun 2019 20:55:22 +0800
Subject: [PATCH 7/8] trim quotation marks

---
 acme.sh          | 7 ++++++-
 deploy/docker.sh | 7 +++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/acme.sh b/acme.sh
index 4c856dbd..42988acc 100755
--- a/acme.sh
+++ b/acme.sh
@@ -2088,7 +2088,12 @@ _savedeployconf() {
 #key
 _getdeployconf() {
   _rac_key="$1"
-  if [ "$(eval echo \$"$_rac_key")" ]; then
+  _rac_value="$(eval echo \$"$_rac_key")"
+  if [ "$_rac_value" ]; then
+    if _startswith "$_rac_value" '"' && _endswith "$_rac_value" '"'; then
+      _debug2 "trim quotation marks"
+      eval "export $_rac_key=$_rac_value" 
+    fi
     return 0 # do nothing
   fi
   _saved=$(_readdomainconf "SAVED_$_rac_key")
diff --git a/deploy/docker.sh b/deploy/docker.sh
index 6f3a2718..dc3c0108 100755
--- a/deploy/docker.sh
+++ b/deploy/docker.sh
@@ -20,6 +20,7 @@ docker_deploy() {
   _cfullchain="$5"
   _debug _cdomain "$_cdomain"
   _getdeployconf DEPLOY_DOCKER_CONTAINER_LABEL
+  _debug2 DEPLOY_DOCKER_CONTAINER_LABEL "$DEPLOY_DOCKER_CONTAINER_LABEL"
   if [ -z "$DEPLOY_DOCKER_CONTAINER_LABEL" ]; then
     _err "The DEPLOY_DOCKER_CONTAINER_LABEL variable is not defined, we use this label to find the container."
     _err "See: $_DEPLOY_DOCKER_WIKI"
@@ -64,26 +65,31 @@ docker_deploy() {
   fi
 
   _getdeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE
+  _debug2 DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
   if [ "$DEPLOY_DOCKER_CONTAINER_KEY_FILE" ]; then
     _savedeployconf DEPLOY_DOCKER_CONTAINER_KEY_FILE "$DEPLOY_DOCKER_CONTAINER_KEY_FILE"
   fi
 
   _getdeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE
+  _debug2 DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
   if [ "$DEPLOY_DOCKER_CONTAINER_CERT_FILE" ]; then
     _savedeployconf DEPLOY_DOCKER_CONTAINER_CERT_FILE "$DEPLOY_DOCKER_CONTAINER_CERT_FILE"
   fi
 
   _getdeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE
+  _debug2 DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
   if [ "$DEPLOY_DOCKER_CONTAINER_CA_FILE" ]; then
     _savedeployconf DEPLOY_DOCKER_CONTAINER_CA_FILE "$DEPLOY_DOCKER_CONTAINER_CA_FILE"
   fi
 
   _getdeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE
+  _debug2 DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
   if [ "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE" ]; then
     _savedeployconf DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE "$DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE"
   fi
 
   _getdeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD
+  _debug2 DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
   if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
     _savedeployconf DEPLOY_DOCKER_CONTAINER_RELOAD_CMD "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
   fi
@@ -188,6 +194,7 @@ _docker_cp() {
   _to="$3"
   _info "Copying file from $_from to $_to"
   _dir="$(dirname "$_to")"
+  _debug2 _dir "$_dir"
   _docker_exec "$_dcid" mkdir -p "$_dir"
   if [ "$_USE_DOCKER_COMMAND" ]; then
     if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then

From 951bd3a5172945d36344428d6710e211157ad50b Mon Sep 17 00:00:00 2001
From: neilpang <neil@neilpang.com>
Date: Mon, 3 Jun 2019 21:03:03 +0800
Subject: [PATCH 8/8] minor, check for mkdir

---
 deploy/docker.sh | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/deploy/docker.sh b/deploy/docker.sh
index dc3c0108..4e550991 100755
--- a/deploy/docker.sh
+++ b/deploy/docker.sh
@@ -195,7 +195,10 @@ _docker_cp() {
   _info "Copying file from $_from to $_to"
   _dir="$(dirname "$_to")"
   _debug2 _dir "$_dir"
-  _docker_exec "$_dcid" mkdir -p "$_dir"
+  if ! _docker_exec "$_dcid" mkdir -p "$_dir"; then
+    _err "Can not create dir: $_dir"
+    return 1
+  fi
   if [ "$_USE_DOCKER_COMMAND" ]; then
     if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
       _docker_exec "$_dcid" tee "$_to" <"$_from"