Getting started - classic way

Requirements

  • PHP 8

  • PHP-FPM

  • Reverse Proxy (NGINX, Apache 2 or other. We recommend NGINX)

  • PostgreSQL 11+

  • One of storages: Google Cloud Storage, AWS S3, Min.io. If you don’t want to use any of them, don’t worry - you can still use a local disk storage provider

Notice: Application handles file uploads - it may be problematic to use a shared webhosting, AWS lambdas, Google Cloud Applications and other services that have hard limits on request size and duration

Manual installation

1. Configure reverse proxy (NGINX, Apache 2 or other)

Use following configuration snippet as a reference.

Notices:

  • Application cannot be installed in a subdirectory, must be at root path of a domain (“/”) ex. https://backups.example.org/

  • ^/api/stable/repository/collection/([A-Za-z0-9-]+)/versions$ endpoint should be allowed to take long and big requests, it is a path where files are uploaded

  • If you have multiple layers of reverse proxy you may want to adjust proxy_read_timeout, proxy_send_timeout and consider turning off proxy_buffering and proxy_request_buffering

user www-data;
daemon off;
worker_processes 4;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    # multi_accept on;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    types_hash_max_size 4096;
    client_max_body_size 200000M;
    server_tokens off;
    max_ranges 1;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    fastcgi_temp_file_write_size 20m;
    fastcgi_busy_buffers_size 786k;
    fastcgi_buffer_size 512k;
    fastcgi_buffers 16 512k;
    proxy_request_buffering on;

    client_header_timeout 900s;
    client_body_timeout 7200s;
    keepalive_timeout 120s;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    gzip off;
    gzip_disable "msie6";

    server {
        listen 80 default_server;
        server_name _;

        root /var/www/public;
        index index.html index.php;


        location / {
            try_files $uri /index.php$is_args$args;
        }

        # turn off requests buffering for backup collections
        location ~ ^/api/stable/repository/collection/([A-Za-z0-9\-]+)/versions$ {
            fastcgi_request_buffering off;
            try_files $uri /index.php$is_args$args;
        }

        location ~ ^/index\.php(/|$) {
            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
            fastcgi_param  SERVER_SOFTWARE    RiotKit-Docker-Container;
            fastcgi_param  QUERY_STRING       $query_string;
            fastcgi_param  REQUEST_METHOD     $request_method;
            fastcgi_param  CONTENT_TYPE       $content_type;
            fastcgi_param  CONTENT_LENGTH     $content_length;
            fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
            fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
            fastcgi_param  REQUEST_URI        $request_uri;
            fastcgi_param  DOCUMENT_URI       $document_uri;
            fastcgi_param  DOCUMENT_ROOT      $document_root;
            fastcgi_param  SERVER_PROTOCOL    $server_protocol;
            fastcgi_param  REMOTE_ADDR        $remote_addr;
            fastcgi_param  REMOTE_PORT        $remote_port;
            fastcgi_param  SERVER_ADDR        $server_addr;
            fastcgi_param  SERVER_PORT        $server_port;
            fastcgi_param  SERVER_NAME        $server_name;

            fastcgi_param  X_REAL_IP          $http_x_real_ip;
            fastcgi_param  X_FORWARDED_FOR    $proxy_add_x_forwarded_for;

            fastcgi_split_path_info ^(.+\.php)(/.+)$;

            try_files $fastcgi_script_name =404;
            set $path_info $fastcgi_path_info;
            fastcgi_param PATH_INFO $path_info;
            fastcgi_index index.php;

            # Allow requests to take long, big backups takes long to generate and send
            fastcgi_read_timeout 7200s;
            fastcgi_send_timeout 7200s;

            fastcgi_pass localhost:9000;
        }

        location ~ /\.ht {
            deny all;
        }
    }
}

2. Create a user and a database in PostgreSQL

Best practice is to have a separate user for each application, we recommend you to create a separate user with non-trivial password.

# optionally jump into a postgres user
su postgres

# you may be asked for a password (it depends on how is your access configured in pg_hba.conf)
psql

Hints:

  • Use a difficult, long, generated database password for security. You don’t have to remember that password, it will be in a configuration file

  • Use a non-standard username and database name, so the potential attacker could even not guess that

CREATE USER backup_repository WITH PASSWORD 'psssst_put_your_secret_there';
CREATE DATABASE backup_repository_db;
GRANT ALL PRIVILEGES ON DATABASE backup_repository_db TO backup_repository;

Now think about how the application should be connecting to database - using TCP/IP or Unix socket, you may want to check of the pg_hba.conf documentation at https://www.postgresql.org/docs/current/auth-pg-hba-conf.html

3. Unpack Backup Repository server to target directory ex. /var/www - download a fresh distribution from releases tab on Github

4. Configure application

cd /var/www

# create configuration from template
cp .env.dist .env

edit .env

# 1) Put your database credentials in line: DATABASE_URL=postgres://chomsky:chomsky@127.0.0.1:5432/chomsky
# 2) Generate a random string and replace passphrase in line: JWT_PASSPHRASE=fc0774955def1f2e92e6bdcad18a9f97
# 3) Change a health check code in line: HEALTH_CHECK_CODE=test

# Configure a storage adapter
# 1) Pick AWS, GC (Google Cloud) or LOCAL configuration
# 2) Modify selected configuration to your needs
# 3) Put configuration name in FS_RW_NAME and in FS_RO_NAME

5. Generate JWT keys

Generate private keys, replace “$JWT_PASSPHRASE” with a passphrase you have in env file. Keep the files in secret.

openssl genpkey -out config/jwt/private.pem -aes256 -pass pass:$JWT_PASSPHRASE -algorithm rsa -pkeyopt rsa_keygen_bits:4096
openssl pkey -in config/jwt/private.pem -out config/jwt/public.pem -pubout -passin pass:$JWT_PASSPHRASE

6. Install dependencies

cd /var/www
composer install

7. Create an administrator account

cd /var/www
./bin/console auth:create-admin-account --email example@riseup.net --password example_1234

8. DONE! Navigate to http://localhost and login using your created administrator account