Jump to content

Vernissage: Difference between revisions

From Official NixOS Wiki
Cameo007 (talk | contribs)
m Added links and clearer expressions
Cameo007 (talk | contribs)
 
(3 intermediate revisions by the same user not shown)
Line 12: Line 12:
   };
   };
   web.enable = true;
   web.enable = true;
}
};
</syntaxhighlight>
</syntaxhighlight>


Line 33: Line 33:
     KEY-SECRET
     KEY-SECRET
   '';
   '';
}
};
</syntaxhighlight>
</syntaxhighlight>


Line 116: Line 116:


# Follow the upstream [https://garagehq.deuxfleurs.fr/documentation/quick-start/#creating-a-cluster-layout Quick Start guide] to setup your node(s), the S3 bucket and a keypair.
# Follow the upstream [https://garagehq.deuxfleurs.fr/documentation/quick-start/#creating-a-cluster-layout Quick Start guide] to setup your node(s), the S3 bucket and a keypair.
# Enable exposition as a website with <code>sudo garage -c /etc/garage.toml bucket website --allow vernissage</code>
# Enable exposition as a website with <code>garage bucket website --allow vernissage</code>
# Optionally set a bucket quota through <code>sudo garage -c /etc/garage.toml bucket set-quotas --max-size 25G vernissage</code>
# Optionally set a bucket quota through <code>garage bucket set-quotas --max-size 25GiB vernissage</code>


