Great Blog

01 Mar 2021

Full system backup with restic and minio

Minio

Install

mkdir /opt/minio
cd /opt/minio
wget https://dl.min.io/server/minio/release/darwin-amd64/minio
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc minio
echo 'PATH="${PATH}:/opt/minio"' >> /root/.bashrc
useradd minio
mkdir -p /data/minio
chown minio: -R /opt/minio /data/minio

Configure Systemd service

nano /etc/systemd/system/minio.service

Paste the following in the above file

# https://github.com/minio/minio-service/tree/master/linux-systemd

[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/opt/minio/minio

[Service]
WorkingDirectory=/opt/minio

User=minio
Group=minio

EnvironmentFile=/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"

ExecStart=/opt/minio/minio server $MINIO_OPTS $MINIO_VOLUMES

# Let systemd restart this service always
Restart=always

# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65536

# Specifies the maximum number of threads this process can create
TasksMax=infinity

# Disable timeout logic and wait until process is stopped
TimeoutStopSec=infinity
SendSIGKILL=no

[Install]
WantedBy=multi-user.target

# Built for ${project.name}-${project.version} (${project.name})

nano /etc/default/minio

Paste the following in the above file. Make sure to change RANDOM_ROOT_USERNAME and RANDOM_ROOT_PASSWORD, and change MINIO_VOLUMES to where you’d like the data to be stored.

# Volume to be used for MinIO server.
MINIO_VOLUMES="/data/minio"
# Use if you want to run MinIO on a custom port.
MINIO_OPTS="--address :9199"
# Root user for the server.
MINIO_ROOT_USER='RANDOM_ROOT_USERNAME'
# Root secret for the server.
MINIO_ROOT_PASSWORD='RANDOM_ROOT_PASSWORD'

systemctl daemon-reload

systemctl enable minio --now

Minio is now started


Configure Minio

configure minio-client

We will configure mc to connect to the minio server

mc config host add minio http://localhost:9199 RANDOM_ROOT_USERNAME 'RANDOM_ROOT_PASSWORD'

Create User

mc admin user add minio RANDOM_RESTIC_USERNAME 'RANDOM_RESTIC_PASSWORD'

Create bucket via WebUI

  1. Log in to the WebUI by going to http://IP_OF_SERVER:9199 and use your RANDOM_ROOT_USERNAME and RANDOM_ROOT_PASSWORD.

  2. Go to the lower right hand corner where the plus sign is and click it.

  3. Click the middle icon (looks like a bucket, if you hover over it, it will say “Create Bucket”

  4. Input what you’d like your bucket name to be. For this tut I’m using BUCKETNAME.

  5. The bucket is now created.

Grant user access to bucket

We will be creating the json file with permissions

mkdir /opt/minio/json
cd /opt/minio/json
nano server-domain-com-rw.json

Below is the json file with the permissions. Can be pasted into the file above

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::BUCKETNAME"
    },
    {
  "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::BUCKETNAME/server-domain-com/*"
    }
  ]
}

Now we will import the json policy to make it a policy in minio

mc admin policy add minio server-domain-com-rw server-domain-com.json

Now we assign the policy to the user created before.

mc admin policy set minio server-domain-com-rw user=RANDOM_RESTIC_USERNAME

Minio should now be up and working. You should be able to access your S3 dashboard now by http://IP_OF_SERVER:9199 and you should be able to log in with RANDOM_RESTIC_USERNAME and RANDOM_ROOT_USERNAME credentials from above.


Configure NGiNX reverse proxy

config files

You will have to get the SSL certs installed at /etc/nginx/ssl/minio.domain.com/fullchain.crt and /etc/nginx/ssl/minio.domain.com/key. I have in instructions HERE

nano /etc/nginx/conf.d/minio.domain.com.conf

server {
  listen 443 ssl http2;
  server_name minio.domain.com;

  ssl_certificate /etc/nginx/ssl/minio.domain.com/fullchain.crt;
  ssl_certificate_key /etc/nginx/ssl/minio.domain.com/key;

  access_log /var/log/nginx/minio.domain.com_access.log;

  # To allow special characters in headers
  ignore_invalid_headers off;
  # Allow any size file to be uploaded.
  # Set to a value such as 1000m; to restrict file size to a specific value
  client_max_body_size 0;
  # To disable buffering
  proxy_buffering off;

  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;

    proxy_connect_timeout 300;
    # Default is HTTP/1, keepalive is only enabled in HTTP/1.1
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    chunked_transfer_encoding off;

    proxy_pass http://minio_backend; # If you are using docker-compose this would be the hostname i.e. minio
    # Health Check endpoint might go here. See https://www.nginx.com/resources/wiki/modules/healthcheck/
    # /minio/health/live;
  }
}

nano /etc/nginx/conf.d/upstream.conf

upstream minio_backend {
  server 192.168.9.171:9199;
}

Check nginx config and make sure there’s no errors

nginx -t

Now reload nginx

nginx -s reload

NGiNX should no be working and listening on :443 at minio.domain.com


To install rustic it’s very easy. apt install rustic

Configure Rustic

We will export the required variables. This make it easier to run the restic commands. Make sure now to exit the shell while running the commands since the env variable need to be there for it to work

export AWS_ACCESS_KEY_ID='RANDOM_RESTIC_USERNAME'
export AWS_SECRET_ACCESS_KEY='RANDOM_RESTIC_PASSWORD'
export RESTIC_PASSWORD='PASSWORD_TO_SECURE_REPO_ENCRYPTION'
export RESTIC_REPOSITORY='s3:https://minio.domain.com/BUCKETNAME/server-domain-com/restic

Now we will create the repo with the following

restic init

Now we will backup the server to the repo

restic --exclude={/dev,/media,/mnt,/proc,/run,/sys,/tmp,/var/tmp,/var/lib/mysql} backup /

This might take a while. Now your server will be backed up once completed. Also remember if you’re backing up a mysql server you’ll want to dump the mysql databases somewhere since this script doesn’t backup the /var/lib/mysql to make sure the DB doesn’t get corrupted.

If you’d like to prune (cleanup) old files the below is what I recommend

restic forget --prune --keep-daily 5 --keep-weekly 15 --keep-monthly 15

Now whenever you’d like to run a backup all you have to do it export the variables above and run the backup command.

If you’d like to view snapshots it’s as easy as the following

restic snapshots