From a9e1f1e82e29320f3497bab5ebbc6c4873c99cda Mon Sep 17 00:00:00 2001 From: Gabe Kangas Date: Tue, 9 Jun 2020 16:49:42 -0700 Subject: [PATCH] Add documentation for setting up some storage providers --- README.md | 17 +++--- doc/S3.md | 129 +++++++++++++++++++++++++++++++++++++++++-- doc/linodebucket.png | Bin 0 -> 26495 bytes 3 files changed, 134 insertions(+), 12 deletions(-) create mode 100644 doc/linodebucket.png diff --git a/README.md b/README.md index de3d6e694..e30f5be33 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ The goal is to have a single service that you can run and it works out of the bo ### Prerequisites -* **A computer that's on the public internet to run it on.** While crunching through video and serving it to viewers can be intensive from the computing side, you can get away with pretty meager resources. If you don't already have a server to run it on you can get a [Linode](https://www.linode.com/products/nanodes/) instance for $5/mo that runs it fine. If you worry that you'll be maxing out the bandwidth or transfer limits allotted to you, then utilize [Amazon S3](https://aws.amazon.com/s3/) very cheaply (or even free for a certain amount) to serve the files instead. +* **A computer that's on the public internet to run it on.** While crunching through video and serving it to viewers can be intensive from the computing side, you can get away with pretty meager resources. If you don't already have a server to run it on you can get a [Linode](https://www.linode.com/products/nanodes/) instance for $5/mo that runs it fine. If you worry that you'll be maxing out the bandwidth or transfer limits allotted to you, then utilize [S3 Storage](https://github.com/gabek/owncast/blob/master/doc/S3.md) very cheaply (or even free for a certain amount) to serve the files instead. * [ffmpeg](https://ffmpeg.org/) is required to function. [Install it](https://ffmpeg.org/download.html) first. * These instructions are assuming you're using [OBS](https://obsproject.com/) on your personal computer to stream from. It's not required, but it's a great free piece of software. @@ -99,16 +99,18 @@ The goal is to have a single service that you can run and it works out of the bo Three ways of storing and distributing the video are supported. 1. [Locally](#local-file-distribution) via the built-in web server. -2. [Amazon S3](#amazon-s3). +2. [S3-compatible storage](#s3-compatible-storage). 3. Experimental [IPFS](#ipfs) support. ### Local file distribution This is the simplest and works out of the box. In this scenario video will be served to the public from the computer that is running the server. If you have a fast internet connection, enough bandwidth alotted to you, and a small audience this may be fine for many people. -### Amazon S3 +### S3-Compatible Storage -Enable S3 support in `config.yaml` and add your AWS access credentials. Files will be distributed from a S3 bucket that you have created for this purpose. This is a good option for almost any case since S3 is cheap and you don't have to worry about your own bandwdith. +Enable S3 support in `config.yaml` and add your access credentials. Files will be distributed from a S3 bucket that you have created for this purpose. This is a good option for almost any case since S3 is cheap and you don't have to worry about your own bandwidth. + +Please read the [more detailed documentation about configuration of S3-Compatible Services](https://github.com/gabek/owncast/blob/master/doc/S3.md). ### IPFS @@ -124,9 +126,10 @@ By editing the config file you can change what IPFS gateway server is used, and Here's a list of some things you can do to increase performance and make things nicer for yourself. +* Get a faster server with more cores so you can [enable more bitrates at once](https://github.com/gabek/owncast/blob/master/doc/configuration.md). * Put a CDN in front of your server if you serve your files locally. You can even get a free one like [Cloudflare](https://www.cloudflare.com/). Then as more people view your stream people will no longer be downloading the stream directly from your server, but from the CDN instead, and it'll be faster. This is also a good way to enable SSL for your site. -* If you use Amazon S3 for storage, have it [expire files from your bucket after N days](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-lifecycle.html) because old files sitting on your S3 bucket aren't useful to anybody. +* If you use S3 for storage, have it [expire files from your bucket after N days](https://github.com/gabek/owncast/blob/master/doc/S3.md) because old files sitting on your S3 bucket aren't useful to anybody. * Edit the `webroot/index.html` file and make it look however you want. @@ -148,14 +151,12 @@ The following is a list of things, as long as there's some traction, I'd like to * Real web layout and chat UI is being worked on by [gingervitis](https://github.com/gingervitis). -* Utilizing non-Amazon owned, but still S3 compatible storage. There's so many services out there that are S3 compatible such as [Linode Object Storage](https://www.linode.com/products/object-storage/), [Wasabi](https://wasabi.com/what-is-wasabi/), [Backblaze](https://www.backblaze.com/b2/cloud-storage-pricing.html), [Google Storage](https://cloud.google.com/storage/), [DreamHost DreamObjects](https://www.dreamhost.com/cloud/storage/), or you can [even run your own](https://min.io/). So it's good to have options. +* Document more non-Amazon owned, but still S3 compatible storage. There's so many services out there that are S3 compatible such as [Backblaze](https://www.backblaze.com/b2/cloud-storage-pricing.html), [Google Storage](https://cloud.google.com/storage/), [DreamHost DreamObjects](https://www.dreamhost.com/cloud/storage/), or you can [even run your own](https://min.io/). So it's good to have options. * Refactor chat so it's more controlled by the server and doesn't accept just anything from clients and relay it back to everyone. * Add more functionality to chat UI such as moderation (deleting messages), emojis/gif search, etc. You know, the stuff other services have and people are used to. -* HLS adaptive bitrates. Right now there's a single bitrate being generated. We should be able to enable an array of bitrates in the config and spit out a HLS master playlist pointing to all of them. - * Collect viewer stats so you know how many people tuned into a stream. People seem to care about that kind of thing. * Add a simple setup wizard that will generate the config file for you on the first run by asking simple questions. diff --git a/doc/S3.md b/doc/S3.md index 8f6bb36c3..1b3c31699 100644 --- a/doc/S3.md +++ b/doc/S3.md @@ -1,6 +1,101 @@ -Here are some details and tips specific to using S3 for storage. +Here are some setup details, general information and tips specific to using external storage. -## File expiration +Choose your storage provider of choice. Yours not listed? [File an issue](https://github.com/gabek/owncast/issues) and we'll test and write up some documentation for it. + +* [Linode Object Storage](#linode-object-storage) +* [AWS S3](#aws-s3) +* [Wasabi](#wasabi-cloud-storage) + +## [Linode Object Storage](https://www.linode.com/pricing/?r=588ad4bf08ce8394e8eb11f0a463fde64637af9d/#row--storage) + +250 GB storage + 1 TB Outbound Transfer for $5/mo. + +Linode Object Storage is a good choice if you're already using Linode to host your server. It should be fast to transfer your video from your server to their storage service, and their pricing will probably just be the flat $5/mo for you, so it's easy to know what you're paying. + + + +* Create a new bucket at the [Linode Object Storage](https://cloud.linode.com/object-storage/buckets) admin page. +* Edit your config file and change the S3 `endpoint` to match the hostname listed below your newly created bucket that looks something like `myvideo.us-east-1.linodeobjects.com`, the bucket name to match the one you just created and the S3 region to match the `us-east-1` equivalent of the above hostname. +* Using the [Linode Object Access Keys](https://cloud.linode.com/object-storage/access-keys) page create a new Access Key and add the Key and Secret to your `config.yaml` file. + +In the following steps Linode requires you to interact with your bucket using the s3cmd tool. So install that on your terminal and configure it. + +Run `s3cmd --configure` and fill in the values with what is currently in your config file. It should look similar to this: +``` +Access Key: ABC12334 +Secret Key: fj3kd83jdkh +Default Region: US +S3 Endpoint: us-east-1.linodeobjects.com +DNS-style bucket+hostname:port template for accessing a bucket: us-east-1.linodeobjects.com +Use HTTPS protocol: False +``` + +### Add permissions to access video. + +_This part sucks_. But you only have to do it once per bucket. [These are the full instructions](https://www.linode.com/docs/platform/object-storage/how-to-use-object-storage-acls-and-bucket-policies/#bucket-policies) but let me summarize. + + +1. Create a file called bucket_policy.json that has the following: +``` +{ + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": [ + "*" + ] + }, + "Action": [ + "s3:GetObject" + ], + "Resource": [ + "arn:aws:s3::MYBUCKETNAME/*" + ] + } + ] +} +``` + +1. Replace `MYBUCKETNAME` with your actual bucket name. +1. Run `s3cmd setpolicy bucket_policy.json s3://MYBUCKETNAME` replacing `MYBUCKETNAME` with your bucket name. +1. Run `s3cmd info s3://MYBUCKETNAME` to make sure the new policy saved. + +Now files video saved to Linode Object Storage will be readable. + +More details about how to get started using Linode Object Storage can be found [on their documentation](https://www.linode.com/docs/platform/object-storage/how-to-use-object-storage/). + + +### File expiration + +Make files older than one day expire and delete themselves so you don't pay for storage of old video. + +Full details are in [their documentation](https://www.linode.com/docs/platform/object-storage/how-to-manage-objects-with-lifecycle-policies/). + +Create a file called `lifecycle_policy.json` with the following contents: + +``` + + + delete-all-objects + + Enabled + + 1 + + + +``` + +* Run `s3cmd setlifecycle lifecycle_policy.xml s3://MYBUCKETNAME`. +* Run `s3cmd info s3://MYBUCKETNAME` and you should now see ` Expiration Rule: all objects in this bucket will expire in '1' day(s) after creation`. + + +## AWS S3 + +AWS S3 is a good choice if you're already using AWS for your server or are comfortable using AWS for other things. If you're brand new to object storage and not using AWS already I'm not sure I'd recommend jumping into it just for Owncast. There are other options. + +### File expiration You should expire old segments on your S3 bucket. [Here are some instructions on how to do that.](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-lifecycle.html) @@ -8,6 +103,32 @@ You should expire old segments on your S3 bucket. [Here are some instructions o * A one day object expiration lifecycle rule on objects is as low as you can go, so use that. * Because AWS [rounds the expiration to midnight of the next day](https://aws.amazon.com/premiumsupport/knowledge-center/s3-lifecycle-rule-delay/) you may have a lot of old video chunks sitting around. You can make the most of this by increasing the `maxNumberInPlaylist` value in your config file to something much higher, allowing users to rewind your stream back in time further. If the video is available then you might as well make it available to your users. -## CORS +### CORS -* Ugh. CORS. [You will need to enable CORS on your bucket](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html#how-do-i-enable-cors) so the web player can access the video. \ No newline at end of file +* Ugh. CORS. [You will need to enable CORS on your bucket](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html#how-do-i-enable-cors) so the web player can access the video. + + +## [Wasabi cloud storage](https://wasabi.com/content-delivery/) + +Most people would end up paying $5.99/mo with Wasabi, and there's no additional costs for the amount of people or amount of times people access your video. So if you have a ton of viewers, this is probably a good option. + +### Create a user and access key. + +1. [Create a new user on Wasabi](https://wasabi.com/wp-content/themes/wasabi/docs/Getting_Started/index.html#t=topics%2FCreating_a_User.htm) for yourself. +1. [Create a new Access Key](https://wasabi.com/wp-content/themes/wasabi/docs/Getting_Started/index.html#t=topics%2FAssigning_an_Access_Key.htm) in the Users Panel. +1. Update your Owncast `config.json` file with the above Access Key and Secret as well as the other required details. + +Depending on the region where your bucket lives look up the service URL [from this page](https://wasabi-support.zendesk.com/hc/en-us/articles/360015106031-What-are-the-service-URLs-for-Wasabi-s-different-regions-). + +* Endpoint: Is the "service URL" you looked up above. Likely ` s3.wasabisys.com` or similar. +* Bucket + +### Making files public + +Wasabi makes it easy to make a bucket public. [Full documentation is here](https://wasabi.com/wp-content/themes/wasabi/docs/Getting_Started/index.html#t=topics%2FMaking_Folders_and_or_Files_Public.htm), but simply select the folder and choose "_Make Public_". + +### Expiration of old files on Wasabi + +**Important note!** Wasabi does **NOT* seem to have a way to set a policy for deleting old files like AWS and Linode does. You may have your own way of cleaning up old files, or some other solution. But it's something to keep in mind in case you really start to build up a lot of old video files. + +If anybody knows how to enable Lifecycle Policies on Wasabi, please [file an issue with details](https://github.com/gabek/owncast/issues). \ No newline at end of file diff --git a/doc/linodebucket.png b/doc/linodebucket.png new file mode 100644 index 0000000000000000000000000000000000000000..d9532790de0d965b4c4bf25d55d2c06f641b4b33 GIT binary patch literal 26495 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 vT#*ESjW%lr{jtRV&qRWK@&Av(y literal 0 HcmV?d00001