Giter VIP home page Giter VIP logo

docker-mc-backup's Introduction

Docker Pulls Build Discord

Provides a side-car container to back up itzg/minecraft-server world data. Backups are coordinated automatically by using RCON to flush data, pause writes, and resume after backup is completed.

This does NOT support Bedrock edition. Use a community provided solution for that.

Environment variables

Common variables:
  • SRC_DIR=/data

  • BACKUP_NAME=world

  • INITIAL_DELAY=2m

  • BACKUP_INTERVAL=24h

  • PAUSE_IF_NO_PLAYERS=false

  • PLAYERS_ONLINE_CHECK_INTERVAL=5m

  • PRUNE_BACKUPS_DAYS=7

  • PRUNE_RESTIC_RETENTION=--keep-within 7d

  • RCON_HOST=localhost

  • RCON_PORT=25575

  • RCON_PASSWORD=minecraft

  • RCON_PASSWORD_FILE: Can be set to read the RCON password from a file. Overrides RCON_PASSWORD if both are set.

  • RCON_RETRIES=5 : Set to a negative value to retry indefinitely

  • RCON_RETRY_INTERVAL=10s

  • SERVER_HOST=RCON_HOST : Can be set if the game and RCON are accessible on different addresses.

  • SERVER_PORT=25565

  • INCLUDES=. : comma separated list of include patterns relative to directory specified by SRC_DIR where . specifies all of that directory should be included in the backup.

    For Restic the default is the value of SRC_DIR to remain backward compatible with previous images.

  • EXCLUDES=*.jar,cache,logs,*.tmp : commas separated list of file patterns to exclude from the backup. To disable exclusions, set to an empty string.

  • EXCLUDES_FILE: Can be set to read the list of excludes (one per line) from a file. Can be used with EXCLUDES to add more excludes.

  • BACKUP_METHOD=tar

  • RESTIC_ADDITIONAL_TAGS=mc_backups : additional tags to apply to the backup. Set to an empty string to disable additional tags.

  • RESTIC_VERBOSE=false : set to "true" to enable verbose output during restic backup operation

  • TZ : Can be set to the timezone to use for logging

  • PRE_SAVE_ALL_SCRIPT, PRE_BACKUP_SCRIPT, PRE_SAVE_ON_SCRIPT, POST_BACKUP_SCRIPT, *_SCRIPT_FILE: See Backup scripts

If PRUNE_BACKUPS_DAYS is set to a positive number, it'll delete old .tgz backup files from DEST_DIR. By default deletes backups older than a week.

If BACKUP_INTERVAL is set to 0 or smaller, script will run once and exit.

Both INITIAL_DELAY and BACKUP_INTERVAL accept times in sleep format: NUMBER[SUFFIX] NUMBER[SUFFIX] .... SUFFIX may be 's' for seconds (the default), 'm' for minutes, 'h' for hours or 'd' for days.

Examples:

  • BACKUP_INTERVAL="1.5d" -> backup every one and a half days (36 hours)
  • BACKUP_INTERVAL="2h 30m" -> backup every two and a half hours
  • INITIAL_DELAY="120" -> wait 2 minutes before starting

The PAUSE_IF_NO_PLAYERS option lets you pause backups if no players are online.

If PAUSE_IF_NO_PLAYERS="true" and there are no players online after a backup is made, then instead of immediately scheduling the next backup, the script will start checking the server's player count every PLAYERS_ONLINE_CHECK_INTERVAL (defaults to 5 minutes). Once a player joins the server, the next backup will be scheduled in BACKUP_INTERVAL.

EXCLUDES is a comma-separated list of glob(3) patterns to exclude from backups. By default excludes all jar files (plugins, server files), logs folder and cache (used by i.e. PaperMC server).

tar backup method
  • DEST_DIR=/backups
  • LINK_LATEST=false
  • TAR_COMPRESS_METHOD=gzip
  • ZSTD_PARAMETERS=-3 --long=25 --single-thread

LINK_LATEST is a true/false flag that creates a symbolic link to the latest backup.

TAR_COMPRESS_METHOD is the compression method used by tar. Valid value: gzip bzip2 zstd

ZSTD_PARAMETERS sets the parameters for zstd compression. The --long parameter affects RAM requirements for both compression and decompression (the default of 25 means 2^25 bytes = 32 MB).

rsync backup method
  • DEST_DIR=/backups
  • LINK_LATEST=false

LINK_LATEST is a true/false flag that creates a symbolic link to the latest backup.

restic backup method

See restic documentation on what variables are needed to be defined. At least one of RESTIC_PASSWORD* variables need to be defined, along with RESTIC_REPOSITORY.

Use the RESTIC_ADDITIONAL_TAGS variable to define a space separated list of additional restic tags. The backup will always be tagged with the value of BACKUP_NAME. e.g.: RESTIC_ADDITIONAL_TAGS=mc_backups foo bar will tag your backup with foo, bar, mc_backups and the value of BACKUP_NAME.

By default, the hostname, typically the container/pod's name, will be used as the Restic backup's hostname. That can be overridden by setting RESTIC_HOSTNAME

You can fine tune the retention cycle of the restic backups using the PRUNE_RESTIC_RETENTION variable. Take a look at the restic documentation for details.

EXAMPLE
Setting PRUNE_RESTIC_RETENTION to --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 75 will keep the most recent 7 daily snapshots, then 4 (remember, 7 dailies already include a week!) last-day-of-the-weeks and 11 or 12 last-day-of-the-months (11 or 12 depends if the 5 weeklies cross a month). And finally 75 last-day-of-the-year snapshots. All other snapshots are removed.

⚠️ When using restic as your backup method, make sure that you fix your container hostname to a constant value! Otherwise, each time a container restarts it'll use a different, random hostname which will cause it not to rotate your backups created by previous instances!
⚠️ When using restic, at least one of HOSTNAME or BACKUP_NAME must be unique, when sharing a repository. Otherwise other instances using the same repository might prune your backups prematurely.
⚠️ SFTP restic backend is not directly supported. Please use RCLONE backend with SFTP support.
rclone backup method

Rclone acts as the tar backup method but automatically moves the compressed files to a remote drive via rclone.

There are a few special environment variables for the rclone method.

  • RCLONE_REMOTE is the name of the remote you've configured in your rclone.conf, see remote setup.
  • RCLONE_COMPRESS_METHOD=gzip
  • DEST_DIR=/backups is the container path where the archive is temporarily created
  • RCLONE_DEST_DIR is the directory on the remote

Other parameters such as PRUNE_BACKUPS_DAYS, ZSTD_PARAMETERS, and BACKUP_NAME are all used as well.

Note that you will need to place your rclone config file in /config/rclone/rclone.conf. This can be done by adding it through docker-compose,

- ./rclone.config:/config/rclone/rclone.conf:ro

or by running the config wizard in a container and mounting the volume.

docker run -it --rm -v rclone-config:/config/rclone rclone/rclone config

then you must bind the volume for the mc-backup process

volumes:
  - rclone-config:/config/rclone

and the service

volumes:
  rclone-config:
    external: true

Volumes

  • /data : Should be attached read-only to the same volume as the /data of the itzg/minecraft-server container
  • /backups : The volume where incremental tgz files will be created, if using tar backup method.

Restoring tar backups

This image includes a script called restore-backup which will:

  1. Check if the $SRC_DIR (default is /data) is empty
  2. and if any files are available in $DEST_DIR (default is /backups),
  3. then un-tars the newest one into $SRC_DIR

The compose file example shows creating an "init container" to run the restore

Restoring rsync backups

This image includes a script called restore-rsync-backup which will:

  1. Check if the $SRC_DIR (default is /data) is empty
  2. and if any folders are available in $DEST_DIR (default is /backups),
  3. then rsyncs back the newest one into $SRC_DIR

The compose file example shows creating an "init container" to run the restore

On-demand backups

If you would like to kick off a backup prior to the next backup interval, you can exec the command backup now within the running backup container. For example, using the Docker Compose example where the service name is backups, the exec command becomes:

docker-compose exec backups backup now

This mechanism can also be used to avoid a long running container completely by running a temporary container, such as:

docker run --rm ...data and backup -v args... itzg/mc-backup backup now

Backup scripts

The PRE_SAVE_ALL_SCRIPT, PRE_BACKUP_SCRIPT, PRE_SAVE_ON_SCRIPT, and POST_BACKUP_SCRIPT, variables may be set to a bash script to run before and after the backup process. Potential use-cases include sending notifications, or replicating a restic repository to a remote store.

The backup waits for the server to respond to a rcon "save-on" command before running the scripts. After, the PRE_SAVE_ALL_SCRIPT is run, followed by rcon "save-off" and "save-all" commands. The, the PRE_BACKUP_SCRIPT is run, followed by the backup process. Then, the PRE_SAVE_ON_SCRIPT is run, followed by a rcon "save-on" command. Finally, the POST_BACKUP_SCRIPT is run.

Alternatively PRE_SAVE_ALL_SCRIPT_FILE PRE_BACKUP_SCRIPT_FILE, PRE_SAVE_ON_SCRIPT_FILE, and POST_BACKUP_SCRIPT_FILE may be set to the path of a script that has been mounted into the container. The file must be executable.

Note that *_FILE variables will be overridden by their non-FILE versions if both are set.

Some notes:

  • When specifying the script directly in Docker compose files any $ that are being used to refer to environment variables must be doubled up (i.e. $$) else Compose will try to substitute them

Example

With an executable file called post-backup.sh next to the compose file with the following contents

echo "Backup from $RCON_HOST to $DEST_DIR finished"

and the following compose definition

version: '3.7'

services:
  mc:
    image: itzg/minecraft-server
    ports:
      - "25565:25565"
    environment:
      EULA: "TRUE"
      TYPE: PAPER
    volumes:
      - mc:/data
  backups:
    image: itzg/mc-backup
    environment:
      BACKUP_INTERVAL: "2h"
      RCON_HOST: mc
      PRE_BACKUP_SCRIPT: |
        echo "Before backup!"
        echo "Also before backup from $$RCON_HOST to $$DEST_DIR"
      POST_BACKUP_SCRIPT_FILE: /post-backup.sh
    volumes:
      # mount the same volume used by server, but read-only
      - mc:/data:ro
      # use a host attached directory so that it in turn can be backed up
      # to external/cloud storage
      - ./mc-backups:/backups
      - ./post-backup.sh:/post-backup.sh:ro

