peertube data in s3 storage
This commit is contained in:
parent
48084fa688
commit
af6e76134a
|
@ -66,15 +66,21 @@ You can then access the apps on your local machine (using the magic of port forw
|
||||||
- [ ] get garage replication running (multiple machines)
|
- [ ] get garage replication running (multiple machines)
|
||||||
- [ ] some way of declaratively defining users?
|
- [ ] some way of declaratively defining users?
|
||||||
- [ ] shared users between fediverse services
|
- [ ] shared users between fediverse services
|
||||||
|
- [ ] s3 cache server (SEE: https://docs.joinpeertube.org/maintain/remote-storage)
|
||||||
|
- [ ] is "s3" the right term, given that it's not an open protocol?
|
||||||
|
|
||||||
# questions
|
# questions
|
||||||
|
|
||||||
- what is meant to be shared between instances?
|
- what is meant to be shared between instances?
|
||||||
- this is relevant to the security model. If garage is being shared between instances, we have to be careful having configurations depend on each other.
|
- this is relevant to the security model. If garage is being shared between instances, we have to be careful having configurations depend on each other.
|
||||||
|
|
||||||
|
- we want to be able to migrate user's data. s3 migration is not supported by peertube. what do? (SEE: https://docs.joinpeertube.org/maintain/remote-storage)
|
||||||
|
|
||||||
# resources
|
# resources
|
||||||
|
|
||||||
- Tutorial for setting up better logging: https://krisztianfekete.org/self-hosting-mastodon-on-nixos-a-proof-of-concept/
|
- Tutorial for setting up better logging: https://krisztianfekete.org/self-hosting-mastodon-on-nixos-a-proof-of-concept/
|
||||||
- Setting up development environment: https://docs.joinmastodon.org/dev/setup/
|
- Setting up development environment: https://docs.joinmastodon.org/dev/setup/
|
||||||
|
|
||||||
- Tutorial for PeerTube that doesn't use `createLocally`: https://nixos.wiki/wiki/PeerTube
|
- Tutorial for PeerTube that doesn't use `createLocally`: https://nixos.wiki/wiki/PeerTube
|
||||||
|
|
||||||
|
- garage settings for specific apps: https://garagehq.deuxfleurs.fr/documentation/connect/apps/
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
peertube = nixpkgs.lib.nixosSystem {
|
peertube = nixpkgs.lib.nixosSystem {
|
||||||
inherit system;
|
inherit system;
|
||||||
modules = [ ./common.nix ./peertube.nix ];
|
modules = [ ./common.nix ./peertube.nix ./garage.nix ];
|
||||||
};
|
};
|
||||||
|
|
||||||
pixelfed = nixpkgs.lib.nixosSystem {
|
pixelfed = nixpkgs.lib.nixosSystem {
|
||||||
|
|
55
garage.nix
55
garage.nix
|
@ -2,8 +2,8 @@ let
|
||||||
# generate one using openssl (somehow)
|
# generate one using openssl (somehow)
|
||||||
# XXX: when importing, garage tells you importing is only meant for keys previously generated by garage. is it okay to generate them using openssl?
|
# XXX: when importing, garage tells you importing is only meant for keys previously generated by garage. is it okay to generate them using openssl?
|
||||||
snakeoil_key = {
|
snakeoil_key = {
|
||||||
id = "GK3515373e4c851ebaad366558";
|
id = "GK22a15201acacbd51cd43e327";
|
||||||
secret = "7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34";
|
secret = "82b2b4cbef27bf8917b350d5b10a87c92fa9c8b13a415aeeea49726cf335d74e";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
# TODO: expand to a multi-machine setup
|
# TODO: expand to a multi-machine setup
|
||||||
|
@ -11,7 +11,7 @@ in
|
||||||
# add in options to ensure creation of buckets and keys
|
# add in options to ensure creation of buckets and keys
|
||||||
options =
|
options =
|
||||||
let
|
let
|
||||||
inherit (lib) types mkOption;
|
inherit (lib) types mkOption mkEnableOption;
|
||||||
in {
|
in {
|
||||||
services.garage = {
|
services.garage = {
|
||||||
ensureBuckets = mkOption {
|
ensureBuckets = mkOption {
|
||||||
|
@ -21,11 +21,31 @@ in
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
};
|
};
|
||||||
|
corsRules = {
|
||||||
|
enable = mkEnableOption "CORS Rules";
|
||||||
|
allowedHeaders = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
allowedMethods = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
allowedOrigins = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
aliases = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
ensureKeys = mkOption {
|
ensureKeys = mkOption {
|
||||||
type = types.attrsOf (types.submodule {
|
type = types.attrsOf (types.submodule {
|
||||||
|
# TODO: these should be managed as secrets, not in the nix store
|
||||||
options = {
|
options = {
|
||||||
id = mkOption {
|
id = mkOption {
|
||||||
type = types.string;
|
type = types.string;
|
||||||
|
@ -75,7 +95,7 @@ in
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
environment.systemPackages = [ pkgs.minio-client ];
|
environment.systemPackages = [ pkgs.minio-client pkgs.awscli ];
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 3901 3902 ];
|
networking.firewall.allowedTCPPorts = [ 3901 3902 ];
|
||||||
services.garage = {
|
services.garage = {
|
||||||
|
@ -100,7 +120,7 @@ in
|
||||||
systemd.services.ensure-garage = {
|
systemd.services.ensure-garage = {
|
||||||
after = [ "garage.service" ];
|
after = [ "garage.service" ];
|
||||||
wantedBy = [ "garage.service" ];
|
wantedBy = [ "garage.service" ];
|
||||||
path = [ config.services.garage.package pkgs.perl ];
|
path = [ config.services.garage.package pkgs.perl pkgs.awscli ];
|
||||||
script = ''
|
script = ''
|
||||||
set -xeuo pipefail
|
set -xeuo pipefail
|
||||||
# give garage time to start up
|
# give garage time to start up
|
||||||
|
@ -114,13 +134,36 @@ in
|
||||||
LAYOUT_VER=$(garage layout show | perl -ne '/Current cluster layout version: (\d*)/ && print $1')
|
LAYOUT_VER=$(garage layout show | perl -ne '/Current cluster layout version: (\d*)/ && print $1')
|
||||||
garage layout apply --version $((LAYOUT_VER + 1))
|
garage layout apply --version $((LAYOUT_VER + 1))
|
||||||
|
|
||||||
|
# XXX: this is a hack because we want to write to the buckets here but we're not guaranteed any access keys
|
||||||
|
garage key import --yes -n tmp ${snakeoil_key.id} ${snakeoil_key.secret}
|
||||||
|
export AWS_ACCESS_KEY_ID=${snakeoil_key.id};
|
||||||
|
export AWS_SECRET_ACCESS_KEY=${snakeoil_key.secret};
|
||||||
|
|
||||||
${
|
${
|
||||||
lib.concatStringsSep "\n" (lib.mapAttrsToList (bucket: { website }: ''
|
lib.concatStringsSep "\n" (lib.mapAttrsToList (bucket: { website, aliases, corsRules }: ''
|
||||||
garage bucket create ${bucket}
|
garage bucket create ${bucket}
|
||||||
# XXX: should this --deny the website if `website` is false?
|
# XXX: should this --deny the website if `website` is false?
|
||||||
${lib.optionalString website ''
|
${lib.optionalString website ''
|
||||||
garage bucket website --allow ${bucket}
|
garage bucket website --allow ${bucket}
|
||||||
''}
|
''}
|
||||||
|
${lib.concatStringsSep "\n" (map (alias: ''
|
||||||
|
garage bucket alias ${bucket} ${alias}
|
||||||
|
'') aliases)}
|
||||||
|
|
||||||
|
${lib.optionalString corsRules.enable ''
|
||||||
|
export CORS=${lib.concatStrings [
|
||||||
|
"'"
|
||||||
|
''{"CORSRules":[{''
|
||||||
|
''"AllowedHeaders":${builtins.toJSON corsRules.allowedHeaders},''
|
||||||
|
''"AllowedMethods":${builtins.toJSON corsRules.allowedMethods},''
|
||||||
|
''"AllowedOrigins":${builtins.toJSON corsRules.allowedOrigins}''
|
||||||
|
''}]}''
|
||||||
|
"'"
|
||||||
|
]}
|
||||||
|
garage bucket allow --read --write --owner ${bucket} --key tmp
|
||||||
|
aws --endpoint http://s3.garage.localhost:3900 s3api put-bucket-cors --bucket ${bucket} --cors-configuration $CORS
|
||||||
|
garage bucket deny --read --write --owner ${bucket} --key tmp
|
||||||
|
''}
|
||||||
'') config.services.garage.ensureBuckets)
|
'') config.services.garage.ensureBuckets)
|
||||||
}
|
}
|
||||||
${
|
${
|
||||||
|
|
80
peertube.nix
80
peertube.nix
|
@ -1,6 +1,86 @@
|
||||||
|
let
|
||||||
|
snakeoil_key = {
|
||||||
|
id = "GK1f9feea9960f6f95ff404c9b";
|
||||||
|
secret = "7295c4201966a02c2c3d25b5cea4a5ff782966a2415e3a196f91924631191395";
|
||||||
|
};
|
||||||
|
in
|
||||||
{ config, lib, pkgs, ... }: {
|
{ config, lib, pkgs, ... }: {
|
||||||
networking.firewall.allowedTCPPorts = [ 80 9000 ];
|
networking.firewall.allowedTCPPorts = [ 80 9000 ];
|
||||||
|
|
||||||
|
services.garage = {
|
||||||
|
ensureBuckets = {
|
||||||
|
peertube-videos = {
|
||||||
|
website = true;
|
||||||
|
corsRules = {
|
||||||
|
enable = true;
|
||||||
|
allowedHeaders = [ "*" ];
|
||||||
|
allowedMethods = [ "GET" ];
|
||||||
|
allowedOrigins = [ "*" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
peertube-playlists = {
|
||||||
|
website = true;
|
||||||
|
corsRules = {
|
||||||
|
enable = true;
|
||||||
|
allowedHeaders = [ "*" ];
|
||||||
|
allowedMethods = [ "GET" ];
|
||||||
|
allowedOrigins = [ "*" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
ensureKeys = {
|
||||||
|
peertube = {
|
||||||
|
inherit (snakeoil_key) id secret;
|
||||||
|
ensureAccess = {
|
||||||
|
peertube-videos = {
|
||||||
|
read = true;
|
||||||
|
write = true;
|
||||||
|
owner = true;
|
||||||
|
};
|
||||||
|
peertube-playlists = {
|
||||||
|
read = true;
|
||||||
|
write = true;
|
||||||
|
owner = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.peertube = {
|
||||||
|
settings = {
|
||||||
|
object_storage = {
|
||||||
|
enabled = true;
|
||||||
|
endpoint = "http://s3.garage.localhost:3900";
|
||||||
|
region = "garage";
|
||||||
|
|
||||||
|
# not supported by garage
|
||||||
|
# SEE: https://garagehq.deuxfleurs.fr/documentation/connect/apps/#peertube
|
||||||
|
proxy.proxyify_private_files = false;
|
||||||
|
|
||||||
|
web_videos = {
|
||||||
|
bucket_name = "peertube-videos";
|
||||||
|
prefix = "";
|
||||||
|
base_url = "http://peertube-videos.web.garage.localhost:3902";
|
||||||
|
};
|
||||||
|
videos = {
|
||||||
|
bucket_name = "peertube-videos";
|
||||||
|
prefix = "";
|
||||||
|
base_url = "http://peertube-videos.web.garage.localhost:3902";
|
||||||
|
};
|
||||||
|
streaming_playlists = {
|
||||||
|
bucket_name = "peertube-playlists";
|
||||||
|
prefix = "";
|
||||||
|
base_url = "http://peertube-playlists.web.garage.localhost:3902";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
serviceEnvironmentFile = "/etc/peertube-env";
|
||||||
|
};
|
||||||
|
environment.etc.peertube-env.text = ''
|
||||||
|
AWS_ACCESS_KEY_ID=${snakeoil_key.id}
|
||||||
|
AWS_SECRET_ACCESS_KEY=${snakeoil_key.secret}
|
||||||
|
'';
|
||||||
# these configurations only apply when producing a VM (e.g. nixos-rebuild build-vm)
|
# these configurations only apply when producing a VM (e.g. nixos-rebuild build-vm)
|
||||||
virtualisation.vmVariant = { config, ... }: {
|
virtualisation.vmVariant = { config, ... }: {
|
||||||
services.peertube = {
|
services.peertube = {
|
||||||
|
|
Reference in a new issue