peertube data in s3 storage
This commit is contained in:
		
							parent
							
								
									48084fa688
								
							
						
					
					
						commit
						af6e76134a
					
				
					 4 changed files with 136 additions and 7 deletions
				
			
		|  | @ -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) | ||||
| - [ ] some way of declaratively defining users? | ||||
| - [ ] 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 | ||||
| 
 | ||||
| - 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. | ||||
| 
 | ||||
| - 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 | ||||
| 
 | ||||
| - 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/ | ||||
| 
 | ||||
| - 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 { | ||||
|         inherit system; | ||||
|         modules = [ ./common.nix ./peertube.nix ]; | ||||
|         modules = [ ./common.nix ./peertube.nix ./garage.nix ]; | ||||
|       }; | ||||
| 
 | ||||
|       pixelfed = nixpkgs.lib.nixosSystem { | ||||
|  |  | |||
							
								
								
									
										55
									
								
								garage.nix
									
										
									
									
									
								
							
							
						
						
									
										55
									
								
								garage.nix
									
										
									
									
									
								
							|  | @ -2,8 +2,8 @@ let | |||
|   # 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? | ||||
|   snakeoil_key = { | ||||
|     id = "GK3515373e4c851ebaad366558"; | ||||
|     secret = "7d37d093435a41f2aab8f13c19ba067d9776c90215f56614adad6ece597dbb34"; | ||||
|     id = "GK22a15201acacbd51cd43e327"; | ||||
|     secret = "82b2b4cbef27bf8917b350d5b10a87c92fa9c8b13a415aeeea49726cf335d74e"; | ||||
|   }; | ||||
| in | ||||
| # TODO: expand to a multi-machine setup | ||||
|  | @ -11,7 +11,7 @@ in | |||
|   # add in options to ensure creation of buckets and keys | ||||
|   options = | ||||
|   let | ||||
|     inherit (lib) types mkOption; | ||||
|     inherit (lib) types mkOption mkEnableOption; | ||||
|   in { | ||||
|     services.garage = { | ||||
|       ensureBuckets = mkOption { | ||||
|  | @ -21,11 +21,31 @@ in | |||
|               type = types.bool; | ||||
|               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 { | ||||
|         type = types.attrsOf (types.submodule { | ||||
|           # TODO: these should be managed as secrets, not in the nix store | ||||
|           options = { | ||||
|             id = mkOption { | ||||
|               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 ]; | ||||
|     services.garage = { | ||||
|  | @ -100,7 +120,7 @@ in | |||
|     systemd.services.ensure-garage = { | ||||
|       after = [ "garage.service" ]; | ||||
|       wantedBy = [ "garage.service" ]; | ||||
|       path = [ config.services.garage.package pkgs.perl ]; | ||||
|       path = [ config.services.garage.package pkgs.perl pkgs.awscli ]; | ||||
|       script = '' | ||||
|         set -xeuo pipefail | ||||
|         # 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') | ||||
|         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} | ||||
|             # XXX: should this --deny the website if `website` is false? | ||||
|             ${lib.optionalString website '' | ||||
|               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) | ||||
|         } | ||||
|         ${ | ||||
|  |  | |||
							
								
								
									
										80
									
								
								peertube.nix
									
										
									
									
									
								
							
							
						
						
									
										80
									
								
								peertube.nix
									
										
									
									
									
								
							|  | @ -1,6 +1,86 @@ | |||
| let | ||||
|   snakeoil_key = { | ||||
|     id = "GK1f9feea9960f6f95ff404c9b"; | ||||
|     secret = "7295c4201966a02c2c3d25b5cea4a5ff782966a2415e3a196f91924631191395"; | ||||
|   }; | ||||
| in | ||||
| { config, lib, pkgs, ... }: { | ||||
|   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) | ||||
|   virtualisation.vmVariant = { config, ... }: { | ||||
|     services.peertube = { | ||||
|  |  | |||
		Reference in a new issue
	
	 Taeer Bar-Yam
						Taeer Bar-Yam