volumes:
  mc: {}

Example

Kubernetes

An example StatefulSet deployment is provided in this repository.

The important part is the containers definition of the deployment:

containers:
  - name: mc
    image: itzg/minecraft-server
    env:
      - name: EULA
        value: "TRUE"
    volumeMounts:
      - mountPath: /data
        name: data
  - name: backup
    image: mc-backup
    imagePullPolicy: Never
    securityContext:
      runAsUser: 1000
    env:
      - name: BACKUP_INTERVAL
        value: "2h 30m"
    volumeMounts:
      - mountPath: /data
        name: data
        readOnly: true
      - mountPath: /backups
        name: backups

Docker Compose

version: "3.8"

services:
  mc:
    image: itzg/minecraft-server:latest
    ports:
      - "25565:25565"
    environment:
      EULA: "TRUE"
      TYPE: PAPER
    depends_on:
      restore-backup:
        condition: service_completed_successfully
    volumes:
      - ./mc-data:/data
  # "init" container for mc to restore the data volume when empty    
  restore-backup:
    # Same image as mc, but any base image with bash and tar will work
    image: itzg/mc-backup
    restart: "no"
    entrypoint: restore-tar-backup
    volumes:
      # Must be same mount as mc service, needs to be writable
      - ./mc-data:/data
      # Must be same mount as backups service, but can be read-only
      - ./mc-backups:/backups:ro
  backups:
    image: itzg/mc-backup
    depends_on:
      mc:
        condition: service_healthy
    environment:
      BACKUP_INTERVAL: "2h"
      RCON_HOST: mc
      # since this service waits for mc to be healthy, no initial delay is needed
      INITIAL_DELAY: 0
    volumes:
      - ./mc-data:/data:ro
      - ./mc-backups:/backups

Restic with rclone

Setup the rclone configuration for the desired remote location

docker run -it --rm -v rclone-config:/config/rclone rclone/rclone config

Setup the itzg/mc-backup container with the following specifics

  • Set BACKUP_METHOD to restic
  • Set RESTIC_PASSWORD to a restic backup repository password to use
  • Use rclone: as the prefix on the RESTIC_REPOSITORY
  • Append the rclone config name, colon (:), and specific sub-path for the config type

In the following example CFG_NAME and BUCKET_NAME need to be changed to specifics for the rclone configuration you created:

version: "3"

services:
  mc:
    image: itzg/minecraft-server
    environment:
      EULA: "TRUE"
    ports:
      - 25565:25565
    volumes:
      - mc:/data
  backup:
    image: itzg/mc-backup
    environment:
      RCON_HOST: mc
      BACKUP_METHOD: restic
      RESTIC_PASSWORD: password
      RESTIC_REPOSITORY: rclone:CFG_NAME:BUCKET_NAME
    volumes:
      # mount volume pre-configured using a host mounted file
      - ./rclone.conf:/config/rclone/rclone.conf
      # or configure one into a named volume using
      # docker run -it --rm -v rclone-config:/config/rclone rclone/rclone config
      # and change the above to
      # - rclone-config:/config/rclone
      - mc:/data:ro
      - backups:/backup

volumes:
# Uncomment this if using the config step above
#  rclone-config:
#    external: true
  mc: {}
  backups: {}

docker-mc-backup's People

Contributors

alb11747 avatar antons- avatar cadenkriese avatar chylex avatar darkspir avatar dependabot[bot] avatar djmattyg007 avatar itzg avatar j-hoelzl avatar jcotton42 avatar johnsturgeon avatar jonbranan avatar jrisebor avatar kevm avatar kylestang avatar lambarchie avatar n-rosati avatar nunzioardi avatar onezero1010101 avatar practicalryan avatar prof-bloodstone avatar ram042 avatar sconaway avatar silthus avatar spiderweak avatar stonelabs avatar toddejohnson avatar wlritchi avatar zebernst avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

docker-mc-backup's Issues

can not connect to rcon / change rcon ip

The container can not connect to rcon.

