├── rootfs ├── etc │ ├── machine-id │ ├── services.d │ │ ├── CrashPlanEngine │ │ │ ├── respawn │ │ │ ├── ignore_failure │ │ │ ├── ready_timeout │ │ │ ├── sgid │ │ │ ├── priority │ │ │ ├── is_ready │ │ │ └── run │ │ └── app │ │ │ └── CrashPlanEngine.dep │ ├── logmonitor │ │ └── notifications.d │ │ │ ├── crashplan-01 │ │ │ ├── level │ │ │ ├── source │ │ │ ├── title │ │ │ ├── desc │ │ │ └── filter │ │ │ ├── crashplan-02 │ │ │ ├── level │ │ │ ├── source │ │ │ ├── title │ │ │ ├── desc │ │ │ └── filter │ │ │ ├── crashplan-03 │ │ │ ├── level │ │ │ ├── source │ │ │ ├── desc │ │ │ ├── title │ │ │ └── filter │ │ │ ├── crashplan-04 │ │ │ ├── level │ │ │ ├── source │ │ │ ├── desc │ │ │ ├── title │ │ │ └── filter │ │ │ ├── crashplan-05 │ │ │ ├── level │ │ │ ├── source │ │ │ ├── desc │ │ │ ├── title │ │ │ └── filter │ │ │ ├── crashplan-06 │ │ │ ├── level │ │ │ ├── title │ │ │ ├── source │ │ │ ├── desc │ │ │ └── filter │ │ │ └── crashplan-07 │ │ │ ├── level │ │ │ ├── source │ │ │ ├── title │ │ │ ├── desc │ │ │ └── filter │ ├── openbox │ │ └── main-window-selection.xml │ ├── nsswitch.conf │ └── cont-init.d │ │ ├── 55-validate_max_mem.sh │ │ └── 55-crashplan.sh ├── usr │ ├── local │ │ └── crashplan │ │ │ ├── bin │ │ │ ├── vars.sh │ │ │ ├── startCrashPlanEngine.sh │ │ │ ├── startCrashPlanGUI.sh │ │ │ ├── restartLinux.sh │ │ │ └── loginCrashPlan.sh │ │ │ └── ~custom │ └── bin │ │ └── xdg-open └── startapp.sh ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feature-request.yml │ └── bug-report.yml ├── FUNDING.yml └── workflows │ └── build-image.yml ├── LICENSE ├── src └── crashplan │ ├── libwrapper.c │ └── build.sh ├── DOCKERHUB.md ├── Dockerfile ├── appdefs.yml └── README.md /rootfs/etc/machine-id: -------------------------------------------------------------------------------- 1 | /config/machine-id -------------------------------------------------------------------------------- /rootfs/etc/services.d/CrashPlanEngine/respawn: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rootfs/etc/services.d/app/CrashPlanEngine.dep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rootfs/etc/services.d/CrashPlanEngine/ignore_failure: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rootfs/usr/local/crashplan/bin/vars.sh: -------------------------------------------------------------------------------- 1 | /config/bin/vars.sh -------------------------------------------------------------------------------- /rootfs/etc/services.d/CrashPlanEngine/ready_timeout: -------------------------------------------------------------------------------- 1 | 30000 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-01/level: -------------------------------------------------------------------------------- 1 | ERROR 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-02/level: -------------------------------------------------------------------------------- 1 | ERROR 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-03/level: -------------------------------------------------------------------------------- 1 | WARNING 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-04/level: -------------------------------------------------------------------------------- 1 | WARNING 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-05/level: -------------------------------------------------------------------------------- 1 | WARNING 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-06/level: -------------------------------------------------------------------------------- 1 | ERROR 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-07/level: -------------------------------------------------------------------------------- 1 | ERROR 2 | -------------------------------------------------------------------------------- /rootfs/etc/services.d/CrashPlanEngine/sgid: -------------------------------------------------------------------------------- 1 | /defaults/service/sgid -------------------------------------------------------------------------------- /rootfs/etc/services.d/CrashPlanEngine/priority: -------------------------------------------------------------------------------- 1 | /defaults/service/priority -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-06/title: -------------------------------------------------------------------------------- 1 | File restore failed. 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-01/source: -------------------------------------------------------------------------------- 1 | /config/log/service.log.0 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-02/source: -------------------------------------------------------------------------------- 1 | /config/log/service.log.0 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-03/source: -------------------------------------------------------------------------------- 1 | status:/config/log/app.log 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-04/source: -------------------------------------------------------------------------------- 1 | status:/config/log/app.log 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-05/source: -------------------------------------------------------------------------------- 1 | status:/config/log/app.log 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-06/source: -------------------------------------------------------------------------------- 1 | /config/log/service.log.0 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-07/source: -------------------------------------------------------------------------------- 1 | /config/log/service.log.0 2 | -------------------------------------------------------------------------------- /rootfs/etc/openbox/main-window-selection.xml: -------------------------------------------------------------------------------- 1 | normal 2 | CrashPlan 3 | -------------------------------------------------------------------------------- /rootfs/usr/local/crashplan/~custom: -------------------------------------------------------------------------------- 1 | # This file is left intentionally empty to make CrashPlan happy :) 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-01/title: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "$APP_NAME is running out of memory." 3 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-07/title: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "$APP_NAME failed to monitor path(s)." 3 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-02/title: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "$APP_NAME is exceeding inotify's max watch limit." 3 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-02/desc: -------------------------------------------------------------------------------- 1 | Real-time file watching cannot work properly. The inotify watch limit needs to be increased on the host. 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-07/desc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "Real-time file watching failed to be setup on one or more path(s) because $APP_NAME doesn't have proper permissions." 3 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-01/desc: -------------------------------------------------------------------------------- 1 | The application crashed because of lack of memory. More memory needs to be allocated. This can be done via the CRASHPLAN_SRV_MAX_MEM environment variable. 2 | -------------------------------------------------------------------------------- /rootfs/etc/services.d/CrashPlanEngine/is_ready: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -u # Treat unset variables as an error. 3 | 4 | # Service considered ready when port 4243 is open. 5 | nc -z -w5 127.0.0.1 4243 6 | 7 | # vim:ft=sh:ts=4:sw=4:et:sts=4 8 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-03/desc: -------------------------------------------------------------------------------- 1 | More than 75% of allocated memory is used. Consider increasing memory allocation to avoid unexpected crashes. This can be done via the CRASHPLAN_SRV_MAX_MEM environment variable. 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-04/desc: -------------------------------------------------------------------------------- 1 | More than 85% of allocated memory is used. Consider increasing memory allocation to avoid unexpected crashes. This can be done via the CRASHPLAN_SRV_MAX_MEM environment variable. 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-05/desc: -------------------------------------------------------------------------------- 1 | More than 95% of allocated memory is used. Consider increasing memory allocation to avoid unexpected crashes. This can be done via the CRASHPLAN_SRV_MAX_MEM environment variable. 2 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-03/title: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | echo "$APP_NAME's memory consumption comes close to its limit." 7 | 8 | # vim:ft=sh:ts=4:sw=4:et:sts=4 9 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-04/title: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | echo "$APP_NAME's memory consumption comes very close to its limit." 7 | 8 | # vim:ft=sh:ts=4:sw=4:et:sts=4 9 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-05/title: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | echo "$APP_NAME's memory consumption comes critically close to its limit." 7 | 8 | # vim:ft=sh:ts=4:sw=4:et:sts=4 9 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-06/desc: -------------------------------------------------------------------------------- 1 | One or more files failed to be restored because the mapping of the /storage volume is read-only. This can be fixed by re-creating the container with the volume mapped with read/write permissions. Please see the documentation at https://github.com/jlesage/docker-crashplan-pro for more details. 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Ask a question, discuss 4 | url: https://github.com/jlesage/docker-crashplan-pro/discussions 5 | about: Get help using this Docker container. 6 | - name: Documentation 7 | url: https://github.com/jlesage/docker-crashplan-pro#readme 8 | about: Documentation about this Docker container. 9 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-01/filter: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | LINE="$1" 7 | 8 | if echo "$LINE" | grep -q "OutOfMemoryError occurred...RESTARTING!"; then 9 | exit 0 10 | fi 11 | 12 | # No match found. 13 | exit 1 14 | 15 | # vim:ft=sh:ts=4:sw=4:et:sts=4 16 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-07/filter: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | LINE="$1" 7 | 8 | if echo "$LINE" | grep -q " Unable to add watch for path .* errno: , 13"; then 9 | exit 0 10 | fi 11 | 12 | # No match found. 13 | exit 1 14 | 15 | # vim:ft=sh:ts=4:sw=4:et:sts=4 16 | -------------------------------------------------------------------------------- /rootfs/usr/bin/xdg-open: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ARG="$1" 4 | 5 | die() { 6 | echo "$1" >&2 7 | exit 1 8 | } 9 | 10 | if [ -z "$ARG" ]; then 11 | die "no argument provided" 12 | fi 13 | 14 | case "$ARG" in 15 | https://*/login/*) 16 | /usr/local/crashplan/bin/loginCrashPlan.sh "$ARG" 17 | ;; 18 | *) 19 | die "don't know how to open: $ARG" 20 | ;; 21 | esac 22 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-06/filter: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | LINE="$1" 7 | 8 | if echo "$LINE" | grep -q "Problem restoring file - .* sourcePath=/storage/.* (Read-only file system)"; then 9 | exit 0 10 | fi 11 | 12 | # No match found. 13 | exit 1 14 | 15 | # vim:ft=sh:ts=4:sw=4:et:sts=4 16 | -------------------------------------------------------------------------------- /rootfs/etc/services.d/CrashPlanEngine/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | # Workaround for https://github.com/jlesage/docker-crashplan-pro/issues/341 7 | rm -rf /config/log/native/logs 8 | 9 | exec /usr/local/crashplan/bin/startCrashPlanEngine.sh >> /config/log/engine_output.log 2>> /config/log/engine_error.log 10 | 11 | # vim:ft=sh:ts=4:sw=4:et:sts=4 12 | -------------------------------------------------------------------------------- /rootfs/usr/local/crashplan/bin/startCrashPlanEngine.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | export CRASHPLAN_DIR=/usr/local/crashplan 7 | 8 | export LD_PRELOAD=$CRASHPLAN_DIR/nlib/libwrapper.so 9 | 10 | export JAVACOMMON="$CRASHPLAN_DIR/jre/bin/java" 11 | 12 | cd $CRASHPLAN_DIR 13 | exec $CRASHPLAN_DIR/bin/CrashPlanService 14 | 15 | # vim:ft=sh:ts=4:sw=4:et:sts=4 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea for this project. 3 | title: "[Feature request] Provide a short description of the feature here" 4 | labels: ["enhancement"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thank you for suggesting an idea to make this project better. 10 | - type: textarea 11 | attributes: 12 | label: Idea 13 | description: | 14 | Please describe the desired behavior, pitch your idea, or suggest improvements. 15 | validations: 16 | required: true 17 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-02/filter: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | LINE="$1" 7 | 8 | if echo "$LINE" | grep -q " Unable to add watch for path "; then 9 | if echo "$LINE" | grep -q " errno: , 13"; then 10 | # Exclude inotify errors related to improper permissions. These are 11 | # handled by another notification. 12 | exit 1 13 | fi 14 | exit 0 15 | fi 16 | 17 | # No match found. 18 | exit 1 19 | 20 | # vim:ft=sh:ts=4:sw=4:et:sts=4 21 | -------------------------------------------------------------------------------- /rootfs/usr/local/crashplan/bin/startCrashPlanGUI.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | export HOME=/config 7 | export SWT_GTK3=0 8 | export VERSION_5_UI=true 9 | export CRASHPLAN_DIR=/usr/local/crashplan 10 | export LD_PRELOAD=$CRASHPLAN_DIR/nlib/libwrapper.so 11 | export GDK_PIXBUF_MODULE_FILE=/usr/local/crashplan/loaders.cache 12 | 13 | cd /config 14 | exec ${CRASHPLAN_DIR}/electron/crashplan --no-sandbox >> /config/log/ui_output.log 2>> /config/log/ui_error.log 15 | 16 | # vim:ft=sh:ts=4:sw=4:et:sts=4 17 | -------------------------------------------------------------------------------- /rootfs/etc/nsswitch.conf: -------------------------------------------------------------------------------- 1 | # /etc/nsswitch.conf 2 | # 3 | # Example configuration of GNU Name Service Switch functionality. 4 | # If you have the `glibc-doc-reference' and `info' packages installed, try: 5 | # `info libc "Name Service Switch"' for information about this file. 6 | 7 | passwd: compat systemd 8 | group: compat systemd 9 | shadow: compat 10 | gshadow: files 11 | 12 | hosts: files mdns4_minimal [NOTFOUND=return] dns myhostname 13 | networks: files 14 | 15 | protocols: db files 16 | services: db files 17 | ethers: db files 18 | rpc: db files 19 | 20 | netgroup: nis 21 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: jlesage 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ["https://paypal.me/JocelynLeSage", "https://www.tesla.com/referral/jocelyn4590"] 13 | -------------------------------------------------------------------------------- /rootfs/startapp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | trap "exit" TERM QUIT INT 4 | trap "kill_cp" EXIT 5 | 6 | kill_cp() { 7 | RC=$? 8 | if [ -n "${CP_PID:-}" ]; then 9 | kill "$CP_PID" 10 | wait $CP_PID 11 | exit $? 12 | fi 13 | exit $RC 14 | } 15 | 16 | while true 17 | do 18 | # Start CrashPlan. 19 | /usr/local/crashplan/bin/startCrashPlanGUI.sh & 20 | 21 | # Wait until it dies. 22 | CP_PID=$! 23 | wait $CP_PID 24 | RC=$? 25 | CP_PID= 26 | 27 | # Exit now if exit was not requested by user. 28 | if [ ! -f /tmp/.cp_restart_requested ]; then 29 | exit $RC 30 | fi 31 | 32 | rm /tmp/.cp_restart_requested 33 | done 34 | 35 | # vim:ft=sh:ts=4:sw=4:et:sts=4 36 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-05/filter: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | LINE="$1" 7 | 8 | if echo "$LINE" | grep -q "^memory "; then 9 | MAX_MEM="$(echo "$LINE" | grep -o 'maxMemory=[0-9\.]* GB' | sed 's/maxMemory=\([[:alnum:].]*\) GB/\1 * 1024/' | bc | cut -d'.' -f1)" 10 | if [ -z "$MAX_MEM" ]; then 11 | MAX_MEM="$(echo "$LINE" | grep -o 'maxMemory=[0-9\.]* MB' | sed 's/maxMemory=\([[:alnum:].]*\) MB/\1/' | cut -d'.' -f1)" 12 | fi 13 | USED_MEM="$(echo "$LINE" | grep -o 'usedMemory=[0-9\.]* MB' | sed 's/usedMemory=\([[:alnum:].]*\) MB/\1/' | cut -d'.' -f1)" 14 | if [ -z "$USED_MEM" ]; then 15 | USED_MEM="$(echo "$LINE" | grep -o 'usedMemory=[0-9\.]* GB' | sed 's/usedMemory=\([[:alnum:].]*\) GB/\1 * 1024/' | bc | cut -d'.' -f1)" 16 | fi 17 | PERCENT_USED_MEM="$(expr "$USED_MEM" \* 100 / "$MAX_MEM")" 18 | if [ "$PERCENT_USED_MEM" -gt 95 ]; then 19 | exit 0 20 | fi 21 | fi 22 | 23 | # No match found. 24 | exit 1 25 | 26 | # vim:ft=sh:ts=4:sw=4:et:sts=4 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Jocelyn Le Sage 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-03/filter: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | LINE="$1" 7 | 8 | if echo "$LINE" | grep -q "^memory "; then 9 | MAX_MEM="$(echo "$LINE" | grep -o 'maxMemory=[0-9\.]* GB' | sed 's/maxMemory=\([[:alnum:].]*\) GB/\1 * 1024/' | bc | cut -d'.' -f1)" 10 | if [ -z "$MAX_MEM" ]; then 11 | MAX_MEM="$(echo "$LINE" | grep -o 'maxMemory=[0-9\.]* MB' | sed 's/maxMemory=\([[:alnum:].]*\) MB/\1/' | cut -d'.' -f1)" 12 | fi 13 | USED_MEM="$(echo "$LINE" | grep -o 'usedMemory=[0-9\.]* MB' | sed 's/usedMemory=\([[:alnum:].]*\) MB/\1/' | cut -d'.' -f1)" 14 | if [ -z "$USED_MEM" ]; then 15 | USED_MEM="$(echo "$LINE" | grep -o 'usedMemory=[0-9\.]* GB' | sed 's/usedMemory=\([[:alnum:].]*\) GB/\1 * 1024/' | bc | cut -d'.' -f1)" 16 | fi 17 | PERCENT_USED_MEM="$(expr "$USED_MEM" \* 100 / "$MAX_MEM")" 18 | if [ "$PERCENT_USED_MEM" -gt 75 ] && [ "$PERCENT_USED_MEM" -le 85 ]; then 19 | exit 0 20 | fi 21 | fi 22 | 23 | # No match found. 24 | exit 1 25 | 26 | # vim:ft=sh:ts=4:sw=4:et:sts=4 27 | -------------------------------------------------------------------------------- /rootfs/etc/logmonitor/notifications.d/crashplan-04/filter: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | LINE="$1" 7 | 8 | if echo "$LINE" | grep -q "^memory "; then 9 | MAX_MEM="$(echo "$LINE" | grep -o 'maxMemory=[0-9\.]* GB' | sed 's/maxMemory=\([[:alnum:].]*\) GB/\1 * 1024/' | bc | cut -d'.' -f1)" 10 | if [ -z "$MAX_MEM" ]; then 11 | MAX_MEM="$(echo "$LINE" | grep -o 'maxMemory=[0-9\.]* MB' | sed 's/maxMemory=\([[:alnum:].]*\) MB/\1/' | cut -d'.' -f1)" 12 | fi 13 | USED_MEM="$(echo "$LINE" | grep -o 'usedMemory=[0-9\.]* MB' | sed 's/usedMemory=\([[:alnum:].]*\) MB/\1/' | cut -d'.' -f1)" 14 | if [ -z "$USED_MEM" ]; then 15 | USED_MEM="$(echo "$LINE" | grep -o 'usedMemory=[0-9\.]* GB' | sed 's/usedMemory=\([[:alnum:].]*\) GB/\1 * 1024/' | bc | cut -d'.' -f1)" 16 | fi 17 | PERCENT_USED_MEM="$(expr "$USED_MEM" \* 100 / "$MAX_MEM")" 18 | if [ "$PERCENT_USED_MEM" -gt 85 ] && [ "$PERCENT_USED_MEM" -le 95 ]; then 19 | exit 0 20 | fi 21 | fi 22 | 23 | # No match found. 24 | exit 1 25 | 26 | # vim:ft=sh:ts=4:sw=4:et:sts=4 27 | -------------------------------------------------------------------------------- /rootfs/etc/cont-init.d/55-validate_max_mem.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | if [ "${CRASHPLAN_SRV_MAX_MEM:-UNSET}" = "UNSET" ]; then 7 | exit 0 8 | fi 9 | 10 | if ! echo "$CRASHPLAN_SRV_MAX_MEM" | grep -q "^[0-9]\+[g|G|m|M|k|K]$" 11 | then 12 | echo "ERROR: invalid value for CRASHPLAN_SRV_MAX_MEM variable: '$CRASHPLAN_SRV_MAX_MEM'." 13 | exit 1 14 | fi 15 | 16 | MEM_VALUE="$(echo "$CRASHPLAN_SRV_MAX_MEM" | sed 's/[^0-9]*//g')" 17 | MEM_UNIT="$(echo "$CRASHPLAN_SRV_MAX_MEM" | sed 's/[0-9]*//g' | tr '[:lower:]' '[:upper:]')" 18 | 19 | MEM_UNIT="${MEM_UNIT:-UNSET}" 20 | 21 | if [ "$MEM_UNIT" = "G" ]; then 22 | MEM_VALUE="$(expr "$MEM_VALUE" \* 1024 \* 1024 \* 1024)" 23 | elif [ "$MEM_UNIT" = "M" ]; then 24 | MEM_VALUE="$(expr "$MEM_VALUE" \* 1024 \* 1024)" 25 | elif [ "$MEM_UNIT" = "K" ]; then 26 | MEM_VALUE="$(expr "$MEM_VALUE" \* 1024)" 27 | fi 28 | 29 | if [ "$MEM_VALUE" -lt $(expr 1024 \* 1024 \* 1024) ]; then 30 | echo "ERROR: CRASHPLAN_SRV_MAX_MEM variable must have a minimum value of 1024MB (1GB)." 31 | if [ "$MEM_UNIT" = "UNSET" ]; then 32 | echo " Current value ('$CRASHPLAN_SRV_MAX_MEM') doesn't have any unit set. Verify this is not an oversight." 33 | fi 34 | exit 1 35 | fi 36 | 37 | # vim:ft=sh:ts=4:sw=4:et:sts=4 38 | -------------------------------------------------------------------------------- /rootfs/usr/local/crashplan/bin/restartLinux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | APP_NAME="CrashPlanService" 4 | APP_DESC="CrashPlan Engine" 5 | 6 | CRASHPLAN_DIR=/usr/local/crashplan 7 | 8 | LOG_FILE="$CRASHPLAN_DIR/log/restart.`date +'%Y-%m-%d_%H.%M.%S'`.log" 9 | 10 | _findpid() { 11 | /bin/ps -o pid,args | grep "$APP_NAME" | grep -v grep | awk '{ print $1 }' 12 | } 13 | 14 | _log() { 15 | echo "$(date) : $*" >> $LOG_FILE 2>&1 16 | } 17 | 18 | _exit() { 19 | EXIT_CODE=$? 20 | 21 | _log "Exiting restart script" 22 | sleep 1 23 | 24 | exit $? 25 | } 26 | trap _exit EXIT 27 | 28 | _log "$(pwd)/$(basename $0)" 29 | 30 | _log "Stopping $APP_DESC ... " 31 | PID_TO_KILL=`_findpid` 32 | if [ -n "$PID_TO_KILL" ]; then 33 | touch /tmp/.cp_restart_requested 34 | kill $PID_TO_KILL 35 | for i in $(seq 1 10); do 36 | sleep 1 37 | PID=`_findpid` 38 | if [ -z "$PID" ] || [ "$PID" != "$PID_TO_KILL" ]; then 39 | break 40 | fi 41 | done 42 | fi 43 | PID=`_findpid` 44 | if [ -n "$PID" ] && [ "$PID" = "$PID_TO_KILL" ]; then 45 | _log "Still running, killing PID=$PID ... " 46 | kill -9 $PID 47 | sleep 2 48 | fi 49 | PID=`_findpid` 50 | if [ -n "$PID" ] && [ "$PID" = "$PID_TO_KILL" ]; then 51 | _log "ERROR: Failed to kill $APP_DESC (PID $PID_TO_KILL)" 52 | exit 1 53 | else 54 | _log "OK" 55 | fi 56 | 57 | _log "Waiting for $APP_DESC to be restarted automatically ..." 58 | for i in $(seq 1 30); do 59 | PID=`_findpid` 60 | if [ -n "$PID" ]; then 61 | break 62 | fi 63 | sleep 1 64 | done 65 | if [ -n "$PID" ]; then 66 | _log "New $APP_DESC process started with PID $PID" 67 | else 68 | _log "ERROR: $APP_DESC process not started after 30 seconds" 69 | exit 1 70 | fi 71 | -------------------------------------------------------------------------------- /src/crashplan/libwrapper.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define DIM(a) (sizeof(a)/sizeof(a[0])) 10 | 11 | static const char *deny_domain_names[] = { 12 | "download.crashplan.com", 13 | }; 14 | 15 | static void init(void) __attribute__((constructor)); 16 | 17 | /* 18 | * Constructor. 19 | * 20 | * This function is called when the library is loaded. 21 | */ 22 | static void init(void) 23 | { 24 | } 25 | 26 | /* 27 | * Wrapper for the `uname` function. 28 | */ 29 | int uname(struct utsname *buf) 30 | { 31 | #ifdef DEBUG 32 | printf("OVERRIDING uname\n"); 33 | #endif 34 | 35 | // Get the original function. 36 | static int (*f)() = NULL; 37 | if (f == NULL) { 38 | f = dlsym (RTLD_NEXT, "uname"); 39 | } 40 | 41 | // Invoke the original function. 42 | int rc = f(buf); 43 | if (rc != 0) { 44 | return rc; 45 | } 46 | 47 | // Override the kernel version. 48 | { 49 | const char* env = getenv("CRASHPLAN_KERNEL_RELEASE"); 50 | // Fallback on valid linux kernel version for Ubuntu 20.04. 51 | // https://packages.ubuntu.com/focal-updates/linux-image-generic 52 | const char *version = env ? env : "5.4.0-96-generic"; 53 | strncpy(buf->release, version, sizeof(buf->release)); 54 | } 55 | return rc; 56 | } 57 | 58 | /* 59 | * Wrapper for the `getaddrinfo` function. 60 | */ 61 | int getaddrinfo(const char *node, const char *service, 62 | const struct addrinfo *hints, 63 | struct addrinfo **res) 64 | { 65 | #ifdef DEBUG 66 | printf("OVERRIDING getaddrinfo: '%s'\n", node ? node : "null"); 67 | #endif 68 | 69 | // Get the original function. 70 | static int (*f)() = NULL; 71 | if (f == NULL) { 72 | f = dlsym (RTLD_NEXT, "getaddrinfo"); 73 | } 74 | 75 | // Check if the DNS name is allowed. 76 | for (int i = 0; i < DIM(deny_domain_names); i++) { 77 | if (strcmp(node, deny_domain_names[i]) == 0) { 78 | return EAI_FAIL; 79 | } 80 | } 81 | 82 | // Invoke the original function. 83 | return f(node, service, hints, res); 84 | } 85 | 86 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: File a bug report. 3 | title: "[Bug] Provide a short description of the bug here" 4 | labels: ["bug"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this bug report! 10 | - type: textarea 11 | attributes: 12 | label: Current Behavior 13 | description: A concise description of what you're experiencing. 14 | validations: 15 | required: true 16 | - type: textarea 17 | attributes: 18 | label: Expected Behavior 19 | description: A concise description of what you expected to happen. 20 | validations: 21 | required: false 22 | - type: textarea 23 | attributes: 24 | label: Steps To Reproduce 25 | description: Steps to reproduce the behavior. 26 | validations: 27 | required: false 28 | - type: textarea 29 | attributes: 30 | label: Environment 31 | description: | 32 | Provide details about the host running the container. 33 | Examples: 34 | - Operating system (e.g. Ubuntu, Windows, TrueNAS, openmediavault, unRAID, etc). 35 | - Version of the operating system. 36 | - CPU architecture (x86-64, arm, arm64, etc). 37 | - Model of the device, if applicable (e.g. Raspberry Pi 4B, Synology DS418, QNAP TS-364, etc). 38 | - The Docker version (output of `docker version`). 39 | - Anything else specific to your environment. Examples: 40 | - Network share (NFS, CIFS) mapped to the container. 41 | - Docker running in LXC container. 42 | - etc. 43 | - If applicable, how the UI provided by the container is access: 44 | - Browser (Chrome, Firefox, Edge, etc). 45 | - Version of the browser. 46 | - OS of the browser. 47 | - Is the container accessed through a reverse proxy. 48 | - etc. 49 | value: | 50 | - OS: 51 | - OS version: 52 | - CPU: 53 | - Docker version: 54 | - Device model: 55 | - Browser/OS: 56 | validations: 57 | required: false 58 | - type: textarea 59 | attributes: 60 | label: Container creation 61 | description: | 62 | How did you create the container ? 63 | Examples: 64 | - The `docker run` command used. 65 | - The compose file used. 66 | - Screenshots of the management tool UI (e.g. Portainer, unRAID, etc) showing container settings. 67 | validations: 68 | required: true 69 | - type: textarea 70 | attributes: 71 | label: Container log 72 | description: Please copy/paste the output of `docker logs `. 73 | render: text 74 | validations: 75 | required: true 76 | - type: textarea 77 | attributes: 78 | label: Container inspect 79 | description: | 80 | If the container is running, please provide the output of `docker inspect `. 81 | **Attention**: If you defined passwords, secrets or any sensitive information via environment variables, make sure to remove them from the output. 82 | render: text 83 | validations: 84 | required: false 85 | - type: textarea 86 | attributes: 87 | label: Anything else? 88 | description: | 89 | Anything that will give more context about the issue you are encountering. 90 | 91 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 92 | validations: 93 | required: false 94 | -------------------------------------------------------------------------------- /DOCKERHUB.md: -------------------------------------------------------------------------------- 1 | # Docker container for CrashPlan 2 | [![Release](https://img.shields.io/github/release/jlesage/docker-crashplan-pro.svg?logo=github&style=for-the-badge)](https://github.com/jlesage/docker-crashplan-pro/releases/latest) 3 | [![Docker Image Size](https://img.shields.io/docker/image-size/jlesage/crashplan-pro/latest?logo=docker&style=for-the-badge)](https://hub.docker.com/r/jlesage/crashplan-pro/tags) 4 | [![Docker Pulls](https://img.shields.io/docker/pulls/jlesage/crashplan-pro?label=Pulls&logo=docker&style=for-the-badge)](https://hub.docker.com/r/jlesage/crashplan-pro) 5 | [![Docker Stars](https://img.shields.io/docker/stars/jlesage/crashplan-pro?label=Stars&logo=docker&style=for-the-badge)](https://hub.docker.com/r/jlesage/crashplan-pro) 6 | [![Build Status](https://img.shields.io/github/actions/workflow/status/jlesage/docker-crashplan-pro/build-image.yml?logo=github&branch=master&style=for-the-badge)](https://github.com/jlesage/docker-crashplan-pro/actions/workflows/build-image.yml) 7 | [![Source](https://img.shields.io/badge/Source-GitHub-blue?logo=github&style=for-the-badge)](https://github.com/jlesage/docker-crashplan-pro) 8 | [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg?style=for-the-badge)](https://paypal.me/JocelynLeSage) 9 | 10 | This is a Docker container for [CrashPlan](https://www.crashplan.com). 11 | 12 | The graphical user interface (GUI) of the application can be accessed through a 13 | modern web browser, requiring no installation or configuration on the client 14 | 15 | This Docker container can be used with all CrashPlan products: Essential, 16 | Professional, Enterprise, MSPs and Small Business (no longer sold). 17 | 18 | > This Docker container is entirely unofficial and not made by the creators of CrashPlan. 19 | 20 | --- 21 | 22 | [![CrashPlan logo](https://images.weserv.nl/?url=raw.githubusercontent.com/jlesage/docker-templates/master/jlesage/images/crashplan-pro-icon.png&w=110)](https://www.crashplan.com)[![CrashPlan](https://images.placeholders.dev/?width=288&height=110&fontFamily=monospace&fontWeight=400&fontSize=52&text=CrashPlan&bgColor=rgba(0,0,0,0.0)&textColor=rgba(121,121,121,1))](https://www.crashplan.com) 23 | 24 | CrashPlan provides peace of mind through secure, scalable, and 25 | straightforward endpoint data backup. We help organizations recover from 26 | any worst-case scenario, whether it is a disaster, simple human error, a 27 | stolen laptop, ransomware or an as-of-yet undiscovered calamity. 28 | 29 | --- 30 | 31 | ## Quick Start 32 | 33 | **NOTE**: 34 | The Docker command provided in this quick start is an example, and parameters 35 | should be adjusted to suit your needs. 36 | 37 | Launch the CrashPlan docker container with the following command: 38 | ```shell 39 | docker run -d \ 40 | --name=crashplan-pro \ 41 | -p 5800:5800 \ 42 | -v /docker/appdata/crashplan-pro:/config:rw \ 43 | -v /home/user:/storage:ro \ 44 | jlesage/crashplan-pro 45 | ``` 46 | 47 | Where: 48 | 49 | - `/docker/appdata/crashplan-pro`: Stores the application's configuration, state, logs, and any files requiring persistency. 50 | - `/home/user`: Contains files from the host that need to be accessible to the application. 51 | 52 | Access the CrashPlan GUI by browsing to `http://your-host-ip:5800`. 53 | Files from the host appear under the `/storage` folder in the container. 54 | 55 | ## Documentation 56 | 57 | Full documentation is available at https://github.com/jlesage/docker-crashplan-pro. 58 | 59 | ## Support or Contact 60 | 61 | Having troubles with the container or have questions? Please 62 | [create a new issue](https://github.com/jlesage/docker-crashplan-pro/issues). 63 | 64 | For other Dockerized applications, visit https://jlesage.github.io/docker-apps. 65 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # crashplan-pro Dockerfile 3 | # 4 | # https://github.com/jlesage/docker-crashplan-pro 5 | # 6 | 7 | # Docker image version is provided via build arg. 8 | ARG DOCKER_IMAGE_VERSION= 9 | 10 | # Define software versions. 11 | ARG CRASHPLAN_VERSION=11.8.0 12 | ARG CRASHPLAN_BUILD=609 13 | 14 | # Define software download URLs. 15 | ARG CRASHPLAN_URL=https://download.crashplan.com/installs/agent/cloud/${CRASHPLAN_VERSION}/${CRASHPLAN_BUILD}/install/CrashPlan_${CRASHPLAN_VERSION}_${CRASHPLAN_BUILD}_Linux.tgz 16 | 17 | # Build CrashPlan. 18 | FROM ubuntu:22.04 AS crashplan 19 | ARG CRASHPLAN_URL 20 | WORKDIR /tmp 21 | COPY src/crashplan /build 22 | RUN /build/build.sh "${CRASHPLAN_URL}" 23 | 24 | # Pull base image. 25 | FROM jlesage/baseimage-gui:alpine-3.21-v4.10.3 26 | 27 | ARG DOCKER_IMAGE_VERSION 28 | ARG CRASHPLAN_VERSION 29 | 30 | # Define container build variables. 31 | ARG TARGETDIR=/usr/local/crashplan 32 | 33 | # Define working directory. 34 | WORKDIR /tmp 35 | 36 | # Misc adjustments. 37 | RUN \ 38 | # Clear stuff from /etc/fstab to avoid showing irrelevant devices in the open 39 | # file dialog window. 40 | echo > /etc/fstab && \ 41 | # Save the current CrashPlan version. 42 | echo "${CRASHPLAN_VERSION}" > /defaults/cp_version 43 | 44 | # Install dependencies. 45 | RUN \ 46 | add-pkg \ 47 | # For the login. 48 | curl \ 49 | jq \ 50 | # For the monitor. 51 | bc 52 | 53 | # Generate and install favicons. 54 | RUN \ 55 | APP_ICON_URL=https://github.com/jlesage/docker-templates/raw/master/jlesage/images/crashplan-pro-icon.png && \ 56 | install_app_icon.sh "$APP_ICON_URL" 57 | 58 | # Add files. 59 | COPY rootfs/ / 60 | 61 | # Install CrashPlan. 62 | # NOTE: Make sure to do this after installing/removing packages that can affect 63 | # the installed rootfs of CrashPlan. 64 | COPY --from=crashplan /tmp/crashplan-rootfs / 65 | RUN \ 66 | # Keep a copy of the default config. 67 | mv ${TARGETDIR}/conf /defaults/conf && \ 68 | # Make sure the UI connects by default to the engine using the loopback IP address (127.0.0.1). 69 | sed-patch '/<\/serviceBackupConfig>/a \\t\n\t\t127.0.0.1<\/serviceHost>\n\t<\/serviceUIConfig>' /defaults/conf/default.service.xml && \ 70 | # Add the javaMemoryHeapMax setting to the default service file. 71 | #sed-patch '//i\\t' /defaults/conf/default.service.xml && \ 72 | # Prevent automatic updates. 73 | rm -r /usr/local/crashplan/upgrade && \ 74 | touch /usr/local/crashplan/upgrade && chmod 400 /usr/local/crashplan/upgrade && \ 75 | # The configuration directory should be stored outside the container. 76 | ln -s /config/conf $TARGETDIR/conf && \ 77 | # The cache directory should be stored outside the container. 78 | ln -s /config/cache $TARGETDIR/cache && \ 79 | # The log directory should be stored outside the container. 80 | rm -r $TARGETDIR/log && \ 81 | ln -s /config/log $TARGETDIR/log && \ 82 | # The '/var/lib/crashplan' directory should be stored outside the container. 83 | ln -s /config/var /var/lib/crashplan && \ 84 | # The '/repository' directory should be stored outside the container. 85 | # NOTE: The '/repository/metadata' directory in 6.7.0 changed to 86 | # '/usr/local/crashplan/metadata' in 6.7.1. 87 | ln -s /config/repository/metadata /usr/local/crashplan/metadata 88 | 89 | # Set internal environment variables. 90 | RUN \ 91 | set-cont-env APP_NAME "CrashPlan" && \ 92 | set-cont-env APP_VERSION "$CRASHPLAN_VERSION" && \ 93 | set-cont-env DOCKER_IMAGE_VERSION "$DOCKER_IMAGE_VERSION" && \ 94 | true 95 | 96 | # Set public environment variables. 97 | ENV \ 98 | CRASHPLAN_SRV_MAX_MEM=1024M 99 | 100 | # Define mountable directories. 101 | VOLUME ["/storage"] 102 | 103 | # Metadata. 104 | LABEL \ 105 | org.label-schema.name="crashplan-pro" \ 106 | org.label-schema.description="Docker container for CrashPlan" \ 107 | org.label-schema.version="${DOCKER_IMAGE_VERSION:-unknown}" \ 108 | org.label-schema.vcs-url="https://github.com/jlesage/docker-crashplan-pro" \ 109 | org.label-schema.schema-version="1.0" 110 | -------------------------------------------------------------------------------- /rootfs/etc/cont-init.d/55-crashplan.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | # Generate machine id. 7 | # NOTE: CrashPlan requires the machine-id to be the same to avoid re-login. 8 | # Thus, it needs to be saved into the config directory. 9 | if [ ! -f /config/machine-id ]; then 10 | echo "generating machine-id..." 11 | cat /proc/sys/kernel/random/uuid | tr -d '-' > /config/machine-id 12 | fi 13 | 14 | # Set a home directory in passwd, needed by the engine. 15 | sed-patch "s|app::$USER_ID:$GROUP_ID::/dev/null:|app::$USER_ID:$GROUP_ID::/config:|" /etc/passwd 16 | 17 | # Make sure required directories exist. 18 | mkdir -p /config/bin 19 | mkdir -p /config/log 20 | mkdir -p /config/cache 21 | mkdir -p /config/var 22 | mkdir -p /config/repository/metadata 23 | mkdir -p /config/.crashplan 24 | 25 | # Workaround for a crash that occurs with the engine with version 11.0.1.33. 26 | # See https://github.com/jlesage/docker-crashplan-pro/issues/416 27 | mkdir -p /dev/input/by-path 28 | 29 | # Make sure the app can write files into /usr/local/crashplan. This is needed 30 | # to restore files. 31 | chgrp app /usr/local/crashplan 32 | chmod 0775 /usr/local/crashplan 33 | 34 | # Redirect log directory. 35 | ln -sf /config/log /config/.crashplan/log 36 | 37 | # Determine if it's a first/initial installation or an upgrade. 38 | FIRST_INSTALL=0 39 | UPGRADE=0 40 | if [ ! -d /config/conf ]; then 41 | echo "handling initial run..." 42 | FIRST_INSTALL=1 43 | elif [ ! -f /config/cp_version ]; then 44 | echo "handling upgrade to CrashPlan version $(cat /defaults/cp_version)..." 45 | UPGRADE=1 46 | elif [ "$(cat /config/cp_version)" != "$(cat /defaults/cp_version)" ]; then 47 | echo "handling upgrade from CrashPlan version $(cat /config/cp_version) to $(cat /defaults/cp_version)..." 48 | UPGRADE=1 49 | fi 50 | 51 | # Install defaults. 52 | if [ "$FIRST_INSTALL" -eq 1 ] || [ "$UPGRADE" -eq 1 ]; then 53 | # Copy default config files. 54 | cp -r /defaults/conf /config/ 55 | 56 | # Set the current CrashPlan version. 57 | cp /defaults/cp_version /config/ 58 | 59 | # Clear the cache. 60 | rm -rf /config/cache/* 61 | fi 62 | 63 | # run.conf was used before CrashPlan 7.0.0. 64 | if [ -f /config/bin/run.conf ]; then 65 | mv /config/bin/run.conf /config/bin/run.conf.old 66 | fi 67 | 68 | # Update CrashPlan Engine max memory if needed. 69 | if [ "${CRASHPLAN_SRV_MAX_MEM:-UNSET}" != "UNSET" ]; then 70 | # Validate the max memory value. 71 | if ! echo "$CRASHPLAN_SRV_MAX_MEM" | grep -q "^[0-9]\+[g|G|m|M|k|K]$" 72 | then 73 | echo "ERROR: invalid value for CRASHPLAN_SRV_MAX_MEM variable: '$CRASHPLAN_SRV_MAX_MEM'." 74 | exit 1 75 | fi 76 | 77 | # Convert the max memory value to megabytes. 78 | MEM_VALUE="$(echo "$CRASHPLAN_SRV_MAX_MEM" | sed 's/[^0-9]*//g')" 79 | MEM_UNIT="$(echo "$CRASHPLAN_SRV_MAX_MEM" | sed 's/[0-9]*//g' | tr '[:lower:]' '[:upper:]')" 80 | if [ "${MEM_UNIT:-UNSET}" == "G" ]; then 81 | CRASHPLAN_SRV_MAX_MEM="$(expr "$MEM_VALUE" \* 1024)m" 82 | elif [ "${MEM_UNIT:-UNSET}" == "K" ]; then 83 | CRASHPLAN_SRV_MAX_MEM="$(expr "$MEM_VALUE" / 1024)m" 84 | fi 85 | 86 | echo "setting CrashPlan Engine maximum memory to $CRASHPLAN_SRV_MAX_MEM" 87 | echo "-Xmx$CRASHPLAN_SRV_MAX_MEM" > /config/conf/jvm_args 88 | fi 89 | 90 | # On some systems (e.g QNAP NAS), instead of the loopback IP address 91 | # (127.0.0.1), the IP address of the host is used by the CrashPlan UI to connect 92 | # to the engine. This connection cannot succeed when using the Docker `bridge` 93 | # network mode. 94 | # Make sure to fix this situation by forcing the loopback IP address in 95 | # concerned configuration files. 96 | if [ -f /config/conf/my.service.xml ]; then 97 | sed -i 's|.*|127.0.0.1|' /config/conf/my.service.xml 98 | fi 99 | if [ -f /config/var/.ui_info ]; then 100 | sed -i 's|,[0-9.]\+$|,127.0.0.1|' /config/var/.ui_info 101 | fi 102 | 103 | # Clear some log files. 104 | rm -f /config/log/engine_output.log \ 105 | /config/log/engine_error.log \ 106 | /config/log/ui_output.log \ 107 | /config/log/ui_error.log 108 | 109 | # Make sure monitored log files exist. 110 | for LOGFILE in /config/log/service.log.0 /config/log/app.log 111 | do 112 | [ -f "$LOGFILE" ] || touch "$LOGFILE" 113 | done 114 | 115 | # vim:ft=sh:ts=4:sw=4:et:sts=4 116 | -------------------------------------------------------------------------------- /src/crashplan/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | export DEBIAN_FRONTEND=noninteractive 7 | 8 | function log { 9 | echo ">>> $*" 10 | } 11 | 12 | if [ -z "${1:-}" ]; then 13 | echo "ERROR: CrashPlan URL not provided." 14 | exit 1 15 | fi 16 | 17 | CRASHPLAN_URL="$1" 18 | 19 | CRASHPLAN_ROOTFS="/tmp/crashplan-rootfs" 20 | CRASHPLAN_INSTALL_DIR="/usr/local/crashplan" 21 | 22 | log "Updating APT cache..." 23 | apt update 24 | 25 | log "Installing build prerequisites..." 26 | apt upgrade -y 27 | apt install -y --no-install-recommends \ 28 | build-essential \ 29 | locales \ 30 | curl \ 31 | rsync \ 32 | ca-certificates \ 33 | patchelf \ 34 | cpio \ 35 | file \ 36 | libxss1 \ 37 | libgtk-3-0 \ 38 | libx11-xcb1 \ 39 | libxshmfence1 \ 40 | libasound2 \ 41 | libgbm1 \ 42 | libgconf-2-4 \ 43 | librsvg2-common \ 44 | libsqlite3-0 \ 45 | 46 | # Generate locale. 47 | locale-gen en_US.UTF-8 48 | 49 | # Download CrashPlan. 50 | log "Downloading CrashPlan..." 51 | mkdir /tmp/crashplan 52 | curl -# -L -f ${CRASHPLAN_URL} | tar -xz --strip 1 -C /tmp/crashplan 53 | 54 | # Install CrashPlan. 55 | log "Installing CrashPlan..." 56 | mkdir -p /usr/share/applications 57 | sed 's/^start_service/#start_service/' -i /tmp/crashplan/install.sh 58 | /tmp/crashplan/install.sh 59 | 60 | # Perform some post-install fixes. 61 | chmod 755 "$CRASHPLAN_INSTALL_DIR"/bin/CrashPlanService 62 | cp /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders.cache "$CRASHPLAN_INSTALL_DIR"/ 63 | sed "s|/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/|$CRASHPLAN_INSTALL_DIR/nlib/|" -i "$CRASHPLAN_INSTALL_DIR"/loaders.cache 64 | 65 | # Remove unneeded libraries. 66 | find "$CRASHPLAN_INSTALL_DIR"/electron -type f -maxdepth 1 -name "*.so" -not -name "libffmpeg.so" -delete 67 | rm -r \ 68 | "$CRASHPLAN_INSTALL_DIR"/jre/legal \ 69 | 70 | # Compile the wrapper. 71 | log "Compiling wrapper..." 72 | gcc -o "$CRASHPLAN_INSTALL_DIR"/nlib/libwrapper.so /build/libwrapper.c -Wall -Werror -fPIC -shared -ldl 73 | strip /"$CRASHPLAN_INSTALL_DIR"/nlib/libwrapper.so 74 | 75 | # Extra libraries that need to be installed into the CrashPlan lib 76 | # folder. These libraries are loaded dynamically (dlopen) and are not catched 77 | # by tracking dependencies. 78 | EXTRA_LIBS=" 79 | /lib/x86_64-linux-gnu/libnss_dns 80 | /lib/x86_64-linux-gnu/libnss_files 81 | /lib/x86_64-linux-gnu/libnss_compat 82 | /lib/x86_64-linux-gnu/libudev.so.1 83 | /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so 84 | /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1 85 | " 86 | 87 | echo "Copying extra libraries..." 88 | for LIB in $EXTRA_LIBS 89 | do 90 | cp -av "$LIB"* "$CRASHPLAN_INSTALL_DIR"/nlib/ 91 | done 92 | 93 | # Extract dependencies of all binaries and libraries. 94 | find "$CRASHPLAN_INSTALL_DIR" -type f -and '(' -name CrashPlanService -or -name crashplan -or -name 'lib*.so*' ')' | while read BIN 95 | do 96 | RAW_DEPS="$(LD_LIBRARY_PATH="$CRASHPLAN_INSTALL_DIR"/nlib:"$CRASHPLAN_INSTALL_DIR"/jre/lib/server ldd "$BIN")" 97 | echo "Dependencies for $BIN:" 98 | echo "================================" 99 | echo "$RAW_DEPS" 100 | echo "================================" 101 | 102 | if echo "$RAW_DEPS" | grep -q " not found"; then 103 | echo "ERROR: Some libraries are missing!" 104 | exit 1 105 | fi 106 | 107 | LD_LIBRARY_PATH="$CRASHPLAN_INSTALL_DIR"/nlib:"$CRASHPLAN_INSTALL_DIR"/jre/lib/server ldd "$BIN" | (grep " => " || true) | cut -d'>' -f2 | sed 's/^[[:space:]]*//' | cut -d'(' -f1 | while read dep 108 | do 109 | dep_real="$(realpath "$dep")" 110 | dep_basename="$(basename "$dep_real")" 111 | 112 | # Skip already-processed libraries. 113 | if [[ "$dep_real" == "$CRASHPLAN_INSTALL_DIR"/* ]]; then 114 | continue 115 | fi 116 | 117 | echo " -> Found library: $dep" 118 | cp "$dep_real" "$CRASHPLAN_INSTALL_DIR"/nlib/ 119 | while true; do 120 | [ -L "$dep" ] || break; 121 | ln -sf "$dep_basename" "$CRASHPLAN_INSTALL_DIR"/nlib/"$(basename $dep)" 122 | dep="$(readlink -f "$dep")" 123 | done 124 | done 125 | done 126 | 127 | log "Patching ELF of binaries..." 128 | find "$CRASHPLAN_INSTALL_DIR" -type f | xargs file | grep -w executable | grep "dynamically linked" | cut -d : -f 1 | while read FILE 129 | do 130 | echo " -> Setting interpreter of "$FILE"..." 131 | patchelf --set-interpreter "$CRASHPLAN_INSTALL_DIR/nlib/ld-linux-x86-64.so.2" "$FILE" 132 | 133 | echo " -> Setting rpath of $FILE..." 134 | patchelf --set-rpath '$ORIGIN:$ORIGIN/../nlib:$ORIGIN/../../nlib:$ORIGIN/../jre/lib:$ORIGIN/../jre/lib/jli:$ORIGIN/../jre/lib/server' "$FILE" 135 | 136 | # Make sure the executable is executable by all. 137 | chmod a+rx "$FILE" 138 | done 139 | 140 | log "Patching ELF of libraries..." 141 | find "$CRASHPLAN_INSTALL_DIR"/nlib -type f -name "*.so*" -exec echo " -> Setting rpath of {}..." ';' -exec patchelf --set-rpath '$ORIGIN' {} ';' 142 | find "$CRASHPLAN_INSTALL_DIR"/jre/lib -maxdepth 1 -type f -name "lib*.so*" -exec echo " -> Setting rpath of {}..." ';' -exec patchelf --set-rpath "\$ORIGIN:\$ORIGIN/jli::$CRASHPLAN_INSTALL_DIR/nlib" {} ';' 143 | find "$CRASHPLAN_INSTALL_DIR"/jre/lib -mindepth 2 -type f -name "lib*.so*" -exec echo " -> Setting rpath of {}..." ';' -exec patchelf --set-rpath "\$ORIGIN:\$ORIGIN/../:$CRASHPLAN_INSTALL_DIR/nlib" {} ';' 144 | 145 | log "Copying interpreter..." 146 | cp -av /lib/x86_64-linux-gnu/ld-* "$CRASHPLAN_INSTALL_DIR"/nlib/ 147 | 148 | log "Creating rootfs..." 149 | mkdir "$CRASHPLAN_ROOTFS" 150 | ROOTFS_CONTENT="\ 151 | $CRASHPLAN_INSTALL_DIR 152 | /usr/share/glib-2.0/schemas 153 | /usr/share/icons/Adwaita/index.theme 154 | /usr/share/icons/Adwaita/scalable 155 | /usr/lib/locale/locale-archive 156 | /etc/fonts 157 | /usr/share/mime 158 | /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf 159 | " 160 | echo "$ROOTFS_CONTENT" | while read i 161 | do 162 | if [ -n "$i" ]; then 163 | rsync -Rav "$i" "$CRASHPLAN_ROOTFS" 164 | fi 165 | done 166 | 167 | log "CrashPlan built successfully." 168 | -------------------------------------------------------------------------------- /.github/workflows/build-image.yml: -------------------------------------------------------------------------------- 1 | name: Docker image CI/CD 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | env: 8 | DOCKER_IMAGE_NAME: jlesage/crashplan-pro 9 | PLATFORMS: linux/amd64 10 | 11 | on: 12 | push: 13 | branches: '*' 14 | tags: 15 | - v[0-9][0-9].[0-9][0-9].[0-9]+ 16 | - v[0-9][0-9].[0-9][0-9].[0-9]+-pre.[0-9]+ 17 | pull_request: 18 | 19 | jobs: 20 | build: 21 | name: Build image 22 | runs-on: ubuntu-22.04 23 | 24 | steps: 25 | - name: Free disk space 26 | uses: jlumbroso/free-disk-space@main 27 | with: 28 | tool-cache: true 29 | android: true 30 | dotnet: true 31 | haskell: true 32 | large-packages: true 33 | docker-images: true 34 | swap-storage: false 35 | 36 | - name: Prepare 37 | id: prep 38 | run: | 39 | # Determine the Docker container version. 40 | VERSION=unknown 41 | if [[ $GITHUB_REF =~ refs/tags/* ]]; then 42 | # Git tag pushed: use tag as the version. 43 | VERSION=${GITHUB_REF#refs/tags/} 44 | elif [[ $GITHUB_REF =~ refs/heads/* ]]; then 45 | # Git commit pushed: use the commit SHA as the version. 46 | VERSION=${GITHUB_SHA::8} 47 | elif [[ $GITHUB_REF =~ refs/pull/* ]]; then 48 | # Pull request: use PR number as the version. 49 | VERSION=pr-${{ github.event.number }} 50 | else 51 | echo "::error::Unexpected GITHUB_REF: $GITHUB_REF" 52 | exit 1 53 | fi 54 | # Determine the version to put in container label. 55 | LABEL_VERSION=${VERSION} 56 | if [[ $GITHUB_REF =~ refs/tags/* ]]; then 57 | # Do not include the starting 'v' of the version. 58 | LABEL_VERSION=${VERSION:1} 59 | fi 60 | # Determine the Docker container tags. 61 | TAGS="${{ env.DOCKER_IMAGE_NAME }}:${VERSION}" 62 | if [[ $GITHUB_REF =~ refs/tags/* ]]; then 63 | TAGS="$TAGS,${{ env.DOCKER_IMAGE_NAME }}:latest" 64 | fi 65 | TAGS="$TAGS,$(echo $TAGS | tr ',' '\n' | sed 's|^|ghcr.io/|' | tr '\n' ',')" 66 | # Determine the release type. 67 | if [[ $GITHUB_REF =~ refs/tags/* ]]; then 68 | IS_RELEASE=yes 69 | if [[ $GITHUB_REF =~ -pre\.[0-9]+ ]]; then 70 | RELEASE_TYPE="pre" 71 | else 72 | RELEASE_TYPE="standard" 73 | fi 74 | else 75 | IS_RELEASE=no 76 | RELEASE_TYPE="n/a" 77 | fi 78 | # Print results. 79 | echo "::group::Results" 80 | echo "Github reference: $GITHUB_REF" 81 | echo "Release: $IS_RELEASE" 82 | echo "Release type: $RELEASE_TYPE" 83 | echo "Docker container version: $VERSION" 84 | echo "Docker container version label: $LABEL_VERSION" 85 | echo "Docker container tag(s): $TAGS" 86 | echo "::endgroup::" 87 | # Export outputs. 88 | echo "is_release=${IS_RELEASE}" >> $GITHUB_OUTPUT 89 | echo "release_type=${RELEASE_TYPE}" >> $GITHUB_OUTPUT 90 | echo "version=${VERSION}" >> $GITHUB_OUTPUT 91 | echo "label_version=${LABEL_VERSION}" >> $GITHUB_OUTPUT 92 | echo "tags=${TAGS}" >> $GITHUB_OUTPUT 93 | #echo "build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT 94 | 95 | - name: Setup QEMU 96 | uses: docker/setup-qemu-action@v3 97 | with: 98 | platforms: arm,arm64,ppc64le,mips64,s390x 99 | 100 | - name: Setup Docker Buildx 101 | uses: docker/setup-buildx-action@v3 102 | 103 | - name: Login to DockerHub 104 | if: ${{ steps.prep.outputs.is_release == 'yes' }} 105 | uses: docker/login-action@v3 106 | with: 107 | username: ${{ secrets.DOCKERHUB_USERNAME }} 108 | password: ${{ secrets.DOCKERHUB_PASSWORD }} 109 | 110 | - name: Login to GitHub Container Registry 111 | if: ${{ steps.prep.outputs.is_release == 'yes' }} 112 | uses: docker/login-action@v3 113 | with: 114 | registry: ghcr.io 115 | username: ${{ github.repository_owner }} 116 | password: ${{ secrets.GITHUB_TOKEN }} 117 | 118 | - name: Build and push 119 | uses: docker/build-push-action@v6 120 | with: 121 | push: ${{ steps.prep.outputs.is_release == 'yes' }} 122 | provenance: false 123 | platforms: ${{ env.PLATFORMS }} 124 | tags: ${{ steps.prep.outputs.tags }} 125 | build-args: | 126 | DOCKER_IMAGE_VERSION=${{ steps.prep.outputs.label_version }} 127 | cache-from: type=gha,scope=${{ env.DOCKER_IMAGE_NAME }} 128 | cache-to: type=gha,mode=max,scope=${{ env.DOCKER_IMAGE_NAME }} 129 | 130 | - name: Inspect 131 | if: ${{ steps.prep.outputs.is_release == 'yes' }} 132 | run: | 133 | docker buildx imagetools inspect ${{ env.DOCKER_IMAGE_NAME }}:${{ steps.prep.outputs.version }} 134 | 135 | - name: Checkout 136 | uses: actions/checkout@v4 137 | if: ${{ steps.prep.outputs.release_type == 'standard' }} 138 | 139 | - name: Dockerhub description 140 | if: ${{ steps.prep.outputs.release_type == 'standard' }} 141 | uses: peter-evans/dockerhub-description@v4 142 | with: 143 | username: ${{ secrets.DOCKERHUB_USERNAME }} 144 | password: ${{ secrets.DOCKERHUB_PASSWORD }} 145 | repository: ${{ env.DOCKER_IMAGE_NAME }} 146 | readme-filepath: DOCKERHUB.md 147 | 148 | notification: 149 | name: Notification 150 | needs: [ build ] 151 | runs-on: ubuntu-22.04 152 | if: ${{ always() && github.event_name != 'pull_request' }} 153 | 154 | steps: 155 | - name: Pushover notification 156 | uses: desiderati/github-action-pushover@v1 157 | with: 158 | job-status: ${{ needs.build.result }} 159 | pushover-api-token: ${{ secrets.PUSHOVER_API_TOKEN }} 160 | pushover-user-key: ${{ secrets.PUSHOVER_USER_KEY }} 161 | -------------------------------------------------------------------------------- /rootfs/usr/local/crashplan/bin/loginCrashPlan.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #set -e # Exit immediately if a command exits with a non-zero status. 4 | set -u # Treat unset variables as an error. 5 | 6 | YAD="/opt/base/bin/yad" 7 | 8 | log() { 9 | if is-bool-val-true "${CONTAINER_DEBUG:-0}"; then 10 | echo "$*" >> /tmp/cp_login.log 11 | fi 12 | } 13 | 14 | die() { 15 | echo "ERROR: $*" >&2 16 | exit 1 17 | } 18 | 19 | url_decode() { 20 | strg="${*}" 21 | printf '%s' "${strg%%[%+]*}" 22 | j="${strg#"${strg%%[%+]*}"}" 23 | strg="${j#?}" 24 | case "${j}" in "%"* ) 25 | printf '%b' "\\0$(printf '%o' "0x${strg%"${strg#??}"}")" 26 | strg="${strg#??}" 27 | ;; "+"* ) printf ' ' 28 | ;; * ) return 29 | esac 30 | if [ -n "${strg}" ] ; then url_decode "${strg}"; fi 31 | } 32 | 33 | success() { 34 | /opt/base/bin/yad \ 35 | --on-top \ 36 | --fixed \ 37 | --center \ 38 | --title "$APP_NAME" \ 39 | --window-icon /opt/noVNC/app/images/icons/master_icon.png \ 40 | --borders 10 \ 41 | --image dialog-info \ 42 | --image-on-top \ 43 | --text "$1" \ 44 | --button=gtk-ok:0 45 | } 46 | 47 | error() { 48 | /opt/base/bin/yad \ 49 | --on-top \ 50 | --fixed \ 51 | --center \ 52 | --title "$APP_NAME" \ 53 | --window-icon /opt/noVNC/app/images/icons/master_icon.png \ 54 | --borders 10 \ 55 | --image dialog-error \ 56 | --image-on-top \ 57 | --text "$1" \ 58 | --button=gtk-ok:0 59 | } 60 | 61 | curl_err() { 62 | if [ -f "$1" ]; then 63 | cat "$1" | head -n1 | sed 's/^curl: ([0-9]\+) //' 64 | else 65 | echo "$1" | head -n1 | sed 's/^curl: ([0-9]\+) //' 66 | fi 67 | } 68 | 69 | # Get the login URL. 70 | LOGIN_URL="${1:-}" 71 | if [ -n "$LOGIN_URL" ]; then 72 | log "login url provided by CrashPlan app: $LOGIN_URL" 73 | else 74 | error "No login URL specified." 75 | exit 1 76 | fi 77 | 78 | # Extract the CrashPlan server address from login URL. 79 | SERVER="$(echo "$LOGIN_URL" | awk -F[/:] '{print $4}')" 80 | if [ -n "$SERVER" ]; then 81 | log "CrashPlan server to use: $SERVER" 82 | else 83 | error "Failed to parse login URL: could not extract server address." 84 | exit 1 85 | fi 86 | 87 | # Extract username from login URL. 88 | USER="$(echo "$LOGIN_URL" | sed -r 's/.*[&?]username=([^&]+)(&|$).*/\1/')" 89 | USER="$(url_decode "$USER")" 90 | if [ -n "$USER" ]; then 91 | log "username to use: $USER" 92 | else 93 | error "Failed to parse login URL: could not extract username." 94 | exit 1 95 | fi 96 | 97 | # Extract UUID from login URL. 98 | UUID="$(echo "$LOGIN_URL" | sed -r 's/.*[&?]uuid=([^&]+)(&|$).*/\1/')" 99 | if [ -n "$UUID" ]; then 100 | log "uuid to use: $UUID" 101 | else 102 | error "Failed to parse login URL: could not extract uuid." 103 | exit 1 104 | fi 105 | 106 | output=$(mktemp) 107 | stderr=$(mktemp) 108 | trap '{ rm -f "$output" "$stderr"; }' EXIT 109 | 110 | while true; do 111 | # Ask user credentials. 112 | $YAD \ 113 | --separator='\n' \ 114 | --geometry=400x100 \ 115 | --borders=10 \ 116 | --on-top \ 117 | --center \ 118 | --title "$APP_NAME" \ 119 | --window-icon /opt/noVNC/app/images/icons/master_icon.png \ 120 | --text "Sign in to CrashPlan" \ 121 | --text-align=center \ 122 | --form \ 123 | --field="Username:RO" \ 124 | --field="Password:H" \ 125 | --field="Authentication code" \ 126 | "$USER" \ 127 | > "$output" 128 | 129 | if [ $? -ne 0 ]; then 130 | # User clicked cancel. 131 | exit 1 132 | fi 133 | 134 | # Get fields. 135 | PASSWORD="$(awk 'NR==2' "$output" | xargs)" 136 | TOTP="$(awk 'NR==3' "$output" | xargs)" 137 | 138 | if [ -z "$PASSWORD" ]; then 139 | error "Password must be provided." 140 | continue 141 | fi 142 | 143 | # Fetch the CrashPlan server environment. 144 | code="$(curl \ 145 | -sS \ 146 | --output "$output" \ 147 | --write-out '%{http_code}' \ 148 | --max-time 60 \ 149 | https://$SERVER/api/v1/ServerEnv \ 150 | 2>$stderr)" 151 | 152 | log "fetch of server environment completed:" 153 | log "HTTP status: $code" 154 | log "output: $(cat "$output")" 155 | log "stderr: $(cat "$stderr")" 156 | 157 | if [ $code -eq 0 ] || [ $code -ge 400 ]; then 158 | error "Unable to fetch CrashPlan server environment: $(curl_err "$stderr")." 159 | continue 160 | else 161 | log "CrashPlan server environment: $(cat "$output")" 162 | fi 163 | 164 | # Extract the "lcts" field from the environment. 165 | LCTS="$(grep 'lcts":' "$output" | cut -d ':' -f2 | tr -d '", ')" 166 | if [ -n "$LCTS" ]; then 167 | log "lcts value: '$LCTS'" 168 | else 169 | error "Received unexpected CrashPlan server environment." 170 | continue 171 | fi 172 | 173 | # Build the challenge. 174 | CHALLENGE="1.$(printf "%s:%s" "$USER" "$LCTS" | openssl dgst -sha256 -binary | base64)" 175 | 176 | # Perform the login. 177 | code=$(curl \ 178 | -sS \ 179 | --output "$output" \ 180 | --write-out '%{http_code}' \ 181 | --max-time 60 \ 182 | -H "Authorization: Basic $(printf "%s:%s" "$USER" "$PASSWORD" | base64)" \ 183 | -H "totp-auth: $TOTP" \ 184 | -H "X-CrashPlan-LCC: $CHALLENGE" \ 185 | "https://$SERVER/api/v3/auth/jwt?useBody=true" \ 186 | 2>$stderr 187 | ) 188 | 189 | log "login completed:" 190 | log "HTTP status: $code" 191 | log "output: $(cat "$output")" 192 | log "stderr: $(cat "$stderr")" 193 | 194 | if [ $code -eq 0 ]; then 195 | error "Unable to sign in: $(curl_err "$stderr")." 196 | continue 197 | elif [ $code -ge 400 ]; then 198 | if [ $code -eq 401 ]; then 199 | error "Unable to sign in. Please check username, password and authentication code." 200 | else 201 | error "Unable to sign in (HTTP status $code)." 202 | fi 203 | continue 204 | fi 205 | 206 | # Finalize the login. 207 | code=$(curl \ 208 | -sS \ 209 | -X POST \ 210 | -d "{\"uuid\":\"$UUID\"}" \ 211 | --output "$output" \ 212 | --write-out '%{http_code}' \ 213 | --max-time 60 \ 214 | -H "Content-Type: application/json" \ 215 | -H "Authorization: Bearer $(cat "$output" | jq -r .data.v3_user_token)" \ 216 | "https://$SERVER/api/v3/agent-login-finalize" \ 217 | 2>$stderr 218 | ) 219 | 220 | log "post login completed:" 221 | log "HTTP status: $code" 222 | log "output: $(cat "$output")" 223 | log "stderr: $(cat "$stderr")" 224 | 225 | if [ $code -eq 0 ]; then 226 | error "Unable to complete sign in: $(curl_err "$stderr")." 227 | continue 228 | elif [ $code -ge 400 ]; then 229 | error "Unable to complete sign in (HTTP status $code)." 230 | continue 231 | else 232 | success "Sign in successful. The $APP_NAME app will be signed in automatically." 233 | break 234 | fi 235 | done 236 | -------------------------------------------------------------------------------- /appdefs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # 4 | # Definitions for CrashPlan PRO docker container. 5 | # 6 | # This file is used as data source to generate README.md and unRAID template files 7 | # from Jinja2 templates. 8 | # 9 | 10 | app: 11 | id: 10 12 | name: crashplan-pro 13 | friendly_name: CrashPlan 14 | gui_type: x11 15 | base_os: alpine 16 | project: 17 | description: |- 18 | CrashPlan provides peace of mind through secure, scalable, and 19 | straightforward endpoint data backup. We help organizations recover from 20 | any worst-case scenario, whether it is a disaster, simple human error, a 21 | stolen laptop, ransomware or an as-of-yet undiscovered calamity. 22 | url: https://www.crashplan.com 23 | unraid: 24 | name: CrashPlanPRO 25 | extra_description: >- 26 | **Warning**: Make sure to read the *Taking Over Existing Backup* section of the 27 | documentation if you are installing this container to replace another CrashPlan 28 | installation (from Windows, Linux, Mac or even another Docker container). 29 | support_url: https://forums.unraid.net/topic/59647-support-crashplan-pro/ 30 | category: "Backup:" 31 | documentation: 32 | overview: |- 33 | This Docker container can be used with all CrashPlan products: Essential, 34 | Professional, Enterprise, MSPs and Small Business (no longer sold). 35 | sections: 36 | - title: Taking Over Existing Backup 37 | level: 2 38 | content: |- 39 | If this container is replacing a CrashPlan installation (from Linux, Windows, 40 | MAC or another Docker container), your existing backup can be taken over to 41 | avoid re-uploading all your data. 42 | 43 | To proceed, make sure to carefully read the [official documentation]. 44 | 45 | Here is a summary of what needs to be done: 46 | 1. Start CrashPlan Docker container. Make sure the configuration directory 47 | is not mapped to a folder used by a different CrashPlan container. 48 | 2. Sign in to your account. 49 | 3. Click the **Replace Existing** button to start the wizard. 50 | 4. Skip *Step 2 - File Transfer*. 51 | 4. Once done with the wizard, go to your device's details and click 52 | *Manage Files*. You will probably see missing items in the file 53 | selection. This is normal, since path to your files may be different in 54 | the container. 55 | 5. Update the file selection by re-adding your files. **Do not unselect 56 | missing items yet**. 57 | 6. Perform a backup. Because of deduplication, files will not be uploaded 58 | again. 59 | 7. Once the backup is terminated, you can remove missing items **if you 60 | don't care about file versions**. Else, keep missing items. 61 | 62 | **NOTE**: Don't be confused by the directory structure from your old being 63 | visible in the *Manage Files* window. By default, your files are now located 64 | under the `/storage` folder. 65 | 66 | [official documentation]: https://support.code42.com/hc/en-us/articles/14827668736279-Replace-your-device 67 | - title: Why CrashPlan Self Update Is Disabled 68 | level: 2 69 | content: |- 70 | One advantage of a Docker image is that it can be versioned and predictable, 71 | meaning that a specific version of the image always behaves the same way. So 72 | if, for any reason, a new image version has a problem and doesn't work as 73 | expected, it's easy for one to revert to the previous version and be back on 74 | track. 75 | 76 | Allowing CrashPlan to update itself obviously breaks this benefit. Also, since 77 | the container has only the minimal set of libraries and tools required to run 78 | CrashPlan, it would be easy for an automatic update to break the container by 79 | requiring new dependencies. Finally, the automatic update script is not adapted 80 | for Alpine Linux (the distribution on which this container is based on) and 81 | assumes it is running on a full-featured distribution. For example, this image 82 | doesn't have a desktop like normal installations and some of the tools required 83 | to perform the update are missing. 84 | - title: Troubleshooting 85 | level: 2 86 | - title: Crashes / Maximum Amount of Allocated Memory 87 | level: 3 88 | content: |- 89 | If CrashPlan crashes unexpectedly with large backups, try to increase the 90 | maximum amount of memory CrashPlan is allowed to use. This can be done by: 91 | 92 | 1. Setting the `CRASHPLAN_SRV_MAX_MEM` environment variable. See the 93 | [Environment Variables](#environment-variables) section for more details. 94 | 2. Using the [solution provided by CrashPlan] from its support site. 95 | 96 | [solution provided by CrashPlan]: https://support.code42.com/hc/en-us/articles/14827635282583-Adjust-Code42-agent-settings-for-memory-usage-with-large-backups 97 | - title: Inotify's Watch Limit 98 | level: 3 99 | content: |- 100 | If CrashPlan exceeds inotify's max watch limit, real-time file watching cannot 101 | work properly and the inotify watch limit needs to be increased on the **host**, 102 | not the container. 103 | 104 | For more details, see the CrashPlan's [Linux real-time file watching errors] 105 | article. 106 | 107 | [Linux real-time file watching errors]: https://support.code42.com/hc/en-us/articles/14827708807959-Linux-real-time-file-watching-errors 108 | - title: Synology 109 | level: 4 110 | content: |- 111 | On Synology NAS, the instructions provided by the article mentioned in the 112 | previous section apply, except that the inotify's max watch limit must be set in 113 | `/etc.defaults/sysctl.conf` (instead of `/etc/sysctl.conf`) to make the setting 114 | permanent. 115 | 116 | **NOTE**: After an upgrade of the DSM software, verify that the content of the 117 | file has not been overwritten. 118 | - title: Empty `/storage` 119 | level: 3 120 | content: |- 121 | If the `/storage` folder inside the container is empty: 122 | 123 | - Make sure the folder is properly mapped to the host. This is done via the 124 | `-v` parameter of the `docker run` command. See the [Usage](#usage) 125 | section. 126 | - Make sure permissions and ownership of files on the host are correct and are 127 | compatible with the user under which the container application is running 128 | (defined by the `USER_ID` and `GROUP_ID` environment variables). See the 129 | [User/Group IDs](#usergroup-ids) section. 130 | 131 | NOTE: If running the application as root (`USER_ID=0` and `GROUP_ID=0`) makes 132 | the files visible, it confirms that there is a permission issue. 133 | - title: Device Status Is Waiting For Connection 134 | level: 3 135 | content: |- 136 | If the status of your device is stuck on *Waiting for connection*, clearing the 137 | the cache of CrashPlan can help resolve the issue: 138 | 139 | - Stop the container. 140 | - Remove all the content of the `cache` directory found under the container's 141 | configuration directory. For example, if the `/config` folder of the 142 | container is mapped to `/docker/appdata/crashplan-pro` on the host, the 143 | following command (ran on the host) would clear the cache: 144 | ``` 145 | rm -rf /docker/appdata/crashplan-pro/cache/* 146 | ``` 147 | - Start the container. 148 | - title: Cannot Restore Files 149 | level: 3 150 | content: |- 151 | If CrashPlan fails to restore files, make sure the location where files are 152 | restored have write permission. 153 | 154 | A typical installation has the data to be backup under the `/storage` folder. 155 | This folder is usually mapped to the host with *read-only* permission. Thus, 156 | restoring files to `/storage` won't be allowed. The solution is to temporarily 157 | change the permission of the volume to *read-write*. 158 | 159 | For example, if `/storage` is mapped to `/home/user` on the host, the container 160 | would need to be deleted and then re-created with the same arguments, with the 161 | exception of `-v /home/user:/storage:ro` that is replaced with 162 | `-v /home/user:/storage:rw`. 163 | - title: Upgrade Failed Error Message 164 | level: 3 165 | content: |- 166 | Because the CrashPlan's self-upgrade feature is disabled in this container, an 167 | error message about failed upgrade can be seen when a new CrashPlan version is 168 | released. 169 | 170 | To fix this, [updating the container's image](#docker-image-update) to the 171 | latest version will also bring the latest version of CrashPlan. 172 | changelog: 173 | - version: 25.12.2 174 | date: 2025-12-07 175 | changes: 176 | - 'Updated baseimage to version 4.10.3.' 177 | - version: 25.12.1 178 | date: 2025-12-02 179 | changes: 180 | - 'Updated baseimage to version 4.10.1.' 181 | - version: 25.11.2 182 | date: 2025-11-28 183 | changes: 184 | - 'Updated baseimage to version 4.10.0, which brings the following changes:' 185 | - '2:Added hardware acceleration support for the X server.' 186 | - '2:Added seamless clipboard synchronization for Chromium-based browsers.' 187 | - '2:Added web notification service to forward desktop notifications to the browser.' 188 | - '2:Added the ability to restrict web and VNC connections from localhost only.' 189 | - '2:Added web server support for TLS 1.3.' 190 | - '2:Removed web server support of static Diffie-Hellman parameters file (no longer needed in modern TLS configurations and ECDHE).' 191 | - version: 25.11.1 192 | date: 2025-11-20 193 | changes: 194 | - 'Updated CrashPlan to version 11.8.0.' 195 | - version: 25.07.2 196 | date: 2025-07-24 197 | changes: 198 | - 'Updated baseimage to version 4.9.0.' 199 | - version: 25.07.1 200 | date: 2025-07-05 201 | changes: 202 | - 'Updated baseimage to version 4.8.2, which brings the following changes:' 203 | - '2:Fixed automatic reconnect of the web interface when web authentication is enabled.' 204 | - '2:Fixed some resources that could not be accessed behind a reverse proxy based on URL path.' 205 | - version: 25.06.2 206 | date: 2025-06-25 207 | changes: 208 | - 'Updated baseimage to version 4.8.1, which brings the following changes:' 209 | - '2:Fixed crash with some binaries on systems using old kernel.' 210 | - version: 25.06.1 211 | date: 2025-06-20 212 | changes: 213 | - 'Updated baseimage to version 4.8.0, which brings the following changes:' 214 | - '2:Added automatic reconnect support of the web interface.' 215 | - '2:Added web file manager.' 216 | - '2:Updated noVNC to version 1.6.0.' 217 | - '2:Updated web UI components (Bootstrap).' 218 | - '2:Do not ask VNC password when accessing the web interface and web authentication is enabled.' 219 | - version: 25.05.1 220 | date: 2025-05-23 221 | changes: 222 | - 'Updated CrashPlan to version 11.6.0.' 223 | - version: 25.02.2 224 | date: 2025-02-24 225 | changes: 226 | - 'Fixed crash that would occur when opening a file/folder selection dialog.' 227 | - version: 25.02.1 228 | date: 2025-02-09 229 | changes: 230 | - 'Updated baseimage to version 4.7.1, which brings the following changes (since last used version):' 231 | - '2:Added environment variable that allows configuring the web authentication token lifetime.' 232 | - '2:Fixed compatibility issues that were introduced with support of GTK4 applications.' 233 | - '2:Increased the default service ready timeout from 5 seconds to 10 seconds and allow runtime adjustment via environment variable.' 234 | - '2:Rebuild against latest distro images to get security fixes.' 235 | - version: 24.12.1 236 | date: 2024-12-07 237 | changes: 238 | - 'Updated baseimage to version 4.6.7, which brings the following changes:' 239 | - '2:Fixed web audio feature with URL path-based reverse proxy.' 240 | - '2:Fixed TLS secure connection method for VNC that was preventing web access.' 241 | - '2:Fixed CJK font installation.' 242 | - '2:Rebuild against latest distro images to get security fixes.' 243 | - version: 24.11.1 244 | date: 2024-11-18 245 | changes: 246 | - 'Updated CrashPlan to version 11.5.0.' 247 | - version: 24.10.1 248 | date: 2024-10-14 249 | changes: 250 | - 'Updated CrashPlan to version 11.4.1.' 251 | - 'Updated baseimage to version 4.6.4, which brings the following changes:' 252 | - '2:Fixed web authentication feature with URL path-based reverse proxy.' 253 | - '2:Rebuild against latest distro images to get security fixes.' 254 | - version: 24.08.1 255 | date: 2024-08-01 256 | changes: 257 | - 'Updated CrashPlan to version 11.4.0.' 258 | - 'Updated baseimage to version 4.6.3, which brings the following changes:' 259 | - '2:Audio support through web browser.' 260 | - '2:Web authentication support.' 261 | - '2:Better support of GTK4 applications.' 262 | - '2:Updated noVNC to version 1.5.0.' 263 | - '2:Updated web UI components (Bootstrap, Font Awesome).' 264 | - '2:When connecting, the control bar is now temporarily shown only once.' 265 | - '2:During package mirror setup, make sure to keep permissions of copied files.' 266 | - version: 24.01.1 267 | date: 2024-01-12 268 | changes: 269 | - 'Updated CrashPlan to version 11.2.1.' 270 | - 'Updated baseimage to version 4.5.3, which brings the following changes:' 271 | - '2:Disabled fullscreen support when page is loaded into an iFrame.' 272 | - '2:Rebuilt against latest distro images to get security fixes.' 273 | - version: 23.12.1 274 | date: 2023-12-16 275 | changes: 276 | - 'Make sure the server used for the Small Business edition is configured, even when the container is not upgrading or running for the first time.' 277 | - version: 23.11.4 278 | date: 2023-11-28 279 | changes: 280 | - 'Added support for new CrashPlan products.' 281 | - 'The CrashPlan server address can be set via the `CRASHPLAN_SERVER_ADDRESS` environment variable.' 282 | - version: 23.11.3 283 | date: 2023-11-19 284 | changes: 285 | - 'Updated baseimage to version 4.5.2, which brings the following changes:' 286 | - '2:Fixed issue that would cause the helper that takes ownership of a directory to fail when using a very high user or group ID.' 287 | - version: 23.11.2 288 | date: 2023-11-10 289 | changes: 290 | - 'Updated baseimage to version 4.5.1, which brings the following changes:' 291 | - '2:Mirror for packages installation can be set via the `PACKAGES_MIRROR` environment variable.' 292 | - '2:Improved the way the `take-ownership` script is working.' 293 | - '2:Readiness and minimum running time checks should not be done for a service defined with an interval.' 294 | - '2:Raise an error when a synched service fails to start.' 295 | - '2:Minimum running time check of a service was using an incorrect way to verify if process is still alive.' 296 | - '2:Fixed installation of CJK font.' 297 | - version: 23.11.1 298 | date: 2023-11-07 299 | changes: 300 | - 'Updated CrashPlan to version 11.2.0.' 301 | - version: 23.06.2 302 | date: 2023-06-21 303 | changes: 304 | - 'Updated CrashPlan to version 11.1.1.' 305 | - version: 23.06.1 306 | date: 2023-06-07 307 | changes: 308 | - 'Updated baseimage to version 4.4.2, which brings the following changes:' 309 | - '2:Rebuilt against latest distro images to get security fixes.' 310 | - '2:Updated X server to version 1.20.14.' 311 | - version: 23.04.2 312 | date: 2023-04-29 313 | changes: 314 | - 'Updated baseimage to version 4.4.1, which brings the following changes:' 315 | - '2:Updated TigerVNC to version 1.13.1.' 316 | - version: 23.04.1 317 | date: 2023-04-13 318 | changes: 319 | - 'Updated CrashPlan to version 11.0.1.' 320 | - version: 23.03.1 321 | date: 2023-03-05 322 | changes: 323 | - 'Updated baseimage to version 4.4.0, which brings the following changes:' 324 | - '2:Updated components providing access to application''s UI over web.' 325 | - '2:Improved web UI usage with touch devices.' 326 | - '2:Fixed issue with initialization of Linux users and groups when the `GROUP_ID` is also part of `SUP_GROUP_IDS`.' 327 | - '2:Limit the maximum number of opened files on system having a very large, unlimited value. This prevents unnecessary waste of CPU resources and time for applications trying to close all possible file descriptors.' 328 | - version: 23.02.2 329 | date: 2023-02-08 330 | changes: 331 | - 'Updated baseimage to version 4.3.4, which brings the following changes:' 332 | - '2:Fixed error message from openbox about missing Fontconfig cache directory.' 333 | - 'Do not use the OCI Docker image format yet to keep better compatibility (e.g with older docker clients).' 334 | - version: 23.02.1 335 | date: 2023-02-04 336 | changes: 337 | - 'Updated baseimage to version 4.3.3, which brings robustness related enhancements.' 338 | - version: 23.01.1 339 | date: 2023-01-04 340 | changes: 341 | - 'Update of the baseimage to version 4.3.1 brings the following changes:' 342 | - '2:Control menu can be moved to the right side of the screen.' 343 | - '2:Automatic focus of the clipboard text box when opening the control menu.' 344 | - '2:Automatic close of the control menu when clicking into the application.' 345 | - '2:Rotation of the internal web server log files.' 346 | - version: 22.12.2 347 | date: 2022-12-11 348 | changes: 349 | - 'Implemented workaround for issue seen with Synology devices where container would not start after an image update. The problem is caused by Synology explicitly setting all environment variables and keeping values from the old version.' 350 | - version: 22.12.1 351 | date: 2022-12-10 352 | changes: 353 | - 'Updated baseimage to version 4.2.1, which brings multiple internal enhancements.' 354 | - version: 22.11.3 355 | date: 2022-11-21 356 | changes: 357 | - 'Updated CrashPlan to version 10.4.1.' 358 | - version: 22.11.2 359 | date: 2022-11-07 360 | changes: 361 | - 'Fixed issue where the log monitor would use too much CPU.' 362 | - 'Fixed issue where the same alert would be shown multiple times.' 363 | - version: 22.11.1 364 | date: 2022-11-02 365 | changes: 366 | - 'Fixed display of non-english characters in filenames.' 367 | - version: 22.10.4 368 | date: 2022-10-30 369 | changes: 370 | - 'Fixed UI crash that was occuring when opening a file/directory selection window.' 371 | - version: 22.10.3 372 | date: 2022-10-30 373 | changes: 374 | - 'Fixed the history window being full screen.' 375 | - version: 22.10.2 376 | date: 2022-10-29 377 | changes: 378 | - 'Do not prevent the container from starting if CrashPlan engine is taking too long to start.' 379 | - version: 22.10.1 380 | date: 2022-10-29 381 | changes: 382 | - 'Updated CrashPlan to version 10.4.0.' 383 | - 'Versioning scheme of the Docker image changed to `YY.MM.SEQUENCE`.' 384 | - 'Update of the baseimage to version 4.1.2 brings the following new features:' 385 | - '2:Support for remote window resize.' 386 | - '2:Updated the web UI with a new, simplified and less intrusive look.' 387 | - version: 2.17.2 388 | date: 2022-08-06 389 | changes: 390 | - 'Updated CrashPlan to version 10.2.1.' 391 | - version: 2.17.1 392 | date: 2022-07-15 393 | changes: 394 | - 'Updated CrashPlan to version 10.2.0.' 395 | - version: 2.17.0 396 | date: 2022-05-15 397 | changes: 398 | - 'Updated CrashPlan to version 10.0.0.' 399 | - version: 2.16.8 400 | date: 2022-03-24 401 | changes: 402 | - 'Updated CrashPlan to version 8.8.4.' 403 | - version: 2.16.7 404 | date: 2022-02-25 405 | changes: 406 | - 'Updated CrashPlan to version 8.8.3.39.' 407 | - version: 2.16.6 408 | date: 2022-02-15 409 | changes: 410 | - 'Fixed an issue where restoring files would not work.' 411 | - 'Now using baseimage version 3.5.8, based on Alpine 3.14, which brings the following change:' 412 | - '2:Updated installed packages to get latest security fixes.' 413 | - version: 2.16.5 414 | date: 2022-01-21 415 | changes: 416 | - 'Updated CrashPlan to version 8.8.2.143.' 417 | - version: 2.16.4 418 | date: 2021-12-26 419 | changes: 420 | - 'Fixed, again, an issue where restoring files to an "other" location would crash the UI.' 421 | - version: 2.16.3 422 | date: 2021-12-25 423 | changes: 424 | - 'Added workaround for an issue where the CrashPlan engine would not start on devices running older kernel version.' 425 | - version: 2.16.2 426 | date: 2021-12-25 427 | changes: 428 | - 'Fixed an issue where restoring files to an "other" location would crash the UI.' 429 | - 'Fixed handling of filenames with special characters.' 430 | - version: 2.16.1 431 | date: 2021-12-20 432 | changes: 433 | - 'Updated CrashPlan to version 8.8.1.36.' 434 | - version: 2.16.0 435 | date: 2021-12-16 436 | changes: 437 | - 'Updated CrashPlan to version 8.8.1.' 438 | - version: 2.15.1 439 | date: 2021-09-08 440 | changes: 441 | - 'Updated CrashPlan to version 8.7.1.' 442 | - version: 2.15.0 443 | date: 2021-08-12 444 | changes: 445 | - 'Updated CrashPlan to version 8.7.0.' 446 | - version: 2.14.1 447 | date: 2021-06-03 448 | changes: 449 | - 'Updated CrashPlan to version 8.6.1.' 450 | - version: 2.14.0 451 | date: 2021-03-18 452 | changes: 453 | - 'Updated CrashPlan to version 8.6.0.' 454 | - version: 2.13.1 455 | date: 2020-10-29 456 | changes: 457 | - 'Removed debug messages that were left by mistake.' 458 | - version: 2.13.0 459 | date: 2020-10-20 460 | changes: 461 | - 'Updated CrashPlan PRO to version 8.5.0.' 462 | - version: 2.12.2 463 | date: 2020-09-10 464 | changes: 465 | - 'Fixed an issue that was preventing files to be restored.' 466 | - 'Fixed an issue where the restart command of the console would not work.' 467 | - version: 2.12.1 468 | date: 2020-08-05 469 | changes: 470 | - 'Upgraded CrashPlan PRO to version 8.2.2.' 471 | - 'Now using baseimage version 3.5.6, which brings the following changes:' 472 | - '2:Other small adjustments for the YAD log monitor target.' 473 | - version: 2.12.0 474 | date: 2020-07-19 475 | changes: 476 | - 'Upgraded CrashPlan PRO to version 8.2.0.' 477 | - 'Now using baseimage v3.5.5, which brings the following changes:' 478 | - '2:Upgraded glibc to version 2.31 on Alpine Linux images with glibc integrated.' 479 | - '2:Updated installed packages to get latest security fixes.' 480 | - '2:Adjusted the log monitor target for recent versions of YAD.' 481 | - version: 2.11.0 482 | date: 2020-05-10 483 | changes: 484 | - 'Upgraded CrashPlan PRO to version 8.0.0.' 485 | - version: 2.10.1 486 | date: 2020-04-06 487 | changes: 488 | - 'Fixed handling of CRASHPLAN_SRV_MAX_MEM.' 489 | - version: 2.10.0 490 | date: 2020-02-12 491 | changes: 492 | - 'Upgraded CrashPlan PRO to version 7.7.0.' 493 | - version: 2.9.0 494 | date: 2019-11-22 495 | changes: 496 | - 'Upgraded CrashPlan PRO to version 7.4.0.' 497 | - 'Now using baseimage v3.5.3, which brings the following changes:' 498 | - '2:Updated installed packages to get latest security fixes.' 499 | - '2:Make sure the tzdata is installed.' 500 | - version: 2.8.2 501 | date: 2019-10-22 502 | changes: 503 | - 'Fixed a notification message.' 504 | - version: 2.8.1 505 | date: 2019-10-08 506 | changes: 507 | - 'Fixed issue where the wrong log file was monitored.' 508 | - version: 2.8.0 509 | date: 2019-09-18 510 | changes: 511 | - 'Upgraded CrashPlan Enterprise to version 7.2.0.' 512 | - version: 2.7.3 513 | date: 2019-09-05 514 | changes: 515 | - 'Fixed misleading message about real-time file watching failure.' 516 | - version: 2.7.2 517 | date: 2019-07-13 518 | changes: 519 | - 'Upgraded CrashPlan PRO to version 7.0.0 build 585.' 520 | - version: 2.7.1 521 | date: 2019-06-22 522 | changes: 523 | - 'Fixed an issue where setting (via the environment variable) the maximum amount of memory CrashPlan is allowed to use would prevent the engine to start.' 524 | - version: 2.7.0 525 | date: 2019-06-22 526 | changes: 527 | - 'Upgraded CrashPlan PRO to version 7.0.0.' 528 | - version: 2.6.4 529 | date: 2019-04-24 530 | changes: 531 | - 'Now using baseimage v3.5.2, which brings the following changes:' 532 | - '2:Updated installed packages to get latest security fixes.' 533 | - '2:Fixed issue where the container could have a zombie process.' 534 | - '2:Fixed issue where the password would not be submitted when pressing the enter key in the password modal.' 535 | - '2:Use relative path for favicon ressources to be more friendly with reverse proxy senarios.' 536 | - version: 2.6.3 537 | date: 2019-04-20 538 | changes: 539 | - 'Upgraded CrashPlan PRO to version 6.9.4.' 540 | - version: 2.6.2 541 | date: 2019-02-20 542 | changes: 543 | - 'Upgraded CrashPlan PRO to version 6.9.2.' 544 | - version: 2.6.1 545 | date: 2018-12-19 546 | changes: 547 | - 'Upgraded to build 827 of CrashPlan PRO 6.9.0.' 548 | - 'Updated logo of Crashplan.' 549 | - version: 2.6.0 550 | date: 2018-12-09 551 | changes: 552 | - 'Upgraded CrashPlan PRO to version 6.9.0.' 553 | - 'Make sure only the numerical kernel version is reported to CrashPlan PRO.' 554 | - version: 2.5.0 555 | date: 2018-09-20 556 | changes: 557 | - 'Upgraded CrashPlan PRO to version 6.8.3.' 558 | - version: 2.4.1 559 | date: 2018-09-18 560 | changes: 561 | - 'Now using baseimage v3.5.1, which brings the following changes:' 562 | - '2:Updated installed packages to get latest security fixes.' 563 | - version: 2.4.0 564 | date: 2018-08-22 565 | changes: 566 | - 'Upgraded CrashPlan PRO to version 6.8.2.' 567 | - 'Now using baseimage v3.5.0, which brings the following changes (since last used version):' 568 | - '2:Based on Alpine Linux 3.8.' 569 | - '2:Upgraded s6-overlay to version 1.21.4.0.' 570 | - '2:Wait for a limited time when terminating a service.' 571 | - '2:Set and create the XDG_RUNTIME_DIR directory.' 572 | - version: 2.3.8 573 | date: 2018-08-10 574 | changes: 575 | - 'Fixed and issue where container would fail to start on host running CentOS.' 576 | - version: 2.3.7 577 | date: 2018-06-14 578 | changes: 579 | - 'To make sure the CrashPlan Engine will start, validate the value of CRASHPLAN_SRV_MAX_MEM variable during startup.' 580 | - version: 2.3.6 581 | date: 2018-06-11 582 | changes: 583 | - 'Fixed more instances where parsing of CrashPlan memory usage would fail.' 584 | - version: 2.3.5 585 | date: 2018-06-06 586 | changes: 587 | - 'Fixed an issue where parsing of CrashPlan memory usage would fail.' 588 | - version: 2.3.4 589 | date: 2018-05-15 590 | changes: 591 | - 'Upgraded CrashPlan to version 6.7.2.' 592 | - version: 2.3.3 593 | date: 2018-04-23 594 | changes: 595 | - 'Fixed issue where supplementary groups were not applied to the CrashPlan engine.' 596 | - version: 2.3.2 597 | date: 2018-04-03 598 | changes: 599 | - 'Upgraded CrashPlan to version 6.7.1.' 600 | - 'Fixed an issue where running the container as user `nobody` (id 65534) would fail.' 601 | - 'Switched to a baseimage based on Alpine Linux 3.7.' 602 | - version: 2.3.1 603 | date: 2018-03-05 604 | changes: 605 | - 'Use the correct variable to keep the application running.' 606 | - version: 2.3.0 607 | date: 2018-03-02 608 | changes: 609 | - 'Now using baseimage v3.3.4, which brings the following changes (since last used version):' 610 | - '2:Make sure the log monitor is started after the X server.' 611 | - '2:Fixed an issue where the log monitor `yad` target would use XDG folders of the application.' 612 | - '2:Fixed issue where log monitor states were not cleared during container startup.' 613 | - 'Trigger a notification when file restore fails due to `/storage` being read-only.' 614 | - version: 2.2.1 615 | date: 2018-02-03 616 | changes: 617 | - 'Now using baseimage v3.3.2, which brings the following changes:' 618 | - '2:Restored timezone support in Alpine Linux images with glibc.' 619 | - '2:Fixed issue in `add-pkg` helper where a package could be incorrectly detected as installed.' 620 | - version: 2.2.0 621 | date: 2018-02-02 622 | changes: 623 | - 'Updated CrashPlan PRO to version 6.7.0.' 624 | - version: 2.1.1 625 | date: 2018-01-30 626 | changes: 627 | - 'Now using baseimage v3.3.1, which brings the following changes:' 628 | - '2:Adjusted the way some ressources are accessed to better support reverse proxy to the container.' 629 | - version: 2.1.0 630 | date: 2018-01-22 631 | changes: 632 | - 'Now using baseimage v3.3.0, which brings the following changes (since last used version):' 633 | - '2:For Alpine Linux images with glibc, automatically update dynamic linker''s cache after new libraries are installed.' 634 | - '2:Fixed the LANG environment variable not being set properly.' 635 | - '2:Added the ability to automatically install a CJK (Chinese/Japanese/Korean) font.' 636 | - version: 2.0.4 637 | date: 2018-01-11 638 | changes: 639 | - 'Fixed issue where libraries were not found.' 640 | - version: 2.0.3 641 | date: 2018-01-11 642 | changes: 643 | - 'Now using baseimage v3.2.2, which brings the following changes (since last used version):' 644 | - '2:Upgraded S6 overlay to version 1.21.2.2.' 645 | - '2:Upgraded glibc to version 2.26 (Alpine Linux glibc images).' 646 | - '2:Adjusted the way ownership of /config is taken to better support cases where the folder is mapped to a network share.' 647 | - 'Small adjustment to the way ownership of files are taken.' 648 | - version: 2.0.2 649 | date: 2017-12-14 650 | changes: 651 | - 'Fixed an issue where the CrashPlan UI would not connect to the engine using the loopback IP.' 652 | - 'Fixed an issue where automatic update could be partially done when running the container as root.' 653 | - version: 2.0.1 654 | date: 2017-12-12 655 | changes: 656 | - 'Now using baseimage v3.1.4, which brings the following changes:' 657 | - '2:Set 2 worker processes for nginx.' 658 | - version: 2.0.0 659 | date: 2017-12-08 660 | changes: 661 | - 'Upgraded CrashPlan to version 6.6.0.' 662 | - version: 1.2.2 663 | date: 2017-11-20 664 | changes: 665 | - 'Now using baseimage v3.1.3, which brings the following changes:' 666 | - '2:Upgraded S6 overlay to version 1.21.2.1.' 667 | - version: 1.2.1 668 | date: 2017-11-07 669 | changes: 670 | - 'Now using baseimage v3.1.2, which brings the following changes (from last used version):' 671 | - '2:Fixed an issue where a self-disabled service could be restarted.' 672 | - '2:Upgraded S6 overlay to version 1.21.2.0.' 673 | - '2:Use a more efficient way to monitor status files.' 674 | - 'Wait for the CrashPlan engine to be ready before starting the UI.' 675 | - version: 1.2.0 676 | date: 2017-10-30 677 | changes: 678 | - 'Now using baseimage v3.1.0, which brings the following changes:' 679 | - '2:Upgraded S6 overlay to version 1.21.1.1.' 680 | - '2:Enhanced integration of service dependencies functionality.' 681 | - '2:Added a simple log monitor.' 682 | - '2:Fixed race condition where container''s exit code would not be the expected one.' 683 | - '2:Fixed issue where application''s GUI fails to displayed when accessing it through the web interface via standard ports 80/443.' 684 | - 'Alert user of common problems.' 685 | - version: 1.1.2 686 | date: 2017-10-09 687 | changes: 688 | - 'Now using baseimage v3.0.2, which brings the following changes:' 689 | - '2:Fixed issue where nginx config change was not applied correctly on systems without IPV6 support and secure connection disabled.' 690 | - version: 1.1.1 691 | date: 2017-10-08 692 | changes: 693 | - 'Now using baseimage v3.0.1, which brings the following changes:' 694 | - '2:Fixed nginx config for systems without IPV6 support.' 695 | - version: 1.1.0 696 | date: 2017-10-08 697 | changes: 698 | - 'Now using baseimage v3.0.0, which brings the following changes:' 699 | - '2:Better support for service dependencies.' 700 | - '2:Added support for secure access to the application''s GUI.' 701 | - version: 1.0.1 702 | date: 2017-09-08 703 | changes: 704 | - 'Now using baseimage v2.0.8, which brings the following changes (from last used version):' 705 | - '2:Fixed timezone support on alpine-glibc images.' 706 | - '2:Fixed duplicated entries in /etc/passwd and /etc/group that were created after a restart of the container.' 707 | - version: 1.0.0 708 | date: 2017-08-24 709 | changes: 710 | - 'Initial release.' 711 | 712 | container: 713 | storage_permissions: ro 714 | 715 | # Environment variables. 716 | environment_variables: 717 | - name: CRASHPLAN_SRV_MAX_MEM 718 | description: >- 719 | Maximum amount of memory the CrashPlan Engine is allowed to use. One of 720 | the following memory unit (case insensitive) should be added as a suffix 721 | to the size: `G`, `M` or `K`. By default, when this variable is not 722 | set, a maximum of 1024MB (`1024M`) of memory is allowed. **NOTE**: 723 | Setting this variable as the same effect as running the `java mx VALUE, 724 | restart` command from the CrashPlan command line. 725 | type: public 726 | default: 1024M 727 | unraid_template: 728 | title: Maximum Memory 729 | description: >- 730 | Maximum amount of memory the CrashPlan Engine is allowed to use. One 731 | of the following memory unit (case insensitive) should be added as a 732 | suffix to the size: G, M or K. 733 | display: advanced 734 | required: false 735 | mask: false 736 | 737 | # Volumes 738 | volumes: [] 739 | 740 | # Network ports 741 | ports: [] 742 | 743 | # Devices 744 | devices: [] 745 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker container for CrashPlan 2 | [![Release](https://img.shields.io/github/release/jlesage/docker-crashplan-pro.svg?logo=github&style=for-the-badge)](https://github.com/jlesage/docker-crashplan-pro/releases/latest) 3 | [![Docker Image Size](https://img.shields.io/docker/image-size/jlesage/crashplan-pro/latest?logo=docker&style=for-the-badge)](https://hub.docker.com/r/jlesage/crashplan-pro/tags) 4 | [![Docker Pulls](https://img.shields.io/docker/pulls/jlesage/crashplan-pro?label=Pulls&logo=docker&style=for-the-badge)](https://hub.docker.com/r/jlesage/crashplan-pro) 5 | [![Docker Stars](https://img.shields.io/docker/stars/jlesage/crashplan-pro?label=Stars&logo=docker&style=for-the-badge)](https://hub.docker.com/r/jlesage/crashplan-pro) 6 | [![Build Status](https://img.shields.io/github/actions/workflow/status/jlesage/docker-crashplan-pro/build-image.yml?logo=github&branch=master&style=for-the-badge)](https://github.com/jlesage/docker-crashplan-pro/actions/workflows/build-image.yml) 7 | [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg?style=for-the-badge)](https://paypal.me/JocelynLeSage) 8 | 9 | This project provides a Docker container for [CrashPlan](https://www.crashplan.com). 10 | 11 | The graphical user interface (GUI) of the application can be accessed through a 12 | modern web browser, requiring no installation or configuration on the client 13 | side, or via any VNC client. 14 | 15 | This Docker container can be used with all CrashPlan products: Essential, 16 | Professional, Enterprise, MSPs and Small Business (no longer sold). 17 | 18 | > [!NOTE] 19 | > This Docker container is entirely unofficial and not made by the creators of CrashPlan. 20 | 21 | --- 22 | 23 | [![CrashPlan logo](https://images.weserv.nl/?url=raw.githubusercontent.com/jlesage/docker-templates/master/jlesage/images/crashplan-pro-icon.png&w=110)](https://www.crashplan.com)[![CrashPlan](https://images.placeholders.dev/?width=288&height=110&fontFamily=monospace&fontWeight=400&fontSize=52&text=CrashPlan&bgColor=rgba(0,0,0,0.0)&textColor=rgba(121,121,121,1))](https://www.crashplan.com) 24 | 25 | CrashPlan provides peace of mind through secure, scalable, and 26 | straightforward endpoint data backup. We help organizations recover from 27 | any worst-case scenario, whether it is a disaster, simple human error, a 28 | stolen laptop, ransomware or an as-of-yet undiscovered calamity. 29 | 30 | --- 31 | 32 | ## Table of Contents 33 | 34 | * [Quick Start](#quick-start) 35 | * [Usage](#usage) 36 | * [Environment Variables](#environment-variables) 37 | * [Deployment Considerations](#deployment-considerations) 38 | * [Data Volumes](#data-volumes) 39 | * [Ports](#ports) 40 | * [Changing Parameters of a Running Container](#changing-parameters-of-a-running-container) 41 | * [Docker Compose File](#docker-compose-file) 42 | * [Docker Image Versioning and Tags](#docker-image-versioning-and-tags) 43 | * [Docker Image Update](#docker-image-update) 44 | * [Synology](#synology) 45 | * [unRAID](#unraid) 46 | * [User/Group IDs](#usergroup-ids) 47 | * [Accessing the GUI](#accessing-the-gui) 48 | * [Security](#security) 49 | * [SSVNC](#ssvnc) 50 | * [Certificates](#certificates) 51 | * [VNC Password](#vnc-password) 52 | * [Web Authentication](#web-authentication) 53 | * [Configuring Users Credentials](#configuring-users-credentials) 54 | * [Reverse Proxy](#reverse-proxy) 55 | * [Routing Based on Hostname](#routing-based-on-hostname) 56 | * [Routing Based on URL Path](#routing-based-on-url-path) 57 | * [Web Control Panel](#web-control-panel) 58 | * [Automatic Clipboard Sync](#automatic-clipboard-sync) 59 | * [Web Audio](#web-audio) 60 | * [Web File Manager](#web-file-manager) 61 | * [Web Notifications](#web-notifications) 62 | * [GPU Acceleration Support](#gpu-acceleration-support) 63 | * [Shell Access](#shell-access) 64 | * [Taking Over Existing Backup](#taking-over-existing-backup) 65 | * [Why CrashPlan Self Update Is Disabled](#why-crashplan-self-update-is-disabled) 66 | * [Troubleshooting](#troubleshooting) 67 | * [Crashes / Maximum Amount of Allocated Memory](#crashes--maximum-amount-of-allocated-memory) 68 | * [Inotify's Watch Limit](#inotifys-watch-limit) 69 | * [Synology](#synology-1) 70 | * [Empty /storage](#empty-storage) 71 | * [Device Status Is Waiting For Connection](#device-status-is-waiting-for-connection) 72 | * [Cannot Restore Files](#cannot-restore-files) 73 | * [Upgrade Failed Error Message](#upgrade-failed-error-message) 74 | * [Support or Contact](#support-or-contact) 75 | 76 | ## Quick Start 77 | 78 | > [!IMPORTANT] 79 | > The Docker command provided in this quick start is an example, and parameters 80 | > should be adjusted to suit your needs. 81 | 82 | Launch the CrashPlan docker container with the following command: 83 | 84 | ```shell 85 | docker run -d \ 86 | --name=crashplan-pro \ 87 | -p 5800:5800 \ 88 | -v /docker/appdata/crashplan-pro:/config:rw \ 89 | -v /home/user:/storage:ro \ 90 | jlesage/crashplan-pro 91 | ``` 92 | 93 | Where: 94 | 95 | - `/docker/appdata/crashplan-pro`: Stores the application's configuration, state, logs, and any files requiring persistency. 96 | - `/home/user`: Contains files from the host that need to be accessible to the application. 97 | 98 | Access the CrashPlan GUI by browsing to `http://your-host-ip:5800`. 99 | Files from the host appear under the `/storage` folder in the container. 100 | 101 | ## Usage 102 | 103 | ```shell 104 | docker run [-d] \ 105 | --name=crashplan-pro \ 106 | [-e =]... \ 107 | [-v :[:PERMISSIONS]]... \ 108 | [-p :]... \ 109 | jlesage/crashplan-pro 110 | ``` 111 | 112 | | Parameter | Description | 113 | |-----------|-------------| 114 | | -d | Runs the container in the background. If not set, the container runs in the foreground. | 115 | | -e | Passes an environment variable to the container. See [Environment Variables](#environment-variables) for details. | 116 | | -v | Sets a volume mapping to share a folder or file between the host and the container. See [Data Volumes](#data-volumes) for details. | 117 | | -p | Sets a network port mapping to expose an internal container port to the host). See [Ports](#ports) for details. | 118 | 119 | ### Environment Variables 120 | 121 | To customize the container's behavior, you can pass environment variables using 122 | the `-e` parameter in the format `=`. 123 | 124 | | Variable | Description | Default | 125 | |----------------|----------------------------------------------|---------| 126 | |`USER_ID`| ID of the user the application runs as. See [User/Group IDs](#usergroup-ids) for details. | `1000` | 127 | |`GROUP_ID`| ID of the group the application runs as. See [User/Group IDs](#usergroup-ids) for details. | `1000` | 128 | |`SUP_GROUP_IDS`| Comma-separated list of supplementary group IDs for the application. | (no value) | 129 | |`UMASK`| Mask controlling permissions for newly created files and folders, specified in octal notation. By default, `0022` ensures files and folders are readable by all but writable only by the owner. See the umask calculator at http://wintelguy.com/umask-calc.pl. | `0022` | 130 | |`LANG`| Sets the [locale](https://en.wikipedia.org/wiki/Locale_(computer_software)), defining the application's language, if supported. Format is `language[_territory][.codeset]`, where language is an [ISO 639 language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), territory is an [ISO 3166 country code](https://en.wikipedia.org/wiki/ISO_3166-1#Current_codes), and codeset is a character set, like `UTF-8`. For example, Australian English using UTF-8 is `en_AU.UTF-8`. | `en_US.UTF-8` | 131 | |`TZ`| [TimeZone](http://en.wikipedia.org/wiki/List_of_tz_database_time_zones) used by the container. The timezone can also be set by mapping `/etc/localtime` between the host and the container. | `Etc/UTC` | 132 | |`KEEP_APP_RUNNING`| When set to `1`, the application is automatically restarted if it crashes or terminates. | `0` | 133 | |`APP_NICENESS`| Priority at which the application runs. A niceness value of -20 is the highest, 19 is the lowest and 0 the default. **NOTE**: A negative niceness (priority increase) requires additional permissions. The container must be run with the Docker option `--cap-add=SYS_NICE`. | `0` | 134 | |`INSTALL_PACKAGES`| Space-separated list of packages to install during container startup. List of available packages can be found at https://pkgs.alpinelinux.org. | (no value) | 135 | |`PACKAGES_MIRROR`| Mirror of the repository to use when installing packages. List of mirrors is available at https://mirrors.alpinelinux.org. | (no value) | 136 | |`CONTAINER_DEBUG`| When set to `1`, enables debug logging. | `0` | 137 | |`DISPLAY_WIDTH`| Width (in pixels) of the application's window. | `1920` | 138 | |`DISPLAY_HEIGHT`| Height (in pixels) of the application's window. | `1080` | 139 | |`DARK_MODE`| When set to `1`, enables dark mode for the application. See Dark Mode](#dark-mode) for details. | `0` | 140 | |`WEB_AUDIO`| When set to `1`, enables audio support, allowing audio produced by the application to play through the browser. See [Web Audio](#web-audio) for details. | `0` | 141 | |`WEB_FILE_MANAGER`| When set to `1`, enables the web file manager, allowing interaction with files inside the container through the web browser, supporting operations like renaming, deleting, uploading, and downloading. See [Web File Manager](#web-file-manager) for details. | `0` | 142 | |`WEB_FILE_MANAGER_ALLOWED_PATHS`| Comma-separated list of paths within the container that the file manager can access. By default, the container's entire filesystem is not accessible, and this variable specifies allowed paths. If set to `AUTO`, commonly used folders and those mapped to the container are automatically allowed. The value `ALL` allows access to all paths (no restrictions). See [Web File Manager](#web-file-manager) for details. | `AUTO` | 143 | |`WEB_FILE_MANAGER_DENIED_PATHS`| Comma-separated list of paths within the container that the file manager cannot access. A denied path takes precedence over an allowed path. See [Web File Manager](#web-file-manager) for details. | (no value) | 144 | |`WEB_NOTIFICATION`| When set to `1`, enables the web notification service, allowing the browser to display desktop notifications from the application. Requires the container to be configured with secure web access (HTTPS). See [Web Notifications](#web-notifications) for details. | `0` | 145 | |`WEB_AUTHENTICATION`| When set to `1`, protects the application's GUI with a login page when accessed via a web browser. Access is granted only with valid credentials. Requires the container to be configured with secure web access (HTTPS). See [Web Authentication](#web-authentication) for details. | `0` | 146 | |`WEB_AUTHENTICATION_TOKEN_VALIDITY_TIME`| Lifetime of a token, in hours. A token is assigned to the user after successful login. As long as the token is valid, the user can access the application's GUI without logging in again. Once the token expires, the login page is displayed again. | `24` | 147 | |`WEB_AUTHENTICATION_USERNAME`| Optional username for web authentication. Provides a quick and easy way to configure credentials for a single user. For more secure configuration or multiple users, see the [Web Authentication](#web-authentication) section. | (no value) | 148 | |`WEB_AUTHENTICATION_PASSWORD`| Optional password for web authentication. Provides a quick and easy way to configure credentials for a single user. For more secure configuration or multiple users, see the [Web Authentication](#web-authentication) section. | (no value) | 149 | |`SECURE_CONNECTION`| When set to `1`, uses an encrypted connection to access the application's GUI (via web browser or VNC client). See [Security](#security) for details. | `0` | 150 | |`SECURE_CONNECTION_VNC_METHOD`| Method used for encrypted VNC connections. Possible values are `SSL` or `TLS`. See [Security](#security) for details. | `SSL` | 151 | |`SECURE_CONNECTION_CERTS_CHECK_INTERVAL`| Interval, in seconds, at which the system checks if web or VNC certificates have changed. When a change is detected, affected services are automatically restarted. A value of `0` disables the check. | `60` | 152 | |`WEB_LOCALHOST_ONLY`| When set to `1`, allows web connections only from localhost (127.0.0.1 and ::1). | `0` | 153 | |`VNC_LOCALHOST_ONLY`| When set to `1`, allows VNC connections only from localhost (127.0.0.1 and ::1). | `0` | 154 | |`WEB_LISTENING_PORT`| Port used by the web server to serve the application's GUI. This port is internal to the container and typically does not need to be changed. By default, a container uses the default bridge network, requiring each internal port to be mapped to an external port (using the `-p` or `--publish` argument). If another network type is used, changing this port may prevent conflicts with other services/containers. **NOTE**: A value of `-1` disables HTTP/HTTPS access to the application's GUI. | `5800` | 155 | |`VNC_LISTENING_PORT`| Port used by the VNC server to serve the application's GUI. This port is internal to the container and typically does not need to be changed. By default, a container uses the default bridge network, requiring each internal port to be mapped to an external port (using the `-p` or `--publish` argument). If another network type is used, changing this port may prevent conflicts with other services/containers. **NOTE**: A value of `-1` disables VNC access to the application's GUI. | `5900` | 156 | |`VNC_PASSWORD`| Password required to connect to the application's GUI. See the [VNC Password](#vnc-password) section for details. | (no value) | 157 | |`ENABLE_CJK_FONT`| When set to `1`, installs the open-source font `WenQuanYi Zen Hei`, supporting a wide range of Chinese/Japanese/Korean characters. | `0` | 158 | |`CRASHPLAN_SRV_MAX_MEM`| Maximum amount of memory the CrashPlan Engine is allowed to use. One of the following memory unit (case insensitive) should be added as a suffix to the size: `G`, `M` or `K`. By default, when this variable is not set, a maximum of 1024MB (`1024M`) of memory is allowed. **NOTE**: Setting this variable as the same effect as running the `java mx VALUE, restart` command from the CrashPlan command line. | `1024M` | 159 | 160 | #### Deployment Considerations 161 | 162 | Many tools used to manage Docker containers extract environment variables 163 | defined by the Docker image to create or deploy the container. 164 | 165 | For example, this behavior is seen in: 166 | - The Docker application on Synology NAS 167 | - The Container Station on QNAP NAS 168 | - Portainer 169 | - etc. 170 | 171 | While this is useful for users to adjust environment variable values to suit 172 | their needs, keeping all of them can be confusing and even risky. 173 | 174 | A good practice is to set or retain only the variables necessary for the 175 | container to function as desired in your setup. If a variable is left at its 176 | default value, it can be removed. Keep in mind that all environment variables 177 | are optional; none are required for the container to start. 178 | 179 | Removing unneeded environment variables offers several benefits: 180 | 181 | - Prevents retaining variables no longer used by the container. Over time, 182 | with image updates, some variables may become obsolete. 183 | - Allows the Docker image to update or fix default values. With image updates, 184 | default values may change to address issues or support new features. 185 | - Avoids changes to variables that could disrupt the container's 186 | functionality. Some undocumented variables, like `PATH` or `ENV`, are 187 | required but not meant to be modified by users, yet container management 188 | tools may expose them. 189 | - Addresses a bug in Container Station on QNAP and the Docker application on 190 | Synology, where variables without values may not be allowed. This behavior 191 | is incorrect, as variables without values are valid. Removing unneeded 192 | variables prevents deployment issues on these devices. 193 | 194 | ### Data Volumes 195 | 196 | The following table describes the data volumes used by the container. Volume 197 | mappings are set using the `-v` parameter with a value in the format 198 | `:[:PERMISSIONS]`. 199 | 200 | | Container path | Permissions | Description | 201 | |-----------------|-------------|-------------| 202 | |`/config`| rw | Stores the application's configuration, state, logs, and any files requiring persistency. | 203 | |`/storage`| ro | Contains files from the host that need to be accessible to the application. | 204 | 205 | ### Ports 206 | 207 | The following table lists the ports used by the container. 208 | 209 | When using the default bridge network, ports can be mapped to the host using the 210 | `-p` parameter with value in the format `:`. The 211 | internal container port may not be changeable, but you can use any port on the 212 | host side. 213 | 214 | See the Docker [Docker Container Networking](https://docs.docker.com/config/containers/container-networking) 215 | documentation for details. 216 | 217 | | Port | Protocol | Mapping to Host | Description | 218 | |------|----------|-----------------|-------------| 219 | | 5800 | TCP | Optional | Port to access the application's GUI via the web interface. Mapping to the host is optional if web access is not needed. For non-default bridge networks, the port can be changed with the `WEB_LISTENING_PORT` environment variable. | 220 | | 5900 | TCP | Optional | Port to access the application's GUI via the VNC protocol. Mapping to the host is optional if VNC access is not needed. For non-default bridge networks, the port can be changed with the `VNC_LISTENING_PORT` environment variable. | 221 | 222 | ### Changing Parameters of a Running Container 223 | 224 | Environment variables, volume mappings, and port mappings are specified when 225 | creating the container. To modify these parameters for an existing container, 226 | follow these steps: 227 | 228 | 1. Stop the container (if it is running): 229 | ```shell 230 | docker stop crashplan-pro 231 | ``` 232 | 233 | 2. Remove the container: 234 | ```shell 235 | docker rm crashplan-pro 236 | ``` 237 | 238 | 3. Recreate and start the container using the `docker run` command, adjusting 239 | parameters as needed. 240 | 241 | > [!NOTE] 242 | > Since all application data is saved under the `/config` container folder, 243 | > destroying and recreating the container does not result in data loss, and the 244 | > application resumes with the same state, provided the `/config` folder 245 | > mapping remains unchanged. 246 | 247 | ### Docker Compose File 248 | 249 | Below is an example `docker-compose.yml` file for use with 250 | [Docker Compose](https://docs.docker.com/compose/overview/). 251 | 252 | Adjust the configuration to suit your needs. Only mandatory settings are 253 | included in this example. 254 | 255 | ```yaml 256 | version: '3' 257 | services: 258 | crashplan-pro: 259 | image: jlesage/crashplan-pro 260 | ports: 261 | - "5800:5800" 262 | volumes: 263 | - "/docker/appdata/crashplan-pro:/config:rw" 264 | - "/home/user:/storage:ro" 265 | ``` 266 | 267 | ## Docker Image Versioning and Tags 268 | 269 | Each release of a Docker image is versioned, and each version as its own image 270 | tag. Before October 2022, the versioning scheme followed 271 | [semantic versioning](https://semver.org). 272 | 273 | Since then, the versioning scheme has shifted to 274 | [calendar versioning](https://calver.org) with the format `YY.MM.SEQUENCE`, 275 | where: 276 | - `YY` is the zero-padded year (relative to year 2000). 277 | - `MM` is the zero-padded month. 278 | - `SEQUENCE` is the incremental release number within the month (first release 279 | is 1, second is 2, etc). 280 | 281 | View all available tags on [Docker Hub] or check the [Releases] page for version 282 | details. 283 | 284 | [Releases]: https://github.com/jlesage/docker-crashplan-pro/releases 285 | [Docker Hub]: https://hub.docker.com/r/jlesage/crashplan-pro/tags 286 | 287 | ## Docker Image Update 288 | 289 | The Docker image is regularly updated to incorporate new features, fix issues, 290 | or integrate newer versions of the containerized application. Several methods 291 | can be used to update the Docker image. 292 | 293 | If your system provides a built-in method for updating containers, this should 294 | be your primary approach. 295 | 296 | Alternatively, you can use [Watchtower], a container-based solution for 297 | automating Docker image updates. Watchtower seamlessly handles updates when a 298 | new image is available. 299 | 300 | To manually update the Docker image, follow these steps: 301 | 302 | 1. Fetch the latest image: 303 | ```shell 304 | docker pull jlesage/crashplan-pro 305 | ``` 306 | 307 | 2. Stop the container: 308 | ```shell 309 | docker stop crashplan-pro 310 | ``` 311 | 312 | 3. Remove the container: 313 | ```shell 314 | docker rm crashplan-pro 315 | ``` 316 | 317 | 4. Recreate and start the container using the `docker run` command, with the 318 | same parameters used during initial deployment. 319 | 320 | [Watchtower]: https://github.com/containrrr/watchtower 321 | 322 | ### Synology 323 | 324 | For Synology NAS users, follow these steps to update a container image: 325 | 326 | 1. Open the *Docker* application. 327 | 2. Click *Registry* in the left pane. 328 | 3. In the search bar, type the name of the container (`jlesage/crashplan-pro`). 329 | 4. Select the image, click *Download*, and choose the `latest` tag. 330 | 5. Wait for the download to complete. A notification will appear once done. 331 | 6. Click *Container* in the left pane. 332 | 7. Select your CrashPlan container. 333 | 8. Stop it by clicking *Action* -> *Stop*. 334 | 9. Clear the container by clicking *Action* -> *Reset* (or *Action* -> 335 | *Clear* if you don't have the latest *Docker* application). This removes 336 | the container while keeping its configuration. 337 | 10. Start the container again by clicking *Action* -> *Start*. **NOTE**: The 338 | container may temporarily disappear from the list while it is recreated. 339 | 340 | ### unRAID 341 | 342 | For unRAID users, update a container image with these steps: 343 | 344 | 1. Select the *Docker* tab. 345 | 2. Click the *Check for Updates* button at the bottom of the page. 346 | 3. Click the *apply update* link of the container to be updated. 347 | 348 | ## User/Group IDs 349 | 350 | When mapping data volumes (using the `-v` flag of the `docker run` command), 351 | permission issues may arise between the host and the container. Files and 352 | folders in a data volume are owned by a user, which may differ from the user 353 | running the application. Depending on permissions, this could prevent the 354 | container from accessing the shared volume. 355 | 356 | To avoid this, specify the user the application should run as using the 357 | `USER_ID` and `GROUP_ID` environment variables. 358 | 359 | To find the appropriate IDs, run the following command on the host for the user 360 | owning the data volume: 361 | 362 | ```shell 363 | id 364 | ``` 365 | 366 | This produces output like: 367 | 368 | ``` 369 | uid=1000(myuser) gid=1000(myuser) groups=1000(myuser),4(adm),24(cdrom),27(sudo),46(plugdev),113(lpadmin) 370 | ``` 371 | 372 | Use the `uid` (user ID) and `gid` (group ID) values to configure the container. 373 | 374 | ## Accessing the GUI 375 | 376 | Assuming the container's ports are mapped to the same host's ports, access the 377 | application's GUI as follows: 378 | 379 | - Via a web browser: 380 | 381 | ```text 382 | http://:5800 383 | ``` 384 | 385 | - Via any VNC client: 386 | 387 | ```text 388 | :5900 389 | ``` 390 | 391 | ## Security 392 | 393 | By default, access to the application's GUI uses an unencrypted connection (HTTP 394 | or VNC). 395 | 396 | A secure connection can be enabled via the `SECURE_CONNECTION` environment 397 | variable. See the [Environment Variables](#environment-variables) section for 398 | details on configuring environment variables. 399 | 400 | When enabled, the GUI is accessed over HTTPS when using a browser, with all HTTP 401 | accesses redirected to HTTPS. 402 | 403 | For VNC clients, the connection can be secured using on of two methods, 404 | configured via the `SECURE_CONNECTION_VNC_METHOD` environment variable: 405 | 406 | - `SSL`: An SSL tunnel is used to transport the VNC connection. Few VNC 407 | clients supports this method; [SSVNC] is one that does. 408 | - `TLS`: A VNC security type negotiated during the VNC handshake. It uses TLS 409 | to establish a secure connection. Clients may optionally validate the 410 | server’s certificate. Valid certificates must be provided for this 411 | validation to succeed. See [Certificates](#certificates) for details. 412 | [TigerVNC] is a client that supports TLS encryption. 413 | 414 | [TigerVNC]: https://tigervnc.org 415 | 416 | ### SSVNC 417 | 418 | [SSVNC] is a VNC viewer that adds encryption to VNC connections by using an 419 | SSL tunnel to transport the VNC traffic. 420 | 421 | While the Linux version of [SSVNC] works well, the Windows version has issues. 422 | At the time of writing, the latest version `1.0.30` fails with the error: 423 | 424 | ```text 425 | ReadExact: Socket error while reading 426 | ``` 427 | 428 | For convenience, an unofficial, working version is provided here: 429 | 430 | https://github.com/jlesage/docker-baseimage-gui/raw/master/tools/ssvnc_windows_only-1.0.30-r1.zip 431 | 432 | This version upgrades the bundled `stunnel` to version `5.49`, resolving the 433 | connection issues. 434 | 435 | [SSVNC]: http://www.karlrunge.com/x11vnc/ssvnc.html 436 | 437 | ### Certificates 438 | 439 | The following certificate files are required by the container. If missing, 440 | self-signed certificates are generated and used. All files are PEM-encoded x509 441 | certificates. 442 | 443 | | Container Path | Purpose | Content | 444 | |---------------------------------|----------------------------|---------| 445 | |`/config/certs/vnc-server.pem` |VNC connection encryption. |VNC server's private key and certificate, bundled with any root and intermediate certificates.| 446 | |`/config/certs/web-privkey.pem` |HTTPS connection encryption.|Web server's private key.| 447 | |`/config/certs/web-fullchain.pem`|HTTPS connection encryption.|Web server's certificate, bundled with any root and intermediate certificates.| 448 | 449 | > [!TIP] 450 | > To avoid certificate validity warnings or errors in browsers or VNC clients, 451 | > provide your own valid certificates. 452 | 453 | > [!NOTE] 454 | > Certificate files are monitored, and relevant services are restarted when 455 | > changes are detected. 456 | 457 | ### VNC Password 458 | 459 | To restrict access to your application, set a password using one of two methods: 460 | - Via the `VNC_PASSWORD` environment variable. 461 | - Via a `.vncpass_clear` file at the root of the `/config` volume, containing 462 | the password in clear text. During container startup, the content is 463 | obfuscated and moved to `.vncpass`. 464 | 465 | The security of the VNC password depends on: 466 | - The communication channel (encrypted or unencrypted). 467 | - The security of host access. 468 | 469 | When using a VNC password, configure the container with secure web access 470 | (HTTPS) to prevent sending the password in clear text over an unencrypted 471 | channel. 472 | 473 | Unauthorized users with sufficient host privileges can retrieve the password by: 474 | 475 | - Viewing the `VNC_PASSWORD` environment variable via `docker inspect`. By 476 | default, the `docker` command requires root access, but it can be configured 477 | to allow users in a specific group. 478 | - Decrypting the `/config/.vncpass` file, which requires root or `USER_ID` 479 | permissions. 480 | 481 | > [!CAUTION] 482 | > VNC password is limited to 8 characters. This limitation comes from the Remote 483 | > Framebuffer Protocol [RFC](https://tools.ietf.org/html/rfc6143) (see section 484 | > [7.2.2](https://tools.ietf.org/html/rfc6143#section-7.2.2)). 485 | 486 | ### Web Authentication 487 | 488 | Access to the application's GUI via a web browser can be protected with a login 489 | page. When enabled, users must provide valid credentials to gain access. 490 | 491 | Enable web authentication by setting the `WEB_AUTHENTICATION` environment 492 | variable to `1`. See the [Environment Variables](#environment-variables) section 493 | for details on configuring environment variables. 494 | 495 | > [!IMPORTANT] 496 | > Web authentication requires the container to be configured with secure web 497 | > access (HTTPS). See [Security](#security) for details. 498 | 499 | #### Configuring Users Credentials 500 | 501 | User credentials can be configured in two ways: 502 | 503 | 1. Via container environment variables. 504 | 2. Via a password database. 505 | 506 | Container environment variables provide a quick way to configure a single user. 507 | Set the username and password using: 508 | - `WEB_AUTHENTICATION_USERNAME` 509 | - `WEB_AUTHENTICATION_PASSWORD` 510 | 511 | See the [Environment Variables](#environment-variables) section for details on 512 | configuring environment variables. 513 | 514 | For a more secure method or to configure multiple users, use a password database 515 | at `/config/webauth-htpasswd` within the container. This file uses the Apache 516 | HTTP server's htpasswd format, storing bcrypt-hashed passwords. 517 | 518 | Manage users with the `webauth-user` tool: 519 | - Add a user: `docker exec -ti webauth-user add ` 520 | - Update a user: `docker exec -ti webauth-user update ` 521 | - Remove a user: `docker exec webauth-user del ` 522 | - List users: `docker exec webauth-user list` 523 | 524 | ## Reverse Proxy 525 | 526 | The following sections provide NGINX configurations for setting up a reverse 527 | proxy to this container. 528 | 529 | A reverse proxy server can route HTTP requests based on the hostname or URL 530 | path. 531 | 532 | ### Routing Based on Hostname 533 | 534 | In this scenario, each hostname is routed to a different application or 535 | container. 536 | 537 | For example, if the reverse proxy server runs on the same machine as this 538 | container, it would proxy all HTTP requests for `crashplan-pro.domain.tld` to 539 | the container at `127.0.0.1:5800`. 540 | 541 | Here are the relevant configuration elements to add to the NGINX configuration: 542 | 543 | ```nginx 544 | map $http_upgrade $connection_upgrade { 545 | default upgrade; 546 | '' close; 547 | } 548 | 549 | upstream docker-crashplan-pro { 550 | # If the reverse proxy server is not running on the same machine as the 551 | # Docker container, use the IP of the Docker host here. 552 | # Make sure to adjust the port according to how port 5800 of the 553 | # container has been mapped on the host. 554 | server 127.0.0.1:5800; 555 | } 556 | 557 | server { 558 | [...] 559 | 560 | server_name crashplan-pro.domain.tld; 561 | 562 | location / { 563 | proxy_pass http://docker-crashplan-pro; 564 | } 565 | 566 | location /websockify { 567 | proxy_pass http://docker-crashplan-pro; 568 | proxy_http_version 1.1; 569 | proxy_set_header Upgrade $http_upgrade; 570 | proxy_set_header Connection $connection_upgrade; 571 | proxy_read_timeout 86400; 572 | } 573 | 574 | # Needed when audio support is enabled. 575 | location /websockify-audio { 576 | proxy_pass http://docker-crashplan-pro; 577 | proxy_http_version 1.1; 578 | proxy_set_header Upgrade $http_upgrade; 579 | proxy_set_header Connection $connection_upgrade; 580 | proxy_read_timeout 86400; 581 | } 582 | } 583 | 584 | ``` 585 | 586 | ### Routing Based on URL Path 587 | 588 | In this scenario, the same hostname is used, but different URL paths route to 589 | different applications or containers. For example, if the reverse proxy server 590 | runs on the same machine as this container, it would proxy all HTTP requests for 591 | `server.domain.tld/filebot` to the container at `127.0.0.1:5800`. 592 | 593 | Here are the relevant configuration elements to add to the NGINX configuration: 594 | 595 | ```nginx 596 | map $http_upgrade $connection_upgrade { 597 | default upgrade; 598 | '' close; 599 | } 600 | 601 | upstream docker-crashplan-pro { 602 | # If the reverse proxy server is not running on the same machine as the 603 | # Docker container, use the IP of the Docker host here. 604 | # Make sure to adjust the port according to how port 5800 of the 605 | # container has been mapped on the host. 606 | server 127.0.0.1:5800; 607 | } 608 | 609 | server { 610 | [...] 611 | 612 | location = /crashplan-pro {return 301 $scheme://$http_host/crashplan-pro/;} 613 | location /crashplan-pro/ { 614 | proxy_pass http://docker-crashplan-pro/; 615 | # Uncomment the following line if your Nginx server runs on a port that 616 | # differs from the one seen by external clients. 617 | #port_in_redirect off; 618 | location /crashplan-pro/websockify { 619 | proxy_pass http://docker-crashplan-pro/websockify; 620 | proxy_http_version 1.1; 621 | proxy_set_header Upgrade $http_upgrade; 622 | proxy_set_header Connection $connection_upgrade; 623 | proxy_read_timeout 86400; 624 | } 625 | # Needed when audio support is enabled. 626 | location /crashplan-pro/websockify-audio { 627 | proxy_pass http://docker-crashplan-pro/websockify-audio; 628 | proxy_http_version 1.1; 629 | proxy_set_header Upgrade $http_upgrade; 630 | proxy_set_header Connection $connection_upgrade; 631 | proxy_read_timeout 86400; 632 | } 633 | } 634 | } 635 | 636 | ``` 637 | 638 | ## Web Control Panel 639 | 640 | The control panel is available whenever the application GUI is accessed through 641 | a web browser. Click the small three-dots tab on the left edge of the browser 642 | window to open it. 643 | 644 | ![Web Control Panel](https://images.weserv.nl/?url=raw.githubusercontent.com/jlesage/docker-templates/master/jlesage/images/control-panel.png&w=500) 645 | 646 | | Control | Action / Purpose | 647 | |---------|------------------| 648 | | **X** icon | Closes the control panel. | 649 | | **Logout** icon | Logs out from the web interface. Visible only when [web authentication](#web-authentication) is enabled. | 650 | | **Keyboard** icon | Toggle the on-screen keyboard. Visible only on touch devices. | 651 | | **Fullscreen** icon | Toggle fullscreen mode for the browser window. | 652 | | **Hand** icon| Allows dragging/moving the application window. Visible only when **Scaling Mode** is *None* and **Clip to Window** is enabled. 653 | | **Folder** icon | Opens the intgegrated file browser. Visible only when the [file manager](#web-file-manager) is enabled. | 654 | | **Clipboard** text box| Mirrors the application’s clipboard. Any text typed or pasted here is sent to the application, and text copied inside the application automatically appears here. Hidden when [automatic clipboard synchronization](#automatic-clipboard-sync) is active. | 655 | | **Clear** button | Clears the clipboard. Hidden when [automatic clipboard synchronization](#automatic-clipboard-sync) is active. | 656 | | **Audio** icon | Mutes or unmutes audio streaming from the container. Visible only when [audio support](#web-audio) is enabled. | 657 | | **Volume** slider| Controls the playback volume of the audio streaming from the container. Visible only when [audio support](#web-audio) is enabled. | 658 | | **Clip to Window** toggle | Only applies when **Scaling Mode** is *None*. When disabled, scrollbars appear if the application window is larger than the browser window. When enabled, no scrollbars are shown and the hand icon is used to pan. | 659 | | **Scaling Mode** dropdown | Controls how the application window is scaled to fit the browser. **None** – no scaling, the application window keeps its original size. **Local Scaling** – the image is scaled in the browser (application window size unchanged). **Remote Scaling** – the application window inside the container is automatically resized to match the browser window size. | 660 | | **Quality** slider | Adjusts image quality. Moving the slider left reduces bandwidth at the cost of visual quality. | 661 | | **Compression** slider | Adjusts compression level applied to screen updates. Moving the slider right increases compression, which lowers bandwidth but raises CPU usage. | 662 | | **Logging** dropdown | Sets the verbosity level of the web interface logs shown in the browser console. | 663 | | **Application version** label | Displays the version of CrashPlan integrated into Docker image. | 664 | | **Docker image** version label | Displays the version of the Docker image currently running. | 665 | 666 | ## Automatic Clipboard Sync 667 | 668 | When the container is accessed through a web browser, automatic clipboard 669 | synchronization enables seamless sharing of clipboard contents between the host 670 | system and the application running inside the container. This makes it possible 671 | to copy and paste text or data directly between the two environments without 672 | manual transfer steps. 673 | 674 | This functionality is not available when using VNC clients and is supported only 675 | in browsers based on the Chromium engine, such as Google Chrome and Microsoft 676 | Edge. 677 | 678 | Clipboard synchronization operates transparently once permission has been 679 | granted by the browser. Depending on browser implementation, a prompt may appear 680 | the first time clipboard access is requested. 681 | 682 | > [!IMPORTANT] 683 | > Web browsers only allow access to the clipboard in secure contexts (HTTPS). 684 | > This means the container must be configured with secure web access. See 685 | > [Security](#security) for details. 686 | 687 | > [!TIP] 688 | > If automatic clipboard synchronization is not available, text can still be 689 | > copied and pasted using the clipboard of the 690 | > [control panel](#web-control-panel), which provides manual clipboard access 691 | > between the host and the container. 692 | 693 | ## Web Audio 694 | 695 | The container supports streaming audio from the application, played through the 696 | user's web browser. Audio is not supported for VNC clients. 697 | 698 | Audio is streamed with the following specification: 699 | 700 | * Raw PCM format 701 | * 2 channels 702 | * 16-bit sample depth 703 | * 44.1kHz sample rate 704 | 705 | Enable web audio by setting `WEB_AUDIO` to `1`. See the 706 | [Environment Variables](#environment-variables) section for details on 707 | configuring environment variables. 708 | 709 | Control of the audio stream (mute, unmute and volume) is done via the 710 | [control panel](#web-control-panel). 711 | 712 | ## Web File Manager 713 | 714 | The container includes a simple file manager for interacting with container 715 | files through a web browser, supporting operations like renaming, deleting, 716 | uploading, and downloading. 717 | 718 | Enable the file manager by setting `WEB_FILE_MANAGER` to `1`. See the 719 | [Environment Variables](#environment-variables) section for details on 720 | configuring environment variables. 721 | 722 | Open the file manager by clicking the folder icon of the 723 | [control panel](#web-control-panel) 724 | 725 | By default, the container's entire filesystem is not accessible. The 726 | `WEB_FILE_MANAGER_ALLOWED_PATHS` environment variable is a comma-separated list 727 | that specifies which paths within the container are allowed to be accessed. When 728 | set to `AUTO` (the default), it automatically includes commonly used folders and 729 | any folders mapped to the container. 730 | 731 | The `WEB_FILE_MANAGER_DENIED_PATHS` environment variable defines which paths are 732 | explicitly denied access by the file manager. A denied path takes precedence 733 | over an allowed one. 734 | 735 | ## Web Notifications 736 | 737 | The container includes support for notifications sent through the web browser. 738 | Any desktop notification generated by CrashPlan is forwarded to the 739 | browser, which then displays it as a native notification on the user's system. 740 | 741 | Enable the web notification service by setting `WEB_NOTIFICATION` to `1`. See 742 | the [Environment Variables](#environment-variables) section for details on 743 | configuring environment variables. 744 | 745 | > [!IMPORTANT] 746 | > Web browsers only allow notifications in secure contexts (HTTPS). This means 747 | > the container must be configured with secure web access. See 748 | > [Security](#security) for details. 749 | 750 | ## GPU Acceleration Support 751 | 752 | This container supports hardware-accelerated rendering of the application's 753 | graphical user interface. When enabled, the X server running inside the 754 | container can use the host GPU, providing improved rendering performance and 755 | full hardware acceleration for OpenGL via the GLX extension. 756 | 757 | This feature requires open-source kernel drivers on the host system, such as 758 | `amdgpu` for AMD GPUs, `i915` for Intel GPUs, or `nouveau` for NVIDIA GPUs, to 759 | support the Direct Rendering Infrastructure (DRI3) and Generic Buffer Management 760 | (GBM). Proprietary drivers, such as NVIDIA's, are not supported. 761 | 762 | To enable GPU acceleration, the host must have compatible open-source kernel 763 | drivers installed, and the GPU device `/dev/dri` must be exposed to the 764 | container. For example, this is done by adding the `--device /dev/dri` 765 | argument to the `docker run` command. 766 | ## Shell Access 767 | 768 | To access the shell of a running container, execute the following command: 769 | 770 | ```shell 771 | docker exec -ti CONTAINER sh 772 | ``` 773 | 774 | Where `CONTAINER` is the ID or the name of the container used during its 775 | creation. 776 | 777 | ## Taking Over Existing Backup 778 | 779 | If this container is replacing a CrashPlan installation (from Linux, Windows, 780 | MAC or another Docker container), your existing backup can be taken over to 781 | avoid re-uploading all your data. 782 | 783 | To proceed, make sure to carefully read the [official documentation]. 784 | 785 | Here is a summary of what needs to be done: 786 | 1. Start CrashPlan Docker container. Make sure the configuration directory 787 | is not mapped to a folder used by a different CrashPlan container. 788 | 2. Sign in to your account. 789 | 3. Click the **Replace Existing** button to start the wizard. 790 | 4. Skip *Step 2 - File Transfer*. 791 | 4. Once done with the wizard, go to your device's details and click 792 | *Manage Files*. You will probably see missing items in the file 793 | selection. This is normal, since path to your files may be different in 794 | the container. 795 | 5. Update the file selection by re-adding your files. **Do not unselect 796 | missing items yet**. 797 | 6. Perform a backup. Because of deduplication, files will not be uploaded 798 | again. 799 | 7. Once the backup is terminated, you can remove missing items **if you 800 | don't care about file versions**. Else, keep missing items. 801 | 802 | **NOTE**: Don't be confused by the directory structure from your old being 803 | visible in the *Manage Files* window. By default, your files are now located 804 | under the `/storage` folder. 805 | 806 | [official documentation]: https://support.code42.com/hc/en-us/articles/14827668736279-Replace-your-device 807 | 808 | ## Why CrashPlan Self Update Is Disabled 809 | 810 | One advantage of a Docker image is that it can be versioned and predictable, 811 | meaning that a specific version of the image always behaves the same way. So 812 | if, for any reason, a new image version has a problem and doesn't work as 813 | expected, it's easy for one to revert to the previous version and be back on 814 | track. 815 | 816 | Allowing CrashPlan to update itself obviously breaks this benefit. Also, since 817 | the container has only the minimal set of libraries and tools required to run 818 | CrashPlan, it would be easy for an automatic update to break the container by 819 | requiring new dependencies. Finally, the automatic update script is not adapted 820 | for Alpine Linux (the distribution on which this container is based on) and 821 | assumes it is running on a full-featured distribution. For example, this image 822 | doesn't have a desktop like normal installations and some of the tools required 823 | to perform the update are missing. 824 | 825 | ## Troubleshooting 826 | 827 | ### Crashes / Maximum Amount of Allocated Memory 828 | 829 | If CrashPlan crashes unexpectedly with large backups, try to increase the 830 | maximum amount of memory CrashPlan is allowed to use. This can be done by: 831 | 832 | 1. Setting the `CRASHPLAN_SRV_MAX_MEM` environment variable. See the 833 | [Environment Variables](#environment-variables) section for more details. 834 | 2. Using the [solution provided by CrashPlan] from its support site. 835 | 836 | [solution provided by CrashPlan]: https://support.code42.com/hc/en-us/articles/14827635282583-Adjust-Code42-agent-settings-for-memory-usage-with-large-backups 837 | 838 | ### Inotify's Watch Limit 839 | 840 | If CrashPlan exceeds inotify's max watch limit, real-time file watching cannot 841 | work properly and the inotify watch limit needs to be increased on the **host**, 842 | not the container. 843 | 844 | For more details, see the CrashPlan's [Linux real-time file watching errors] 845 | article. 846 | 847 | [Linux real-time file watching errors]: https://support.code42.com/hc/en-us/articles/14827708807959-Linux-real-time-file-watching-errors 848 | 849 | #### Synology 850 | 851 | On Synology NAS, the instructions provided by the article mentioned in the 852 | previous section apply, except that the inotify's max watch limit must be set in 853 | `/etc.defaults/sysctl.conf` (instead of `/etc/sysctl.conf`) to make the setting 854 | permanent. 855 | 856 | **NOTE**: After an upgrade of the DSM software, verify that the content of the 857 | file has not been overwritten. 858 | 859 | ### Empty `/storage` 860 | 861 | If the `/storage` folder inside the container is empty: 862 | 863 | - Make sure the folder is properly mapped to the host. This is done via the 864 | `-v` parameter of the `docker run` command. See the [Usage](#usage) 865 | section. 866 | - Make sure permissions and ownership of files on the host are correct and are 867 | compatible with the user under which the container application is running 868 | (defined by the `USER_ID` and `GROUP_ID` environment variables). See the 869 | [User/Group IDs](#usergroup-ids) section. 870 | 871 | NOTE: If running the application as root (`USER_ID=0` and `GROUP_ID=0`) makes 872 | the files visible, it confirms that there is a permission issue. 873 | 874 | ### Device Status Is Waiting For Connection 875 | 876 | If the status of your device is stuck on *Waiting for connection*, clearing the 877 | the cache of CrashPlan can help resolve the issue: 878 | 879 | - Stop the container. 880 | - Remove all the content of the `cache` directory found under the container's 881 | configuration directory. For example, if the `/config` folder of the 882 | container is mapped to `/docker/appdata/crashplan-pro` on the host, the 883 | following command (ran on the host) would clear the cache: 884 | ``` 885 | rm -rf /docker/appdata/crashplan-pro/cache/* 886 | ``` 887 | - Start the container. 888 | 889 | ### Cannot Restore Files 890 | 891 | If CrashPlan fails to restore files, make sure the location where files are 892 | restored have write permission. 893 | 894 | A typical installation has the data to be backup under the `/storage` folder. 895 | This folder is usually mapped to the host with *read-only* permission. Thus, 896 | restoring files to `/storage` won't be allowed. The solution is to temporarily 897 | change the permission of the volume to *read-write*. 898 | 899 | For example, if `/storage` is mapped to `/home/user` on the host, the container 900 | would need to be deleted and then re-created with the same arguments, with the 901 | exception of `-v /home/user:/storage:ro` that is replaced with 902 | `-v /home/user:/storage:rw`. 903 | 904 | ### Upgrade Failed Error Message 905 | 906 | Because the CrashPlan's self-upgrade feature is disabled in this container, an 907 | error message about failed upgrade can be seen when a new CrashPlan version is 908 | released. 909 | 910 | To fix this, [updating the container's image](#docker-image-update) to the 911 | latest version will also bring the latest version of CrashPlan. 912 | 913 | ## Support or Contact 914 | 915 | Having troubles with the container or have questions? Please 916 | [create a new issue](https://github.com/jlesage/docker-crashplan-pro/issues). 917 | 918 | For other Dockerized applications, visit https://jlesage.github.io/docker-apps. 919 | --------------------------------------------------------------------------------