==== Reverse proxy configuration (until anonymous HTTP access is possible) ====
==== Reverse proxy configuration (until anonymous HTTP access is possible) ====
Until support for anonymous HTTP access is there ([https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/1306 upstream PR]) you need configure your reverse proxy to redirect unauthenticated file requests to [[Garage]]’s web backend.<syntaxhighlight lang="nix">
Until support for anonymous HTTP access is there ([https://git.deuxfleurs.fr/Deuxfleurs/garage/pulls/1306 upstream PR]) you need configure your reverse proxy to redirect unauthenticated file requests to [[Garage]]’s web backend.<syntaxhighlight lang="nix">
services.nginx.virtualHosts."s3.garage.example.com".locations."~ \/vernissage\/(.*\.jpg)" = {
services.nginx.appendHttpConfig = lib.mkAfter ''
proxyPass = "http://127.0.0.1:3902/$1";
  map "$http_content_type:$http_accept" $vernissage_machine {
    default "127.0.0.1:4200";
    ~*json  "127.0.0.1:8080";
  }
  # Choose the right endpoint for Garage
  map $request_method $garage_endpoint {
    default "127.0.0.1:3900$request_uri";
    GET    "127.0.0.1:3902/$key$is_args$args";
    HEAD    "127.0.0.1:3902/$key$is_args$args";
  }
'';
 
locations."~ ^/vernissage/(?<key>.+\\.jpg)$" = {
  recommendedProxySettings = false;
  proxyPass = "http://$garage_endpoint";
   extraConfig = ''
   extraConfig = ''
     proxy_set_header Host "vernissage.web.garage.example.com"
     set $host_header $http_host;
    if ($request_method ~ ^(GET|HEAD)$ ) {
      set $host_header "vernissage.web.garage.example.com";
    }
    proxy_set_header Host $host_header;
 
    # Disable buffering to a temporary file.
    proxy_max_temp_file_size 0;
 
    # Set remaining recommended proxy settings
    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 X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $hostname;
   '';
   '';
};
};
</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 10:30, 13 October 2026

Vernissage is an application that enables users to share their photographs with others.

⚠︎
Warning: The packages and the module to run Vernissage are not merged yet. See https://github.com/NixOS/nixpkgs/pull/568316

Setup

The following configuration provides a minimal example to configure VernissageServer and VernissageWeb, with the default SQLite database, without Redis or S3 object store. The necessary configuration options for VernissageWeb are automatically derived from the base address, set on the API.

services.vernissage = {
  api = {
    enable = true;
    settings.baseAddress = "https://vernissage.example.com";
  };
  web.enable = true;
};

Configuration

Check the upstream example on how to configure the API server.

Here is an example, including secret configuration. As you can see, secrets are specified via a _secret sub-option.

services.vernissage.api.settings = {
  baseAddress = "https://vernissage.example.com";
  connectionString._secret = pkgs.writeText "vernissage-conn-string" ''
    postgres://vernissage:PASSWORD@127.0.0.1:5432/vernissage
  '';
  queueUrl = "redis://127.0.0.1:6379";
  s3Address = "https://s3.garage.example.com";
  s3Bucket = "vernissage";
  s3AccessKeyId._secret = pkgs.writeText "vernissage-s3-id" ''
    KEY-ID
  '';
  s3SecretAccessKey._secret = pkgs.writeText "vernissage-s3-secret" ''
    KEY-SECRET
  '';
};

WebPush

services.vernissage.push = {
  enable = true;
  vpushKeyFile = pkgs.writeText "vernissage-push-key" ''
    9c52bba3682020aa21b8562dc4f1975370284e95e92f4d7d21bd0473214fdf03
  '';
};

Then in the Vernissage settings (web frontend), enable WebPush and enter the following values:

  • Service endpoint: http://127.0.0.1:3000
  • Service secret key: the key you specified in your config (e.g. 9c52bba3682020aa21b8562dc4f1975370284e95e92f4d7d21bd0473214fdf03)
  • Vapid subject: mailto:postmaster@example.com

The Vapid public and private key have to be generated.

openssl ecparam -name prime256v1 -genkey -noout -out vapid_private.pem

# Vapid private key
sed '1d;5d' vapid_private.pem | tr --delete '\n' | tr '+' '-' | tr '/' '_'

# Vapid public key
openssl ec -in vapid_private.pem -pubout | sed '1d;4d' | tr --delete '\n' | tr '+' '-' | tr '/' '_'

Reverse Proxy (nginx)

The nginx configuration is adapted from VernissageProxy, which is is a preconfigured nginx server the upstream project provides as a Docker container.

services.nginx = {
  enable = true;

  appendHttpConfig = ''
    map "$http_content_type:$http_accept" $vernissage_machine {
      default "127.0.0.1:${config.services.vernissage.web.port}";
      ~*json  "127.0.0.1:${config.services.vernissage.api.port}";
    }
  '';

  virtualHosts."vernissage.example.com" = {
    locations."~ \/(api\/v1|storage|.well-known|rss|atom)\/".proxyPass = "http://127.0.0.1:${config.services.vernissage.api.port}";
    locations."/".proxyPass = "http://$vernissage_machine";

    extraConfig = ''
      client_max_body_size 10M;
    '';
  };

S3 Object Store

The project suggests to use Minio but since it has been abandoned, Garage is a nearly perfect replacement.

Configuration

services.garage = {
  enable = true;
  package = pkgs.garage_2;
  settings = {
    replication_factor = 1;
    rpc_bind_addr = "[::]:3901";
    rpc_secret = "687335124ab1c88816cb5fd7e8d77ffe164c04e6bba8ea9d6d8301a92cf96c01";
    s3_api = {
      api_bind_addr = "[::]:3900";
      s3_region = "us-east-1";
      root_domain = ".s3.garage.example.com";
    };
      s3_web = {
        bind_addr = "[::]:3902";
        root_domain = ".web.garage.example.com";
      };
      admin = {
        api_bind_addr = "[::]:3903";
        admin_token = "DDZcCyhTSJGKGN4ukojesKL9aO7zVxQFsWG8FpFW6fw=";
        # Effectively disables metrics because no metrics token is specified (besides the admin token)
        metrics_require_token = true;
      };
    };
  };

Setup

  1. Follow the upstream Quick Start guide to setup your node(s), the S3 bucket and a keypair.
  2. Enable exposition as a website with garage bucket website --allow vernissage
  3. Optionally set a bucket quota through garage bucket set-quotas --max-size 25GiB vernissage

Reverse proxy configuration (until anonymous HTTP access is possible)

Until support for anonymous HTTP access is there (upstream PR) you need configure your reverse proxy to redirect unauthenticated file requests to Garage’s web backend.

services.nginx.appendHttpConfig = lib.mkAfter ''
  map "$http_content_type:$http_accept" $vernissage_machine {
    default "127.0.0.1:4200";
    ~*json  "127.0.0.1:8080";
  }
  # Choose the right endpoint for Garage
  map $request_method $garage_endpoint {
    default "127.0.0.1:3900$request_uri";
    GET     "127.0.0.1:3902/$key$is_args$args";
    HEAD    "127.0.0.1:3902/$key$is_args$args";
  }
'';

locations."~ ^/vernissage/(?<key>.+\\.jpg)$" = {
  recommendedProxySettings = false;
  proxyPass = "http://$garage_endpoint";
  extraConfig = ''
    set $host_header $http_host;
    if ($request_method ~ ^(GET|HEAD)$ ) {
      set $host_header "vernissage.web.garage.example.com";
    }
    proxy_set_header Host $host_header;

    # Disable buffering to a temporary file.
    proxy_max_temp_file_size 0;

    # Set remaining recommended proxy settings
    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 X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $hostname;
  '';
};