backup_1     | 2019-10-07T12:49:27+0000 INFO waiting initial delay of 30s...
minecraft_1  | usermod: no changes
minecraft_1  | Changing ownership of /data to 1000 ...
minecraft_1  | Running as uid=1000 gid=1000 with /data as 'drwxrwxr-x    2 1000     1000          4096 Oct  7 12:49 /data'
minecraft_1  | Checking version information.
minecraft_1  | Checking type information.
minecraft_1  | Downloading minecraft_server.1.14.4.jar ...
minecraft_1  | Creating server.properties in /data/server.properties
minecraft_1  | Setting server-name to 'Dedicated Server' in /data/server.properties
minecraft_1  | Setting server-port to '25565' in /data/server.properties
minecraft_1  | Setting motd to 'A Vanilla Minecraft Server powered by Docker' in /data/server.properties
minecraft_1  | Skip setting allow-nether
minecraft_1  | Skip setting announce-player-achievements
minecraft_1  | Skip setting enable-command-block
minecraft_1  | Skip setting spawn-animals
minecraft_1  | Skip setting spawn-monsters
minecraft_1  | Skip setting spawn-npcs
minecraft_1  | Skip setting spawn-protection
minecraft_1  | Skip setting generate-structures
minecraft_1  | Skip setting view-distance
minecraft_1  | Skip setting hardcore
minecraft_1  | Skip setting snooper-enabled
minecraft_1  | Skip setting max-build-height
minecraft_1  | Skip setting force-gamemode
minecraft_1  | Skip setting max-tick-time
minecraft_1  | Skip setting enable-query
minecraft_1  | Skip setting query.port
minecraft_1  | Setting enable-rcon to 'true' in /data/server.properties
minecraft_1  | Setting rcon.password to 'testing' in /data/server.properties
minecraft_1  | Setting rcon.port to '25575' in /data/server.properties
minecraft_1  | Skip setting max-players
minecraft_1  | Skip setting max-world-size
minecraft_1  | Setting level-name to 'world' in /data/server.properties
minecraft_1  | Skip setting level-seed
minecraft_1  | Setting pvp to 'true' in /data/server.properties
minecraft_1  | Skip setting generator-settings
minecraft_1  | Setting online-mode to 'true' in /data/server.properties
minecraft_1  | Skip setting allow-flight
minecraft_1  | Setting level-type to 'DEFAULT' in /data/server.properties
minecraft_1  | Skip setting resource-pack
minecraft_1  | Skip setting resource-pack-sha1
minecraft_1  | Setting difficulty to '1' in /data/server.properties
minecraft_1  | Checking for JSON files.
minecraft_1  | Copying any mods over...
minecraft_1  | Setting initial memory to 1G and max to 5G
minecraft_1  | Starting the Minecraft server...
minecraft_1  | [12:49:34] [main/WARN]: Ambiguity between arguments [teleport, destination] and [teleport, targets] with inputs: [Player, 0123, @e, dd12be42-52a9-4a91-a8a1-11c01849e498]
minecraft_1  | [12:49:34] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
minecraft_1  | [12:49:34] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, targets] with inputs: [0.1 -0.5 .9, 0 0 0]
minecraft_1  | [12:49:34] [main/WARN]: Ambiguity between arguments [teleport, targets] and [teleport, destination] with inputs: [Player, 0123, dd12be42-52a9-4a91-a8a1-11c01849e498]
minecraft_1  | [12:49:34] [main/WARN]: Ambiguity between arguments [teleport, targets, location] and [teleport, targets, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
minecraft_1  | [12:49:35] [Server thread/INFO]: Starting minecraft server version 1.14.4
minecraft_1  | [12:49:35] [Server thread/INFO]: Loading properties
minecraft_1  | [12:49:35] [Server thread/INFO]: Default game type: SURVIVAL
minecraft_1  | [12:49:35] [Server thread/INFO]: Generating keypair
minecraft_1  | [12:49:35] [Server thread/INFO]: Starting Minecraft server on *:25565
minecraft_1  | [12:49:35] [Server thread/INFO]: Using epoll channel type
minecraft_1  | [12:49:36] [Server thread/INFO]: Preparing level "world"
minecraft_1  | [12:49:36] [Server thread/INFO]: Found new data pack vanilla, loading it automatically
minecraft_1  | [12:49:36] [Server thread/INFO]: Reloading ResourceManager: Default
minecraft_1  | [12:49:37] [Server thread/INFO]: Loaded 6 recipes
minecraft_1  | [12:49:38] [Server thread/INFO]: Loaded 811 advancements
backup_1     | 2019-10-07T12:49:57+0000 INFO waiting for rcon readiness...
backup_1     | 2019-10-07T12:50:07+0000 ERROR Unable to execute rcon-cli save-on - try 0/20. Retrying in 10s
backup_1     | 2019-10-07T12:50:07+0000 ERROR Failure reason: 2019/10/07 12:50:07 Failed to connect to RCON serverdial tcp: i/o timeout	
minecraft_1  | [12:50:13] [Server thread/INFO]: Preparing start region for dimension minecraft:overworld
minecraft_1  | [12:50:13] [Server-Worker-1/INFO]: Preparing spawn area: 0%
minecraft_1  | [12:50:13] [Server-Worker-1/INFO]: Preparing spawn area: 0%
minecraft_1  | [12:50:14] [Server-Worker-1/INFO]: Preparing spawn area: 0%
minecraft_1  | [12:50:14] [Server-Worker-1/INFO]: Preparing spawn area: 0%
minecraft_1  | [12:50:15] [Server-Worker-1/INFO]: Preparing spawn area: 0%
minecraft_1  | [12:50:15] [Server-Worker-1/INFO]: Preparing spawn area: 1%
minecraft_1  | [12:50:16] [Server-Worker-1/INFO]: Preparing spawn area: 1%
minecraft_1  | [12:50:16] [Server-Worker-1/INFO]: Preparing spawn area: 3%
minecraft_1  | [12:50:17] [Server-Worker-1/INFO]: Preparing spawn area: 3%
minecraft_1  | [12:50:17] [Server-Worker-1/INFO]: Preparing spawn area: 4%
minecraft_1  | [12:50:18] [Server-Worker-1/INFO]: Preparing spawn area: 6%
minecraft_1  | [12:50:18] [Server-Worker-1/INFO]: Preparing spawn area: 7%
minecraft_1  | [12:50:19] [Server-Worker-1/INFO]: Preparing spawn area: 9%
minecraft_1  | [12:50:19] [Server-Worker-1/INFO]: Preparing spawn area: 10%
minecraft_1  | [12:50:20] [Server-Worker-1/INFO]: Preparing spawn area: 12%
minecraft_1  | [12:50:20] [Server-Worker-1/INFO]: Preparing spawn area: 13%
minecraft_1  | [12:50:21] [Server-Worker-1/INFO]: Preparing spawn area: 15%
minecraft_1  | [12:50:21] [Server-Worker-1/INFO]: Preparing spawn area: 17%
minecraft_1  | [12:50:22] [Server-Worker-1/INFO]: Preparing spawn area: 19%
minecraft_1  | [12:50:22] [Server-Worker-1/INFO]: Preparing spawn area: 21%
minecraft_1  | [12:50:23] [Server-Worker-1/INFO]: Preparing spawn area: 24%
minecraft_1  | [12:50:23] [Server-Worker-1/INFO]: Preparing spawn area: 26%
minecraft_1  | [12:50:24] [Server-Worker-1/INFO]: Preparing spawn area: 28%
minecraft_1  | [12:50:24] [Server-Worker-1/INFO]: Preparing spawn area: 31%
minecraft_1  | [12:50:25] [Server-Worker-1/INFO]: Preparing spawn area: 33%
minecraft_1  | [12:50:25] [Server-Worker-1/INFO]: Preparing spawn area: 37%
minecraft_1  | [12:50:26] [Server-Worker-1/INFO]: Preparing spawn area: 39%
minecraft_1  | [12:50:26] [Server-Worker-1/INFO]: Preparing spawn area: 42%
minecraft_1  | [12:50:27] [Server-Worker-1/INFO]: Preparing spawn area: 44%
minecraft_1  | [12:50:27] [Server-Worker-1/INFO]: Preparing spawn area: 47%
backup_1     | 2019-10-07T12:50:27+0000 ERROR Unable to execute rcon-cli save-on - try 1/20. Retrying in 10s
backup_1     | 2019-10-07T12:50:27+0000 ERROR Failure reason: 2019/10/07 12:50:27 Failed to connect to RCON serverdial tcp 127.0.0.1:25575: i/o timeout	
minecraft_1  | [12:50:28] [Server-Worker-1/INFO]: Preparing spawn area: 48%
minecraft_1  | [12:50:28] [Server-Worker-1/INFO]: Preparing spawn area: 50%
minecraft_1  | [12:50:29] [Server-Worker-1/INFO]: Preparing spawn area: 52%
minecraft_1  | [12:50:29] [Server-Worker-1/INFO]: Preparing spawn area: 55%
minecraft_1  | [12:50:30] [Server-Worker-1/INFO]: Preparing spawn area: 56%
minecraft_1  | [12:50:30] [Server-Worker-1/INFO]: Preparing spawn area: 57%
minecraft_1  | [12:50:31] [Server-Worker-1/INFO]: Preparing spawn area: 59%
minecraft_1  | [12:50:31] [Server-Worker-1/INFO]: Preparing spawn area: 61%
minecraft_1  | [12:50:32] [Server-Worker-1/INFO]: Preparing spawn area: 65%
minecraft_1  | [12:50:32] [Server-Worker-1/INFO]: Preparing spawn area: 68%
minecraft_1  | [12:50:33] [Server-Worker-1/INFO]: Preparing spawn area: 70%
minecraft_1  | [12:50:33] [Server-Worker-1/INFO]: Preparing spawn area: 73%
minecraft_1  | [12:50:34] [Server-Worker-1/INFO]: Preparing spawn area: 75%
minecraft_1  | [12:50:34] [Server-Worker-1/INFO]: Preparing spawn area: 78%
minecraft_1  | [12:50:35] [Server-Worker-1/INFO]: Preparing spawn area: 80%
minecraft_1  | [12:50:35] [Server-Worker-1/INFO]: Preparing spawn area: 83%
minecraft_1  | [12:50:36] [Server-Worker-1/INFO]: Preparing spawn area: 85%
minecraft_1  | [12:50:36] [Server-Worker-1/INFO]: Preparing spawn area: 86%
minecraft_1  | [12:50:37] [Server-Worker-1/INFO]: Preparing spawn area: 90%
minecraft_1  | [12:50:37] [Server-Worker-1/INFO]: Preparing spawn area: 93%
minecraft_1  | [12:50:38] [Server-Worker-1/INFO]: Preparing spawn area: 96%
minecraft_1  | [12:50:38] [Server-Worker-1/INFO]: Preparing spawn area: 99%
minecraft_1  | [12:50:38] [Server thread/INFO]: Time elapsed: 25585 ms
minecraft_1  | [12:50:38] [Server thread/INFO]: Done (62.620s)! For help, type "help"
minecraft_1  | [12:50:38] [Server thread/INFO]: Starting remote control listener
minecraft_1  | [12:50:38] [RCON Listener #1/INFO]: RCON running on 0.0.0.0:25575
backup_1     | 2019-10-07T12:50:47+0000 ERROR Unable to execute rcon-cli save-on - try 2/20. Retrying in 10s
backup_1     | 2019-10-07T12:50:47+0000 ERROR Failure reason: 2019/10/07 12:50:47 Failed to connect to RCON serverdial tcp: i/o timeout	
backup_1     | 2019-10-07T12:51:07+0000 ERROR Unable to execute rcon-cli save-on - try 3/20. Retrying in 10s

The container appears to be using the wrong ip to connect to rcon.

backup_1     | 2019-10-07T12:50:27+0000 ERROR Failure reason: 2019/10/07 12:50:27 Failed to connect to RCON serverdial tcp 127.0.0.1:25575: i/o timeout	

I find no option to change it to the ip of the minecraftserver-container

I use following docker-compose.yml:

version: '3'


services:
  minecraft:
    image: itzg/minecraft-server
    ports:
      - "25565:25565"
    volumes:
      - "./mc:/data"
    environment:
      TYPE: VANILLA
      EULA: "TRUE"
      MAX_MEMORY: 5G
      ENABLE_RCON: "true"
      RCON_PASSWORD: "testing"
    networks:
      default:
      mc-backup:
        aliases:
          - mc
    restart: unless-stopped

  backup:
    image: itzg/mc-backup
    user: 1000:1000
    environment:
      BACKUP_INTERVAL: 1h
      PRUNE_BACKUPS_DAYS: 14
      BACKUP_METHOD: tar
      EXCLUDES: "*.jar,cache,logs"
      INITIAL_DELAY: 30s
      RCON_PASSWORD: "testing"
    volumes:
      - "./mc:/data:ro"
      - "./backup:/backups"
    networks:
      mc-backup:
    depends_on:
      - minecraft
    restart: unless-stopped

networks:
  mc-backup:
    internal: true

Removing online backups

When using the rclone option, are the uploaded files also deleted after the PRUNE_BACKUPS_DAYS option?

Add an environment variable for EXCLUDES_FILE

Sometimes when you need to exclude a lot of files having them all in one line can become unwieldy. I think an option should be added to support a excludes file. This is already implemented as option in rclone, rsync (--exclude-from), and restic (--exclude-file).

Backup folder is created as root

Not sure if this is intentional or not, but the backup folder and the contents in it are owned by the root user. Running docker as root is required in my environment. I was wondering if there is a way to change this without having to run separate scripts to change the ownership. This issue doesn't appear with the docker-minecraft-server image.

Feature request: invoke extra commands before/after backup

As an administrator of a Minecraft server, I would like to be able to specify custom RCON commands to run before and after a backup. I would like to use this in production to provide backup status notifications to operators. I also would like to use this on a force-upgrade migration cronjob[1], to stop the Minecraft server after the backup completes.

I imagine that admins may want to be able to run more than one command at each step. I can see two ways to implement this:

  1. Accept COMMANDS_BEFORE_BACKUP and COMMANDS_AFTER_BACKUP as env vars, parse them slightly (e.g. split on ;), and pass the commands along. This is perhaps a little bit underpowered and might lead to frustration around escaping if users want to run commands that contain our chosen separator.
  2. Allow Docker mounts to provide e.g. /etc/before-backup.sh and /etc/after-backup.sh which, if present, will be sourced at the appropriate time. This gives administrators more control, but it's potentially overpowered for this use case.

Thoughts on either of these, or another alternative that meets my use cases?


[1] Why I'm doing this: I have a world save from a previous version which I'm aiming to migrate to 1.18. While I'm testing the migration, I'm running a cronjob after each backup from the original server, which loads that backup in a temporary 1.18 server with --forceUpgrade. The migrated world is then backed up, and loaded into the final 1.18 testing server. This allows me to run the upgrade process on a separate node, without downtime on the testing server.

Timezone

Hi,
Can the TZ environment be added to the image?
It would be nice if my timezone lines up with the timezone in my minecraft containers :)

Error Querying the server

Hello, I just tried to get this container back up and running after not running it for a few months and I noticed that the backup worked successfully the first time around, but after that it would not connect to the minecraft server container.

As you can see it generates the first backup successfully on startup, but after that it cannot seem to connect to the server.

2022-05-10T00:54:26-0400 INFO waiting initial delay of 2m...
2022-05-10T00:56:26-0400 INFO waiting for rcon readiness...
2022-05-10T00:56:26-0400 INFO Command executed successfully rcon-cli save-on
2022-05-10T00:56:26-0400 INFO Command executed successfully rcon-cli save-off
2022-05-10T00:56:27-0400 INFO Command executed successfully rcon-cli save-all flush
2022-05-10T00:56:27-0400 INFO Command executed successfully sync
2022-05-10T00:56:27-0400 INFO Backing up content in /data
2022-05-10T00:56:28-0400 INFO using parent snapshot 2848ceb8
2022-05-10T00:56:28-0400 INFO
2022-05-10T00:56:28-0400 INFO Files:           0 new,  1329 changed,  3173 unmodified
2022-05-10T00:56:28-0400 INFO Dirs:            0 new,   146 changed,   576 unmodified
2022-05-10T00:56:28-0400 INFO Added to the repo: 22.716 MiB
2022-05-10T00:56:28-0400 INFO
2022-05-10T00:56:28-0400 INFO processed 4502 files, 16.455 GiB in 0:00
2022-05-10T00:56:28-0400 INFO snapshot 15cbc603 saved
2022-05-10T00:56:28-0400 INFO Command executed successfully rcon-cli save-on
2022-05-10T00:56:29-0400 ERROR Error querying the server, waiting 5m...
2022-05-10T01:01:29-0400 ERROR Error querying the server, waiting 5m...```

Keeping a minumum number of backups

Is there any way of keeping a minimum number of backups safe from being pruned? I'm worried about setting PRUNE_BACKUPS_DAYS and PAUSE_IF_NO_PLAYERS=true at the same time, because, if my understanding is correct, if the server goes PRUNE_BACKUPS_DAYS days without any players then all backups would get deleted.

Maybe adding a new option like MIN_BACKUPS could be a solution to this.

UTC TimeZone in filename

Hello, in filename you used ts=$(date -u +"%Y%m%d-%H%M%S")
thus, even if a time zone (TZ) is defined, the file name will contain the time in the UTC:
2021-11-07T19:18:56+0300 INFO Backing up content in /data to /backups/world-20211107-161856.tgz
Maybe you can delete -u flag?

Question: how to handle multiple backup setups?

I'm currently using rclone to Google Drive but am thinking of switching to restic for a couple personal reasons. However, I would also like to have local tar backups as well, for easier/faster restores. I'm thinking a local tar every 30min, plus a restic every day. How would I go about setting that up?

The first idea that comes to mind is just having multiple mc-backup containers all attached to the same data volume, but I'm wondering if might end up conflicting with one another, especially around the rcon commands to disable/enable automatic saving.

Crash when using AutoPause in the game container

I've been struggling with this on and off now for a bit, and I've finally narrowed the crashes of this container to the fact that the main game container is "paused". Could we add the rcon connection port to the wake up sequence? So the game can be woken up for backups?

Add support for restic compression

The latest restic update, 0.14 finally added support for compressing data stored in the repository, while this likely won't do much to Minecrafts region files, it would still be nice to have in case people are storing other things that could benefit greatly from compression like log files.

add autopause compatibility with dynmap

The Dynmap plugin comes with a built-in web server for the rendered world maps (and optionally up-to-the-second time, weather, player positions, and chat), but since its a server plugin, that all runs within the server's java process which is stopped by autopause. Consequently, if no players are connected to the server and the autopause kicks in, the web map stops working as well.

Could there be an environment variable to add additional ports to listen for knocks, and to check for open connections? Dynmap runs on port 8123 by default, so any activity there should ideally resume the server and prevent it from pausing again (possibly even with a separate timeout -- i.e. wait 60 minutes after the last player disconnects, but only 5 minutes after the last dynmap connection).

Container exits after first backup

After the first backup no further backups followed so I tried to understand what's happening. The container keeps stopping after the first backup.

Compose File

version: '3.7'
services:
  mc:
    image: itzg/minecraft-server
    ports:
    - 25565:25565
    environment:
      EULA: "TRUE"
      OVERRIDE_SERVER_PROPERTIES: "TRUE"
      MOTD: "..."
      ICON: "..."
      VIEW_DISTANCE: "16"
      SERVER_NAME: "..."
      MEMORY: 3G
    volumes:
    - mc:/data
  backups:
    image: itzg/mc-backup
    environment:
      BACKUP_INTERVAL: "1h"
      # instead of network_mode below, could declare RCON_HOST
      # RCON_HOST: mc
    volumes:
    # mount the same volume used by server, but read-only
    - mc:/data:ro
    # use a host attached directory so that it in turn can be backed up
    # to external/cloud storage
    - ./mc-backups:/backups
    # share network namespace with server to simplify rcon access
    network_mode: "service:mc"

volumes:
  mc: {}

Container Overview


CONTAINER ID   IMAGE                             COMMAND                  CREATED        STATUS                    PORTS                                                                                  NAMES
048040e452d6   itzg/mc-backup                    "/opt/entrypoint-dem…"   46 hours ago   Exited (1) 45 hours ago                                                                                          minecraft_backups_1
136670636adf   itzg/minecraft-server             "/start"                 46 hours ago   Up 46 hours (healthy)     0.0.0.0:25565->25565/tcp, :::25565->25565/tcp, 25575/tcp                               minecraft_mc_1

Log

2021-12-05T17:57:15+0000 INFO waiting initial delay of 2m...
2021-12-05T17:59:15+0000 INFO waiting for rcon readiness...
2021-12-05T17:59:15+0000 INFO Command executed successfully rcon-cli save-on
2021-12-05T17:59:15+0000 INFO Command executed successfully rcon-cli save-off
2021-12-05T17:59:15+0000 INFO Command executed successfully rcon-cli save-all
2021-12-05T17:59:15+0000 INFO Command executed successfully sync
2021-12-05T17:59:15+0000 INFO Backing up content in /data to /backups/world-20211205-175915.tgz
2021-12-05T17:59:20+0000 INFO Command executed successfully rcon-cli save-on
2021-12-05T17:59:20+0000 INFO sleeping 1h...
2021-12-05T18:59:20+0000 INFO Command executed successfully rcon-cli save-off
2021-12-05T18:59:20+0000 INFO Command executed successfully rcon-cli save-all
2021-12-05T18:59:20+0000 INFO Command executed successfully sync
2021-12-05T18:59:20+0000 INFO Backing up content in /data to /backups/world-20211205-185920.tgz
tar: ./world/entities/r.2.1.mca: file changed as we read it
tar: ./world/entities/r.0.0.mca: file changed as we read it
tar: ./world/entities/r.1.0.mca: file changed as we read it
2021-12-05T18:59:27+0000 INFO Command executed successfully rcon-cli save-on

Inspect

[
    {
        "Id": "048040e452d6f4618ab606966db896b2c551581d824929a3cd547fc11438451e",
        "Created": "2021-12-05T17:57:15.140760585Z",
        "Path": "/opt/entrypoint-demoter",
        "Args": [
            "--match",
            "/backups",
            "backup",
            "loop"
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 1,
            "Error": "",
            "StartedAt": "2021-12-05T17:57:15.326928937Z",
            "FinishedAt": "2021-12-05T18:59:27.375662406Z"
        },
        "Image": "sha256:cb8691c1bf155a096791c02918c07927fc377c932934fb69ba69ee4f8e2e6ec5",
        "ResolvConfPath": "/var/lib/docker/containers/136670636adf73b097df51ef08fd43ad596789b35f443dc31b0296da96dcae5f/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/136670636adf73b097df51ef08fd43ad596789b35f443dc31b0296da96dcae5f/hostname",
        "HostsPath": "/var/lib/docker/containers/136670636adf73b097df51ef08fd43ad596789b35f443dc31b0296da96dcae5f/hosts",
        "LogPath": "/var/lib/docker/containers/048040e452d6f4618ab606966db896b2c551581d824929a3cd547fc11438451e/048040e452d6f4618ab606966db896b2c551581d824929a3cd547fc11438451e-json.log",
        "Name": "/minecraft_backups_1",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "docker-default",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": [
                "minecraft_mc:/data:ro",
                "/home/games/minecraft/mc-backups:/backups:rw"
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "container:136670636adf73b097df51ef08fd43ad596789b35f443dc31b0296da96dcae5f",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": [],
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "private",
            "Dns": null,
            "DnsOptions": null,
            "DnsSearch": null,
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": null,
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": null,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/22766048d958e6c38211f56615c7a4645cc9c43dd75a7e28ca997c93138d056c-init/diff:/var/lib/docker/overlay2/02a1bdc61026ccc8e365d33791f4c040ccb91e8541a22b875b7da1dee28f4484/diff:/var/lib/docker/overlay2/928abf623227044d80f253ccd044c2d7b6667940e93b5f9210d8c1f2d450c1e2/diff:/var/lib/docker/overlay2/99e1777f2bb825401269c36e3d9b0b04aa9890990bece5b1677b60785f25040b/diff:/var/lib/docker/overlay2/6ec8afb3476e10c65028a60261e88feb24f8af368610a87406701f6fb91e5716/diff:/var/lib/docker/overlay2/a1c0b6b5656cfa8d6730cf42496481866f88348438ccf50eda33139ed84976c1/diff:/var/lib/docker/overlay2/35ed11231ce0397b6952b1aef9b6062952de0ec996419d194e93c7530fb3b7fd/diff:/var/lib/docker/overlay2/bbebe113994837afe342f9ff4fbfaf65965294d4f16d4ea12ed671c681f8c138/diff:/var/lib/docker/overlay2/82415d761cbc91dc772ff4c254c3108dfb376d303695cb5301f9b53608377d28/diff:/var/lib/docker/overlay2/38835db10885bb933b29311e124a6bce870209ca8266c3ff187c1f0519a44d84/diff:/var/lib/docker/overlay2/a1c0fdfc2fa2d33f459ef30603985ae182b434dadf9316b731998a93f9670508/diff:/var/lib/docker/overlay2/7ebca3febc5f3cc95b22866656cc587f27e480b2e59f1abf5aae34e8077056c7/diff:/var/lib/docker/overlay2/bd54835b3f2351256b9b0a572633d4730ef6d32d2983ea560d69753c0208d804/diff:/var/lib/docker/overlay2/b589e1a8c81d492a195a58f36980344ba15c55ec7f7f6cf11035431bbd470896/diff:/var/lib/docker/overlay2/a732244fc0a63377e19880c3ceabcbb9ef912558ce94667a32e56efb3564748b/diff",
                "MergedDir": "/var/lib/docker/overlay2/22766048d958e6c38211f56615c7a4645cc9c43dd75a7e28ca997c93138d056c/merged",
                "UpperDir": "/var/lib/docker/overlay2/22766048d958e6c38211f56615c7a4645cc9c43dd75a7e28ca997c93138d056c/diff",
                "WorkDir": "/var/lib/docker/overlay2/22766048d958e6c38211f56615c7a4645cc9c43dd75a7e28ca997c93138d056c/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "volume",
                "Name": "minecraft_mc",
                "Source": "/var/lib/docker/volumes/minecraft_mc/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "ro",
                "RW": false,
                "Propagation": ""
            },
            {
                "Type": "bind",
                "Source": "/home/games/minecraft/mc-backups",
                "Destination": "/backups",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
        "Config": {
            "Hostname": "136670636adf",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "BACKUP_INTERVAL=1h",
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "HOME=/tmp"
            ],
            "Cmd": [
                "backup",
                "loop"
            ],
            "Image": "itzg/mc-backup",
            "Volumes": {
                "/backups": {},
                "/data": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "/opt/entrypoint-demoter",
                "--match",
                "/backups"
            ],
            "OnBuild": null,
            "Labels": {
                "com.docker.compose.config-hash": "78c3e039b5dfc3414c1c5443870fbe1124fcc5d1d266369349e167464e40fbcb",
                "com.docker.compose.container-number": "1",
                "com.docker.compose.oneoff": "False",
                "com.docker.compose.project": "minecraft",
                "com.docker.compose.project.config_files": "docker-compose.yml",
                "com.docker.compose.project.working_dir": "/home/games/minecraft",
                "com.docker.compose.service": "backups",
                "com.docker.compose.version": "1.29.2"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {}
        }
    }
]

file changed as we read it

  backups:
    image: itzg/mc-backup
    environment:
      INITIAL_DELAY: 2m
      BACKUP_INTERVAL: "1d"
      PRUNE_BACKUPS_DAYS: "3"
      RCON_HOST: smp
      SRC_DIR: /data
      DEST_DIR: /backups
    volumes:
      # mount the same volume used by server, but read-only
      - ./orchestration/smp/data:/data:ro
      - ./backups:/backups
2022-01-20T07:26:34+0000 INFO waiting initial delay of 2m...
2022-01-20T07:28:34+0000 INFO waiting for rcon readiness...
2022-01-20T07:28:34+0000 INFO Command executed successfully rcon-cli save-on
2022-01-20T07:28:34+0000 INFO Command executed successfully rcon-cli save-off
2022-01-20T07:28:34+0000 INFO Command executed successfully rcon-cli save-all flush
2022-01-20T07:28:34+0000 INFO Command executed successfully sync
2022-01-20T07:28:34+0000 INFO Backing up content in /data to /backups/world-20220120-072834.tgz
tar: ./world: file changed as we read it
tar: ./world_nether: file changed as we read it
2022-01-20T07:47:42+0000 WARN tar exited with code 1. Ignoring
2022-01-20T07:47:43+0000 INFO Command executed successfully rcon-cli save-on
2022-01-20T07:47:43+0000 INFO sleeping 1d...

cfg_name and repo

In the following example CFG_NAME and BUCKET_NAME need to be changed to specifics for the rclone configuration you created:

Just curious on what these values should be created a rclone configed called nextcloud.

Thanks!

Manually exec'ing `restic tag` command results in mismatch of user execution

Steps to reproduce:

  1. Start container
  2. Make sure restic repository has snapshots
  3. Check restic snapshot cache ownership: docker exec <container name> ls -lR /tmp/.cache/restic | grep root
  4. Notice nothing is owned by root
  5. Modify restic snapshot tags: docker exec <container name> restic tag --add vanilla <snapshot ID>
  6. Check restic snapshot cache ownership again: docker exec <container name> ls -lR /tmp/.cache/restic | grep root
  7. Notice that the cache's modified snapshot(s) are now owned by root

I haven't tested with other restic "writable" functions but I suppose they'll probably do the same.

RCON Issue with Tekkit Modpack

I'm struggling to get the backup script to fire. These are steps that I've followed so far in debugging.

  1. Turn on RCON in server.properties
  2. Set RCON password to minecraft
  3. Succesfully connected through docker exec -i tekkit rcon-cli - this is without the port in docker-compose
  4. Change network_mode to container:tekkit

I believe the issue due to this error that occurs when I run docker-compose exec backup backup now

tekkit    | 2022-09-04 19:18:10 [INFO] [Minecraft-Server] Disconnecting /127.0.0.1:56050: Protocol error
tekkit    | 2022-09-04 19:18:10 [INFO] [Minecraft-Server] /127.0.0.1:56050 lost connection

Here is a copy of my docker-compose.yml - the server is running a very old version. So maybe its a protocol issue?

My docker-compose file is below

version: "3.8"
services:
  tekkit:
    image: itzg/minecraft-server:java8
    container_name: tekkit
    environment:
      EULA: "true"
      TYPE: "custom"
      CUSTOM_SERVER: "Tekkit.jar"
      DEBUG: "true"
      MEMORY: "8G"
      USE_AIKAR_FLAGS: "true"
    ports:
      - "25565:25565"
    volumes:
      - /var/minecraft/server/tekkit:/data
    restart: unless-stopped
  backup:
    image: itzg/mc-backup
    container_name: mc-backup
    environment:
      BACKUP_INTERVAL: "2h"
    volumes:
      - /var/minecraft/server/tekkit:/data:ro
      - /var/minecraft/backup/tekkit:/backups
    network_mode: "container:tekkit"
    restart: unless-stopped

networks:
  default:
    name: minecraft

Backups not pruned

I am using the tar backup method and old backups are not pruned. Do you have any idea where my configuration error is?

backup:
    image: itzg/mc-backup
    restart: unless-stopped
    container_name: minecraft-backup
    environment:
      BACKUP_INTERVAL: "4h"
      PRUNE_BACKUPS_DAYS: 3
      INITIAL_DELAY: "5m"
      RCON_HOST: "minecraft"
      RCON_PORT: "28016"
      RCON_PASSWORD: "notmypassword"
      EXCLUDES: "*.jar,cache,logs"
      BACKUP_METHOD: "tar"
    volumes:
      - "./server-data:/data:ro"
      - "./server-backups:/backups"
    networks: 
      - default

the log output says nothing about pruning:

minecraft-backup | 2020-03-20T11:25:19+0000 INFO waiting initial delay of 5m...
minecraft-backup | 2020-03-20T11:30:19+0000 INFO waiting for rcon readiness...
minecraft-backup | 2020-03-20T11:30:19+0000 INFO Command executed successfully rcon-cli save-on
minecraft-backup | 2020-03-20T11:30:19+0000 INFO Command executed successfully rcon-cli save-off
minecraft-backup | 2020-03-20T11:30:19+0000 INFO Command executed successfully rcon-cli save-all
minecraft-backup | 2020-03-20T11:30:19+0000 INFO Command executed successfully sync
minecraft-backup | 2020-03-20T11:30:19+0000 INFO Backing up content in /data to /backups/world-20200320-113019.tgz
minecraft-backup | 2020-03-20T11:31:35+0000 INFO Command executed successfully rcon-cli save-on
minecraft-backup | 2020-03-20T11:31:35+0000 INFO sleeping 4h...
ll server-backups 
total 18G
-rw-r--r-- 1 root root 429M Mar 16 15:02 world-20200316-140138.tgz
-rw-r--r-- 1 root root 430M Mar 16 19:02 world-20200316-180209.tgz
-rw-r--r-- 1 root root 430M Mar 16 23:03 world-20200316-220237.tgz
-rw-r--r-- 1 root root 431M Mar 17 03:03 world-20200317-020304.tgz
-rw-r--r-- 1 root root 431M Mar 17 07:04 world-20200317-060332.tgz
-rw-r--r-- 1 root root 431M Mar 17 11:04 world-20200317-100400.tgz
-rw-r--r-- 1 root root 558M Mar 17 15:05 world-20200317-140427.tgz
-rw-r--r-- 1 root root 558M Mar 17 19:05 world-20200317-180503.tgz
-rw-r--r-- 1 root root 687M Mar 17 23:06 world-20200317-220540.tgz
-rw-r--r-- 1 root root 793M Mar 18 03:07 world-20200318-020627.tgz
-rw-r--r-- 1 root root 793M Mar 18 07:08 world-20200318-060717.tgz
-rw-r--r-- 1 root root 793M Mar 18 11:08 world-20200318-100807.tgz
-rw-r--r-- 1 root root 793M Mar 18 15:09 world-20200318-140858.tgz
-rw-r--r-- 1 root root 793M Mar 18 19:10 world-20200318-180949.tgz
-rw-r--r-- 1 root root 846M Mar 18 23:11 world-20200318-221042.tgz
-rw-r--r-- 1 root root 846M Mar 19 03:12 world-20200319-021135.tgz
-rw-r--r-- 1 root root 846M Mar 19 07:13 world-20200319-061227.tgz
-rw-r--r-- 1 root root 848M Mar 19 11:14 world-20200319-101321.tgz
-rw-r--r-- 1 root root 852M Mar 19 15:20 world-20200319-141921.tgz
-rw-r--r-- 1 root root 852M Mar 19 19:21 world-20200319-182015.tgz
-rw-r--r-- 1 root root 894M Mar 19 23:22 world-20200319-222110.tgz
-rw-r--r-- 1 root root 894M Mar 20 03:23 world-20200320-022207.tgz
-rw-r--r-- 1 root root 894M Mar 20 07:23 world-20200320-062302.tgz
-rw-r--r-- 1 root root 990M Mar 20 11:25 world-20200320-102359.tgz
-rw-r--r-- 1 root root 1.1G Mar 20 12:31 world-20200320-113019.tgz

And thanks for your great docker images ❤️

Add a PRE_SAVE_SCRIPT environment variable

It would be nice to have a PRE_SAVE_SCRIPT / PRE_SAVE_SCRIPT_FILE environment variable where the script is executed before "/save-off". Most of the time when the server executes a "/save-all" it freezes the server for a few seconds. I would be nice to be able to announce to the players, "Server Backup starting in x seconds". Another use cases might be to perform cleanup task like removing drop entities with "/lagg clear", etc... It would be nice to also add a POST_SAVE_SCRIPT but spot is already taken by POST_BACKUP_SCRIPT. I don't know if it would be a breaking change to swap the order of POST_BACKUP_SCRIPT and "/save-on".

If this gets added the lines

log INFO "waiting for rcon readiness..."
retry ${RCON_RETRIES} ${RCON_RETRY_INTERVAL} rcon-cli save-on

should probably be moved inside the while loop to make sure that PRE_SAVE_SCRIPT doesn't get called if the server is offline

"Failed to save config" error in service logs despite backup working

I'm getting multiple "failed to save config" errors in the logs for mc-backup. I suspect they're actually coming from rclone, but I'm unsure so I'm asking here first.

2022-05-01T23:02:58+0000 INFO waiting initial delay of 2m...
2022-05-01T23:04:58+0000 INFO waiting for rcon readiness...
2022-05-01T23:04:58+0000 INFO Command executed successfully rcon-cli save-on
2022-05-01T23:04:58+0000 INFO Command executed successfully rcon-cli save-off
2022-05-01T23:04:58+0000 INFO Command executed successfully rcon-cli save-all flush
2022-05-01T23:04:58+0000 INFO Command executed successfully sync
2022-05-01T23:04:58+0000 INFO Backing up content in /data to /backups/world-20220501-230458.tgz
2022/05/01 23:05:21 ERROR : Failed to save config after 10 tries: Failed to move previous config to backup location: rename /config/rclone/rclone.conf /config/rclone/rclone.conf.old: device or resource busy
2022-05-01T23:05:49+0000 INFO Command executed successfully rcon-cli save-on
2022/05/01 23:05:56 ERROR : Failed to save config after 10 tries: Failed to move previous config to backup location: rename /config/rclone/rclone.conf /config/rclone/rclone.conf.old: device or resource busy
2022-05-01T23:05:57+0000 INFO sleeping 24h...

This is how mc-backup is configured

version: '3.7'

services:
  flappack-backup:
    image: docker.io/itzg/mc-backup:latest
    environment:
      - BACKUP_INTERVAL=24h
      - RCON_HOST=flappack
      - RCON_PASSWORD_FILE=/run/secrets/flappack-rcon-password
      - BACKUP_METHOD=rclone
      - RCLONE_REMOTE=Google Drive
      - EXCLUDES=*.jar,cache,logs,mods,tmp,llibrary,libraries,*.so
    volumes:
      - flappack-data:/data:ro
    secrets:
      - source: google-drive-rclone-config
        target: /config/rclone/rclone.conf
      - source: flappack-rcon-password

volumes:
  flappack-data:
    external: true

secrets:
  google-drive-rclone-config:
    external: true
  flappack-rcon-password:
    external: true

It looks like rclone (?) is trying to move rclone.conf, but that's not working since it's mounted into the container by Docker. Any ideas on what to do? It's a not deal-breaker since the backups still work, but it would be nice to have less noise in my logs.

Unable to execute rcon-cli save-on

I use your demo Docker Compose file in my server, the service mc runs well,
but the backups exits with wrongs.

The full logs are:

ERROR Unable to execute rcon-cli save-on - try 0/20. Retrying in 10s
ERROR Failure reason: 2020/06/15 13:06:44 Failed to connect to RCON serverdial tcp: i/o timeout
...

And the rcon-cli runs well because the command docker-compose exec mc rcon-cli runs well.

Help: Unable to get mc-backup working, cannot connect to RCON.

Hi, me again. Realised I wasn't running backups for my server the past 6 months when I thought I was. So, went about getting backups started and found this repo. Just having some teething issues getting it working and would appreciate any guidance you could share! This is the following issue I am seeing in the logs of my "minecraft_backups_1" container that is running.

2021-07-11T17:41:14+0000 ERROR Unable to execute rcon-cli save-on - try 0/20. Retrying in 10s,
2021-07-11T17:41:14+0000 ERROR Failure reason: 2021/07/11 17:41:14 Failed to connect to RCON serverdial tcp 127.0.0.1:25575: connect: connection refused	

The docker-compose.yml file I used is as follows:

version: '3.7'

services:
  backups:
    image: itzg/mc-backup
    environment:
      BACKUP_INTERVAL: "1d"
      BACKUP_NAME: "new-survival"  # I put this as the name of my world incase they needed to match, was unsure
      PRUNE_BACKUP_DAYS: "7"
      EXCLUDES: ".jar,cache,logs"
      BACKUP_METHOD: "tar"
      INITIAL_DELAY: 30s
      # instead of network_mode below, could declare RCON_HOST
      RCON_HOST: minecraft # tried this with localhost as well but to no avail
      RCON_PORT: 25575 # default
      RCON_PASSWORD: minecraft # default
    volumes:
    # mount the same volume used by server, but read-only
    - minecraft:/data:ro
    # use a host attached directory so that it in turn can be backed up
    # to external/cloud storage
    - ./mc-backups:/backups # I have created a directory called `mc-backups` at the same level as this file
    # share network namespace with server to simplify rcon access - there is no minecraft service yet.
    # network_mode: "service:minecraft"
    networks:
      mc-backup:
    restart: unless-stopped

volumes:
  minecraft: {}  # I think this needs mapping to my volume used for the server but was unable to do so, hence changed in portainer

# Saw this mentioned in Issue 5 for this repo and thought I may need it. 
networks:
  mc-backup:
    internal: true

Once the container has booted, I always need to change the /data for the read-only aspect as it never points at the volume I use for my server container (likely a config issue in the script but easy enough to change on portainer). I think the issue is to do with networking/services? I don't have a "minecraft" service running on my box - I didn't use docker-compose file for setting that up.

Very much on a learning curve with containers currently so any guidance appreciated. If you need any more details please let me know. Have read the documentation but wasn't able to get anywhere.

INTERNALERROR Unhandled restic repository state.

I was using rclone with s3 as backup method and am trying to switch to restic, but it prompt errors. I am not sure how to fix it.

Logs:

2022-08-07T05:37:25+0000 INFO Initializing new restic repository...
2022-08-07T05:37:28+0000 INFO created restic repository 4f195d09aa at rclone:ocl:mc-new-horizons-backup
2022-08-07T05:37:28+0000 INFO 
2022-08-07T05:37:28+0000 INFO Please note that knowledge of your password is required to access
2022-08-07T05:37:28+0000 INFO the repository. Losing your password means that your data is
2022-08-07T05:37:28+0000 INFO irrecoverably lost.
2022-08-07T05:37:28+0000 INFO waiting initial delay of 2m...
2022-08-07T05:39:28+0000 INFO waiting for rcon readiness...
2022-08-07T05:39:28+0000 INFO Command executed successfully rcon-cli save-on
2022-08-07T05:39:28+0000 INFO Command executed successfully rcon-cli save-off
2022-08-07T05:39:28+0000 INFO Command executed successfully rcon-cli save-all flush
2022-08-07T05:39:28+0000 INFO Command executed successfully sync
2022-08-07T05:39:28+0000 INFO Backing up content in /data
Load(<key/f7812163f9>, 0, 0) returned error, retrying after 720.254544ms: <key/f7812163f9> does not exist
Load(<key/f7812163f9>, 0, 0) returned error, retrying after 873.42004ms: <key/f7812163f9> does not exist
Load(<key/f7812163f9>, 0, 0) returned error, retrying after 1.054928461s: <key/f7812163f9> does not exist
Load(<key/f7812163f9>, 0, 0) returned error, retrying after 1.560325776s: <key/f7812163f9> does not exist
Load(<key/f7812163f9>, 0, 0) returned error, retrying after 3.004145903s: <key/f7812163f9> does not exist
Load(<key/f7812163f9>, 0, 0) returned error, retrying after 2.147653057s: <key/f7812163f9> does not exist
Load(<key/f7812163f9>, 0, 0) returned error, retrying after 3.739082318s: <key/f7812163f9> does not exist
Load(<key/f7812163f9>, 0, 0) returned error, retrying after 5.099891944s: <key/f7812163f9> does not exist
Load(<key/f7812163f9>, 0, 0) returned error, retrying after 10.263247495s: <key/f7812163f9> does not exist
2022-08-07T05:39:52+0000 INFO Command executed successfully rcon-cli save-on
2022-08-07T05:59:35+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 720.254544ms: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 873.42004ms: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 1.054928461s: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 1.560325776s: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 3.004145903s: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 2.147653057s: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 3.739082318s: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 5.099891944s: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 10.263247495s: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 19.514091959s: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 ERROR Fatal: <key/f7812163f9> does not exist
2022-08-07T05:59:35+0000 INTERNALERROR Unhandled restic repository state.
2022-08-07T05:59:35+0000 INTERNALERROR Please report this: https://github.com/itzg/docker-mc-backup/issues
2022-08-07T06:00:24+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 720.254544ms: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 873.42004ms: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 1.054928461s: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 1.560325776s: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 3.004145903s: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 2.147653057s: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 3.739082318s: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 5.099891944s: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 10.263247495s: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 ERROR Load(<key/f7812163f9>, 0, 0) returned error, retrying after 19.514091959s: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 ERROR Fatal: <key/f7812163f9> does not exist
2022-08-07T06:00:24+0000 INTERNALERROR Unhandled restic repository state.
2022-08-07T06:00:24+0000 INTERNALERROR Please report this: https://github.com/itzg/docker-mc-backup/issues

docker-compose.yml

#...
  backup:
    container_name: mc_gtnh_backup
    image: itzg/mc-backup
    environment:
      RCON_HOST: mc
      BACKUP_NAME: gtnh
      BACKUP_INTERVAL: 24h
      # BACKUP_METHOD: rclone
      # RCLONE_REMOTE: ocl
      # RCLONE_DEST_DIR: /mc-new-horizons-backup
      # RCLONE_COMPRESS_METHOD: gzip
      BACKUP_METHOD: restic
      RESTIC_PASSWORD: password
      RESTIC_REPOSITORY: rclone:ocl:mc-new-horizons-backup
      PRUNE_RESTIC_RETENTION: --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 75
      PRUNE_BACKUPS_DAYS: 60
      PAUSE_IF_NO_PLAYERS: true
      EXCLUDES: "*.jar,cache,logs,dynmap"
    restart: unless-stopped
    volumes:
      - mc-new-horizons:/data:ro
      - mc_new_horizons_rclone:/config/rclone:ro
      - mc_new_horizons_backup:/backups
    depends_on:
      mc:
        condition: service_healthy
#...

Additionally, from my bucket I can see new files created so S3 connection seems not the issue here, but with my limited knowledge still not sure what the issue is.
image

[Question/suggestion] Is it possible to query the server for connected players without knocking?

I am using PAUSE_IF_NO_PLAYERS, but on the minecraft server I enabled AUTOPAUSE to save on resources. Everytime the backup container checks for active players, the server gets knocked and spins up the java process, resulting in flooded logs and unnecessary resource consumption.
I don't really know RCON, but would it be possible to avoid knocking the actual server or constructing a mechanism that filters knocks from the backup-container?

mc-backup kill server.

Hi im trying to run mc-backup on my synology server.
MC Server is there too, run like host on server network interface.
When i run mc-backup it will crash mc-server. I think that can be caused in when MC server is autopaused.
Log from export included
minecraft.zip

Failing to connect to RCON serverdial

I'm using the following compose file:

version: '3.9'

services:
  minecraft:
    container_name: minecraft-atm7
    image: itzg/minecraft-server:java17
    ports:
      - "25565:25565"
    restart: unless-stopped
    stdin_open: true
    tty: true
    environment:
      EULA: "TRUE"
      WORLD: /worlds/world
      MEMORY: 16G
      JVM_XX_OPTS: "-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=50 -XX:G1HeapRegionSize=32M -XX:G1ReservePercent=15 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -X>
      TYPE: FORGE
      VERSION: 1.18.2
      STOP_SERVER_ANNOUNCE_DELAY: 300
      # Need to manually rev these (place downloaded pack in ./modpacks). This will be pulled in unless SKIP_GENERIC_PACK_UPDATE_CHECK: false is set here.
      FORGEVERSION: 40.1.68
      GENERIC_PACK: /modpacks/Server-Files-0.4.24.zip
      # UUID ops here
      OPS: 9d5101ef-4f07-431e-b86c-cc734e8a5952
      # Server listing info
      # config options
      DIFFICULTY: normal
    volumes:
      # maps from host:container for data persistence
      - ./data:/data
      - ./modpacks:/modpacks:ro
      - ./worlds:/worlds:ro
    # Docker reservations
    mem_limit: 25g
    mem_reservation: 18g
    # cpus: 0.5
  backups:
    container_name: backup-atm7
    image: itzg/mc-backup
    environment:
      SERVER_PORT: 25565
      # timing
      BACKUP_INTERVAL: "1h"
      INITIAL_DELAY: "2m"
      # online player
      PAUSE_IF_NO_PLAYERS: "true"
      PLAYERS_ONLINE_CHECK_INTERVAL: "2m"
      PRUNE_BACKUPS_DAYS: 2
      # method info
      BACKUP_METHOD: tar
      DEST_DIR: /backups
      TAR_COMPRESS_METHOD: zstd
      ZSTD_PARAMETERS: "-11 --long --single-thread"
    volumes:
      # IMPORTANT: Must mount to same location as server data volume above
      - ./data:/data:ro
      # Where the backups will be saved to
      - /media/HDD/game_backups/mc/ATM7/0.4.24:/backups
    # share network namespace with server to simplify rcon access
    network_mode: "service:minecraft"

And receiving the following error:

Unable to execute rcon-cli save-on - try 0/5. Retrying in 10s
Failure reason: 2022/08/06 Failed to RCON serverdial tcp 127.0.0.1:25575: connect: connection refused

Running on headless Ubuntu. I've tried looking at some of the other bug reports here with similar issues, but I can't seem to figure this one out. Is this expected since I'm specifying tar mode?

New enhancing on backups "START_WHEN_PLAYERS_JOIN"

I know that setting PAUSE_IF_NO_PLAYERS=true lets you pause backups if no players are online, and will start checking the server's player count every minute.

However, it's appeared that the back up process is starting immediately as soon as I started the server - which no player is entered yet - and cluttered the back up snapshot being made last time, plus for some modded server the waiting time before the server can start is very long, and I can't seem to config the 'right' "INITIAL_DELAY" very well.

So I'm suggest that maybe, if you includes another configurable env variable "START_WHEN_PLAYERS_JOIN=true" to let the backing up process start when first player join - so that I don't need to specify the INITIAL_DELAY and don't cluttered the back up instance, that'll be great!

Thank you very much.

Not working when i restart the mc server

I use a script with rcon-cli to restart the server of minecraft and if i do when mc-backup is working, dont work anymore. When the server is up again cant connect so i restart both at once or only the mc-backup container when mc server is UP.

Here is the debug:

  • : /data
  • : /backups
  • : Vault-Hunters
  • : 2m
  • : 4h
  • : true
  • : 10m
  • : tar
  • : gzip
  • : '-3 --long=25 --single-thread'
  • : 1
  • : '--keep-within 7d'

    5
  • : mc

    5
  • : ''
  • : serverjk-mc
  • : -1
  • : 10s
  • : '*.jar,cache,logs'

    e
  • : mc_backups
  • : /config

    e
  • : Europe/Madrid
  • : gzip
  • : ''
  • : ''
  • : ''
  • : ''
  • : ''
  • : ''
  • export TZ
  • export RCON_HOST
  • export RCON_PORT
  • export RCON_PASSWORD
  • export XDG_CONFIG_HOME
  • export SRC_DIR
  • export DEST_DIR
  • export BACKUP_NAME
  • [[ -n '' ]]
  • [[ -n '' ]]
  • [[ -n '' ]]
  • '[' -n '' ']'
  • '[' '!' -d /data ']'
  • is_function tar
  • '[' 1 -ne 1 ']'
  • name=tar
    ++ type -t tar
  • '[' function == function ']'
  • readarray -td, excludes_patterns
    ++ printf %s '*.jar,cache,logs'
  • excludes=()
  • for pattern in "${excludes_patterns[@]}"
  • excludes+=(--exclude "${pattern}")
  • for pattern in "${excludes_patterns[@]}"
  • excludes+=(--exclude "${pattern}")
  • for pattern in "${excludes_patterns[@]}"
  • excludes+=(--exclude "${pattern}")
  • tar init
  • call_if_function_exists init
  • '[' 1 -lt 1 ']'
  • function_name=init
  • is_function init
  • '[' 1 -ne 1 ']'
  • name=init
    ++ type -t init
  • '[' function == function ']'
  • init
  • mkdir -p /backups
  • case "${TAR_COMPRESS_METHOD}" in
  • tar_parameters=('--gzip')
  • readonly tar_parameters
  • readonly backup_extension=tgz
  • backup_extension=tgz
  • is_one_shot
  • [[ FALSE = TRUE ]]
  • return 1
  • log INFO 'waiting initial delay of 2m...'
  • '[' 2 -lt 1 ']'
  • local level=INFO
  • shift
  • valid_levels=('INFO' 'WARN' 'ERROR' 'INTERNALERROR')
  • local valid_levels
  • is_elem_in_array INFO INFO WARN ERROR INTERNALERROR
  • '[' 5 -lt 2 ']'
  • local element=INFO
  • shift

    e
  • for e in "$@"
  • '[' INFO == INFO ']'
  • return 0
  • '[' 1 -ge 1 ']'
  • cat -
  • awk -v level=INFO '{ printf("%s %s %s\n", strftime("%FT%T%z"), level, $0); fflush(); }'
    2022-09-01T16:35:51+0200 INFO waiting initial delay of 2m...
  • '[' INFO == INTERNALERROR ']'
  • sleep 2m
  • log INFO 'waiting for rcon readiness...'
  • '[' 2 -lt 1 ']'
  • local level=INFO
  • shift
  • valid_levels=('INFO' 'WARN' 'ERROR' 'INTERNALERROR')
  • local valid_levels
  • is_elem_in_array INFO INFO WARN ERROR INTERNALERROR
  • '[' 5 -lt 2 ']'
  • local element=INFO
  • shift

    e
  • for e in "$@"
  • '[' INFO == INFO ']'
  • return 0
  • '[' 1 -ge 1 ']'
  • cat -
  • awk -v level=INFO '{ printf("%s %s %s\n", strftime("%FT%T%z"), level, $0); fflush(); }'
    2022-09-01T16:37:51+0200 INFO waiting for rcon readiness...
  • '[' INFO == INTERNALERROR ']'
  • retry -1 10s rcon-cli save-on
  • '[' 4 -lt 3 ']'
  • local retries=-1
  • local interval=10s
  • readonly retries interval

    2
  • (( retries < 0 ))
  • local retries_msg=infinite
  • local i=-1
  • (( retries >= ++i ))
  • '[' infinite '!=' -1 ']'
    ++ timeout --signal=SIGINT --kill-after=30s 5m rcon-cli save-on
    ++ tr '\n' '\t'
  • output='2022/09/01 16:37:51 Failed to connect to RCON serverdial tcp: lookup mc on 127.0.0.11:53: read udp 127.0.0.1:43190->127.0.0.11:53: read: connection refused '
  • log ERROR 'Unable to execute rcon-cli save-on - try 0/infinite. Retrying in 10s'
  • '[' 2 -lt 1 ']'
  • local level=ERROR
  • shift
  • valid_levels=('INFO' 'WARN' 'ERROR' 'INTERNALERROR')
  • local valid_levels
  • is_elem_in_array ERROR INFO WARN ERROR INTERNALERROR
  • '[' 5 -lt 2 ']'
  • local element=ERROR
  • shift

    e
  • for e in "$@"
  • '[' ERROR == INFO ']'
  • for e in "$@"
  • '[' ERROR == WARN ']'
  • for e in "$@"
  • '[' ERROR == ERROR ']'
  • return 0
  • '[' 1 -ge 1 ']'
  • cat -
  • awk -v level=ERROR '{ printf("%s %s %s\n", strftime("%FT%T%z"), level, $0); fflush(); }'
    2022-09-01T16:37:51+0200 ERROR Unable to execute rcon-cli save-on - try 0/infinite. Retrying in 10s
  • '[' ERROR == INTERNALERROR ']'
  • '[' -n '2022/09/01 16:37:51 Failed to connect to RCON serverdial tcp: lookup mc on 127.0.0.11:53: read udp 127.0.0.1:43190->127.0.0.11:53: read: connection refused ' ']'
  • log ERROR 'Failure reason: 2022/09/01 16:37:51 Failed to connect to RCON serverdial tcp: lookup mc on 127.0.0.11:53: read udp 127.0.0.1:43190->127.0.0.11:53: read: connection refused '

...

Backup exits with command not found when file is changed while reading

image

The container exits with code 127 even though it says successful. Happens when backuping using tar method and has error in compression due to file changing while reading. And then goes to a line with next command which isn't found.

I'm not sure what "next" is supposed to do in this case? Should it instead be continue

The backup container is running with docker compose. Haven't changed anything within the container which had been working, but have added spigot plugins which seem to be causing the error. Any idea how to get around this?
Thank you

Instantly create backups by command at any time

Hello. First of all, thank you for an amazing product!

I want to create backups at the time I want to create a backup in addition to the periodical backups.
From what I have read in the backup script(backup-loop.sh), the following part appeared to be performing the backup function.

tar() {
_find_old_backups() {
find "${DEST_DIR}" -maxdepth 1 -name "*.${backup_extension}" -mtime "+${PRUNE_BACKUPS_DAYS}" "${@}"
}
init() {
mkdir -p "${DEST_DIR}"
case "${TAR_COMPRESS_METHOD}" in
gzip)
readonly tar_parameter="gzip"
readonly backup_extension="tgz"
;;
bzip2)
readonly tar_parameter="bzip2"
readonly backup_extension="bz2"
;;
*)
log ERROR 'TAR_COMPRESS_METHOD is not valid!'
exit 1
;;
esac
}
backup() {
ts=$(date -u +"%Y%m%d-%H%M%S")
outFile="${DEST_DIR}/${BACKUP_NAME}-${ts}.${backup_extension}"
log INFO "Backing up content in ${SRC_DIR} to ${outFile}"
command tar "${excludes[@]}" -c --${tar_parameter} -f "${outFile}" -C "${SRC_DIR}" .
if [ "${LINK_LATEST^^}" == "TRUE" ]; then
ln -sf "${BACKUP_NAME}-${ts}.${backup_extension}" "${DEST_DIR}/latest.${backup_extension}"
fi
}
prune() {
if [ -n "$(_find_old_backups -print -quit)" ]; then
log INFO "Pruning backup files older than ${PRUNE_BACKUPS_DAYS} days"
_find_old_backups -print -delete | awk '{ printf "Removing %s\n", $0 }' | log INFO
fi
}
call_if_function_exists "${@}"
}

Is it possible to separate the backup function for this part?
For example, I would like to run it from the command line like this.
docker exec -it mc-backup <backup script>.sh
I would appreciate it if you could consider it.
Please let me know if the feature already exists.
Thanks.

Restic prune log message is misleading

The log message says the following:

log INFO "Forgetting snapshots older than ${PRUNE_BACKUPS_DAYS} days"

But that environment variable isn't actually used when running restic forget if you've overridden PRUNE_RESTIC_RETENTION.

restic operations hang with Backblaze B2 backend

Yesterday, I noticed that no backup to B2 had taken place, and I wasn't seeing any output for the backups container in the logs.

After investigating further, I realized the container was stuck at running restic snapshots because the command was hanging indefinitely, with no output. Other commands like restic check hung, too.

I suspect this is a TLS-related issue (system certificates?) because of the following output when I connect to the B2 API using curl:

$ docker exec -i backups /bin/bash -i
bash: cannot set terminal process group (-1): Not a tty
bash: no job control in this shell
bash-5.1# curl -vvv https://api.backblazeb2.com
curl -vvv https://api.backblazeb2.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 206.190.215.15:443...
* Connected to api.backblazeb2.com (206.190.215.15) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [161 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [155 bytes data]
  0     0    0     0    0     0      0      0 --:--:--  0:03:23 --:--:--     0* OpenSSL SSL_connect: Connection reset by peer in connection to api.backblazeb2.com:443
  0     0    0     0    0     0      0      0 --:--:--  0:03:24 --:--:--     0
* Closing connection 0
curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection to api.backblazeb2.com:443

There isn't any custom network configuration for the container, and the request above goes through successfully outside of the container. Requests to other sites (e.g., https://google.com) go through fine within the container.

Best practice for storing data locally and offsite.

Currently my data is backed up on the server which the Minecraft server is running off, however I would like to be able to store data both locally and then off site. What would be the best practice for doing this?

As it stands I think there may be two options, but I would welcome your input on deciding which is the preferred on or whether or not they are both the same.

  1. Running two versions of the docker-mc-backup container. Both with restic but with one on a remote container, this does give the option of customizing the backup time. I may only back up remotely every 2 hours but keep a local backup every fifteen minutes. Then I can set the remote repository in my docker-compose.yml
  2. Writing my own script to back up the restic repo to the cloud.

I am leaning towards option one but can you see any issue with running two versions of the container. If they both tried to backup at the same time could that lead to some weird behavior? I suppose I could customise them with initial delay, having the local start up three minutes after the server starts and the second starting up after seven with then irregular intervals?

Could the project implement some kind of lock file? Or since that it only has the files mounted as read only it might be okay. My only worry would be sending the rcon command twice.

Readme.md contains confusing suggestions for rclone.conf

The Readme.md could use some improvement regarding rclone.conf file. The examples suggest using a file mount, however, rclone requires write access to the file and creates a new temporary file when making updates, so a directory mount seems to be necessary.

There are multiple references:

An example mount is given in the rclone backup method section:
- ./rclone.config:/config/rclone/rclone.conf:ro

This is mounting the file itself, however, rclone creates a new temporary file when it edits the rclone.conf file, so a folder mount seems to be necessary. Also, the source file is named rclone.config and this may be confusing.

Another reference exists in the Restic with rclone section:

volumes:
# mount volume pre-configured using a host mounted file
- ./rclone.conf:/config/rclone/rclone.conf

It will be helpful to also point out that the mount needs to be mounted rw.

Lastly, a Troubleshooting section that mentions "setting the environment variable DEBUG to true" may be useful for readers.

backup method "rsync"

It would be great to have a BACKUP_METHOD that simply makes a straight copy of the loose world files using i.e. rsync, without archiving or compressing them like tar. Further rolling or incremental backups could be made from that snapshot using any desired backup tool, or other tools could be run on it such as generating world maps, safe in the knowledge that the snapshot is internally consistent.

Container stops on `tar: file changed as we read it`

Currently, it appears, the container will stop if tar throws this warning.

2021-12-09T12:31:31+0100 INFO waiting for rcon readiness...
2021-12-09T12:31:31+0100 INFO Command executed successfully rcon-cli save-on
2021-12-09T12:31:31+0100 INFO Command executed successfully rcon-cli save-off
2021-12-09T12:31:37+0100 INFO Command executed successfully rcon-cli save-all flush
2021-12-09T12:31:38+0100 INFO Command executed successfully sync
2021-12-09T12:31:38+0100 INFO Backing up content in /data to /backups/world-20211209-123138.tgz
tar: ./world/region: file changed as we read it
tar: ./world: file changed as we read it
2021-12-09T12:32:51+0100 INFO Command executed successfully rcon-cli save-on

However, I think this should not be the case. It is very common for the minecraft server to write files in the world directory even if saving is disabled. You can easily verify this by turning saving off manually (using /save-off) and flying straight in one direction. The server will generate new .mca files in the region folder, as it can not possibly keep them all in memory. The container should therefore not stop if this warning is thrown. It should only stop if tar encounters a critical failure.

As described in the tar manual, the exit code of tar will be either 0, 1, or 2. In the case of the above warning, it will be 1. Exit code 2 indicates fatal failure.

image

I therefore believe, the script should check the exit code of tar and continue operation if it is 1 instead of stopping. I would open a PR for this, but my bash scripting skills are not on the level where I would trust my solution ;)

Thanks, Stone

Unhandled restic repository state

I'm getting these errors that are blocking backups from happening; something to do with a stale lock not getting cleaned up?

backups    | 2021-12-31T17:47:58+0000 ERROR unable to create lock in backend: repository is already locked exclusively by PID 29 on backups by root (UID 0, GID 0)
backups    | 2021-12-31T17:47:58+0000 ERROR lock was created at 2021-12-17 22:29:45 (331h18m12.754164122s ago)
backups    | 2021-12-31T17:47:58+0000 ERROR storage ID dda39961
backups    | 2021-12-31T17:47:58+0000 ERROR the `unlock` command can be used to remove stale locks
backups    | 2021-12-31T17:47:58+0000 INTERNALERROR Unhandled restic repository state.
backups    | 2021-12-31T17:47:58+0000 INTERNALERROR Please report this: https://github.com/itzg/docker-mc-backup/issues
backups exited with code 2

Support for RCON password from a file

Does this container support reading the RCON password from a file like the minecraft server container does? I'm using Docker Swarm which represents secrets as files.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.