diff --git a/.cirun.yml b/.cirun.yml deleted file mode 100644 index cdd6307..0000000 --- a/.cirun.yml +++ /dev/null @@ -1,8 +0,0 @@ -runners: - - name: big-runner - cloud: digitalocean - instance_type: c-2 - machine_image: docker-20-04 - region: ams3 - labels: - - cirun-runner diff --git a/.env b/.env new file mode 100644 index 0000000..ed1705a --- /dev/null +++ b/.env @@ -0,0 +1,33 @@ +# Invidious +INV_CPU_CORES=1 +INV_MEM_LIMIT="768m" +INV_MEM_RESERVATION="512m" +INV_IMAGE="invidious-nerdvpn:latest" +INV_RESTART_POLICY="unless-stopped" + +INV_HEALTHCHECK_URL="watch?v=jNQXAC9IVRw" + +BANNER_MSG="
" + +# PSQL +POSTGRES_DB="invidious" +POSTGRES_USER="invidious" +POSTGRES_PASSWORD="" + +INV_PSQL_CPU_CORES=6 +INV_PSQL_MEM_LIMIT="8448m" +INV_PSQL_MEM_RESERVATION="6400m" +INV_PSQL_IMAGE="docker.io/library/postgres:14" + +# Materialious +VITE_DEFAULT_INVIDIOUS_INSTANCE="https://api.invidious.nerdvpn.de" +VITE_DEFAULT_RETURNYTDISLIKES_INSTANCE="https://ryd.invidious.nerdvpn.de" +VITE_DEFAULT_FRONTEND_URL="https://materialious.nerdvpn.de" +VITE_DEFAULT_SPONSERBLOCK_INSTANCE="https://sponsor.ajay.app" +VITE_DEFAULT_DEARROW_INSTANCE="" +VITE_DEFAULT_DEARROW_THUMBNAIL_INSTANCE="" +VITE_DEFAULT_SYNCIOUS_INSTANCE="https://sync.invidious.nerdvpn.de" +VITE_DEFAULT_PEERJS_HOST="peer.invidious.nerdvpn.de" +VITE_DEFAULT_PEERJS_PATH="/" +VITE_DEFAULT_PEERJS_PORT=443 +VITE_DEFAULT_SETTINGS='{"region": "DE", "darkMode": false, "themeColor": "#FFB81C", "autoPlay": true, "alwaysLoop": false, "proxyVideos": false, "listenByDefault": false, "savePlaybackPosition": true, "dashEnabled": false, "theatreModeByDefault": false, "autoplayNextByDefault": true, "returnYtDislikes": true, "searchSuggestions": true, "previewVideoOnHover": false, "sponsorBlock": true, "sponsorBlockCategories": "sponsor,interaction,selfpromo", "deArrowEnabled": false, "playerMiniPlayer": true, "syncious": true}' diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml deleted file mode 100644 index 08f5bcc..0000000 --- a/.github/workflows/docker-image.yml +++ /dev/null @@ -1,98 +0,0 @@ -name: Docker Image CI - -on: - workflow_dispatch: - - push: - branches: - - master - - schedule: - # * is a special character in YAML so you have to quote this string - - cron: '0 0 * * *' - -jobs: - - build: - - runs-on: 'ubuntu-latest' - - steps: - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - if: github.event_name != 'push' - with: - platforms: arm64 - - name: Check Out Repo - uses: actions/checkout@v3 - - - name: Check Out Repo Invidious - uses: actions/checkout@v3 - with: - repository: "iv-org/invidious" - ref: 'master' - path: 'invidious' - - - name: patch invidious main repo - run: | - cd invidious - git config --global user.email "you@example.com" - git config --global user.name "Your Name" - git am ../patches/*.patch - sed -i 's/https:\/\/invidious.io\/donate\//\/donate/g' src/invidious/views/template.ecr - - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v2 - - - name: Set up build commit id - run: echo "commitid=$(cd invidious && git log --format="%H" -n 1)-$(git log --format="%H" -n 1)" >> $GITHUB_ENV - - - name: Build and push alpine docker image - id: docker_build_new - uses: docker/build-push-action@v3 - with: - context: ./ - file: ./Dockerfile.new - build-args: | - release=1 - platforms: linux/arm64/v8 - push: true - tags: unixfox/invidious-custom:new-latest, unixfox/invidious-custom:new-build-${{ env.commitid }} - - # - name: patch invidious API repo - # run: | - # cd invidious - # git config --global user.email "you@example.com" - # git config --global user.name "Your Name" - # git am ../patches-api/*.patch - - # - name: Build and push alpine docker image with API only - # id: docker_build_new_api - # uses: docker/build-push-action@v3 - # with: - # context: ./ - # file: ./Dockerfile.new - # build-args: | - # release=1 - # add_build_args=-Dapi_only - # platforms: linux/amd64,linux/arm64/v8 - # push: true - # tags: unixfox/invidious-custom:api-new-latest, unixfox/invidious-custom:api-new-build-${{ env.commitid }} - - # - name: Build and push official crystal docker image - # id: docker_build - # uses: docker/build-push-action@v3 - # with: - # context: ./ - # build-args: | - # release=1 - # file: ./Dockerfile - # push: true - # tags: unixfox/invidious-custom:latest, unixfox/invidious-custom:build-${{ env.commitid }} diff --git a/.gitignore b/.gitignore index 1213661..567609b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -invidious/ \ No newline at end of file +build/ diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 4761c5b..0000000 --- a/Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -FROM crystallang/crystal:1.4.1-alpine AS builder -RUN apk add --no-cache sqlite-static yaml-static - -WORKDIR /invidious -COPY ./invidious/shard.yml ./shard.yml -COPY ./invidious/shard.lock ./shard.lock -RUN shards update --production && shards install --production - -COPY --from=quay.io/invidious/lsquic-compiled /root/liblsquic.a ./lib/lsquic/src/lsquic/ext/liblsquic.a - -COPY ./invidious/src/ ./src/ -# TODO: .git folder is required for building – this is destructive. -# See definition of CURRENT_BRANCH, CURRENT_COMMIT and CURRENT_VERSION. -COPY ./invidious/.git/ ./.git/ -# Required for fetching player dependencies -COPY ./invidious/scripts/ ./scripts/ -COPY ./invidious/assets/ ./assets/ -COPY ./invidious/videojs-dependencies.yml ./videojs-dependencies.yml -RUN crystal build --release ./src/invidious.cr \ - --static --warnings all \ - --link-flags "-lxml2 -llzma" - -FROM alpine:latest -RUN apk add --no-cache librsvg ttf-opensans tini -WORKDIR /invidious -RUN addgroup -g 1000 -S invidious && \ - adduser -u 1000 -S invidious -G invidious -COPY --chown=invidious ./invidious/config/config.* ./config/ -RUN mv -n config/config.example.yml config/config.yml -RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: postgres/' config/config.yml -COPY ./invidious/config/sql/ ./config/sql/ -COPY ./invidious/locales/ ./locales/ -COPY --from=builder /invidious/assets ./assets/ -COPY --from=builder /invidious/invidious . -RUN chmod o+rX -R ./assets ./config ./locales - -EXPOSE 3000 -USER invidious -ENTRYPOINT ["/sbin/tini", "--"] -CMD [ "/invidious/invidious" ] \ No newline at end of file diff --git a/Dockerfile.new b/Dockerfile.new deleted file mode 100644 index ef1c961..0000000 --- a/Dockerfile.new +++ /dev/null @@ -1,51 +0,0 @@ -FROM alpine:3.19 AS builder -RUN apk add --no-cache 'crystal=1.10.1-r0' shards sqlite-static yaml-static yaml-dev libxml2-static zlib-static openssl-libs-static openssl-dev musl-dev xz-static yq - -ARG add_build_args - -WORKDIR /invidious -COPY ./invidious/shard.yml ./shard.yml -COPY ./invidious/shard.lock ./shard.lock -# Sentry is just for reporting Invidious crashes, no personal data is collected. -#RUN yq e -i '.dependencies.raven.github = "Sija/raven.cr"' shard.yml -#RUN yq e -i '.targets.sentry_crash_handler.main = "lib/raven/src/crash_handler.cr"' shard.yml -RUN shards install --production - -COPY --from=quay.io/invidious/lsquic-compiled /root/liblsquic.a ./lib/lsquic/src/lsquic/ext/liblsquic.a - -COPY ./invidious/src/ ./src/ -# TODO: .git folder is required for building – this is destructive. -# See definition of CURRENT_BRANCH, CURRENT_COMMIT and CURRENT_VERSION. -COPY ./invidious/.git/ ./.git/ -# Required for fetching player dependencies -COPY ./invidious/scripts/ ./scripts/ -COPY ./invidious/assets/ ./assets/ -COPY ./invidious/videojs-dependencies.yml ./videojs-dependencies.yml -RUN crystal build ./src/invidious.cr ${add_build_args} \ - --release \ - -Ddisable_quic \ - --static --warnings all \ - --link-flags "-lxml2 -llzma"; - -#RUN shards build --release --static sentry_crash_handler - -FROM alpine:3.16 -RUN apk add --no-cache librsvg ttf-opensans tini -WORKDIR /invidious -RUN addgroup -g 1000 -S invidious && \ - adduser -u 1000 -S invidious -G invidious -COPY --chown=invidious ./invidious/config/config.* ./config/ -RUN mv -n config/config.example.yml config/config.yml -RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: postgres/' config/config.yml -COPY ./invidious/config/sql/ ./config/sql/ -COPY ./invidious/locales/ ./locales/ -COPY --from=builder /invidious/assets ./assets/ -COPY --from=builder /invidious/invidious . -#COPY --from=builder /invidious/bin/sentry_crash_handler . -RUN chmod o+rX -R ./assets ./config ./locales - -EXPOSE 3000 -USER invidious -#CMD [ "/invidious/sentry_crash_handler", "/invidious/invidious" ] -ENTRYPOINT ["/sbin/tini", "--"] -CMD [ "/invidious/invidious" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..77e7411 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# Invidious.nerdvpn.de +Invidious fork with customizations for invidious.nerdvpn.de + +Theme for my instance is based on: https://github.com/Tsyron/Invidious-Theme + +Original repo at: https://github.com/iv-org/invidious + +Based upon patches from: https://github.com/yewtudotbe/invidious-custom + + +# Build instructions + +1. `git clone https://github.com/Sommerwiesel/invidious-nerdvpn .` +2. `git clone https://github.com/iv-org/invidious build` +3. `./patch.sh` +4. `./build.sh development` for the development image or `./build.sh release` for the production image + +# Update instructions + +- Simply run `./update.sh` + +# Run instructions (docker compose) + +- For the database: `docker compose --profile database up -d` +- For the worker: `docker compose --profile worker up -d` +- For the web client: `docker compose --profile web up -d` +- For the tor web client: `docker compose --profile tor up -d` +- For materialious: `docker compose --profile materialious up -d` + +# Run instructions (systemd) + +First copy the invidious.service to /etc/systemd/system/ + +- For the database: `systemctl enable --now invidious@database.service` +- For the worker: `systemctl enable --now invidious@worker.service` +- For the web client: `systemctl enable --now invidious@web.service` +- For the tor web client: `systemctl enable --now invidious@tor.service` +- For materialious: `systemctl enable --now invidious@materialious.service` + diff --git a/assets/css/default.css b/assets/css/default.css new file mode 100644 index 0000000..858c49c --- /dev/null +++ b/assets/css/default.css @@ -0,0 +1,1174 @@ +:root { + --Color1: #BF616A; + --Color1Hover: rgba(191, 97, 106, 0.9); + --Color1Watched: rgba(191, 97, 106, 0.4); + --Color2: #D08770; + --Color2Hover: rgba(208, 135, 112, 0.9); + --Color3: #B48EAD; + --Color3Hover: rgba(180, 142, 173, 0.9); + --Color4: #EBCB8B; + --Color4Hover: rgba(235, 203, 139, 0.9); + --Color5: #A3BE8C; + --Color5Hover: rgba(163, 190, 140, 0.9); + --Color5Border: rgba(163, 190, 140, 0.3); + --Font: Roboto, Arial, sans-serif !important; +} + +/* Themes */ + +/* Dark Theme */ +body.dark-theme { + background: #2E3440; + color: #D8DEE9; +} + +.dark-theme .pure-g, +.dark-theme .pure-form legend { + background: #2E3440; + color: #D8DEE9; +} + +/* Clickable Links */ +.dark-theme a:not(.navbar .index-link), +.dark-theme a:active:not(.navbar .index-link), +.dark-theme a:visited:not(.navbar .index-link), +.dark-theme footer a, +.dark-theme summary, +.dark-theme a:not([data-id]) > .icon, +.dark-theme a:link:not(.pure-button):not(.channel-owner) { + color: #81A1C1; +} + +.dark-theme a:hover, +.dark-theme footer a:hover, +.dark-theme summary:hover, +.dark-theme a:not([data-id]) > .icon:hover, +.dark-theme a:link:not(.pure-button):not(.channel-owner):hover { + color: rgba(129, 161, 193, 0.9) !important; +} + +/* Multiple option Select Box */ + +.pure-form input[type="color"], +.pure-form input[type="date"], +.pure-form input[type="datetime-local"], +.pure-form input[type="datetime"], +.pure-form input[type="email"], +.pure-form input[type="month"], +.pure-form input[type="number"], +.pure-form input[type="password"], +.pure-form input[type="tel"], +.pure-form input[type="text"], +.pure-form input[type="time"], +.pure-form input[type="url"], +.pure-form input[type="week"], +.pure-form select, +.pure-form textarea { + box-shadow: transparent 1px 1px 1px inset; + border: transparent; + border-radius: 5px 5px 5px; + background-color: #3B4252; + color: #D8DEE9; +} + +/* General Button */ +.dark-theme .pure-button-primary, +.dark-theme .pure-button-secondary, +.dark-theme .pure-button-primary:focus, +.dark-theme .pure-button-secondary:focus { + border: transparent; + background-color: #3B4252 !important; + color: #D8DEE9 !important; +} + +.dark-theme .pure-button-primary:hover, +.dark-theme .pure-button-secondary:hover { + background-color: #434C5E !important; + color: #D8DEE9 !important; +} + +/* Checkbox & Radio: Background color */ +.dark-theme input[type="checkbox"], +.dark-theme input[type="checkbox"]:before, +.dark-theme input[type="checkbox"]:checked:before, +.dark-theme input[type="radio"], +.dark-theme input[type="radio"]:before, +.dark-theme input[type="radio"]:checked:before { + color: #434C5E; +} + +.dark-theme input[disabled] { + background-color: rgba(67, 76, 94, 0.3); +} + +/* Range slider: Background */ +.dark-theme input[type="range"] { + background-color: #434C5E; +} + +/* Home Screen: Clickable links colors */ +.dark-theme p, +.dark-theme p.video-data:hover { + color: #D8DEE9; +} + +/* Home Screen: Donate/Popular/Trending */ +.dark-theme a.feed-menu-item.pure-menu-heading { + color: #81A1C1; +} + +/* Home Screen: Only Highlights YouTube Video's */ +.dark-theme a[href^="/watch?v="] p:not(.length):hover { + color: rgba(216, 222, 233, 0.9); +} + +/* Home Screen: Watched */ +.dark-theme .watched { + background-color: #434C5E; + color: #D8DEE9; +} + +/* Home Screen: Length Time*/ +.dark-theme .length, +.dark-theme p.length { + color: #D8DEE9; + background-color: #434C5E; +} + +.dark-theme p.channel-name { + color: #81A1C1; +} + +.dark-theme p.channel-name:hover { + color: rgba(129, 161, 193, 0.9); +} + +/* Search: Filter box */ +.dark-theme #filters-box { + background: #2E3440 !important; +} + +/* Searchbox: background color */ +.dark-theme .pure-form input[type="search"] { + border: transparent; + background-color: #3B4252; + color: #D8DEE9; +} + +/* Video Player */ +/* Video player: play button: color */ +.dark-theme .video-js .vjs-big-play-button .vjs-icon-placeholder { + color: #D8DEE9; +} + +/* Video player: Controls: Color */ +.dark-theme .video-js .vjs-control-bar, +.dark-theme .video-js .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + background-color: #2E3440; + color: #ECEFF4; +} + +/* Button Hover */ +.dark-theme .video-js button:hover { + color: #ECEFF4; +} + +/* Video player: Controls: Hovering Over Selected Option colors */ +.dark-theme .video-js .vjs-menu li.vjs-menu-item:focus, +.dark-theme .video-js .vjs-menu li.vjs-menu-item:hover { + background-color: var(--Color1Hover); + color: #D8DEE9; +} + +/* Video player: Controls: The Selected option colors */ +.dark-theme .video-js .vjs-menu li.vjs-selected, +.dark-theme .video-js .vjs-menu li.vjs-selected:focus, +.dark-theme .video-js .vjs-menu li.vjs-selected:hover { + background-color: var(--Color1); + color: #D8DEE9; +} + +/* Video player: Share Links */ +.dark-theme .video-js .vjs-share__short-link, +.dark-theme .video-js .vjs-share__btn, +.dark-theme .video-js .vjs-share__short-link-wrapper { + font-family: sans-serif; + background-color: #3B4252; + color: #D8DEE9; +} + +.dark-theme .video-js .vjs-videojs-share_open .vjs-modal-dialog .vjs-close-button, +.dark-theme .video-js .vjs-share__subtitle, +.dark-theme .video-js .vjs-share__title { + font-family: sans-serif; + color: #D8DEE9; +} + +.dark-theme .video-js .vjs-videojs-share_open .vjs-modal-dialog .vjs-modal-dialog-content, +.dark-theme .video-js .vjs-modal-dialog { + background: #D8DEE9; +} + +.dark-theme .video-js .vjs-modal-dialog .vjs-modal-dialog-content, +.dark-theme .video-js .vjs-modal-dialog, +.dark-theme .video-js .vjs-modal-dialog-content { + background: #2E3440 !important; +} + +/* Video player: Settings */ +.dark-theme .video-js .vjs-text-track-settings legend { + color: #D8DEE9; +} + +/* Video Player: Text */ +.dark-theme .video-js .vjs-icon-placeholder, +.dark-theme .video-js .vjs-icon-share { + color: #D8DEE9; +} + +/* Video Player: Sliders */ +.dark-theme .video-js .vjs-play-progress, +.dark-theme .video-js .vjs-volume-level { + color: #D8DEE9; +} + +/* Video player: Controls: Progress Bar: Color */ +.video-js.player-style-invidious .vjs-play-progress { + background-color: var(--Color1); +} + +/* Subscribe button */ +.dark-theme #subscribe, +.dark-theme #subscribe:hover { + border: transparent; + color: #2E3440 !important; +} + +/* Comment Section: OC Channel: Comment */ +body.dark-theme a.channel-owner, +body.dark-theme a.channel-owner:hover, +.dark-theme .channel-owner:visited, +.dark-theme .channel-owner .icon.ion.ion-md-checkmark-circle { + color: #2E3440 !important; +} + +.dark-theme #subscribe, +.dark-theme #subscribe:hover { + color: #ECEFF4 !important; +} + +body.dark-theme a.channel-owner, +body.dark-theme a.channel-owner:hover, +.channel-owner:visited, +.channel-owner .icon.ion.ion-md-checkmark-circle { + color: #ECEFF4 !important; +} + +/* Description: Download Button */ +.dark-theme input, +.dark-theme select, +.dark-theme textarea { + background-color: #3B4252; + color: #D8DEE9; +} + +/* Scrollbar */ +.dark-theme ::-webkit-scrollbar, +.dark-theme ::-webkit-scrollbar { + background-color: #3B4252; +} + +.dark-theme ::-webkit-scrollbar-thumb, +.dark-theme ::-webkit-scrollbar-thumb { + background-color: #434C5E; +} + +/* Selection of text color */ +.dark-theme ::selection, +.dark-theme ::selection { + background-color: #D8DEE9 !important; + color: #434C5E !important; +} + +/* White Line (Spacer/padding) */ +.dark-theme hr, +.dark-theme .pure-form legend, +.dark-theme .pure-form-aligned legend, +.dark-theme .underlined { + border-color: rgba(76, 86, 106, 1); +} + +/* Settings: Volume Text */ +.dark-theme span#volume-value { + color: #D8DEE9; +} + +/* Placeholder */ +.dark-theme ::placeholder { + color: #D8DEE9; +} + +.dark-theme .pure-form input[type="color"], +.dark-theme .pure-form input[type="date"], +.dark-theme .pure-form input[type="datetime-local"], +.dark-theme .pure-form input[type="datetime"], +.dark-theme .pure-form input[type="email"], +.dark-theme .pure-form input[type="month"], +.dark-theme .pure-form input[type="number"], +.dark-theme .pure-form input[type="password"], +.dark-theme .pure-form input[type="tel"], +.dark-theme .pure-form input[type="text"], +.dark-theme .pure-form input[type="time"], +.dark-theme .pure-form input[type="url"], +.dark-theme .pure-form input[type="week"], +.dark-theme .pure-form input[type="search"], +.dark-theme .pure-form select, +.dark-theme .pure-form textarea { + border: 1px solid #4C566A !important; +} + +.dark-theme .pure-form input[type="range"]::-webkit-slider-thumb { + border-right: 1px solid #4C566A !important; +} + +.dark-theme .pure-form input[type="checkbox"], +.dark-theme .pure-form input[type="radio"], +.dark-theme .pure-form input[type="range"] { + border: 1px solid var(--Color5Border) !important; +} + +.dark-theme .pure-form .pure-button-primary, +.dark-theme .pure-form .pure-button-primary:focus, +.dark-theme .pure-form .pure-button-primary:hover, +.dark-theme .pure-form .pure-button-secondary, +.dark-theme .pure-form .pure-button-secondary:focus, +.dark-theme .pure-form .pure-button-secondary:hover { + border: 1px solid #4C566A !important; +} + +.dark-theme .pure-form #subscribe, +.dark-theme .pure-form #subscribe:hover, +.dark-theme .pure-form a.channel-owner, +.dark-theme .pure-form a.channel-owner:hover { + border: 1px solid var(--Color1) !important; +} + + +/* Light Theme */ +body.light-theme { + background: #ECEFF4; + color: #434C5E; +} + + +.light-theme .pure-g, +.light-theme .pure-form legend { + background: #ECEFF4; + color: #434C5E; +} + +/* Clickable Links */ +.light-theme a:not(.pure-u-md-4-24 .pure-menu-heading), +.light-theme a:active:not(.pure-u-md-4-24 .pure-menu-heading), +.light-theme a:visited:not(.pure-u-md-4-24 .pure-menu-heading), +.light-theme footer a, +.light-theme summary, +.light-theme a:not([data-id]) > .icon, +.light-theme a:link:not(.pure-button):not(.channel-owner) { + color: #5E81AC; +} + +.light-theme a:hover, +.light-theme footer a:hover, +.light-theme summary:hover, +.light-theme a:not([data-id]) > .icon:hover, +.light-theme a:link:not(.pure-button):not(.channel-owner):hover { + color: rgba(94, 129, 172, 0.9) !important; +} + +/* Multiple option Select Box */ +.light-theme .pure-form input[type="color"], +.light-theme .pure-form input[type="date"], +.light-theme .pure-form input[type="datetime-local"], +.light-theme .pure-form input[type="datetime"], +.light-theme .pure-form input[type="email"], +.light-theme .pure-form input[type="month"], +.light-theme .pure-form input[type="number"], +.light-theme .pure-form input[type="password"], +.light-theme .pure-form input[type="tel"], +.light-theme .pure-form input[type="text"], +.light-theme .pure-form input[type="time"], +.light-theme .pure-form input[type="url"], +.light-theme .pure-form input[type="week"], +.light-theme .pure-form select, +.light-theme .pure-form textarea { + box-shadow: transparent 1px 1px 1px inset; + border: transparent; + border-radius: 5px 5px 5px; + background-color: #D8DEE9; + color: #434C5E; +} + +/* General Button */ +.light-theme .pure-button-primary, +.light-theme .pure-button-secondary, +.light-theme .pure-button-primary:focus, +.light-theme .pure-button-secondary:focus { + border: transparent; + background-color: #D8DEE9 !important; + color: #434C5E !important; +} +/* new */ +.light-theme .pure-button-primary:hover, +.light-theme .pure-button-secondary:hover { + background-color: #D8DEE9 !important; + color: #434C5E !important; +} + +/* Checkbox & Radio: Background color */ +.light-theme input[type="checkbox"], +.light-theme input[type="checkbox"]:before, +.light-theme input[type="checkbox"]:checked:before, +.light-theme input[type="radio"], +.light-theme input[type="radio"]:before, +.light-theme input[type="radio"]:checked:before { + color: #434C5E; +} + +.light-theme input[disabled] { + background-color: rgba(216, 222, 233, 0.5); +} + +/* Range slider: Background */ +.light-theme input[type="range"] { + background-color: #D8DEE9; +} + +/* Home Screen: Clickable links colors */ +.light-theme p, +.light-theme p.video-data:hover { + color: #4C566A; +} + +/* Home Screen: Donate/Popular/Trending */ +.light-theme a.feed-menu-item.pure-menu-heading { + color: #5E81AC; +} + +/* Home Screen: Only Highlights YouTube Video's */ +.light-theme a[href^="/watch?v="] p:not(.length):hover { + color: rgba(46, 52, 64, 0.9); +} + +/* Home Screen: Watched */ +.light-theme .watched { + background-color: #ECEFF4; + color: #434C5E; +} + +/* Home Screen: Length Time*/ +.light-theme .length, +.light-theme p.length { + color: #434C5E; + background-color: #ECEFF4; +} + +.light-theme p.channel-name { + color: #5E81AC; +} + +.light-theme p.channel-name:hover { + color: rgba(94, 129, 172, 0.9); +} + +/* Search: Filter box */ +.light-theme #filters-box { + background-color: #ECEFF4 !important; +} + +/* Searchbox: background color */ +.light-theme .pure-form input[type="search"] { + border: transparent; + background-color: #D8DEE9; + color: #434C5E; +} + +/* Video Player */ +/* Video player: play button: color */ +.light-theme .video-js .vjs-big-play-button .vjs-icon-placeholder { + color: #D8DEE9; +} + +/* Video player: Controls: Color */ +.light-theme .video-js .vjs-control-bar, +.light-theme .video-js .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + background-color: #ECEFF4; + color: #434C5E; +} + +/* Button Hover */ +.light-theme .video-js button:hover { + color: #434C5E; +} + +/* Video player: Controls: Hovering Over Selected Option colors */ +.light-theme .video-js .vjs-menu li.vjs-menu-item:focus, +.light-theme .video-js .vjs-menu li.vjs-menu-item:hover { + background-color: var(--Color1Hover); + color: #D8DEE9; +} + +/* Video player: Controls: The Selected option colors */ +.light-theme .video-js .vjs-menu li.vjs-selected, +.light-theme .video-js .vjs-menu li.vjs-selected:focus, +.light-theme .video-js .vjs-menu li.vjs-selected:hover { + background-color: var(--Color1); + color: #ECEFF4; +} + +/* Video player: Share Links */ +.light-theme .video-js .light-theme .video-js .vjs-share__short-link, +.light-theme .video-js .light-theme .video-js .vjs-share__btn, +.light-theme .video-js .vjs-share__short-link-wrapper { + font-family: sans-serif; + background-color: #D8DEE9; + color: #2E3440; +} + +.light-theme .video-js .vjs-videojs-share_open .vjs-modal-dialog .vjs-close-button, +.light-theme .video-js .vjs-share__subtitle, +.light-theme .video-js .vjs-share__title { + font-family: sans-serif; + color: #2E3440; +} + +.light-theme .video-js .vjs-videojs-share_open .vjs-modal-dialog .vjs-modal-dialog-content, +.light-theme .video-js .vjs-modal-dialog, +.light-theme .video-js .vjs-modal-dialog-content { + background: #ECEFF4 !important; +} + +.light-theme .video-js .vjs-videojs-share_open .vjs-modal-dialog .vjs-modal-dialog-content, +.light-theme .video-js .vjs-modal-dialog { + background: #ECEFF4; +} + +/* Video player: Settings */ +.light-theme .video-js .vjs-text-track-settings legend { + color: #434C5E; +} + +/* Video Player: Text */ +.light-theme .video-js .vjs-icon-placeholder, +.light-theme .video-js .vjs-icon-share { + color: #4C566A; +} + +/* Video Player: Sliders */ +.light-theme .video-js .vjs-play-progress, +.light-theme .video-js .vjs-volume-level { + color: #4C566A; +} + +/* Video player: Controls: Progress Bar: Color */ +.light-theme .video-js.player-style-invidious .vjs-play-progress { + background-color: var(--Color1); +} + +/* Subscribe button */ +.light-theme #subscribe, +.light-theme #subscribe:hover { + border: transparent; + color: #D8DEE9 !important; +} + +/* Comment Section: OC Channel: Comment */ +body.light-theme a.channel-owner, +body.light-theme a.channel-owner:hover, +.light-theme .channel-owner:visited, +.light-theme .channel-owner .icon.ion.ion-md-checkmark-circle { + color: #D8DEE9 !important; +} + + +/* Description: Download Button */ +.light-theme input, +.light-theme select, +.light-theme textarea { + background-color: #D8DEE9; + color: #434C5E; +} + +/* Scrollbar */ +.light-theme ::-webkit-scrollbar { + background-color: #D8DEE9; +} + +.light-theme ::-webkit-scrollbar-thumb { + background-color: #E5E9F0; +} + +/* Selection of text color */ +.light-theme ::selection { + background-color: #2E3440 !important; + color: #D8DEE9 !important; +} + +/* White Line (Spacer/padding) */ +.light-theme hr, +.light-theme .pure-form legend, +.light-theme .underlined { + border-color: rgba(216, 222, 233, 0.3); +} + +.light-theme .pure-form-aligned legend { + border-color: #D8DEE9; +} + +/* Settings: Volume Text */ +.light-theme span#volume-value { + color: #2E3440; +} + +/* Placeholder */ +.light-theme ::placeholder { + color: #2E3440; +} + +.light-theme .pure-form input[type="color"], +.light-theme .pure-form input[type="date"], +.light-theme .pure-form input[type="datetime-local"], +.light-theme .pure-form input[type="datetime"], +.light-theme .pure-form input[type="email"], +.light-theme .pure-form input[type="month"], +.light-theme .pure-form input[type="number"], +.light-theme .pure-form input[type="password"], +.light-theme .pure-form input[type="tel"], +.light-theme .pure-form input[type="text"], +.light-theme .pure-form input[type="time"], +.light-theme .pure-form input[type="url"], +.light-theme .pure-form input[type="week"], +.light-theme .pure-form input[type="search"], +.light-theme .pure-form select, +.light-theme .pure-form textarea { + border: 1px solid #ECEFF4 !important; +} + +.light-theme .pure-form input[type="range"]::-webkit-slider-thumb { + border-right: 1px solid #ECEFF4 !important; +} + +.light-theme .pure-form input[type="checkbox"], +.light-theme .pure-form input[type="radio"], +.light-theme .pure-form input[type="range"] { + border: 1px solid var(--Color5Border) !important; +} + +.light-theme .pure-form .pure-button-primary, +.light-theme .pure-form .pure-button-primary:focus, +.light-theme .pure-form .pure-button-primary:hover, +.light-theme .pure-form .pure-button-secondary, +.light-theme .pure-form .pure-button-secondary:focus, +.light-theme .pure-form .pure-button-secondary:hover { + border: 1px solid #ECEFF4 !important; +} + +.light-theme .pure-form #subscribe, +.light-theme .pure-form #subscribe:hover, +.light-theme .pure-form a.channel-owner, +.light-theme .pure-form a.channel-owner:hover { + border: 1px solid var(--Color1) !important; +} + + + +/* General Button */ +.pure-button-primary, +.pure-button-secondary { + padding: 0.5em 1em; + margin: 0px; + border-radius: 5px 5px 5px !important; +} + +/* Checkbox & Radio */ +input[type="checkbox"], +input[type="radio"] { + border-radius: 6px; + height: 1.3em; + width: 1.3em; + cursor: pointer; + position: relative; + vertical-align: middle; + -webkit-appearance: none; + -webkit-transition: 0.1s; +} + +/* Checkbox & Radio: Icons */ +input[type="radio"] { + border-radius: 50%; +} + +input[type="checkbox"]:checked:before { + content: "✔"; +} + +/* Color checkbox and radio button */ +input[type="checkbox"]:before, +input[type="checkbox"]:checked:before, +input[type="radio"]:before, +input[type="radio"]:checked:before { + background-color: var(--Color5); + border-radius: 6px; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + line-height: 1.3em; + text-align: center; +} + +/* Checkbox: Autoplay */ +.pure-u-lg-1-5 #continue { + margin-left: 3px; +} + +/* Checkbox & Radio: Color check */ +input[type="checkbox"]:checked, +input[type="radio"]:checked { + background-color: var(--Color5); +} + +/* Range slider: Slider and Round */ +input[type="range"]::-webkit-slider-thumb { + width: 15px; + border-radius: 15px; + -webkit-appearance: none; + height: 15px; + background: var(--Color5); + box-shadow: -80px 0 0 75px var(--Color5Hover); +} + +/* Range slider: Padding */ +input[type="range"] { + cursor: pointer; + overflow: hidden; + -webkit-appearance: none; + border-radius: 1em; +} + +input[type="range"]::-webkit-slider-runnable-track { + height: 15px; + -webkit-appearance: none; +} + +/* Screen Width */ +@media screen and (min-width: 48em) { + .pure-u-md-1-6, + .pure-u-md-1-12, + .pure-u-md-4-24, + .pure-u-md-20-24, + .pure-u-md-12-24 { + width: 0% !important; + } +} + +.pure-u-1.pure-u-md-2-24 { + width: 0%; +} + +#comments { + max-width: 100%; +} + +/* Font */ +html, +body, +.pure-g [class*="pure-u"] { + font-family: var(--Font); + font-size: 1em; +} + +/* Home Screen: Thumbnail */ +img, +div.watched-overlay { + border-radius: 5px 5px 5px; +} + +div.watched-indicator { + border-radius: 0 0 18px 0px 35px 18px 0px 35px; +} + +div.watched-overlay { + background-color: var(--Color1Watched); +} + +div.watched-indicator { + background-color: var(--Color1); +} + +/* Home Screen: Searchbox */ +#search-widget h1 { + color: var(--Color1); +} + +#searchbox { + border: transparent; + box-shadow: rgba(0, 0, 0, 0.35) 1px 1px 1px; + font-size:1.25em; +} + +/* Home Screen: Watched */ +.watched { + border-radius: 5px 5px 5px; +} + +/* Home Screen: Length Time*/ +.length, +p.length { + padding: 5px 8px 5px 8px; + right: 0.4em; + bottom: -0.6em; + font-size: 1em; + border-radius: 5px 5px 5px; +} + +/* Home Screen: Invidious icon / Log in */ +.navbar .index-link, +.pure-menu-heading { + color: var(--Color1); +} + +.navbar .index-link:hover { + color: var(--Color1Hover) !important; +} + +/* Home Screen: Little icons beside video */ +i.icon.ion-md-headset { + color: var(--Color4) !important; +} + +i.icon.ion-md-headset:hover { + color: var(--Color4Hover) !important; +} + +i.icon.ion-logo-youtube { + color: var(--Color1) !important; +} + +i.icon.ion-logo-youtube:hover { + color: var(--Color1Hover) !important; +} + +i.icon.ion-md-jet { + color: var(--Color3) !important; +} + +i.icon.ion-md-jet:hover { + color: var(--Color3Hover) !important; +} + +/* Home Screen: filters */ +#filters-apply { + text-align: right; +} + +/* Searchbox */ +.pure-form input[type="search"] { + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); + border-radius: 5px 5px 5px; + margin: 0px; +} + +/* Zooming */ +.pure-g:not(.h-box) > .pure-u-md-1-4 .h-box, +.pure-g:not(.searchbar) > .searchbar, +.pure-form-aligned { + border-radius: 5px 5px 5px; + padding: 12px; + transition: all 0.2s; +} + +.h-box { + padding-left: 1.1em; + padding-right: 1.1em; +} + +.pure-g:not(.h-box) > .pure-u-md-1-4 .h-box:hover { + transform: scale(1.025); + transition: all 0.2s; + opacity: 1; + z-index: 99999; +} + +/* .video-js */ +/* Video player: play button: Border */ +.video-js .vjs-big-play-button { + border-radius: 5px 5px 5px; + background-color: var(--Color1) !important; + border: 0em solid transparent; + font-size: 4.5em; + top: 50%; + left: 50%; + margin-top: -0.81666em; + margin-left: -1.5em; +} + +/* Volume Slider */ +.video-js .vjs-volume-level { + border-radius: 5px 5px 5px; + background-color: var(--Color1) !important; +} + +/* Video player: Controls: Floating */ +.video-js .vjs-control-bar, +.video-js .vjs-menu-button-popup .vjs-menu .vjs-menu-content { + font-family: sans-serif; + opacity: 1; + border-radius: 18px 0px 35px 18px 0px 35px 0 0; + left: 0.5%; + right: 0.5%; + width: 99%; + margin-bottom: 0.5%; +} + +.video-js .vjs-control-bar { + border-radius: 5px 5px 5px; +} + +/* Video player: Share Links */ +.video-js .vjs-videojs-share_open .vjs-modal-dialog .vjs-modal-dialog-content, +.video-js .vjs-modal-dialog { + width: 80%; + height: 80%; + top: 10%; + left: 10%; + border-radius: 5px 5px 5px; +} + +.video-js .vjs-share__social_fbFeed, +.video-js .vjs-share__social_tw, +.video-js .vjs-share__social_reddit, +.video-js .vjs-share__social_mail, +.video-js .vjs-share__social_email, +.video-js .vjs-share__short-link, +.video-js .vjs-share__btn, +.video-js .vjs-share__short-link-wrapper { + border-radius: 5px 5px 5px; +} + +.video-js .vjs-share__social_fbFeed { + background-color: var(--Color1); +} + +.video-js .vjs-share__social_tw { + background-color: var(--Color3); +} + +.video-js .vjs-share__social_reddit { + background-color: var(--Color2); +} + +.video-js .vjs-share__social_mail, +.video-js .vjs-share__social_email { + background-color: var(--Color4); +} + +/* Video player: Settings */ +.video-js .vjs-videojs-share_open .vjs-modal-dialog .vjs-close-button::before { + display: none; +} + +/* Video player: Size */ +.pure-u-md-20-24 { + width: 94% !important; + max-width: 170em !important; + margin: auto; +} + +/* Video player: Remove black borders */ +.player-dimensions.vjs-fluid { + padding-top: 56.25% !important; +} + +#player-container { + transition: all 0.2s; + padding-bottom: 54.7% !important; +} + +@media screen and (max-width: 48em) { + #player-container { + padding-bottom: 47% !important; + margin-bottom: 8%; + } +} + +/* Theater mode */ +@media screen and (max-width: 170em) { + #player-container { + margin-bottom: 6%; + margin-left: -3.2%; + margin-right: -3.2%; + } +} + +@media screen and (max-width: 767px) { + #player-container { + margin-bottom: 15%; + } +} + + +/* Description: Padding and Form */ +.pure-g:not(.h-box) > .pure-u-md-1-4 .h-box { + margin: 5px; +} + +@media screen and (min-width: 64em) { + .pure-u-lg-3-5 .title { + margin: 0px; + } +} + +/* Description: Title */ +@media screen and (max-width: 767px) { + h1 { + margin: 0.67em 0; + } +} + +/* Description: Subscribe button */ +#subscribe { + border-radius: 5px 5px 5px; + background-color: var(--Color1) !important; + float: right; + padding: 7.5px; + /*margin-top: -55px;*/ +} + +#subscribe:hover { + background-color: var(--Color1Hover) !important; +} + +/* Description: Download Multiple Section Bold */ +select#download_widget { + font-weight: bold; + max-width: 350px !important; + margin-top: 10px; +} + +.pure-form-stacked .pure-button-primary { + margin-top: 5px; +} + +/* Description: Download Button */ +input, +select, +textarea { + font-family: sans-serif; + border: 0px; + border-radius: 5px 5px 5px; +} + +/* Description: Channel Image */ +.channel-profile > img { + width: 36px !important; + margin-right: 6px; + height: auto; +} + +.pure-u-md-2-24 > img { + width: 36px !important; + height: auto; +} + +.pure-u-md-2-24 { + max-width: 46px; +} + +/* Scrollbar */ +::-webkit-scrollbar { + width: 15px; +} + +/* Comment Section: Heart icon */ +.icon.ion-ios-heart.creator-heart-small-container { + color: var(--Color1); +} + +/* Comment Section: OC Channel: Comment */ +body a.channel-owner { + background-color: var(--Color1); + padding: 4px 8px; + border-radius: 5px 5px 5px; +} + +body a.channel-owner:hover { + background-color: var(--Color1Hover); +} + +/* Banner on Channel */ +.pure-u-md-20-24 > .h-box > img { + border-radius: 5px 5px 5px; + margin: 5px; + opacity: 1; + transition: all 0.2s; +} + +/* Channel, Trending UI Links */ +.pure-g .pure-u-1 .pure-md-1-3 { + margin-bottom: 0.5em; +} + +/* White Line (Spacer/padding) */ +hr { + margin: 1.3em 0; +} + +.pure-form legend { + text-align: center; + margin-bottom: 1.3em; + padding: 1.3em; +} + +/* Settings */ +.pure-form-aligned .pure-control-group label, +.pure-form-aligned .pure-control-group a, +.pure-form-aligned .pure-control-group input { + text-align: left !important; + margin: 6px; +} + +.pure-form-aligned .pure-control-group select { + margin: 0px 0px 0px 6px; +} + +.pure-form-aligned .pure-controls { + margin: 0px; + text-align: right; +} + +#max_results { + width: 209.783px; +} + +@media screen and (max-width: 1280px) { + .pure-form-aligned .pure-control-group label, + .pure-form-aligned .pure-control-group a, + .pure-form-aligned .pure-controls { + padding: 0px; + } +} + +/* Shadow */ +.pure-g:not(.h-box) > .pure-u-md-1-4 .h-box:hover { + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); +} + +#player-container { + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); +} + +.pure-u-md-20-24 > .h-box > img { + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); +} diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..c347ceb --- /dev/null +++ b/build.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +if [ $# -eq 0 ]; then + echo "Usage: build [development|release]" + exit 1 +fi + +mode=$1 + + +if [ "$mode" == "release" ]; then + docker compose --profile base build --build-arg release=1 +fi + +if [ "$mode" == "development" ]; then + docker compose --profile base build --build-arg release=0 +fi + +yes | docker system prune diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100755 index 0000000..f8e0122 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,536 @@ +x-volumes: &volumes + volumes: + - /var/run/redis/redis-server.sock:/invidious/redis-server.sock:rw + +services: + + # This service is for building the base image (patch.sh && build.sh) + invidious: + <<: *volumes + env_file: + - .env + profiles: ["base"] + cpus: ${INV_CPU_CORES} + mem_limit: "${INV_MEM_LIMIT}" + mem_reservation: "${INV_MEM_RESERVATION}" + image: "${INV_IMAGE}" + build: + context: build + dockerfile: docker/Dockerfile + restart: "${INV_RESTART_POLICY}" + environment: &environment + INVIDIOUS_CONFIG: | + #force_resolve: ipv6 + modified_source_code_url: "https://github.com/Sommerwiesel/invidious-nerdvpn" + hmac_key: + db: + dbname: invidious + user: invidious + password: + host: invidious-pgbouncer + port: 5432 + redis_socket: "/invidious/redis-server.sock" + redis_db: 4 + redis_auth: "" + http_proxy: + host: "192.42.6.30" + port: 80 + check_tables: true + external_port: 443 + domain: "invidious.nerdvpn.de" + https_only: true + hsts: true + pool_size: 60 + disable_proxy: ["local"] + log_level: "Fatal" + popular_enabled: true + statistics_enabled: true + enable_user_notifications: false + channel_threads: 0 + feed_threads: 0 + use_pubsub_feeds: false + banner: "${BANNER_MSG}" + jobs: + clear_expired_items: + enable: false + refresh_channels: + enable: false + refresh_feeds: + enable: false + default_user_preferences: + locale: "de" + region: "DE" + captions: ["","English","English (auto-generated)"] + dark_mode: "dark" + feed_menu: ["Trending", "Subscriptions", "Playlists", "Search"] + default_home: "Search" + comments: ["youtube", ""] + autoplay: true + continue_autoplay: true + quality: "hd720" + quality_dash: "720p" + unseen_only: true + local: false + automatic_instance_redirect: true + networks: + invidious_proxy: + healthcheck: + test: wget -nv --tries=1 --spider http://127.0.0.1:3000/${INV_HEALTHCHECK_URL} || exit 1 + interval: 5m + retries: 2 + + # Takes care of refreshing the feeds + invidious_worker: + <<: *volumes + env_file: + - .env + profiles: ["worker"] + container_name: invidious_worker + cpus: ${INV_CPU_CORES} + mem_limit: "1536m" + mem_reservation: "768m" + image: "${INV_IMAGE}" + restart: "${INV_RESTART_POLICY}" + environment: + INVIDIOUS_CONFIG: | + #force_resolve: ipv6 + modified_source_code_url: "https://github.com/Sommerwiesel/invidious-nerdvpn" + hmac_key: + db: + dbname: invidious + user: invidious + password: + host: invidious-pgbouncer + port: 5432 + redis_socket: "/invidious/redis-server.sock" + redis_db: 4 + redis_auth: "" + http_proxy: + host: "192.42.6.30" + port: 80 + check_tables: true + external_port: 443 + domain: "invidious.nerdvpn.de" + https_only: true + hsts: true + pool_size: 100 + disable_proxy: ["livestreams","local"] + log_level: "Fatal" + popular_enabled: true + statistics_enabled: true + enable_user_notifications: false + channel_threads: 4 + feed_threads: 4 + channel_refresh_interval: "15m" + use_pubsub_feeds: true + default_user_preferences: + locale: "de" + region: "DE" + captions: ["","English","English (auto-generated)"] + dark_mode: "dark" + feed_menu: ["Trending", "Subscriptions", "Playlists", "Search"] + default_home: "Search" + comments: ["youtube", ""] + autoplay: true + continue_autoplay: true + quality: "hd720" + quality_dash: "720p" + unseen_only: true + local: false + automatic_instance_redirect: true + networks: + invidious_proxy: + ipv4_address: 192.42.6.9 + healthcheck: + test: wget -nv --tries=1 --spider http://127.0.0.1:3000/${INV_HEALTHCHECK_URL} || exit 1 + interval: 3m + timeout: 5s + retries: 2 + + invidious_1: + <<: *volumes + env_file: + - .env + profiles: ["web"] + container_name: invidious_1 + cpus: ${INV_CPU_CORES} + mem_limit: "${INV_MEM_LIMIT}" + mem_reservation: "${INV_MEM_RESERVATION}" + image: "${INV_IMAGE}" + restart: "${INV_RESTART_POLICY}" + environment: + <<: *environment + networks: + invidious_proxy: + ipv4_address: 192.42.6.2 + healthcheck: + test: wget -nv --tries=1 --spider http://127.0.0.1:3000/${INV_HEALTHCHECK_URL} || exit 1 + interval: 5m + timeout: 5s + retries: 2 + + invidious_2: + <<: *volumes + env_file: + - .env + profiles: ["web"] + container_name: invidious_2 + cpus: ${INV_CPU_CORES} + mem_limit: "${INV_MEM_LIMIT}" + mem_reservation: "${INV_MEM_RESERVATION}" + image: "${INV_IMAGE}" + restart: "${INV_RESTART_POLICY}" + environment: + <<: *environment + networks: + invidious_proxy: + ipv4_address: 192.42.6.3 + healthcheck: + test: wget -nv --tries=1 --spider http://127.0.0.1:3000/${INV_HEALTHCHECK_URL} || exit 1 + interval: 5m + timeout: 5s + retries: 2 + + invidious_3: + <<: *volumes + env_file: + - .env + profiles: ["web"] + container_name: invidious_3 + cpus: ${INV_CPU_CORES} + mem_limit: "${INV_MEM_LIMIT}" + mem_reservation: "${INV_MEM_RESERVATION}" + image: "${INV_IMAGE}" + restart: "${INV_RESTART_POLICY}" + environment: + <<: *environment + networks: + invidious_proxy: + ipv4_address: 192.42.6.4 + healthcheck: + test: wget -nv --tries=1 --spider http://127.0.0.1:3000/${INV_HEALTHCHECK_URL} || exit 1 + interval: 5m + timeout: 5s + retries: 2 + + invidious_4: + <<: *volumes + env_file: + - .env + profiles: ["web"] + container_name: invidious_4 + cpus: ${INV_CPU_CORES} + mem_limit: "${INV_MEM_LIMIT}" + mem_reservation: "${INV_MEM_RESERVATION}" + image: "${INV_IMAGE}" + restart: "${INV_RESTART_POLICY}" + environment: + <<: *environment + networks: + invidious_proxy: + ipv4_address: 192.42.6.5 + healthcheck: + test: wget -nv --tries=1 --spider http://127.0.0.1:3000/${INV_HEALTHCHECK_URL} || exit 1 + interval: 5m + timeout: 5s + retries: 2 + + invidious_5: + <<: *volumes + env_file: + - .env + profiles: ["web"] + container_name: invidious_5 + cpus: ${INV_CPU_CORES} + mem_limit: "${INV_MEM_LIMIT}" + mem_reservation: "${INV_MEM_RESERVATION}" + image: "${INV_IMAGE}" + restart: "${INV_RESTART_POLICY}" + environment: + <<: *environment + networks: + invidious_proxy: + ipv4_address: 192.42.6.6 + healthcheck: + test: wget -nv --tries=1 --spider http://127.0.0.1:3000/${INV_HEALTHCHECK_URL} || exit 1 + interval: 5m + timeout: 5s + retries: 2 + + invidious_6: + <<: *volumes + env_file: + - .env + profiles: ["web"] + container_name: invidious_6 + cpus: ${INV_CPU_CORES} + mem_limit: "${INV_MEM_LIMIT}" + mem_reservation: "${INV_MEM_RESERVATION}" + image: "${INV_IMAGE}" + restart: "${INV_RESTART_POLICY}" + environment: + <<: *environment + networks: + invidious_proxy: + ipv4_address: 192.42.6.7 + healthcheck: + test: wget -nv --tries=1 --spider http://127.0.0.1:3000/${INV_HEALTHCHECK_URL} || exit 1 + interval: 5m + timeout: 5s + retries: 2 + + materialious: + env_file: + - .env + profiles: ["materialious"] + container_name: materialious + cpus: "2" + mem_reservation: "32m" + mem_limit: "64m" + image: "wardpearce/materialious" + restart: "unless-stopped" + networks: + invidious_proxy: + ipv4_address: 192.42.6.13 + + # Return YouTube Dislike proxy via tor + materialious_ryd-proxy: + profiles: ["materialious"] + container_name: materialious_ryd-proxy + image: 1337kavin/ryd-proxy:latest + restart: "unless-stopped" + cpus: "2" + mem_reservation: "128m" + mem_limit: "256m" + depends_on: + - materialious_tor + environment: + - PROXY=socks5://materialious_tor:5566 + - WEB_CONCURRENCY=3 + networks: + invidious_proxy: + ipv4_address: 192.42.6.14 + + materialious_api: + profiles: ["materialious"] + container_name: materialious_api + image: wardpearce/invidious_api_extended:latest + restart: "unless-stopped" + cpus: "3" + mem_reservation: "192m" + mem_limit: "320m" + environment: + api_extended_postgre: '{"host": "invidious-db", "port": 5432, "database": "invidious", "user": "invidious", "password": ""}' + api_extended_allowed_origins: '["https://materialious.nerdvpn.de"]' + api_extended_debug: false + api_extended_invidious_instance: "https://api.invidious.nerdvpn.de" + api_extended_production_instance: "https://sync.invidious.nerdvpn.de" + WEB_CONCURRENCY: 3 + networks: + invidious_proxy: + ipv4_address: 192.42.6.15 + + # Opens tor circuits + materialious_tor: + profiles: ["materialious"] + container_name: materialious_tor + image: 1337kavin/alpine-tor:latest + restart: "unless-stopped" + cpus: "2" + mem_reservation: "128m" + mem_limit: "256m" + environment: + - tors=2 + - test_url="http://nerdvpn2awosmfgodp77bavzve3k2kvxw52z364suglul2qaalcdqtad.onion" + networks: + invidious_proxy: + ipv4_address: 192.42.6.20 + + materialious_peerjs: + profiles: ["materialious"] + container_name: materialious_peerjs + build: + context: peerjs + dockerfile: Dockerfile + restart: "unless-stopped" + cpus: "2" + mem_reservation: "32m" + mem_limit: "128m" + labels: + - "com.centurylinklabs.watchtower.enable=false" + networks: + invidious_proxy: + ipv4_address: 192.42.6.19 + + invidious_tor: + <<: *volumes + env_file: + - .env + profiles: ["tor"] + container_name: invidious_tor + cpus: ${INV_CPU_CORES} + mem_limit: "512m" + mem_reservation: "128m" + image: "${INV_IMAGE}" + restart: "${INV_RESTART_POLICY}" + environment: + INVIDIOUS_CONFIG: | + force_resolve: ipv6 + modified_source_code_url: "https://github.com/Sommerwiesel/invidious-nerdvpn" + hmac_key: + db: + dbname: invidious + user: invidious + password: + host: invidious-pgbouncer + port: 5432 + redis_socket: "/invidious/redis-server.sock" + redis_db: 4 + redis_auth: "" + http_proxy: + host: "192.42.6.30" + port: 80 + check_tables: true + external_port: 80 + domain: "jt3wafuew7rumgwp7wfixpbtxc4dw6jvvfjt7dud33xczvwvgih5nfqd.onion" + https_only: false + hsts: false + pool_size: 40 + disable_proxy: ["livestreams","local","dash","downloads"] + log_level: "Fatal" + popular_enabled: false + statistics_enabled: true + enable_user_notifications: false + channel_threads: 0 + feed_threads: 0 + use_pubsub_feeds: false + jobs: + clear_expired_items: + enable: false + refresh_channels: + enable: false + refresh_feeds: + enable: false + default_user_preferences: + locale: "de" + region: "DE" + captions: ["","English","English (auto-generated)"] + dark_mode: "dark" + feed_menu: ["Trending", "Subscriptions", "Playlists", "Search"] + default_home: "Search" + comments: ["youtube", ""] + autoplay: true + continue_autoplay: true + quality: "hd720" + quality_dash: "720p" + unseen_only: true + local: false + automatic_instance_redirect: false + networks: + invidious_proxy: + ipv4_address: 192.42.6.8 + healthcheck: + test: wget -nv --tries=1 --spider http://127.0.0.1:3000/${INV_HEALTHCHECK_URL} || exit 1 + interval: 5m + timeout: 5s + retries: 2 + + invidious-pgbouncer: + env_file: + - .env + profiles: ["database"] + container_name: invidious-pgbouncer + mem_limit: "128m" + mem_reservation: "64m" + image: edoburu/pgbouncer + restart: "${INV_RESTART_POLICY}" + environment: + - DB_HOST=invidious-db + - DB_PORT=5432 + - DB_USER=invidious + - DB_PASSWORD= + - DB_NAME=invidious + - ADMIN_USERS=pgbouncer + - POOL_MODE=transaction + - DEFAULT_POOL_SIZE=80 + - MIN_POOL_SIZE=20 + - RESERVE_POOL_SIZE=80 + - RESERVE_POOL_TIMEOUT=5 + - MAX_DB_CONNECTIONS=160 + - MAX_USER_CONNECTIONS=160 + - MAX_CLIENT_CONN=1000 + - AUTH_TYPE=scram-sha-256 + - IGNORE_STARTUP_PARAMETERS=extra_float_digits + volumes: + - ./docker/userlist.txt:/etc/pgbouncer/userlist.txt:rw + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB -h invidious-db"] + interval: 5m + timeout: 15s + retries: 2 + networks: + invidious_proxy: + ipv4_address: 192.42.6.11 + + invidious-db: + env_file: + - .env + profiles: ["database"] + container_name: invidious-db + cpus: ${INV_PSQL_CPU_CORES} + mem_limit: "${INV_PSQL_MEM_LIMIT}" + memswap_limit: "${INV_PSQL_MEM_LIMIT}" + mem_reservation: "${INV_PSQL_MEM_RESERVATION}" + image: "${INV_PSQL_IMAGE}" + restart: "${INV_RESTART_POLICY}" + volumes: + - type: bind + source: /srv/invidious/database + target: /var/lib/postgresql/data + - ./config/sql:/config/sql + - ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh + - ./docker/pg-tune.sql:/docker-entrypoint-initdb.d/pg-tune.sql + - ./docker/pgstat.sql:/tmp/pgstat.sql + - ./docker/pg-cleanup.sql:/tmp/pgcleanup.sql + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"] + interval: 5m + timeout: 15s + retries: 2 + networks: + invidious_proxy: + ipv4_address: 192.42.6.10 + + invidious-proxy: + profiles: ["web"] + image: 1337kavin/ytproxy:latest + container_name: invidious_proxy + cpus: "4" + mem_reservation: "256m" + mem_limit: "512m" + restart: "unless-stopped" + user: 33:33 + network_mode: "host" + environment: + - DISABLE_WEBP=1 + volumes: + - /srv/ytproxy:/app/socket + + invidious-haproxy: + profiles: ["web"] + image: haproxytech/haproxy-alpine:latest + container_name: invidious_haproxy + cpus: "3" + mem_reservation: "64m" + mem_limit: "128m" + restart: "unless-stopped" + volumes: + - ./docker/haproxy:/usr/local/etc/haproxy:ro + networks: + invidious_proxy: + ipv4_address: 192.42.6.30 + + +networks: + invidious_proxy: + external: true diff --git a/docker/APKBUILD-boringssl b/docker/APKBUILD-boringssl deleted file mode 100644 index 61caa4f..0000000 --- a/docker/APKBUILD-boringssl +++ /dev/null @@ -1,46 +0,0 @@ -# Based on https://aur.archlinux.org/packages/boringssl-git/ -# Maintainer: Omar Roth