Add Peertube + improve CLI instructions

This commit is contained in:
Quentin Dufour 2021-11-03 12:55:03 +01:00
parent eaf54efb25
commit e93d7fb228
No known key found for this signature in database
GPG key ID: A98E9B769E4FF428
2 changed files with 236 additions and 5 deletions

View file

@ -10,7 +10,7 @@ If you want to expand your storage to aggregate multiple servers, Garage is the
A S3 backend can be configured in two ways on Nextcloud, either as Primary Storage or as an External Storage.
Primary storage will store all your data on S3, in an opaque manner, and will provide the best performances.
External storage enable you to select which data will be store on S3, you file hierarchy will be preserved in S3, but it might be slower.
External storage enable you to select which data will be stored on S3, your file hierarchy will be preserved in S3, but it might be slower.
In the following, we cover both methods but before reading our guide, we suppose you have done some preliminary steps.
First, we expect you have an already installed and configured Nextcloud instance.
@ -106,8 +106,239 @@ Do not change the `use_path_style` and `legacy_auth` entries, other configuratio
## Peertube
https://docs.joinpeertube.org/admin-remote-storage
Peertube proposes a clever integration of S3 by directly exposing its endpoint instead of proxifying requests through the application.
In other words, Peertube is only responsible of the "control plane" and offload the "data plane" to Garage.
In return, this system is a bit harder to configure, especially with Garage that supports less feature than other older S3 backends.
We show that it is still possible to configure Garage with Peertube, allowing you to spread the load and the bandiwdth usage on the Garage cluster.
### Enable path-style access by patching Peertube
First, you will need to apply a small patch on Peertube ([#4510](https://github.com/Chocobozzz/PeerTube/pull/4510)):
```diff
From e3b4c641bdf67e07d406a1d49d6aa6b1fbce2ab4 Mon Sep 17 00:00:00 2001
From: Martin Honermeyer <maze@strahlungsfrei.de>
Date: Sun, 31 Oct 2021 12:34:04 +0100
Subject: [PATCH] Allow setting path-style access for object storage
---
config/default.yaml | 4 ++++
config/production.yaml.example | 4 ++++
server/initializers/config.ts | 1 +
server/lib/object-storage/shared/client.ts | 3 ++-
.../production/config/custom-environment-variables.yaml | 2 ++
5 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/config/default.yaml b/config/default.yaml
index cf9d69a6211..4efd56fb804 100644
--- a/config/default.yaml
+++ b/config/default.yaml
@@ -123,6 +123,10 @@ object_storage:
# You can also use AWS_SECRET_ACCESS_KEY env variable
secret_access_key: ''
+ # Reference buckets via path rather than subdomain
+ # (i.e. "my-endpoint.com/bucket" instead of "bucket.my-endpoint.com")
+ force_path_style: false
+
# Maximum amount to upload in one request to object storage
max_upload_part: 2GB
diff --git a/config/production.yaml.example b/config/production.yaml.example
index 70993bf57a3..9ca2de5f4c9 100644
--- a/config/production.yaml.example
+++ b/config/production.yaml.example
@@ -121,6 +121,10 @@ object_storage:
# You can also use AWS_SECRET_ACCESS_KEY env variable
secret_access_key: ''
+ # Reference buckets via path rather than subdomain
+ # (i.e. "my-endpoint.com/bucket" instead of "bucket.my-endpoint.com")
+ force_path_style: false
+
# Maximum amount to upload in one request to object storage
max_upload_part: 2GB
diff --git a/server/initializers/config.ts b/server/initializers/config.ts
index 8375bf4304c..d726c59a4b6 100644
--- a/server/initializers/config.ts
+++ b/server/initializers/config.ts
@@ -91,6 +91,7 @@ const CONFIG = {
ACCESS_KEY_ID: config.get<string>('object_storage.credentials.access_key_id'),
SECRET_ACCESS_KEY: config.get<string>('object_storage.credentials.secret_access_key')
},
+ FORCE_PATH_STYLE: config.get<boolean>('object_storage.force_path_style'),
VIDEOS: {
BUCKET_NAME: config.get<string>('object_storage.videos.bucket_name'),
PREFIX: config.get<string>('object_storage.videos.prefix'),
diff --git a/server/lib/object-storage/shared/client.ts b/server/lib/object-storage/shared/client.ts
index c9a61459336..eadad02f93f 100644
--- a/server/lib/object-storage/shared/client.ts
+++ b/server/lib/object-storage/shared/client.ts
@@ -26,7 +26,8 @@ function getClient () {
accessKeyId: OBJECT_STORAGE.CREDENTIALS.ACCESS_KEY_ID,
secretAccessKey: OBJECT_STORAGE.CREDENTIALS.SECRET_ACCESS_KEY
}
- : undefined
+ : undefined,
+ forcePathStyle: CONFIG.OBJECT_STORAGE.FORCE_PATH_STYLE
})
logger.info('Initialized S3 client %s with region %s.', getEndpoint(), OBJECT_STORAGE.REGION, lTags())
diff --git a/support/docker/production/config/custom-environment-variables.yaml b/support/docker/production/config/custom-environment-variables.yaml
index c7cd28e6521..a960bab0bc9 100644
--- a/support/docker/production/config/custom-environment-variables.yaml
+++ b/support/docker/production/config/custom-environment-variables.yaml
@@ -54,6 +54,8 @@ object_storage:
region: "PEERTUBE_OBJECT_STORAGE_REGION"
+ force_path_style: "PEERTUBE_OBJECT_STORAGE_FORCE_PATH_STYLE"
+
max_upload_part:
__name: "PEERTUBE_OBJECT_STORAGE_MAX_UPLOAD_PART"
__format: "json"
```
You can then recompile it with:
```
npm run build
```
And it can be started with:
```
NODE_ENV=production NODE_CONFIG_DIR=/srv/peertube/config node dist/server.js
```
### Create resources in Garage
Create a key for Peertube:
```bash
garage key new --name peertube-key
```
Keep the Key ID and the Secret key in a pad, they will be needed later.
We need two buckets, one for normal videos (named peertube-video) and one for webtorrent videos (named peertube-playlist).
```bash
garage bucket create peertube-video
garage bucket create peertube-playlist
```
Now we allow our key to read and write on these buckets:
```
garage bucket allow peertube-playlist --read --write --key peertube-key
garage bucket allow peertube-video --read --write --key peertube-key
```
Finally, we need to expose these buckets publicly to serve their content to users:
```bash
garage bucket website --allow peertube-playlist
garage bucket website --allow peertube-video
```
These buckets are now accessible on the web port (by default 3902) with the following URL: `http://<bucket><root_domain>:<web_port>` where the root domain is defined in your configuration file (by default `.web.garage`). So we have currently the following URLs:
* http://peertube-playlist.web.garage:3902
* http://peertube-video.web.garage:3902
Make sure you (will) have a corresponding DNS entry for them.
### Configure a Reverse Proxy to serve CORS
Now we will configure a reverse proxy in front of Garage.
This is required as we have no other way to serve CORS headers yet.
For our example, we will use nginx:
```nginx
server {
# In production you should use TLS instead of plain HTTP
listen [::]:80;
server_name peertube-video.web.garage peertube-playlist.web.garage;
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Max-Age 3600;
add_header Access-Control-Expose-Headers Content-Length;
add_header Access-Control-Allow-Headers Range;
# We do not forward OPTIONS request to Garage
# as it does not know how to interpret them.
# Instead, we simply answers 200.
if ($request_method !~ ^(GET|HEAD)$ ) {
return 200;
}
# If your do not have a Garage instance on the reverse proxy, change the URL here.
proxy_pass http://127.0.0.1:3902;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
}
```
Now make sure that your 2 dns entries are pointing to your reverse proxy.
### Configure Peertube
You must edit the file named `config/production.yaml`, we are only modifying the root key named `object_storage`:
```yaml
object_storage:
enabled: true
# Put localhost only if you have a garage instance running on that node
endpoint: 'http://localhost:3900' # or "garage.example.com" if you have TLS on port 443
# This entry has been added by our patch, must be set to true
force_path_style: true
# Garage supports only one region for now, named garage
region: 'garage'
credentials:
access_key_id: 'GKxxxx'
secret_access_key: 'xxxx'
max_upload_part: 2GB
streaming_playlists:
bucket_name: 'peertube-playlist'
# Keep it empty for our example
prefix: ''
# You must fill this field to make Peertube use our reverse proxy/website logic
base_url: 'http://peertube-playlist.web.garage' # Example: 'https://mirror.example.com'
# Same settings but for webtorrent videos
videos:
bucket_name: 'peertube-video'
prefix: ''
# You must fill this field to make Peertube use our reverse proxy/website logic
base_url: 'http://peertube-video.web.garage'
```
### That's all
Everything must be configured now, simply restart Peertube and try to upload a video.
You must see in your browser console that data are fetched directly from our bucket (through the reverse proxy).
### Miscellaneous
*Known bug:* The playback does not start and some 400 Bad Request Errors appear in your browser console and on Garage.
If the description of the error contains HTTP Invalid Range: InvalidRange, the error is due to a buggy ffmpeg version.
You must avoid the 4.4.0 and use either a newer or older version.
*Associated issues:* [#137](https://git.deuxfleurs.fr/Deuxfleurs/garage/issues/137), [#138](https://git.deuxfleurs.fr/Deuxfleurs/garage/issues/138), [#140](https://git.deuxfleurs.fr/Deuxfleurs/garage/issues/140). These issues are non blocking.
*External link:* [Peertube Documentation > Remote Storage](https://docs.joinpeertube.org/admin-remote-storage)
## Mastodon

View file

@ -57,17 +57,17 @@ Then a file named `~/.aws/config` and put:
region=garage
```
Now, supposing Garage is listening on `http://127.0.0.1:3901`, you can list your buckets with:
Now, supposing Garage is listening on `http://127.0.0.1:3900`, you can list your buckets with:
```bash
aws --endpoint-url http://127.0.0.1:3901 s3 ls
aws --endpoint-url http://127.0.0.1:3900 s3 ls
```
Passing the `--endpoint-url` parameter to each command is annoying but AWS developers do not provide a corresponding configuration entry.
As a workaround, you can redefine the aws command by editing the file `~/.bashrc`:
```
function aws { command aws --endpoint-url http://127.0.0.1:3911 $@ ; }
function aws { command aws --endpoint-url http://127.0.0.1:3900 $@ ; }
```
*Do not forget to run `source ~/.bashrc` or to start a new terminal before running the next commands.*