Merge branch 'iv-org:master' into master

This commit is contained in:
Ramazan Sancar 2025-03-16 20:53:02 +03:00 committed by GitHub
commit 656e8fe689
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
49 changed files with 1702 additions and 386 deletions

View File

@ -4,6 +4,8 @@ title: "[New instance] <instance name>"
assignees:
- unixfox
- samantazfox
- perennialtech
- bugmaschine
labels:
- instance-add
@ -44,7 +46,9 @@ body:
required: true
- label: "If dash, proxy + download is enabled (default settings), the instance has unlimited traffic/bandwidth or close to unlimited (100TB minimum)"
required: true
- label: "Instance is not running any kind of analytics"
- label: "Instance is not running any kind of analytics, including external scripts of any kind"
required: true
- label: "If using Cloudflare or any other DDoS protection service, settings are configured to allow uptime monitoring. Cloudflare users can consult [this](https://updown.io/doc/known-issues-when-monitoring-a-cloudflare-protected-website) guide"
required: true
@ -58,6 +62,14 @@ body:
- label: "Ensure a proper uptime of my instance (around 90%)"
required: true
- type: checkboxes
attributes:
label: Rules for public instances
description: By submitting this proposal, you agree to follow the [rules for public instances](https://docs.invidious.io/instances/#rules-for-public-instances).
options:
- label: I agree to follow the rules for public instances
required: true
- type: input
id: country
attributes:

View File

@ -83,10 +83,6 @@ jobs:
'- Improving the performance and the stability of your public instance: https://docs.invidious.io/improve-public-instance/',
'',
'It is highly recommended to follow these tutorials because it will allow the instance to stay stable and performant over the long term.',
'',
'Please consider joining the Matrix room for public instance maintainers by joining our Matrix room: https://matrix.to/#/#invidious:matrix.org',
'then pinging @ unixfox, @ TheFrenchGhosty and @ SamantazFox for asking to be invited to the Matrix room.',
'We discuss troubles managing a public instance, sharing some advices and more.'
].join('\n');
await github.rest.issues.createComment({
issue_number: context.issue.number,

View File

@ -117,11 +117,20 @@ All endpoints that return a JSON body support `&hl=LANGUAGE` for translating fie
"type": String,
"clen": String,
"lmt": String,
"projectionType": Int32,
"projectionType": String,
"container": String,
"encoding": String,
"qualityLabel": String?,
"resolution": String?
"resolution": String?,
"fps": Int32,
"size": String?,
"targetDurationsec": Int64?,
"maxDvrDurationSec": Int64?,
"audioQuality": String?,
"audioSampleRate": String?,
"audioChannels": String?,
"colorInfo": String?,
"captionTrack": String?
}
],
"formatStreams": [
@ -130,6 +139,7 @@ All endpoints that return a JSON body support `&hl=LANGUAGE` for translating fie
"itag": String,
"type": String,
"quality": String,
"bitrate": String?,
"container": String,
"encoding": String,
"qualityLabel": String,
@ -140,10 +150,18 @@ All endpoints that return a JSON body support `&hl=LANGUAGE` for translating fie
"captions": [
{
"label": String,
"languageCode": String,
"language_code": String,
"url": String
}
],
"musicTracks": [
{
"song": String,
"artist": String,
"album": String,
"license": String
}
],
"recommendedVideos": [
{
"videoId": String,
@ -157,7 +175,18 @@ All endpoints that return a JSON body support `&hl=LANGUAGE` for translating fie
}
],
"author": String,
"authorUrl": String,
"authorId": String?,
"authorVerified": Boolean,
"authorThumbnails": [
{
"url": string,
"width": Int32,
"height": Int32
}
],
"lengthSeconds": Int32,
"viewCount":
"viewCountText": String
}
]
@ -203,6 +232,8 @@ Returns annotation XML from YouTube's `/annotations_invideo` endpoint. Alternati
"isEdited": Boolean,
"isPinned": Boolean,
"isSponsor": Boolean?,
"sponsorIconUrl": String?,
"content": String,
"contentHtml": String,
@ -301,7 +332,7 @@ Captions can also be selected with an ISO `lang`, e.g. &lang=en, `tlang` will au
Parameters:
```
type: "music", "gaming", "news", "movies"
type: "music", "gaming", "movies", "default"
region: ISO 3166 country code (default: "US")
```
@ -337,183 +368,6 @@ region: ISO 3166 country code (default: "US")
]
```
##### GET `/api/v1/channels/comments/:ucid`, `/api/v1/channels/:ucid/comments`
```javascript
{
"authorId": String,
"comments": [
{
"author": String,
"authorThumbnails": [
"url": String,
"width": Int32,
"height": Int32
],
"authorId": String,
"authorUrl": String,
"isEdited": Bool,
"content": String,
"contentHtml": String,
"published": Int64,
"publishedText": String,
"likeCount": Int32,
"commentId": String,
"authorIsChannelOwner": Bool,
"creatorHeart": {
"creatorThumbnail": String,
"creatorName": String
}?,
"replies": {
"replyCount": Int32,
"continuation": String
}?,
"attachment": Attachment?
}
],
"continuation": String?
}
```
The `authorId` for top-level comments will always(?) be the same as the requested channel. Top-level comments will also have an optional `attachment`, which can be one of:
```javascript
{
"type": "image",
"imageThumbnails": [
{
"url": String,
"width": Int32,
"height": Int32
}
]
}
```
```javascript
{
"type": "video",
"title": String,
"videoId": String,
"videoThumbnails": [
{
"quality": String,
"url": String,
"width": Int32,
"height": Int32
}
],
"lengthSeconds": Int32,
"author": String,
"authorId": String,
"authorUrl": String,
"published": Int64,
"publishedText": String,
"viewCount": Int64,
"viewCountText": String
}
```
```javascript
{
"type": "unknown",
"error": "Unrecognized attachment type."
}
```
Some attachments may only have a `type` and `error`, similar to the above. Attachments will *only* be present on top-level comments.
Parameters:
```
continuation: String
```
##### GET `/api/v1/channels/search/:ucid`
> Schema:
```javascript
[
{
type: "video",
title: String,
videoId: String,
author: String,
authorId: String,
authorUrl: String,
videoThumbnails: [
{
quality: String,
url: String,
width: Int32,
height: Int32
}
],
description: String,
descriptionHtml: String,
viewCount: Int64,
published: Int64,
publishedText: String,
lengthSeconds: Int32,
liveNow: Bool,
paid: Bool,
premium: Bool
},
{
type: "playlist",
title: String,
playlistId: String,
author: String,
authorId: String,
authorUrl: String,
videoCount: Int32,
videos: [
{
title: String,
videoId: String,
lengthSeconds: Int32,
videoThumbnails: [
{
quality: String,
url: String,
width: Int32,
height: Int32
}
]
}
]
},
{
type: "channel",
author: String,
authorId: String,
authorUrl: String,
authorThumbnails: [
{
url: String,
width: Int32,
height: Int32
}
],
subCount: Int32,
videoCount: Int32,
description: String,
descriptionHtml: String
}
];
```
Parameters:
```
q: String
page: Int32
```
##### GET `/api/v1/search/suggestions`
> Schema:
@ -607,6 +461,13 @@ q: String
videoCount: Int32,
description: String,
descriptionHtml: String
},
{
type: "hashtag"
title: String,
url: String,
channelCount: Int32,
videoCount: Int32
}
];
```
@ -616,7 +477,7 @@ Parameters:
```
q: String
page: Int32
sort_by: "relevance", "rating", "upload_date", "view_count"
sort: "relevance", "rating", "date", "views"
date: "hour", "today", "week", "month", "year"
duration: "short", "long", "medium"
type: "video", "playlist", "channel", "movie", "show", "all", (default: all)
@ -647,6 +508,7 @@ region: ISO 3166 country code (default: "US")
"videoCount": Int32,
"viewCount": Int64,
"viewCountText": String,
"updated": Int64,
"videos": [
@ -707,3 +569,47 @@ page: Int32
]
}
```
##### GET `/api/v1/hashtag/:tag`
> Schema:
```javascript
{
results: VideoObject[],
}
```
Parameters:
```
page: Int32
```
##### GET `/api/v1/resolveurl`
> Schema:
```javascript
{
ucid?: String,
videoId?: String,
playlistId?: String,
startTimeSeconds?: String,
params?: String,
pageType: string
}
```
Parameters:
```
url: URL
```
##### GET `/api/v1/clips`
> Schema:
```javascript
{
startTime: Float64, // in seconds
endTime: Float64, // in seconds
clipTitle: String,
video: VideoObject
}
```
Parameters:
```
id: string
```

View File

@ -418,3 +418,33 @@ Example request:
```
Returns 204 on success.
##### GET `/api/v1/auth/history`
Get the history of videos played by the user.
Parameters:
```
max_results: Int32
page: Int32
```
> Schema:
```javascript
[
// video IDs
]
```
##### POST `/api/v1/auth/history/:id`
Set a video as watched.
Returns 204 on success.
##### DELETE `/api/v1/auth/history/:id`
Delete a video from the user watched history.
Returns 204 on success.

View File

@ -85,12 +85,46 @@ This is the same as requesting `/api/v1/channels/:id/videos` without URL paramet
}
```
##### GET `/api/v1/channels/:id/podcasts`
> URL parameters:
* `continuation`: A continuation token to get the next chunk of items. The token is provided each time this API is requested.
> Response:
```javascript
{
"playlists": [
// One or more PlaylistOject
],
"continuation": continuation
}
```
##### GET `/api/v1/channels/:id/releases`
> URL parameters:
* `continuation`: A continuation token to get the next chunk of items. The token is provided each time this API is requested.
> Response:
```javascript
{
"playlists": [
// One or more PlaylistOject
],
"continuation": continuation
}
```
##### GET `/api/v1/channels/:id/shorts`
> URL parameters:
* `continuation`: A continuation token to get the next chunk of items. The token is provided each time this API is requested.
* `sort_by`: Sort order filter. Accepted values: `newest`, `popular` or `oldest`
> Response:
@ -102,6 +136,7 @@ See: GET `/api/v1/channels/:id/videos`
> URL parameters:
* `continuation`: A continuation token to get the next chunk of items. The token is provided each time this API is requested.
* `sort_by`: Sort order filter. Accepted values: `newest`, `popular` or `oldest`
> Response:
@ -206,3 +241,34 @@ This usually means that parsing support for the attachment type has not yet been
"error": String
}
```
##### GET `/api/v1/channels/:ucid/search`
> Url parameters
* `q`: The query to search
* `page`: The page number of the search (Int32)
> Response:
```javascript
[
VideoObject,
PlaylistObject
];
```
##### GET `/api/v1/post/:id`
> Url parameters
* `ucid`: You can optionally provide the channel's id for fetching the post.
> Response:
Same as [`/api/v1/channels/:id/community`](#get-apiv1channelsidcommunity) but only returns one post in the comments array
##### GET `/api/v1/post/:id/comments`
* `ucid`: You can optionally provide the channel's id for fetching the post's comments.
> Response:
Same as [`/api/v1/channels/:id/comments`](../api.md#get-apiv1commentsid) but has a postId instead of a videoId

View File

@ -57,7 +57,15 @@
"liveNow": Boolean,
"premium": Boolean,
"isUpcoming": Boolean
"isUpcoming": Boolean,
"isNew" Boolean,
"is4k": Boolean,
"is8k": Boolean,
"isVr180": Boolean,
"isVr360": Boolean,
"is3d": Boolean,
"hasCaptions": Boolean
}
```

View File

@ -13,11 +13,12 @@ Lists of third-party projects that use or support Invidious.
| [WatchTube](https://github.com/WatchTubeTeam/) | Powerful YouTube client for Apple Watch. | [App Store](https://apps.apple.com/app/watchtube/id1599884909) |
| [TubiTui](https://codeberg.org/777/TubiTui) | A lightweight, libre, TUI-based YouTube client. For desktop. | |
| [Ytfzf](https://github.com/pystardust/ytfzf) | A posix script to find and watch youtube videos from the terminal. (Without API). | |
| [Playlet](https://github.com/iBicha/playlet) | A Roku TV YouTube app that uses Invidious as a backend. | [Roku Store](https://channelstore.roku.com/en-ca/details/840aec36f51bfe6d96cf6db9055a372a/playlet) |
| [Playlet](https://github.com/iBicha/playlet) | A Roku TV YouTube app that uses Invidious as a backend. | [Roku Store](https://channelstore.roku.com/details/840aec36f51bfe6d96cf6db9055a372a/playlet) |
| [GTK+ Pipe Viewer](https://github.com/trizen/pipe-viewer) | YouTube client for Linux. | |
| [PlasmaTube](https://invent.kde.org/multimedia/plasmatube/) | YouTube client for Linux. | [KDE Applications](https://apps.kde.org/plasmatube/) |
| [yt2alt](https://github.com/iBicha/yt2alt) | A cli tool to import your profile from Youtube to an alternative platform. | |
| [Materialious](https://github.com/WardPearce/Materialious) | Modern material design for Invidious. | |
| [IInvidious](https://www.colino.net/wordpress/en/iinvidious-an-apple-ii-invidious-client/) | An Invidious client for the Apple II. | [Repository](https://github.com/colinleroy/a2tools) |
### Browser Extensions
@ -27,7 +28,7 @@ Lists of third-party projects that use or support Invidious.
| [Redirector](https://github.com/einaregilsson/Redirector) | Extension for Firefox and Chromium that can manually be configured to process Invidious Redirects. For details, see the [setup page](./redirector.md) to use it with Invidious. | [Source](https://github.com/einaregilsson/Redirector) / [Firefox](https://addons.mozilla.org/addon/redirector) / [Chrome](https://chrome.google.com/webstore/detail/redirector/ocgpenflpmgnfapjedencafcfakcekcd) |
| [Invidious Copy URL](https://github.com/recette-lemon/invidious-copy-url) | Adds context menu options on Invidious to copy shortened YouTube URL at current time or not (Requires using developer mode in Chrome or a developer version of Firefox). | |
| [Privacy Redirect](https://github.com/SimonBrazell/privacy-redirect) | Redirects YouTube to Invidious, Twitter to Nitter, and Instagram to Bibliogram. | [Source](https://github.com/SimonBrazell/privacy-redirect) / [Firefox](https://addons.mozilla.org/addon/privacy-redirect) / [Chrome](https://chrome.google.com/webstore/detail/privacy-redirect/pmcmeagblkinmogikoikkdjiligflglb) |
| [SponsorBlock](https://github.com/ajayyy/SponsorBlock) | A crowd-sourced extension to skip sponsorships. Support invidious instances if enabled in the options. | [Source](https://github.com/ajayyy/SponsorBlock) / [Firefox](https://addons.mozilla.org/addon/sponsorblock) / [Chrome](https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone) |
| [SponsorBlock](https://github.com/ajayyy/SponsorBlock) | A crowd-sourced extension to skip sponsorships. Support Invidious instances if enabled in the options. | [Source](https://github.com/ajayyy/SponsorBlock) / [Firefox](https://addons.mozilla.org/addon/sponsorblock) / [Chrome](https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone) |
| [Inviduration](https://github.com/rsapkf/inviduration) | Firefox extension that shows total duration of playlists on Invidious. | [Source](https://github.com/rsapkf/inviduration) / [Firefox](https://addons.mozilla.org/addon/inviduration) |
| [Alter](https://github.com/w3bdev1/alter) | Firefox extension that redirects YouTube, Twitter and Reddit to Invidious, Nitter and Teddit respectively. | [Source](https://github.com/w3bdev1/alter) / [Firefox](https://addons.mozilla.org/addon/alter) |
@ -51,6 +52,7 @@ Lists of third-party projects that use or support Invidious.
| [FreshRSS Extension](https://github.com/tmiland/freshrss-invidious) | A FreshRSS extension to directly embed videos from Invidious channel feeds. | |
| [UntrackMe](https://f-droid.org/en/packages/app.fedilab.nitterizeme) | Android app to rewrite YouTube links to Invidious. Can optionally play videos in the app as well. | |
| [Kodi add-on](https://github.com/lekma/plugin.video.invidious) | Watch YouTube videos in the Kodi media center, using the Invidious API. Privacy-friendly alternative to the YouTube API add-on. | |
| [Koutube](https://github.com/iGerman00/koutube) | Watch YouTube videos on Discord without loading the YouTube embed. Quickly replace any YouTube links using the sed syntax (s/y/k) or by swapping the <kbd>y</kbd> with a <kbd>k</kbd>. | [Source](https://github.com/iGerman00/koutube) / [Website](https://koutube.com) |
### Utilities

View File

@ -1,9 +1,20 @@
# Community Installation Guide
??? warning "Before following the community installation guide"
All the platforms listed in the community installation guide are not supported officially by the Invidious developers.
This means:
- The Invidious developers can't help you to solve issues with your platform. Ask the community on [Matrix](https://matrix.to/#/#invidious:matrix.org) or [IRC](https://web.libera.chat/?channel=#invidious) before creating GitHub issues. But if you do fix an issue please create a PR for updating the community installation guide.
- The guide for your platform may be outdated because things have changed since the creation of the guide.
If your platform is not listed but you would like to contribute to this guide for adding it, please do [here](https://github.com/iv-org/documentation/edit/master/docs/community-installation-guide.md). We rely on the community to help us.
After installation take a look at the [Post-install steps](installation.md#post-install-configuration).
## Podman (rootless container)
Guide contributor(s): [@sigulete](https://github.com/sigulete)
Podman is usually pre-installed in Fedora, CentOS, RHEL and derivatives. But if this is not the case, the instruction below will install all necessary packages.
RHEL based and RHEL-like systems
@ -14,7 +25,7 @@ sudo dnf install podman
### Download the configuration files from Invidious' repository
Note: Currently the repository has to be cloned, this is because the `init-invidious-db.sh` file and the `config/sql` directory have to be mounted to the postgres container (See the volumes section in the postgres' container). This "problem" will be solved in the future.
> `<INV-PATH>` Absolute path in your home directory where invidious will be downloaded (e.i. /home/johnsmith/.inv)
> `<INV-PATH>` Absolute path in your home directory where Invidious will be downloaded (e.i. /home/johnsmith/.inv)
```bash
cd <INV-PATH>
@ -99,3 +110,191 @@ loginctl enable-linger
podman auto-update
podman image prune -f
```
## Podman via systemd
Guide contributor(s): [@lzap](https://github.com/lzap)
This method is suitable for systems which come with Podman version 5.x or higher and systemd (e.g. Fedora, CentOS Stream 9 or clones). Instructions are written for root-less mode, do not run the commands as root since paths are different. Ensure that SELinux is in enforcing mode for maximum security.
Create a new volume for database:
podman volume create invidious-db
Start a temporary container:
podman run --rm -it --name invidious-init -v invidious-db:/var/lib/postgresql/data:Z -p 5432:5432 -e POSTGRES_DB=invidious -e POSTGRES_USER=kemal -e POSTGRES_PASSWORD=kemal docker.io/library/postgres:14
In another terminal, migrate the database:
export PGPASSWORD=kemal
for F in channels videos channel_videos users session_ids nonces annotations playlists playlist_videos; do
curl -s https://raw.githubusercontent.com/iv-org/invidious/refs/heads/master/config/sql/$F.sql | \
psql -h localhost -p 5432 -U kemal invidious
done
Shutdown the temporary container, it is no longer needed. Create a database volume unit:
cat > ~/.config/containers/systemd/invidious-db.volume <<EOF
[Volume]
VolumeName=invidious-db
EOF
And a database container:
cat > ~/.config/containers/systemd/invidious-db.container <<EOF
[Container]
ContainerName=invidious-db
Environment=POSTGRES_DB=invidious POSTGRES_USER=kemal POSTGRES_PASSWORD=kemal
Image=docker.io/library/postgres:14
HealthCmd=pg_isready -h localhost -p 5432 -U kemal -d invidious
Notify=healthy
Pod=invidious.pod
Volume=invidious-db.volume:/var/lib/postgresql/data:Z
EOF
Create a helper container:
cat > ~/.config/containers/systemd/invidious-sig-helper.container <<EOF
[Container]
ContainerName=invidious-sig-helper
Environment=RUST_LOG=info
Image=quay.io/invidious/inv-sig-helper:latest
Exec=--tcp 0.0.0.0:12999
Pod=invidious.pod
EOF
Generate your `VISITOR_DATA` an `PO_TOKEN` secrets. For more information about these, read the information dialog above.
podman run quay.io/invidious/youtube-trusted-session-generator
Set those secrets as temporary environmental variables, also generate a random string for HMAC secret:
HMAC=$(openssl rand -base64 21)
VISITOR_DATA="ABCDEF%3D%3D" # notsecret
PO_TOKEN="MpOIfiljfsdljds-Lljfsdk-ojrdjXVs==" # notsecret
In the same terminal where you defined the environmental variables, create new environmental config file:
cat > ~/.config/containers/systemd/invidious.env <<EOF
INVIDIOUS_DATABASE_URL="postgres://kemal:kemal@invidious-db:5432/invidious"
#INVIDIOUS_CHECK_TABLES=true
#INVIDIOUS_DOMAIN="inv.example.com"
INVIDIOUS_SIGNATURE_SERVER="invidious-sig-helper:12999"
INVIDIOUS_VISITOR_DATA="$VISITOR_DATA"
INVIDIOUS_PO_TOKEN="$PO_TOKEN"
INVIDIOUS_HMAC_KEY="$HMAC"
EOF
From now on, if you need to change configuration just edit the generated file `~/.config/containers/systemd/invidious.env`. Now, create Invidious container unit:
cat > ~/.config/containers/systemd/invidious.container <<EOF
[Container]
ContainerName=invidious
EnvironmentFile=%h/.config/containers/systemd/invidious.env
Image=quay.io/invidious/invidious:latest
Pod=invidious.pod
[Unit]
After=invidious-db.service
EOF
And finally, create pod unit. Note only port 3000 is exposed, do not expose other ports!
cat > ~/.config/containers/systemd/invidious.pod <<EOF
[Pod]
PodName=invidious
PublishPort=3000:3000
[Install]
WantedBy=multi-user.target default.target
EOF
Systemd units are generated on-the-fly during `daemon-reload` command, but before that let's check syntax with quadlet generator. Note, you need Podman version 5.0 or higher, older versions will not work:
/usr/libexec/podman/quadlet -dryrun -user
Reload systemd daemon. Keep in mind you need to do this command every time you change a unit file, you can change the environmental file freely tho.
systemctl --user daemon-reload
And the whole application can be now started:
systemctl --user start invidious-pod
Keep in mind that generated units cannot be enabled using `systemctl enable`, the main pod will be enabled automatically. If you do not like this behavior, remove the `WantedBy` line from `invidious.pod`.
## MacOS
Guide contributor(s): Previously Invidious developers
### Generate po_token and visitor_data identities
[Follow these instructions here on the official tool `youtube-trusted-session-generator`](https://github.com/iv-org/youtube-trusted-session-generator?tab=readme-ov-file#tutorial-without-docker)
These two parameters will be required for passing all verification checks on YouTube side and you will have to configure them in Invidious.
You have to run this command on the same public IP address as the one blocked by YouTube. Not necessarily the same machine, just the same public IP address.
You will need to copy these two parameters in the `config.yaml` file.
Subsequent usage of this same token will work on the same IP range or even the same ASN. The point is to generate this token on a blocked IP as "unblocked" IP addresses seems to not generate a token valid for passing the checks on a blocked IP.
??? warning "About po_token and visitor_data identities"
po_token known as Proof of Origin Token. This is an attestation token generated by a complex anti robot verification system created by Google named BotGuard/DroidGuard. It is used to confirm that the request is coming from a genuine device.
These identity tokens (po_token and visitor_data) generated in this tutorial will make your entire Invidious session more easily traceable by YouTube because it is tied to a unique identifier.
There is currently no official automatic tool to periodically change these tokens. This is working in progress but, for the time being, this is the solution the Invidious team is offering.
If you want to be less traceable, you can always script the process by changing the identities every X hour.
### Run inv_sig_helper in background
[Follow these instructions here on the official tool `inv_sig_helper`](https://github.com/iv-org/inv_sig_helper?tab=readme-ov-file#building-and-running-without-docker)
inv_sig_helper handle the "deciphering" of the video stream fetched from YouTube servers. As it is running untrusted code from Google themselves, make sure to isolate it by for example running it inside Docker or a VM.
Call for action: An example here is welcome, [if you want to contribute to one](https://github.com/iv-org/documentation/edit/master/docs/installation.md#macos).
### Install the dependencies
```bash
brew update
brew install crystal postgresql imagemagick librsvg
```
### Clone the Invidious repository
```bash
git clone https://github.com/iv-org/invidious
cd invidious
```
### Set up PostgreSQL
```bash
brew services start postgresql
createdb
psql -c "CREATE ROLE kemal WITH LOGIN PASSWORD 'kemal';" # Change 'kemal' here to a stronger password, and update `password` in config/config.yml
createdb -O kemal invidious
psql invidious kemal < config/sql/channels.sql
psql invidious kemal < config/sql/videos.sql
psql invidious kemal < config/sql/channel_videos.sql
psql invidious kemal < config/sql/users.sql
psql invidious kemal < config/sql/session_ids.sql
psql invidious kemal < config/sql/nonces.sql
psql invidious kemal < config/sql/annotations.sql
psql invidious kemal < config/sql/playlists.sql
psql invidious kemal < config/sql/playlist_videos.sql
```
### Set up Invidious
```bash
make
# Configure config/config.yml as you like
cp config/config.example.yml config/config.yml
# edit config.yaml to include po_token and visitor_data previously generated
edit config/config.yaml
```

79
docs/companion-apache2.md Normal file
View File

@ -0,0 +1,79 @@
# Apache2 reverse proxy setup with Invidious companion
- A very basic config, secured with Let's Encrypt. Any log is disabled by default. Do not forget to replace `ServerName` with your domain.
```
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName invidious.domain.tld
ServerAdmin admin@localhost
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://127.0.0.1:3000/ nocanon
ProxyPassReverse / http://127.0.0.1:3000/
ProxyPass /latest_version http://127.0.0.1:8282/ nocanon
ProxyPassReverse /latest_version http://127.0.0.1:8282/
ProxyPass /api/manifest/dash/id/ http://127.0.0.1:8282/ nocanon
ProxyPassReverse /api/manifest/dash/id/ http://127.0.0.1:8282/
ProxyPass /videoplayback http://127.0.0.1:8282/ nocanon
ProxyPassReverse /videoplayback http://127.0.0.1:8282/
AllowEncodedSlashes on
# ErrorLog /var/log/apache2/invidious.domain.tld/error.log
CustomLog /dev/null combined
RewriteEngine on
SSLCertificateFile /etc/letsencrypt/live/invidious.domain.tld/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/invidious.domain.tld/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/invidious.domain.tld/chain.pem
</VirtualHost>
</IfModule>
```
## Another config example without HTTPS, but with Apache Basic Auth HTTP login.
The user will connect to Apache on port 3333 and will be asked to log in. If authentification is successful, Apache will redirect the user to Invidious' page.
To make the VirtualHost config below actually work, you should as well:
- Create a [.htpasswd](http://httpd.apache.org/docs/current/programs/htpasswd.html) file and add required [username/login combos](http://aspirine.org/htpasswd_en.html) to it, if not already existing.
- Open port 3333 (or any other free port) adding `Listen 3333` to Apache `ports.conf` (Debian `/etc/apache2/ports.conf`)
- If you run Invidious with default parameters, you may need to replace default host binding (0.0.0.0) with localhost (127.0.0.1) instead. That way, Invidious won't be publicly available on port 3000 anymore, but only accessible via the reverse proxy on port 3333. So if you run Invidious via a systemd service, you would edit the service file (e.g. `/etc/systemd/system/invidious.service`) and modify the ExecStart line to include the -b switch as follows `ExecStart=/home/invidious/invidious/invidious -b 127.0.0.1 -o invidious.log` and then reload the daemon with `systemctl daemon-reload` so that changes are taken into account.
- A convenient way to open such protected Invidious page without having to log in manually everytime is to access use a URL with the following format: http://username:password@domain:3333
```
<VirtualHost *:3333>
ServerName invidious.domain.tld #add your own domain name (or localhost if you have none)
ServerAdmin admin@localhost
<Location />
Deny from all # Forbid access to all by default...
#Allow from 127.0.0.1 #...Except from specific IPs (which will not need to authenticate)...
AuthUserFile /etc/apache2/.htpasswd #path to .htpasswd file
AuthName "Restricted Area" # name displayed in the promptbox
AuthType Basic # http://httpd.apache.org/docs/current/howto/auth.html
Satisfy Any
Require valid-user # ...and except from authenticated users included in the .htpasswd file
</Location>
ProxyPass / http://127.0.0.1:3000/ nocanon
ProxyPassReverse / http://127.0.0.1:3000/
ProxyPass /latest_version http://127.0.0.1:8282/ nocanon
ProxyPassReverse /latest_version http://127.0.0.1:8282/
ProxyPass /api/manifest/dash/id/ http://127.0.0.1:8282/ nocanon
ProxyPassReverse /api/manifest/dash/id/ http://127.0.0.1:8282/
ProxyPass /videoplayback http://127.0.0.1:8282/ nocanon
ProxyPassReverse /videoplayback http://127.0.0.1:8282/
ProxyPreserveHost On
ProxyRequests Off
AllowEncodedSlashes On
#ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog /dev/null combined
</VirtualHost>
```

22
docs/companion-caddy.md Normal file
View File

@ -0,0 +1,22 @@
# Caddy reverse proxy setup with Invidious companion
This is a very basic config, assuming that you're using Caddy to manage SSL certificates for you.
Any log is disabled by default. Do not forget to replace `server_name` with your domain.
```
https://<server_name> {
@companion {
path /latest_version
path /api/manifest/dash/id/*
path /videoplayback*
}
reverse_proxy @companion localhost:8282
reverse_proxy localhost:3000
log {
output discard
}
}
```

View File

@ -0,0 +1,421 @@
# Temporary installation guide for Invidious companion
After installation take a look at the [Post-install steps](#post-install-configuration).
Note: Any [PaaS](https://en.wikipedia.org/wiki/Platform_as_a_service) or [SaaS](https://en.wikipedia.org/wiki/Software_as_a_service) provider/software (Heroku, YunoHost, Repli...) are unsupported. Use them at your own risk. They **WILL** cause problems with Invidious and might even suspend your account for "abuse" since Invidious is heavy, bandwidth intensive and technically a proxy (and most providers don't like them). If you use one and want to report an issue, please mention which one you use.
# WARNING about this doc
This documentation is temporary and will explain you how to test Invidious companion. Invidious companion is currently in testing in the master branch.
And if you are using a reverse proxy then make sure to read again the post install because you have new routes to add!
## Hardware requirements
Running Invidious requires at least 20GB disk space, 512MB of free RAM (so ~2G installed on the system), as long as it is restarted regularly, as recommended in the post-install configuration. Public instances should ideally have at least 60G disk space, 4GB of RAM, 2vCPU, a 200 mbps link and 20TB of traffic (no data cap/unlimited traffic is preferred).
Compiling Invidious requires at least 2.5GB of free RAM (We recommend to have at least 4GB installed).
If you have less (e.g on a cheap VPS) you can setup a SWAP file or partition, so the combined amount is >= 4GB.
You need at least 1GB of RAM for the machine that will run the tool `youtube-trusted-session-generator` in the 1st step. Doesn't need to be the same machine as the one running Invidious, just a machine running on the same public IP address.
## Docker
**The Invidious docker image is only [available on Quay](https://quay.io/repository/invidious/invidious) because, unlike Docker Hub, [Quay is Free and Open Source Software](https://github.com/quay/quay/blob/master/LICENSE). This is reflected in the `docker-compose.yml` file used in this walk-through.**
Ensure [Docker Engine](https://docs.docker.com/engine/install) and [Docker Compose](https://docs.docker.com/compose/install) are installed before beginning.
### Docker-compose method (production)
**This method uses the pre-built Docker image from quay**
Note: Currently the repository has to be cloned, this is because the `init-invidious-db.sh` file and the `config/sql` directory have to be mounted to the postgres container (See the volumes section in the docker-compose file below). This "problem" will be solved in the future.
Make sure to run the newer Docker Compose V2: https://docs.docker.com/compose/install/linux/. It should already be installed if you can successfully run the command `docker compose` (with a space between the two words).
1. Execute these commands:
```bash
git clone https://github.com/iv-org/invidious.git
cd invidious
```
2. Generate two secret keys, one for Invidious (HMAC_KEY) and one for Invidious companion (invidious_companion_key)
```bash
pwgen 16 1 # for Invidious (HMAC_KEY)
pwgen 16 1 # for Invidious companion (invidious_companion_key)
```
3. Edit the docker-compose.yml with this content:
```docker
version: "3"
services:
invidious:
image: quay.io/invidious/invidious:master
# image: quay.io/invidious/invidious:master-arm64 # ARM64/AArch64 devices
restart: unless-stopped
# Remove "127.0.0.1:" if used from an external IP
ports:
- "127.0.0.1:3000:3000"
environment:
# Please read the following file for a comprehensive list of all available
# configuration options and their associated syntax:
# https://github.com/iv-org/invidious/blob/master/config/config.example.yml
INVIDIOUS_CONFIG: |
db:
dbname: invidious
user: kemal
password: kemal
host: invidious-db
port: 5432
check_tables: true
invidious_companion:
# URL used for the internal communication between invidious and invidious companion
# There is no need to change that except if Invidious companion does not run on the same docker compose file.
- private_url: "http://companion:8282"
# (public) URL used for the communication between your browser and invidious companion
# IF you are using a reverse proxy OR accessing invidious from an external IP then you NEED to change this value
# Please consult for more doc: https://github.com/unixfox/invidious/blob/invidious-companion/config/config.example.yml#L57-L88
# And make sure to add the routes from the post install when using a reverse proxy!
public_url: "http://localhost:8282"
# IT is NOT recommended to use the same key as HMAC KEY. Generate a new key!
# Use the key generated in the 2nd step
invidious_companion_key: "CHANGE_ME!!"
# external_port:
# domain:
# https_only: false
# statistics_enabled: false
# Use the key generated in the 2nd step
hmac_key: "CHANGE_ME!!"
healthcheck:
test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/trending || exit 1
interval: 30s
timeout: 5s
retries: 2
logging:
options:
max-size: "1G"
max-file: "4"
depends_on:
- invidious-db
companion:
image: quay.io/invidious/invidious-companion:latest
environment:
# Use the key generated in the 2nd step
- SERVER_SECRET_KEY=CHANGE_ME!!SAME_AS_INVIDIOUS_COMPANION_SECRET_KEY_FROM_INVIDIOUS_CONFIG
restart: unless-stopped
# Remove "127.0.0.1:" if used from an external IP
ports:
- "127.0.0.1:8282:8282"
logging:
options:
max-size: "1G"
max-file: "4"
cap_drop:
- ALL
read_only: true
# cache for youtube library
volumes:
- companioncache:/var/tmp/youtubei.js:rw
security_opt:
- no-new-privileges:true
invidious-db:
image: docker.io/library/postgres:14
restart: unless-stopped
volumes:
- postgresdata:/var/lib/postgresql/data
- ./config/sql:/config/sql
- ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
environment:
POSTGRES_DB: invidious
POSTGRES_USER: kemal
POSTGRES_PASSWORD: kemal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
volumes:
postgresdata:
companioncache:
```
Note: This compose is made for a true "production" setup, where Invidious is behind a reverse proxy. If you prefer to directly access Invidious, replace `127.0.0.1:3000:3000` with `3000:3000` under the `ports:` section.
4. Run the docker composition:
```
docker compose up -d
```
### Docker-compose method (development)
**This method builds a Docker image from source**
```bash
git clone https://github.com/iv-org/invidious.git
cd invidious
docker-compose up
```
## Manual Installation
### Linux
#### Install Crystal
Follow the instructions for your distribution here: https://crystal-lang.org/install/
**Note:** Invidious currently supports the following Crystal versions: `1.10.x` / `1.11.x` / `1.12.x`. \
Versions `1.9.x` and older are incompatible because we use features only present in the newer versions. \
Versions `1.13.x` should be compatible, however we did not test it.
#### Install the dependencies
Arch Linux
```bash
sudo pacman -S base-devel librsvg postgresql ttf-opensans
```
Debian/Ubuntu
```bash
sudo apt install libssl-dev libxml2-dev libyaml-dev libgmp-dev libreadline-dev postgresql librsvg2-bin libsqlite3-dev zlib1g-dev libpcre3-dev libevent-dev fonts-open-sans
```
RHEL based and RHEL-like systems (RHEL, Fedora, AlmaLinux, RockyLinux...)
```bash
sudo dnf install -y openssl-devel libevent-devel libxml2-devel libyaml-devel gmp-devel readline-devel postgresql librsvg2-devel sqlite-devel zlib-devel gcc open-sans-fonts
```
#### Add an Invidious user and clone the repository
```bash
useradd -m invidious
su - invidious
git clone https://github.com/iv-org/invidious
exit
```
#### Set up PostgreSQL
```bash
systemctl enable --now postgresql
sudo -i -u postgres
psql -c "CREATE USER kemal WITH PASSWORD 'kemal';" # Change 'kemal' here to a stronger password, and update `password` in config/config.yml
createdb -O kemal invidious
exit
```
#### Set up Invidious
```bash
su - invidious
cd invidious
make
# Configure config/config.yml as you like
cp config/config.example.yml config/config.yml
# edit config.yaml to include invidious companion
edit config/config.yaml
add:
invidious_companion:
# URL used for the internal communication between invidious and invidious companion
- private_url: "http://companion:8282"
# (public) URL used for the communication between your browser and invidious companion
# IF you are using a reverse proxy OR accessing invidious from an external IP then you NEED to change this value
# Please consult for more doc: https://github.com/unixfox/invidious/blob/invidious-companion/config/config.example.yml#L57-L88
public_url: "http://localhost:8282"
# IT is NOT recommended to use the same key as HMAC KEY. Generate a new key!
invidious_companion_key: "CHANGE_ME!!"
# Deploy the database
./invidious --migrate
exit
```
#### Systemd service for Invidious
```bash
cp /home/invidious/invidious/invidious.service /etc/systemd/system/invidious.service
systemctl enable --now invidious.service
```
#### Set up Invidious companion
```bash
wget https://github.com/iv-org/invidious-companion???
# or compile it using https://docs.deno.com/runtime/
git clone https://github.com/iv-org/invidious-companion.git
deno compile
# launch it manually
SERVER_SECRET_KEY=CHANGE_ME!!SAME_AS_INVIDIOUS_COMPANION_SECRET_KEY_FROM_INVIDIOUS_CONFIG ./invidious-companion
See more docs about the environment variables: https://github.com/iv-org/invidious-companion/wiki/Environment-variables
# OR create a new systemd service for running it in background
# TODO systemd service not yet available
# https://github.com/iv-org/invidious-companion/issues/3
sudo wget https://github.com/iv-org/invidious-companion/raw/refs/heads/master/systemd.service -O /etc/systemd/systemd/invidious-companion.service
sudo systemctl enable --now invidious.service
```
### MacOS
#### Install the dependencies
```bash
brew update
brew install crystal postgresql imagemagick librsvg
```
#### Clone the Invidious repository
```bash
git clone https://github.com/iv-org/invidious
cd invidious
```
#### Set up PostgreSQL
```bash
brew services start postgresql
createdb
psql -c "CREATE ROLE kemal WITH LOGIN PASSWORD 'kemal';" # Change 'kemal' here to a stronger password, and update `password` in config/config.yml
createdb -O kemal invidious
psql invidious kemal < config/sql/channels.sql
psql invidious kemal < config/sql/videos.sql
psql invidious kemal < config/sql/channel_videos.sql
psql invidious kemal < config/sql/users.sql
psql invidious kemal < config/sql/session_ids.sql
psql invidious kemal < config/sql/nonces.sql
psql invidious kemal < config/sql/annotations.sql
psql invidious kemal < config/sql/playlists.sql
psql invidious kemal < config/sql/playlist_videos.sql
```
#### Set up Invidious
```bash
make
# Configure config/config.yml as you like
cp config/config.example.yml config/config.yml
# edit config.yaml to include invidious companion
edit config/config.yaml
add:
invidious_companion:
# URL used for the internal communication between invidious and invidious companion
- private_url: "http://companion:8282"
# (public) URL used for the communication between your browser and invidious companion
# IF you are using a reverse proxy OR accessing invidious from an external IP then you NEED to change this value
# Please consult for more doc: https://github.com/unixfox/invidious/blob/invidious-companion/config/config.example.yml#L57-L88
public_url: "http://localhost:8282"
invidious_companion_key: "CHANGE_ME!!"
# launch invidious
./invidious
```
#### Set up Invidious companion
```bash
wget https://github.com/iv-org/invidious-companion???
# or compile it using https://docs.deno.com/runtime/
git clone https://github.com/iv-org/invidious-companion.git
deno compile
# launch it
SERVER_SECRET_KEY=CHANGE_ME!!SAME_AS_INVIDIOUS_COMPANION_SECRET_KEY_FROM_INVIDIOUS_CONFIG ./invidious-companion
See more docs about the environment variables: https://github.com/iv-org/invidious-companion/wiki/Environment-variables
```
### Windows
Crystal, the programming language used by Invidious, [doesn't officially support Windows yet](https://github.com/crystal-lang/crystal/issues/5430) but you can still install Invidious:
- By installing [Docker desktop](https://docs.docker.com/desktop/install/windows-install/) and then following [our guide about Docker](#docker).
- By installing [Windows Subsystem for Linux](https://msdn.microsoft.com/en-us/commandline/wsl/about) and then following [our guide about Linux](#linux).
- By installing [Windows-specific builds](https://github.com/crystal-lang/crystal/releases/) of Crystal. Be wary, as we don't currently have records of Invidious being tested on those "unsupported" builds yet.
## Post-install configuration:
Detailed configuration available in the [configuration guide](./configuration.md).
You must set a random generated value for the parameter `hmac_key:`! On Linux you can generate it using the command `pwgen 20 1`.
Because of various issues, Invidious **must** be restarted often, at least once a day, ideally every hour.
If you use a reverse proxy, you **must** configure Invidious to properly serve request through it:
`https_only: true` : if you are serving your instance via https, set it to true
`domain: domain.ext`: if you are serving your instance via a domain name, set it here
`external_port: 443`: if you are serving your instance via https, set it to 443
`use_pubsub_feeds: true`: if you are serving your instance on the internet, allow for faster notification of new videos ([detailed explanation](https://github.com/iv-org/invidious/blob/97c4165f55c4574efb554c9dae8d919d08da1cdd/config/config.example.yml#L409)).
`use_innertube_for_captions: true`: if you are serving a public instance or you are hosting Invidious in a datacenter, allow to unblock captions ([detailed explanation](https://github.com/iv-org/invidious/issues/2567#issuecomment-1727928996)).
AND make sure to add these new routes into your reverse proxy, example in various reverse proxy:
- [NGINX](./companion-nginx.md)
- [Apache2](./companion-apache2.md)
- [Caddy](./companion-caddy.md)
- [Traefik](./companion-traefik.md)
## Update Invidious
#### Updating a Docker install
```bash
docker-compose pull
docker-compose up -d
docker image prune -f
```
#### Update a manual install
```bash
su - invidious
cd invidious
git pull
make
exit
systemctl restart invidious.service
```
## Usage:
```bash
./invidious
```
#### Logrotate configuration
```bash
echo "/home/invidious/invidious/invidious.log {
rotate 4
weekly
notifempty
missingok
compress
minsize 1048576
}" | tee /etc/logrotate.d/invidious.logrotate
chmod 0644 /etc/logrotate.d/invidious.logrotate
```

55
docs/companion-nginx.md Normal file
View File

@ -0,0 +1,55 @@
# NGINX reverse proxy setup with Invidious companion
This is a very basic config, secured with Let's Encrypt. Any log is disabled by default. Do not forget to replace `server_name` with your domain.
```
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name invidious.domain.tld;
access_log off;
error_log /var/log/nginx/error.log crit;
ssl_certificate /etc/letsencrypt/live/invidious.domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/invidious.domain.tld/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host; # so Invidious knows domain
proxy_http_version 1.1; # to keep alive
proxy_set_header Connection ""; # to keep alive
}
location /latest_version {
proxy_pass http://127.0.0.1:8282;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host; # so Invidious companion knows domain
proxy_http_version 1.1; # to keep alive
proxy_set_header Connection ""; # to keep alive
}
location /api/manifest/dash/id/ {
proxy_pass http://127.0.0.1:8282;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host; # so Invidious companion knows domain
proxy_http_version 1.1; # to keep alive
proxy_set_header Connection ""; # to keep alive
}
location /videoplayback {
proxy_pass http://127.0.0.1:8282;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host; # so Invidious companion knows domain
proxy_http_version 1.1; # to keep alive
proxy_set_header Connection ""; # to keep alive
}
if ($https = '') { return 301 https://$host$request_uri; } # if not connected to HTTPS, perma-redirect to HTTPS
}
```

27
docs/companion-traefik.md Normal file
View File

@ -0,0 +1,27 @@
# Traefik reverse proxy setup with Invidious companion
This is a very basic config, assuming that you're using Traefik to manage SSL certificates for you, and Traefik is on the same server as the Invidious and companion container.
Do not forget to replace `<server_name>` with your domain.
**Invidious Setup**
```
...
labels:
- "traefik.enable=true"
- "traefik.http.routers.invidious.rule=Host(`<server_name>`) && !(Path(`/latest_version`) || PathPrefix(`/api/manifest/dash/id/`) || PathPrefix(`/videoplayback*`))"
- "traefik.http.routers.invidious.entrypoints=web-sec"
- "traefik.http.routers.invidious.tls.certresolver=le"
- "traefik.http.services.invidious.loadbalancer.server.port=3000"
...
```
**Companion Setup**
```
...
labels:
- "traefik.enable=true"
- "traefik.http.routers.invidious-companion.rule=Host(`<server_name>`) && (Path(`/latest_version`) || PathPrefix(`/api/manifest/dash/id/`) || PathPrefix(`/videoplayback*`))"
- "traefik.http.routers.invidious-companion.entrypoints=web-sec"
- "traefik.http.routers.invidious-companion.tls.certresolver=le"
- "traefik.http.services.invidious-companion.loadbalancer.server.port=8282"
...
```

View File

@ -1,3 +1,6 @@
# Configuration
An comprehensive list of all the available config options, with detailed explaination and default values is available under [`config/config.example.yml`](https://github.com/iv-org/invidious/blob/master/config/config.example.yml) in the main invidious repository.
An comprehensive list of all the available config options, with detailed explaination and default values is available under [`config/config.example.yml`](https://github.com/iv-org/invidious/blob/master/config/config.example.yml) in the main Invidious repository.
The path to the configuration file can be overridden with the
`INVIDIOUS_CONFIG_FILE` environment variable.

View File

@ -0,0 +1,75 @@
# How to make a new Invidious release
## Preamble
In the following document, `vX.Y.Z` is the release version, which should follow
the pattern `v<MAJOR>.<YYYY><MM><DD>.<PATCH>`
The major component is only updated on breaking changes (database migrations,
incompatible config changes). The minor component is the current UTC date.
The patch component is updated if a second release is done the same day.
## Step 0
Make sure you're synced with upstream:
```sh
git checkout master
git remote update
git pull origin master
```
## Step 1
Update CHANGELOG.md to reflect the changes made since the last release.
Each changelog entry is composed of a summary and a list of PRs (~= diff).
The summary should be simple and concise, and only reflect most important
changes, preferably sorted by impact (new features/breaking changes that the
users will see goes first, changes that affect developers/API users should go
last). Minor changes that are related to repo maintenance can be ignored.
Do not forget to list **ALL** the PRs that have been merged since the last
release, with the proper links.
Note: Maybe this should be done each time a PR is marged?
## Step 2
Commit the changes made to `CHANGELOG.md`:
```sh
git commit -S -m "Release vX.Y.Z"
```
**THEN** tag your release, like so:
```sh
git tag -as vX.Y.Z
```
Git will ask to provide a tag message. All you have to do is copy/pasting the
summary from `CHANGEMLOG.md` and adapt a the formatting as required. Do not
include the list of PRs merged.
## Step 3
Once you have checked everything, push to GitHub:
```sh
git push origin master
git push upstream vX.Y.Z
```
## Step 4
Got to GitHub to make a new release:
https://github.com/iv-org/invidious/releases/new
Select the tag your previously created, leave `target` set to `master`,
and then copy paste the text you wrote to `CHANGELOG.md` (both the summary and
the list of PRs merged since last release).
And then click "publish"!

135
docs/devtools.md Normal file
View File

@ -0,0 +1,135 @@
# Diagnose video playback issues with DevTools
## Why this tutorial?
Invidious or more specifically Video.JS (the library for the video player) can't give you a proper error for the famous message "The media could not be loaded, either because the server or network failed or because the format is not supported.".
Here is how to find the real error and fix it.
## Requirements
This tutorial only works on the desktop version of Firefox and Chromium based browsers (Chrome, Brave, Opera, Vivaldi, Edge and so on).
## Open DevTools and get familiar with the Network tab
1. Press the F12 key on your keyboard. Or Ctrl + Shift + E at the same time if F12 did not work.
2. By default, this will automatically show you the "Elements" category. Click instead on the "Network" tab.
3. You should see a window like this:
![DevTools on Google Chrome](./images/devtools-chrome.png)
![DevTools on Firefox](./images/devtools-firefox.png)
4. You may not see any requests listed yet or already some active requests, follow the second part for the troubleshooting part.
## Troubleshoot failed requests
1. Keep the Devtools open.
2. On Chromium based browser, drag the "Status" column to make it wide as much as possible.
![Wide status bar on Google Chrome](./images/devtools-chrome-wide-status.gif)
On Firefox, drag the "Transferred" column to make it wide as much as possible.
![Wide transferred bar on Google Chrome](./images/devtools-firefox-wide-transferred.gif)
3. Refresh the page (F5 key) and load your video again if refreshing did not play the video again.
4. Every line under Name, Status, Type, Size OR "Status", "Method", "File" is a "Web Request". More info about what it is [here](https://web.archive.org/web/20241207173530/https://sourcedefense.com/glossary/web-request/).
![DevTools requests on Google Chrome](./images/devtools-chrome-requests.png)
![DevTools requests on Firefox](./images/devtools-firefox-requests.png)
5. Look for lines that are in red color. For each one, read the type of request with their cause and possible solutions:
### A) Request with name "videoplayback" and with Status 403 OR NS_BINDING_ABORTED
![videoplayback with status 403 on Firefox](./images/devtools-chrome-videoplayback-403.png)
![videoplayback with status 403 on Firefox](./images/devtools-firefox-videoplayback-403.png)
#### Diagnostic
On Chromium based browser, you will immediately see the status code. You can read "Cause and solutions".
On Firefox, click on the line of the request. Then look for "Status" on the new section opened, if it's 403 then read the "Cause and solutions". If it is not then read the other requests types.
#### Cause and solutions
Please read the dedicated page here: [Videoplayback URLs that returns 403 HTTP errors](./youtube-errors-explained.md#videoplayback-urls-that-returns-403-http-errors)
### B) Request with name "videoplayback" or "latest_version" or some random number/letters with "?local=true" and with Status ERR_NAME_NOT_RESOLVED OR NS_ERROR_UNKNOWN_HOST or CORS failed or NS_ERROR_CONNECTION_REFUSED or ERR_CONNECTION_REFUSED or any error starting with NS_ERROR_CONNECTION or ERR_CONNECTION
![latest_version unknown host](./images/devtools-firefox-unknown-host-latest-version.png)
![dash unknown host](./images/devtools-firefox-unknown-host-dash.png)
![latest_version connection refused](./images/devtools-firefox-connection-refused-latest-version.png)
![latest_version unknown host](./images/devtools-chrome-unknown-host-latest-version.png)
![latest_version connection refused](./images/devtools-chrome-connection-refused-latest-version.png)
#### Cause
Your browser can't resolve an external resource because the domain/hostname doesn't exist or no server is not listening to the port or the port is restricted.
#### Solutions
- Make sure you have correctly followed the post install [in the installation guide](./installation.md).
- Look for possible solutions in the GitHub issues of Invidious by searching for the error message: https://github.com/iv-org/invidious/issues
- If you are trying the new Invidious companion, make sure that public_url and base_url is correctly configured. Double check!
### C) Request with Status 500 or Status 400
![error with status 500](./images/devtools-chrome-500.png)
![error with status 500](./images/devtools-firefox-500.png)
#### Cause
The Invidious backend returned an error.
#### Diagnostic
Click on the line of the request then go "Preview" tab and visualize the error.
If it's an HTML response then you will see the error directly, if it's JSON then you might have to scroll or find more precisely the error.
#### Solution
Keep note of the error found using DevTools and also look at the logs of Invidious for any errors. Once done, search in the Invidious issues for possible solutions: https://github.com/iv-org/invidious/issues
### D) I see red lines for "videoplayback" but my error type is not listed
#### Diagnostic
Click on the line of the request then check the Status Code or "Status" in Firefox.
#### Solution
- Look for possible solutions in the GitHub issues of Invidious by searching for the error message: https://github.com/iv-org/invidious/issues
- If you did not really find any solution then you might have hit a unknown bug, if that's the case then please open a bug report at https://github.com/iv-org/invidious/issues/new/choose.
Make sure to include as much details as possible.
### E) I don't see any red lines
#### Diagnostic
Go to the Console tab and check the errors. If you see errors like: `The media could not be loaded, either because the server or network failed or because the format is not supported.`, then check the solutions:
#### Solution(s)
- If you are on Microsoft Edge or on a non-standard Firefox installation, you might be missing some codecs: https://github.com/iv-org/invidious/issues/3756
- Look for possible solutions in the GitHub issues of Invidious by searching for the error message: https://github.com/iv-org/invidious/issues
- If you did not really find any solution then you might have hit a unknown bug, if that's the case then please open a bug report at https://github.com/iv-org/invidious/issues/new/choose.
Make sure to include as much details as possible.
## Export the requests done for further analysis by Invidious developers
??? warning "Before sending the file to anyone!"
Do not send this file to any random person. The file contains personal info and sensible info.
Only share it to the people that you trust, for example to Invidious developers.
Or remove yourself any personal info by editing the file.
Use the following button on Chromium based browser:
![export har](./images/devtools-chrome-export-har.png)
Or on Firefox:
![export har](./images/devtools-firefox-export-har.png)
## Advanced troubleshooting
For Chromium based browsers, I recommend following this tutorial which explains how to use the Network tab: https://developer.chrome.com/docs/devtools/overview#network
And there is a video too: https://youtu.be/t1c5tNPpXjs?t=206
For Firefox, there is a dedicated guide here: https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/index.html

View File

@ -118,7 +118,7 @@ or delete these data at any time from your user account page.
## **Q:** What data is shared with YouTube?
**A:** By default, the video stream is fetched directly from Google's servers
(`googlevideo.com`) in order to reduce the bandwidth required by invidious,
(`googlevideo.com`) in order to reduce the bandwidth required by Invidious,
meaning that Google will be able to see your IP address and some other data
commonly sent by web browsers, like your user-agent string.
@ -137,6 +137,9 @@ sent by your browser.
**A:** This problem can occur in different scenarios:
* If you are the one that have installed Invidious, please read the page
["All the YouTube error messages explained with solutions"](./youtube-errors-explained.md)
* If you're trying to watch a music clip, Youtube is likely blocking the
video stream. Try enabling `Proxy videos` in the preferences (or add
`&local=1` in the URL). Switching to another instance is also a good
@ -250,7 +253,7 @@ used for the session (`SID`) and preferences (`PREFS`) cookies. If set
incorrectly, the cookies will be invalid, and your browser will silently
ignore them.
**If you access your invidious instance by IP address (like `192.168.1.205`)
**If you access your Invidious instance by IP address (like `192.168.1.205`)
then leave the `domain` config option EMPTY!**
Common invalid values include:

152
docs/gluetun.md Normal file
View File

@ -0,0 +1,152 @@
# Make Invidious requests data from YouTube through a VPN using Gluetun (in case your IP is blocked)
??? warning "No guarantees"
This tutorial does not guarantee Invidious to function again. This depends on the public IP address from the VPN that you will be using.
YouTube has blocked datacenter IP addresses. If you are using the IP address of a well known VPN provider, this won't solve your issues.
IP addresses that may not be blocked are residential IP addresses (like at home).
If following this tutorial made Invidious working again, there is no guarantee that it will keep functioning forever. YouTube may detect traffic coming from Invidious and block your public IP address.
This tutorial has been written by [TheFrenchGhosty](https://github.com/TheFrenchGhosty). He is better suited when looking for help about this tutorial.
## Create the docker network (must be done outside of the compose file):
```
docker network create --subnet=172.80.0.0/16 gluetun_network
```
Note: We're not using the Gluetun default of 172.18.0.0/16, because it might already be used which causes Gluetun to not start with the error `Error response from daemon: invalid pool request: Pool overlaps with other one on this address space`, if you have this issue with 172.80.0.0/16 just use a number higher than "80" (at the second byte) and apply the rest of the documentation accordingly
## Create the compose file for Gluetun
- Global setup: https://github.com/qdm12/gluetun-wiki/tree/main/setup
- Provider setup: https://github.com/qdm12/gluetun-wiki/tree/main/setup/providers
```
services:
gluetun:
image: ghcr.io/qdm12/gluetun
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
ports:
# - 8888:8888/tcp # HTTP proxy # Not relevant
# - 8388:8388/tcp # Shadowsocks # Not relevant
# - 8388:8388/udp # Shadowsocks # Not relevant
- "127.0.0.1:3000:3000" # Invidious (use the Invidious ports configuration)
volumes:
- /docker/gluetun/data:/gluetun
environment:
- VPN_SERVICE_PROVIDER=<REDACTED>
- VPN_TYPE=openvpn # Use openvpn or wireguard
- OPENVPN_USER=<REDACTED>
- OPENVPN_PASSWORD=<REDACTED>
- SERVER_COUNTRIES=Germany # Use your server location
- UPDATER_PERIOD=24h
- TZ=Europe/Paris # Use your timezone
networks:
gluetun_network:
networks:
gluetun_network:
external: true
```
## Make Invidious use gluetun
Add this to your DB:
```
networks:
gluetun_network:
ipv4_address: 172.80.0.22
```
Add this to the end of your compose (to make the Invidious-Postgres stack connect to gluetun):
```
networks:
gluetun_network:
external: true
```
Add this to the Invidious container:
```
network_mode: "container:gluetun"
```
Comment out the "- ports:" of the Invidious container (gluetun replaces it, reason why we configured it with the same value)
Update the Invidious config to use the new database address (since the network is "different", using the hostname wont work):
```
INVIDIOUS_CONFIG: |
db:
dbname: invidious
user: kemal
password: <REDACTED>
host: 172.80.0.22
port: 5432
```
## Tell Gluetun to change IP daily (optional but recommended)
**Don't forget to replace `/path/to/` with a proper path**
- Control server documentation https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md
Start by exposing the Gluetun control server internally (DO NOT EXPOSE IT EXTERNALLY, KEEP `127.0.0.1`), add this port mapping to Gluetun:
```
ports:
- 127.0.0.1:8000:8000/tcp # Control server
```
Write a script named `restartvpn.sh` and add this content to it:
! Remember to replace /path/to/ with the path you want the log to go (either the script location, or `/var/log/`) !
Note: `2>&1` sent STDERR to STDOUT, `tee /path/to/restartvpn.log` will write the output of the script to /path/to/restartvpn.log (in the current directory) (while still printing it to the shell)
```bash
#!/usr/bin/env bash
echo "BEGIN $(date --rfc-3339=seconds)" 2>&1 | tee -a /path/to/restartvpn.log
curl -s -X GET "http://127.0.0.1:8000/v1/publicip/ip" 2>&1 | tee -a /path/to/restartvpn.log # Print the original IP
curl -s -X PUT -H "Content-Type: application/json" -d '{"status":"stopped"}' "http://127.0.0.1:8000/v1/openvpn/status" 2>&1 | tee -a /path/to/restartvpn.log # Stop OpenVPN
sleep 5
curl -s -X PUT -H "Content-Type: application/json" -d '{"status":"running"}' "http://127.0.0.1:8000/v1/openvpn/status" 2>&1 | tee -a /path/to/restartvpn.log # Start OpenVPN (changing the server it's connecting to)
sleep 5
curl -s -X GET "http://127.0.0.1:8000/v1/openvpn/status" 2>&1 | tee -a /path/to/restartvpn.log # Print the Gluetun status
curl -s -X GET "http://127.0.0.1:8000/v1/publicip/ip" 2>&1 | tee -a /path/to/restartvpn.log # Print the new IP
echo "END $(date --rfc-3339=seconds)" 2>&1 | tee -a /path/to/restartvpn.log
```
Run this daily using cron
Run `crontab -e` and add a new cronjob:
```
@daily /path/to/restartvpn.sh
```

View File

@ -12,7 +12,7 @@ This proxy server will only redirect the [TCP](https://en.wikipedia.org/wiki/Tra
By forwarding the actual HTTP protocol this is more compute intensive and won't be covered in this tutorial.
You need to proxy the HTTP protocol normally like you would already do with your current web server for invidious. But in this case from the proxy server to your existing infrastructure. Then also setup the certificates for HTTPS.
You need to proxy the HTTP protocol normally like you would already do with your current web server for Invidious. But in this case from the proxy server to your existing infrastructure. Then also setup the certificates for HTTPS.
Then you optionally preserve the IP address of your clients using for example on NGINX set_real_ip_from and real_ip_header.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -18,12 +18,16 @@
## For Administrators
- [Installation](./installation.md)
- [Invidious companion documentation](./invidious-companion.md)
- [Configuration](./configuration.md)
- [YouTube error messages explained with solutions](./youtube-errors-explained.md)
- [Diagnose video playback issues with DevTools](./devtools.md)
- [NGINX reverse proxy setup](./nginx.md)
- [Caddy reverse proxy setup](./caddy.md)
- [Apache2 reverse proxy setup](./apache2.md)
- [Database maintenance](./db-maintenance.md)
- [CAPTCHA bug on Debian and Ubuntu](./captcha-bug.md)
- [Registering users manually](./register-user.md)
- [Reset user password](./reset-password.md)
- [Known Exception in log](./known-exception.md)

View File

@ -12,6 +12,8 @@ Running Invidious requires at least 20GB disk space, 512MB of free RAM (so ~2G i
Compiling Invidious requires at least 2.5GB of free RAM (We recommend to have at least 4GB installed).
If you have less (e.g on a cheap VPS) you can setup a SWAP file or partition, so the combined amount is >= 4GB.
You need at least 1GB of RAM for the machine that will run the tool `youtube-trusted-session-generator` in the 1st step. Doesn't need to be the same machine as the one running Invidious, just a machine running on the same public IP address.
## Docker
**The Invidious docker image is only [available on Quay](https://quay.io/repository/invidious/invidious) because, unlike Docker Hub, [Quay is Free and Open Source Software](https://github.com/quay/quay/blob/master/LICENSE). This is reflected in the `docker-compose.yml` file used in this walk-through.**
@ -24,71 +26,115 @@ Ensure [Docker Engine](https://docs.docker.com/engine/install) and [Docker Compo
Note: Currently the repository has to be cloned, this is because the `init-invidious-db.sh` file and the `config/sql` directory have to be mounted to the postgres container (See the volumes section in the docker-compose file below). This "problem" will be solved in the future.
```bash
git clone https://github.com/iv-org/invidious.git
cd invidious
```
Make sure to run the newer Docker Compose V2: https://docs.docker.com/compose/install/linux/. It should already be installed if you can successfully run the command `docker compose` (with a space between the two words).
Edit the docker-compose.yml with this content:
??? warning "About po_token and visitor_data identities"
```docker
version: "3"
services:
po_token known as Proof of Origin Token. This is an attestation token generated by a complex anti robot verification system created by Google named BotGuard/DroidGuard. It is used to confirm that the request is coming from a genuine device.
These identity tokens (po_token and visitor_data) generated in this tutorial will make your entire Invidious session more easily traceable by YouTube because it is tied to a unique identifier.
There is currently no official automatic tool to periodically change these tokens. This is working in progress but, for the time being, this is the solution the Invidious team is offering.
invidious:
image: quay.io/invidious/invidious:latest
# image: quay.io/invidious/invidious:latest-arm64 # ARM64/AArch64 devices
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
environment:
# Please read the following file for a comprehensive list of all available
# configuration options and their associated syntax:
# https://github.com/iv-org/invidious/blob/master/config/config.example.yml
INVIDIOUS_CONFIG: |
db:
dbname: invidious
user: kemal
password: kemal
host: invidious-db
port: 5432
check_tables: true
# external_port:
# domain:
# https_only: false
# statistics_enabled: false
hmac_key: "CHANGE_ME!!"
healthcheck:
test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/trending || exit 1
interval: 30s
timeout: 5s
retries: 2
logging:
options:
max-size: "1G"
max-file: "4"
depends_on:
- invidious-db
If you want to be less traceable, you can always script the process by changing the identities every X hour.
1. Generate po_token and visitor_data identities for passing all verification checks on YouTube side:
```
docker run quay.io/invidious/youtube-trusted-session-generator
```
You have to run this command on the same public IP address as the one blocked by YouTube. Not necessarily the same machine, just the same public IP address.
You will need to copy these two parameters in the third step.
Subsequent usage of this same token will work on the same IP range or even the same ASN. The point is to generate this token on a blocked IP as "unblocked" IP addresses seems to not generate a token valid for passing the checks on a blocked IP.
2. Execute these commands:
```bash
git clone https://github.com/iv-org/invidious.git
cd invidious
```
3. Edit the docker-compose.yml with this content:
```docker
version: "3"
services:
invidious:
image: quay.io/invidious/invidious:latest
# image: quay.io/invidious/invidious:latest-arm64 # ARM64/AArch64 devices
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
environment:
# Please read the following file for a comprehensive list of all available
# configuration options and their associated syntax:
# https://github.com/iv-org/invidious/blob/master/config/config.example.yml
INVIDIOUS_CONFIG: |
db:
dbname: invidious
user: kemal
password: kemal
host: invidious-db
port: 5432
check_tables: true
signature_server: inv_sig_helper:12999
visitor_data: "CHANGE_ME!!"
po_token: "CHANGE_ME!!"
# external_port:
# domain:
# https_only: false
# statistics_enabled: false
hmac_key: "CHANGE_ME!!"
healthcheck:
test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/trending || exit 1
interval: 30s
timeout: 5s
retries: 2
logging:
options:
max-size: "1G"
max-file: "4"
depends_on:
- invidious-db
inv_sig_helper:
image: quay.io/invidious/inv-sig-helper:latest
init: true
command: ["--tcp", "0.0.0.0:12999"]
environment:
- RUST_LOG=info
restart: unless-stopped
cap_drop:
- ALL
read_only: true
security_opt:
- no-new-privileges:true
invidious-db:
image: docker.io/library/postgres:14
restart: unless-stopped
volumes:
- postgresdata:/var/lib/postgresql/data
- ./config/sql:/config/sql
- ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
environment:
POSTGRES_DB: invidious
POSTGRES_USER: kemal
POSTGRES_PASSWORD: kemal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
invidious-db:
image: docker.io/library/postgres:14
restart: unless-stopped
volumes:
- postgresdata:/var/lib/postgresql/data
- ./config/sql:/config/sql
- ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
environment:
POSTGRES_DB: invidious
POSTGRES_USER: kemal
POSTGRES_PASSWORD: kemal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
postgresdata:
```
Note: This compose is made for a true "production" setup, where Invidious is behind a reverse proxy. If you prefer to directly access Invidious, replace `127.0.0.1:3000:3000` with `3000:3000` under the `ports:` section.
4. Run the docker composition:
volumes:
postgresdata:
```
Note: This compose is made for a true "production" setup, where Invidious is behind a reverse proxy. If you prefer to directly access Invidious, replace `127.0.0.1:3000:3000` with `3000:3000` under the `ports:` section.
docker compose up -d
```
### Docker-compose method (development)
@ -106,11 +152,42 @@ docker-compose up
### Linux
#### Generate po_token and visitor_data identities
[Follow these instructions here on the official tool `youtube-trusted-session-generator`](https://github.com/iv-org/youtube-trusted-session-generator?tab=readme-ov-file#tutorial-without-docker)
These two parameters will be required for passing all verification checks on YouTube side and you will have to configure them in Invidious.
You have to run this command on the same public IP address as the one blocked by YouTube. Not necessarily the same machine, just the same public IP address.
You will need to copy these two parameters in the `config.yaml` file.
Subsequent usage of this same token will work on the same IP range or even the same ASN. The point is to generate this token on a blocked IP as "unblocked" IP addresses seems to not generate a token valid for passing the checks on a blocked IP.
??? warning "About po_token and visitor_data identities"
po_token known as Proof of Origin Token. This is an attestation token generated by a complex anti robot verification system created by Google named BotGuard/DroidGuard. It is used to confirm that the request is coming from a genuine device.
These identity tokens (po_token and visitor_data) generated in this tutorial will make your entire Invidious session more easily traceable by YouTube because it is tied to a unique identifier.
There is currently no official automatic tool to periodically change these tokens. This is working in progress but, for the time being, this is the solution the Invidious team is offering.
If you want to be less traceable, you can always script the process by changing the identities every X hour.
#### Run inv_sig_helper in background
[Follow these instructions here on the official tool `inv_sig_helper`](https://github.com/iv-org/inv_sig_helper?tab=readme-ov-file#building-and-running-without-docker) and run it in the background with systemd for example.
inv_sig_helper handle the "deciphering" of the video stream fetched from YouTube servers. As it is running untrusted code from Google themselves, make sure to isolate it by for example running it inside a LXC or locked down through systemd.
The following systemd service file can be used to run inv_sig_helper with systemd: https://github.com/iv-org/inv_sig_helper/blob/master/inv_sig_helper.service
#### Install Crystal
Follow the instructions for your distribution here: https://crystal-lang.org/install/
Note: Invidious currently supports the following Crystal versions: `1.9.2` / `1.8.2` / `1.7.X` / `1.6.X`
**Note:** Invidious currently supports the following Crystal versions: `1.12.x` / `1.13.x` / `1.14.x`. \
Versions `1.11.x` and older are incompatible because we use features only present in the newer versions. \
Versions `1.15.x` should be compatible, however we did not test it.
#### Install the dependencies
@ -158,6 +235,10 @@ make
# Configure config/config.yml as you like
cp config/config.example.yml config/config.yml
# edit config.yaml to include po_token and visitor_data previously generated
edit config/config.yaml
# Deploy the database
./invidious --migrate
@ -173,54 +254,22 @@ systemctl enable --now invidious.service
### MacOS
#### Install the dependencies
We recommend installing [Docker desktop](https://docs.docker.com/desktop/setup/install/mac-install/) and then following [our guide about Docker](#docker) which will make the installation easier.
```bash
brew update
brew install crystal postgresql imagemagick librsvg
```
#### Clone the Invidious repository
```bash
git clone https://github.com/iv-org/invidious
cd invidious
```
#### Set up PostgreSQL
```bash
brew services start postgresql
createdb
psql -c "CREATE ROLE kemal WITH LOGIN PASSWORD 'kemal';" # Change 'kemal' here to a stronger password, and update `password` in config/config.yml
createdb -O kemal invidious
psql invidious kemal < config/sql/channels.sql
psql invidious kemal < config/sql/videos.sql
psql invidious kemal < config/sql/channel_videos.sql
psql invidious kemal < config/sql/users.sql
psql invidious kemal < config/sql/session_ids.sql
psql invidious kemal < config/sql/nonces.sql
psql invidious kemal < config/sql/annotations.sql
psql invidious kemal < config/sql/playlists.sql
psql invidious kemal < config/sql/playlist_videos.sql
```
#### Set up Invidious
```bash
make
# Configure config/config.yml as you like
cp config/config.example.yml config/config.yml
```
But if you are more experienced, you may follow the community installation guide about [MacOS](./community-installation-guide.md#macos)
### Windows
Crystal, the programming language used by Invidious, [doesn't officially support Windows yet](https://github.com/crystal-lang/crystal/issues/5430) but you can still install Invidious:
- By installing [Docker desktop](https://docs.docker.com/desktop/install/windows-install/) and then following [our guide about Docker](#docker).
- By installing [Docker desktop](https://docs.docker.com/desktop/setup/install/windows-install/) and then following [our guide about Docker](#docker).
- By installing [Windows Subsystem for Linux](https://msdn.microsoft.com/en-us/commandline/wsl/about) and then following [our guide about Linux](#linux).
- By installing [Windows-specific builds](https://github.com/crystal-lang/crystal/releases/) of Crystal. Be wary, as we don't currently have records of Invidious being tested on those "unsupported" builds yet.
- By installing [Windows-specific builds](https://github.com/crystal-lang/crystal/releases/) of Crystal. Be wary, as we don't currently have records of Invidious being tested on those "unsupported" builds yet.
Not official supported by Invidious developers!
### Is your platform not listed (Podman, BSD, LXC and more)?
Take a look at the community installation guide: [here](./community-installation-guide.md)
## Post-install configuration:
@ -228,9 +277,9 @@ Detailed configuration available in the [configuration guide](./configuration.md
You must set a random generated value for the parameter `hmac_key:`! On Linux you can generate it using the command `pwgen 20 1`.
Because of various issues Invidious **must** be restarted often, at least once a day, ideally every hour.
Because of various issues, Invidious **must** be restarted often, at least once a day, ideally every hour.
If you use a reverse proxy, you **must** configure invidious to properly serve request through it:
If you use a reverse proxy, you **must** configure Invidious to properly serve request through it:
`https_only: true` : if you are serving your instance via https, set it to true
@ -240,7 +289,7 @@ If you use a reverse proxy, you **must** configure invidious to properly serve r
`use_pubsub_feeds: true`: if you are serving your instance on the internet, allow for faster notification of new videos ([detailed explanation](https://github.com/iv-org/invidious/blob/97c4165f55c4574efb554c9dae8d919d08da1cdd/config/config.example.yml#L409)).
`use_innertube_for_captions: true`: if you are serving a public instance or you are hosting invidious in a datacenter, allow to unblock captions ([detailed explanation](https://github.com/iv-org/invidious/issues/2567#issuecomment-1727928996)).
`use_innertube_for_captions: true`: if you are serving a public instance or you are hosting Invidious in a datacenter, allow to unblock captions ([detailed explanation](https://github.com/iv-org/invidious/issues/2567#issuecomment-1727928996)).
## Update Invidious

View File

@ -6,99 +6,31 @@
**Warning: Any public instance that isn't in this list is considered untrustworthy. Use them at your own risk.**
**The list of public instances is short due to the [recent YouTube issues](https://github.com/iv-org/invidious/issues/4734). If you can, [please host Invidious at home](./installation.md) instead of using a public instance.**
## List of public Invidious Instances (sorted from oldest to newest):
* [yewtu.be](https://yewtu.be) 🇩🇪 - Source code/changes: https://github.com/yewtudotbe/invidious-custom
* [vid.puffyan.us](https://vid.puffyan.us) 🇺🇸
* [yt.artemislena.eu](https://yt.artemislena.eu) 🇩🇪
* [invidious.flokinet.to](https://invidious.flokinet.to) 🇷🇴
* [invidious.privacydev.net](https://invidious.privacydev.net) 🇫🇷
* [iv.melmac.space](https://iv.melmac.space) 🇩🇪
* [iv.ggtyler.dev](https://iv.ggtyler.dev) 🇺🇸
* [invidious.lunar.icu](https://invidious.lunar.icu) 🇩🇪 (uses Cloudflare)
* [inv.nadeko.net](https://inv.nadeko.net) 🇨🇱
* [inv.tux.pizza](https://inv.tux.pizza) 🇺🇸
* [invidious.protokolla.fi](https://invidious.protokolla.fi) 🇩🇪
* [iv.nboeck.de](https://iv.nboeck.de) 🇩🇪
* [invidious.private.coffee](https://invidious.private.coffee) 🇦🇹
* [yt.drgnz.club](https://yt.drgnz.club) 🇨🇿
* [iv.datura.network](https://iv.datura.network) 🇫🇮
* [invidious.fdn.fr](https://invidious.fdn.fr) 🇫🇷
* [invidious.perennialte.ch](https://invidious.perennialte.ch) 🇦🇺 (uses Cloudflare)
* [yt.cdaut.de](https://yt.cdaut.de) 🇩🇪
* [invidious.drgns.space](https://invidious.drgns.space) 🇺🇸
* [inv.us.projectsegfau.lt](https://inv.us.projectsegfau.lt) 🇺🇸
* [invidious.einfachzocken.eu](https://invidious.einfachzocken.eu) 🇩🇪
* [invidious.nerdvpn.de](https://invidious.nerdvpn.de) 🇺🇦
* [invidious.jing.rocks](https://invidious.jing.rocks) 🇯🇵
* [vid.lilay.dev](https://vid.lilay.dev) 🇸🇬 (uses Cloudflare)
* [invidious.privacyredirect.com](https://invidious.privacyredirect.com) 🇫🇮
* [invidious.reallyaweso.me](https://invidious.reallyaweso.me) 🇩🇪
* [invidious.materialio.us](https://invidious.materialio.us) 🇳🇿
* [inv.in.projectsegfau.lt](https://inv.in.projectsegfau.lt) 🇮🇳
* [invidious.incogniweb.net](https://invidious.incogniweb.net) 🇺🇸
* [inv.nadeko.net](https://inv.nadeko.net) 🇨🇱 - Source code/changes: https://git.nadeko.net/Fijxu/invidious - CAPTCHA: mCaptcha (https://mcaptcha.org/)
### Tor Onion Services:
* [grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad.onion](http://grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad.onion) 🇺🇸 (Onion of vid.puffyan.us)
* [ng27owmagn5amdm7l5s3rsqxwscl5ynppnis5dqcasogkyxcfqn7psid.onion](http://ng27owmagn5amdm7l5s3rsqxwscl5ynppnis5dqcasogkyxcfqn7psid.onion) 🇩🇪 (Onion of yt.artemislena.eu)
* [invidious.g4c3eya4clenolymqbpgwz3q3tawoxw56yhzk4vugqrl6dtu3ejvhjid.onion](http://invidious.g4c3eya4clenolymqbpgwz3q3tawoxw56yhzk4vugqrl6dtu3ejvhjid.onion) 🇫🇷 (Onion of invidious.privacydev.net)
* [inv.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion](http://inv.pjsfkvpxlinjamtawaksbnnaqs2fc2mtvmozrzckxh7f3kis6yea25ad.onion) 🇩🇪 (Onion of invidious.projectsegfau.lt)
* [inv.nadekonw7plitnjuawu6ytjsl7jlglk2t6pyq6eftptmiv3dvqndwvyd.onion](http://inv.nadekonw7plitnjuawu6ytjsl7jlglk2t6pyq6eftptmiv3dvqndwvyd.onion) 🇨🇱 (Onion of inv.nadeko.net)
* [nerdvpneaggggfdiurknszkbmhvjndks5z5k3g5yp4nhphflh3n3boad.onion](http://nerdvpneaggggfdiurknszkbmhvjndks5z5k3g5yp4nhphflh3n3boad.onion) 🇺🇦 (Onion of invidious.nerdvpn.de)
### I2P Eepsites:
* [http://pjsfhqamc7k6htnumrvn4cwqqdoggeepj7u5viyimgnxg3gar72q.b32.i2p](http://pjsfhqamc7k6htnumrvn4cwqqdoggeepj7u5viyimgnxg3gar72q.b32.i2p) 🇫🇷 (Eepsite of invidious.projectsegfau.lt)
* [http://pjsfi2szfkb4guqzmfmlyq4no46fayertjrwt4h2uughccrh2lvq.b32.i2p](http://pjsfi2szfkb4guqzmfmlyq4no46fayertjrwt4h2uughccrh2lvq.b32.i2p) 🇱🇺 (Eepsite of inv.bp.projectsegfau.lt)
* [zzlsbhhfvwg3oh36tcvx4r7n6jrw7zibvyvfxqlodcwn3mfrvzuq.b32.i2p](http://zzlsbhhfvwg3oh36tcvx4r7n6jrw7zibvyvfxqlodcwn3mfrvzuq.b32.i2p) 🇨🇱 (Eepsite of inv.nadeko.net)
## Rules to have your instance in this list:
1. Instances MUST have been up for at least a month before it can be added to this list.
2. Instances MUST have been updated in the last month. An instance that hasn't been updated in the last month is considered unmaintained and is removed from the list.
2. Instances MUST not be more than a month out of date compared with either the latest commit or latest release. Any instance that is more than a month out of date is considered unmaintained and will be removed from the list.
3. Instances MUST have statistics (`/api/v1/stats`) enabled (`statistics_enabled: true` in the configuration file).
4. Instances MUST have an uptime of at least 90% ([according to uptime.invidious.io](https://uptime.invidious.io/)).
5. Instances MUST be served via domain name.
6. Instances MUST be served via HTTPS (or/and onion).
7. Instances using any DDoS Protection / MITM MUST be marked as such (e.g. Cloudflare, DDoS-Guard).
8. Instances using any type of anti-bot protection MUST be marked as such.
9. Instances MUST NOT use any type of analytics.
9. Instances MUST NOT use any type of analytics, including external scripts of any kind.
10. Any system whose goal is to modify the content served to the user (i.e web server HTML rewrite) is considered the same as modifying the source code.
11. Instances running a modified source code:
- MUST respect the [GNU AGPL](https://en.wikipedia.org/wiki/GNU_Affero_General_Public_License) by publishing their source code and stating their changes **before** they are added to the list

View File

@ -0,0 +1,7 @@
# Invidious companion documentation
If you are looking for the installation guide then please read [companion-installation](./companion-installation.md).
If you are looking for extra documentation about Invidious companion then please visit: [https://github.com/iv-org/invidious-companion/wiki](https://github.com/iv-org/invidious-companion/wiki).
The extra documentation for Invidious companion is not located at https://docs.invidious.io in order to avoid bloating the existing Invidious documentation.

View File

@ -78,7 +78,7 @@ If needed, IPv6 official documentation for Docker is at https://docs.docker.com/
}
```
2. Restart Docker
3. In your docker-compose file of invidious. Add these lines at the end of your docker-compose
3. In your docker-compose file of Invidious. Add these lines at the end of your docker-compose
```yaml
networks:
default:

View File

@ -6,8 +6,9 @@ This is a very basic config, secured with Let's Encrypt. Any log is disabled by
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name invidious.domain.tld;

View File

@ -49,7 +49,7 @@ For clarity, an example of a URL parameter would be &related_videos=false&commen
For redirects with ? in the URL, the Parameter string will start with &, while redirects without ? in the URL should have a Parameter string begining with ?, so https://[Invidious Domain Here]/$2 becomes ```https://[Invidious Domain Here]/$2?related_videos=false&comments=false```
Should you choose to use URL Parameters, I would reccomend adding the following rules to both ensure all invidious videos load with your preference, and to ensure that unnecesary parameters are not added when already applied.
Should you choose to use URL Parameters, I would reccomend adding the following rules to both ensure all Invidious videos load with your preference, and to ensure that unnecesary parameters are not added when already applied.
# Rule 5 (Redirects Invidious Video URLs with parameters)

29
docs/register-user.md Normal file
View File

@ -0,0 +1,29 @@
# Registering users manually
You might want to disable registration in your [instance config](./configuration.md), but still have a quick way to manually register users upon request. To do so, first set up a separate instance that only listens on localhost, has registration enabled,
and captchas as well as background jobs disabled. Make sure you have a way to start it easily with just one or a few commands, e.g. via a systemd service. Then, use something like the script below (in the example, the instance is started via a systemd
service called `podman-invidious_register`, and it listens on localhost port 21742. **Warning**: This script is vulnerable to SQL injections. Only use trusted inputs; if you want to make a custom signup form and use this as a backend, be sure to
sanitize inputs.
```sh
#!/usr/bin/env bash
set -e
systemctl start podman-invidious_register
CONTINUE='y'
while [ "$CONTINUE" = 'y' ]; do
read -rp 'User ID: ' ID
if [ "$(su postgres -c "psql invidious -c \"SELECT email FROM users WHERE email = '\"'$ID'\"';\"" | tail -n 2 | head -n 1)" != '(0 rows)' ]; then
echo 'Error: User ID is already taken'
continue
fi
read -rsp 'Password: ' PASSWORD
curl -L 'http://localhost:21742/login' --form-string "email=$ID" --form-string "password=$PASSWORD" -F 'action=signin' >/dev/null
read -rp 'Register more accounts? [y/N] ' CONTINUE
done
systemctl stop podman-invidious_register
```

View File

@ -1,13 +1,14 @@
# Reset user password
Resetting a user's invidious password needs you to edit the database.
Resetting a user's Invidious password needs you to edit the database.
Firstly, generate a bcrypt-encrypted hash for the new password you want to set for the user.
This can be done with the `bcrypt` python module, though there are other ways of doing the same.
This can, for example, be done with the `bcrypt` python module or the `mkpasswd` shell utility (the latter should be preinstalled on most systems):
```
python3 -c 'import bcrypt; print(bcrypt.hashpw(b"<INSERT PASSWORD HERE>", bcrypt.gensalt(rounds=10)).decode("ascii"))'
python3 -c 'import bcrypt; print(bcrypt.hashpw(b"<INSERT PASSWORD HERE>", bcrypt.gensalt(rounds=10)).decode("ascii"))' # python
mkpasswd --method=bcrypt-a -R 10 # mkpasswd
```
To do so, first attach to the database:
@ -23,3 +24,19 @@ UPDATE users SET password = 'HASH' WHERE email = 'USERNAME';
```
After that, the password should be reset.
This script bundles all needed commands so you don't have to enter everything manually every time, and also checks that the username exists before writing to the database:
```sh
#!/bin/sh
set -e
printf 'User ID: '
read -r ID
if [ "$(su postgres -c "psql invidious -c \"SELECT email FROM users WHERE email = '$ID';\"" | tail -n 2 | head -n 1)" != '(1 row)' ]; then
echo 'Error: User ID does not exist'
exit 1
fi
HASH="$(mkpasswd --method=bcrypt-a -R 10)"
su postgres -c "psql invidious -c \"UPDATE users SET password = '\"'$HASH'\"' WHERE email = '\"'$ID'\"';\""
```

View File

@ -13,8 +13,8 @@ Supported operators:
- `sort:`
- `relevance` (default)
- `rating`
- `upload_date`, `date`
- `view_count`, `views`
- `date`
- `views`
- `date:`
- `hour`
- `today`
@ -30,11 +30,13 @@ Supported operators:
- `show`
- `duration:`
- `short`
- `medium`
- `long`
- `features:` Multiple can be specified, for example `features:live,4k,subtitles`
- `hd`
- `subtitles`
- `creative_commons`,`cc`
- `3d`
- `live`, `livestream`
- `purchased`
- `4k`

View File

@ -9,7 +9,8 @@ _This list is incomplete. You can help by expanding it._
| **Site-wide parameters** | |
| _Dark mode_ | Configure default theme without setting cookies |
| `dark_mode=true` | Use dark theme |
| `dark_mode=false` | Use light theme |
| `dark_mode=false` | Use light theme |
| `dark_mode=auto` | Use system/browser theme
| _Thin mode_ | Load HTML, CSS, JS and video elements (disables images) |
| `thin_mode=true` | Enabled |
| `thin_mode=false` | Disabled |
@ -52,10 +53,20 @@ _This list is incomplete. You can help by expanding it._
| `quality=dash` | [DASH](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP) |
| `quality=hd720` | 720p |
| `quality=medium` | 480p |
| _Quality_DASH_ | Default player quality when using DASH (default is Auto) |
| `quality_dash=auto` | Automatically change quality based on network conditions |
| `quality_dash=best` | Automatically use the best quality avalible |
| `quality_dash=###` | always use desired quality (480, 720, etc). |
| `quality_dash=worst` | Automatically use the worst quality avalible |
| _Related Videos_ | Show "Related videos" tab on the right-hand side |
| `related_videos=false` | Disabled |
| _Comments_ | Show comments below the video|
| `comments=false` | Disabled |
| `comments=false` | Disabled |
| _Extended Description_ | Extend Video Description by default |
| `extend_desc=true` | Enabled
**Player Style** | Define how the Video Player looks asthetically |
| `player_style=invidious` | Invidious, the default |
| `player_style=youtube` | YouTube, using a centered play button and always visible video control bar |
| _Speed_ | Default player speed, can be any positive number |
| `speed=0.5` | Play at 0.5x speed |
| `speed=2` | Play at 2x speed |
@ -86,11 +97,7 @@ _This list is incomplete. You can help by expanding it._
| `type=Default` | Default |
| `type=Music` | Music |
| `type=Gaming` | Gaming |
| `type=News` | News |
| `type=Movies` | Movies |
| _Region_ | Provide "hint" (as ISO 3166 country code) for Invidious to load trending videos from the specified region | |
| `region=JP` | Load videos that are trending in Japan |
| `region=DE` | Load videos that are trending in Germany |
| **Player Style** | |
| `player_style=invidious` | Invidious, the default |
| `player_style=youtube` | YouTube, using a centered play button and always visible video control bar |

View File

@ -0,0 +1,73 @@
# All the YouTube error messages explained with solutions
**DISCLAIMER**: If you are just an user of a public instance. This documentation is not for you. Please instead redirect your Invidious instance maintainer to this page or switch to another public instance: [https://instances.invidious.io](https://instances.invidious.io)
## Error: non 200 status code. Youtube API returned status code 429
### Error explained
YouTube is limiting the traffic that you can send to their servers. This error may appear for a duration of 24 hours.
### Cause(s)
Usually it is related to a lot of traffic being generated for refreshing your subscriptions.
- You have modified the parameter `channel_refresh_interval` and thus you are forcing the refresh of your subscriptions too quickly for YouTube.
- You are subscribed to a lot of channels. YouTube may classify this as abuse due to Invidious having to check for new videos on a lot of channels.
- You have sent a lot of traffic in another manner. Like by using the Invidious API.
- Someone on your network is sending a lot of traffic to YouTube.
### Solution(s)
- Try to keep the `channel_refresh_interval` parameter commented to let Invidious refreshing your subscriptions less frequently.
- Unsubscribe from some channels. While this may not be ideal, this will definitively send less data to YouTube.
- Configure pubsub: [/installation/#post-install-configuration](./installation.md/#post-install-configuration). This requires your Invidious to be available on the internet and through a public domain.
After this you can try to extend the refresh interval, like to `channel_refresh_interval: 240m`.
You will still get almost instantaneous notifications from new YouTube videos thanks to pubsub but you will induce less refreshing traffic to YouTube servers. As pubsub is method for YouTube to notify your Invidious instance for new videos.
- Change your public IP address. This may not solve the issue permanently but temporarily solve it.
## Sign in to confirm you are not a bot - This helps protect our community
### Error explained
YouTube is blocking the communication of Invidious to their servers.
### Cause(s)
- YouTube is running different mechanisms to detect the usage of non official YouTube clients. Your Invidious instance may have been detected by their system.
- Your IP address is blacklisted from YouTube servers. It is known that YouTube block datacenter IP addresses.
### Solution(s)
First make sure that you are running the latest version of Invidious and you are using inv_sig_helper. Please see [the updated installation guide](./installation.md).
After which you can try these solutions:
- Change your public IP address. Reboot your router or by configuring a proxy in Invidious: https://github.com/iv-org/invidious/blob/2150264d849771df8f15bab172ab6d87eeb80c55/config/config.example.yml#L176-L185
- If you have IPv6 on the computer hosting Invidious, you can try to rotate your IPv6 public address, tutorial available here: "[Rotate your IPv6 address for escaping YouTube blocking](./ipv6-rotator.md)"
All of these options do not guarantee you to bring back Invidious to working conditions. These are just advices for trying to unblock your Invidious instance from YouTube. Make sure to always specify any modification being done to your Invidious when reporting issues.
## Videoplayback URLs that returns 403 HTTP errors
### Error explained
YouTube is forbidding you from viewing/downloading videos from their "googlevideo.com" server. Other functions such as viewing channels pages may still work.
### Cause(s)
This error has different root causes:
- You are loading a video stream that is restricted to the IP address that generated that URL. For example this can happen on music videos or copyright content.
- You or someone on your network have downloaded a lot of videos. Your IP address has been blocked from YouTube servers.
### Solution(s)
First make sure that you are running the latest version of Invidious and you are using inv_sig_helper. Please see [the updated installation guide](./installation.md).
After which you can try these solutions:
- Change your public IP address. Reboot your router or by configuring a proxy in Invidious: https://github.com/iv-org/invidious/blob/2150264d849771df8f15bab172ab6d87eeb80c55/config/config.example.yml#L176-L185
- If you have IPv6 on the computer hosting Invidious, you can try to rotate your IPv6 public address, tutorial available here: "[Rotate your IPv6 address for escaping YouTube blocking](./ipv6-rotator.md)"
- If it's a music video or a copyright content, then try to make sure that the video is loaded from the same IP that generated the video URL.

View File

@ -23,12 +23,16 @@ nav:
- 'redirector.md'
- 'For Administrators':
- 'installation.md'
- 'invidious-companion.md'
- 'configuration.md'
- 'youtube-errors-explained.md'
- 'devtools.md'
- 'nginx.md'
- 'caddy.md'
- 'apache2.md'
- 'db-maintenance.md'
- 'captcha-bug.md'
- 'register-user.md'
- 'reset-password.md'
- 'known-exception.md'
- 'For public instances Owners':