generated from coop-cloud/example
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
2e0cf00740
|
24
.drone.yml
24
.drone.yml
@ -3,13 +3,10 @@ kind: pipeline
|
||||
name: deploy to swarm-test.autonomic.zone
|
||||
steps:
|
||||
- name: deployment
|
||||
image: git.coopcloud.tech/coop-cloud/stack-ssh-deploy:latest
|
||||
image: decentral1se/stack-ssh-deploy:latest
|
||||
settings:
|
||||
host: swarm-test.autonomic.zone
|
||||
stack: peertube
|
||||
generate_secrets: true
|
||||
networks:
|
||||
- proxy
|
||||
purge: true
|
||||
deploy_key:
|
||||
from_secret: drone_ssh_swarm_test
|
||||
@ -17,25 +14,16 @@ steps:
|
||||
DOMAIN: peertube.swarm-test.autonomic.zone
|
||||
STACK_NAME: peertube
|
||||
LETS_ENCRYPT_ENV: production
|
||||
NGINX_CONFIG_VERSION: v1
|
||||
APP_ENTRYPOINT_VERSION: v1
|
||||
SECRET_DB_PASSWORD_VERSION: v1
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
---
|
||||
kind: pipeline
|
||||
name: generate recipe catalogue
|
||||
name: recipe release
|
||||
steps:
|
||||
- name: release a new version
|
||||
image: plugins/downstream
|
||||
image: thecoopcloud/drone-abra:latest
|
||||
settings:
|
||||
server: https://build.coopcloud.tech
|
||||
token:
|
||||
from_secret: drone_abra-bot_token
|
||||
fork: true
|
||||
repositories:
|
||||
- toolshed/auto-recipes-catalogue-json
|
||||
|
||||
trigger:
|
||||
event: tag
|
||||
command: recipe peertube release
|
||||
deploy_key:
|
||||
from_secret: abra_bot_deploy_key
|
||||
|
||||
@ -2,7 +2,6 @@ TYPE=peertube
|
||||
|
||||
DOMAIN=peertube.example.com # <= EDIT THIS
|
||||
LETS_ENCRYPT_ENV=production
|
||||
COMPOSE_FILE=compose.yml
|
||||
|
||||
PEERTUBE_WEBSERVER_PORT=443
|
||||
PEERTUBE_WEBSERVER_HTTPS=true
|
||||
@ -13,10 +12,6 @@ PEERTUBE_CONTACT_FORM_ENABLED=false
|
||||
|
||||
SECRET_DB_PASSWORD_VERSION=v1
|
||||
|
||||
# Comment out these lines if you want to store the peertube secret in a config file instead of a docker secret
|
||||
COMPOSE_FILE="$COMPOSE_FILE:compose.peertube-secret.yml"
|
||||
SECRET_PEERTUBE_SECRET_VERSION=v1 # length=32
|
||||
|
||||
## Webseed backend
|
||||
#
|
||||
# If no NGINX_WEBSEED option is enabled, videos will be served
|
||||
@ -50,6 +45,3 @@ SECRET_PEERTUBE_SECRET_VERSION=v1 # length=32
|
||||
|
||||
## Live chat settings
|
||||
#PEERTUBE_LIVE_CHAT_ENABLED=1
|
||||
|
||||
## Healthcheck settings
|
||||
PEERTUBE_LOG_PING_REQUESTS=false
|
||||
|
||||
15
README.md
15
README.md
@ -20,11 +20,12 @@ An ActivityPub-federated video streaming platform using P2P directly in your web
|
||||
|
||||
1. Set up Docker Swarm and [`abra`]
|
||||
2. Deploy [`coop-cloud/traefik`]
|
||||
3. `abra app new peertube`
|
||||
4. `abra app secret generate YOURAPPDOMAIN -a`
|
||||
5. `abra app config YOURAPPDOMAIN` - be sure to change `DOMAIN` to something that resolves to your Docker swarm box
|
||||
6. `abra app deploy YOURAPPDOMAIN`
|
||||
7. Open the configured domain in your browser to finish set-up
|
||||
3. `abra app new peertube --secrets` (optionally with `--pass` if you'd like
|
||||
to save secrets in `pass`)
|
||||
4. `abra app YOURAPPDOMAIN config` - be sure to change `DOMAIN` to something that resolves to
|
||||
your Docker swarm box
|
||||
5. `abra app YOURAPPDOMAIN deploy`
|
||||
6. Open the configured domain in your browser to finish set-up
|
||||
|
||||
## Host-mode networking
|
||||
|
||||
@ -39,8 +40,8 @@ This will avoid issues like [`#7`](https://git.coopcloud.tech/coop-cloud/peertub
|
||||
## Email
|
||||
|
||||
1. Deploy [`coop-cloud/postfix-relay`] or use an external SMTP relay
|
||||
2. `abra app config YOURAPPDOMAIN`, and uncomment the email lines and adjust as needed
|
||||
3. `abra app deploy YOURAPPDOMAIN`
|
||||
2. `abra app YOURAPPDOMAIN config`, and uncomment the email lines and adjust as needed
|
||||
3. `abra app YOURAPPDOMAIN deploy`
|
||||
|
||||
[`abra`]: https://git.autonomic.zone/autonomic-cooperative/abra
|
||||
[`coop-cloud/traefik`]: https://git.autonomic.zone/coop-cloud/traefik
|
||||
|
||||
4
abra.sh
4
abra.sh
@ -1,7 +1,7 @@
|
||||
# shellcheck disable=SC2034,SC2145
|
||||
|
||||
export NGINX_CONFIG_VERSION=v8
|
||||
export APP_ENTRYPOINT_VERSION=v7
|
||||
export NGINX_CONFIG_VERSION=v4
|
||||
export APP_ENTRYPOINT_VERSION=v5
|
||||
|
||||
sub_npm() {
|
||||
abra__service_="app"
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
---
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
app:
|
||||
environment:
|
||||
- PEERTUBE_SECRET_FILE=/run/secrets/peertube_secret
|
||||
secrets:
|
||||
- peertube_secret
|
||||
|
||||
secrets:
|
||||
peertube_secret:
|
||||
external: true
|
||||
name: ${STACK_NAME}_peertube_secret_${SECRET_PEERTUBE_SECRET_VERSION}
|
||||
41
compose.yml
41
compose.yml
@ -3,7 +3,7 @@ version: "3.8"
|
||||
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.29.4
|
||||
image: nginx:1.20.0
|
||||
networks:
|
||||
- proxy
|
||||
- internal
|
||||
@ -27,11 +27,6 @@ services:
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
update_config:
|
||||
failure_action: rollback
|
||||
order: start-first
|
||||
rollback_config:
|
||||
order: start-first
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
|
||||
@ -40,16 +35,15 @@ services:
|
||||
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
|
||||
|
||||
app:
|
||||
image: chocobozzz/peertube:v7.3.0-bookworm
|
||||
image: chocobozzz/peertube:v4.2.2-bullseye
|
||||
environment:
|
||||
- PEERTUBE_ADMIN_EMAIL
|
||||
- PEERTUBE_CONTACT_FORM_ENABLED
|
||||
- PEERTUBE_DB_HOSTNAME=db
|
||||
- PEERTUBE_DB_PASSWORD_FILE=/run/secrets/db_password
|
||||
- PEERTUBE_DB_PORT=5432
|
||||
- PEERTUBE_DB_USERNAME=peertube
|
||||
- PEERTUBE_DB_PASSWORD_FILE=/run/secrets/db_password
|
||||
- PEERTUBE_LIVE_CHAT_ENABLED
|
||||
- PEERTUBE_LOG_PING_REQUESTS
|
||||
- PEERTUBE_REDIS_HOSTNAME=cache
|
||||
- PEERTUBE_SIGNUP_ENABLED
|
||||
- PEERTUBE_SMTP_ENABLED
|
||||
@ -68,48 +62,39 @@ services:
|
||||
- source: app_entrypoint
|
||||
target: /docker-entrypoint.sh
|
||||
mode: 0555
|
||||
command: node dist/server
|
||||
command: npm start
|
||||
healthcheck:
|
||||
test: curl -f http://localhost:9000/v1/api/ping || exit 1
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 20
|
||||
test: 'nodejs -e "http.get(''http://localhost:9000/api/v1/ping'', (res) => { console.log(''status: '', res.statusCode); if (res.statusCode == 200) { process.exit(0); } else { process.exit(1); } });"'
|
||||
interval: 1m
|
||||
timeout: 30s
|
||||
retries: 3
|
||||
start_period: 1m
|
||||
entrypoint: /docker-entrypoint.sh
|
||||
networks:
|
||||
- internal
|
||||
deploy:
|
||||
labels:
|
||||
- "coop-cloud.${STACK_NAME}.version=7.2.1+v7.3.0-bookworm"
|
||||
- "coop-cloud.${STACK_NAME}.version=2.2.0+v4.2.2-bullseye"
|
||||
|
||||
db:
|
||||
image: pgautoupgrade/pgautoupgrade:18-alpine
|
||||
image: postgres:10-alpine
|
||||
environment:
|
||||
- POSTGRES_USER=peertube
|
||||
- POSTGRES_DB=peertube
|
||||
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
|
||||
- POSTGRES_DB=peertube
|
||||
secrets:
|
||||
- db_password
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- internal
|
||||
healthcheck:
|
||||
test: pg_isready -U peertube
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
cache:
|
||||
image: redis:8-alpine
|
||||
image: redis:4-alpine
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
networks:
|
||||
- internal
|
||||
healthcheck:
|
||||
test: redis-cli ping
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
networks:
|
||||
internal:
|
||||
|
||||
@ -25,7 +25,6 @@ file_env() {
|
||||
}
|
||||
|
||||
file_env "PEERTUBE_DB_PASSWORD"
|
||||
file_env "PEERTUBE_SECRET"
|
||||
|
||||
{{ if eq (env "PEERTUBE_SMTP_ENABLED") "1" }}
|
||||
file_env "PEERTUBE_SMTP_PASSWORD"
|
||||
|
||||
@ -39,22 +39,15 @@ http {
|
||||
try_files /dev/null @api;
|
||||
}
|
||||
|
||||
location ~ ^/api/v1/videos/(upload-resumable|([^/]+/source/replace-resumable))$ {
|
||||
location = /api/v1/videos/upload-resumable {
|
||||
client_max_body_size 0;
|
||||
proxy_request_buffering off;
|
||||
|
||||
try_files /dev/null @api;
|
||||
}
|
||||
|
||||
location ~ ^/api/v1/users/[^/]+/imports/import-resumable$ {
|
||||
client_max_body_size 0;
|
||||
proxy_request_buffering off;
|
||||
|
||||
try_files /dev/null @api;
|
||||
}
|
||||
|
||||
location ~ ^/api/v1/videos/(upload|([^/]+/studio/edit))$ {
|
||||
limit_except POST HEAD { deny all; }
|
||||
location ~ ^/api/v1/videos/(upload|([^/]+/editor/edit))$ {
|
||||
limit_except POST HEAD { deny all; }
|
||||
|
||||
# This is the maximum upload size, which roughly matches the maximum size of a video file.
|
||||
# Note that temporary space is needed equal to the total size of all concurrent uploads.
|
||||
@ -66,13 +59,6 @@ http {
|
||||
try_files /dev/null @api;
|
||||
}
|
||||
|
||||
location ~ ^/api/v1/runners/jobs/[^/]+/(update|success)$ {
|
||||
client_max_body_size 12G; # default is 1M
|
||||
add_header X-File-Maximum-Size 8G always; # inform backend of the set value in bytes before mime-encoding (x * 1.4 >= client_max_body_size)
|
||||
|
||||
try_files /dev/null @api;
|
||||
}
|
||||
|
||||
location ~ ^/api/v1/(videos|video-playlists|video-channels|users/me) {
|
||||
client_max_body_size 3M; # default is 1M
|
||||
add_header X-File-Maximum-Size 2M always; # inform backend of the set value in bytes before mime-encoding (x * 1.4 >= client_max_body_size)
|
||||
@ -107,11 +93,6 @@ http {
|
||||
try_files /dev/null @api_websocket;
|
||||
}
|
||||
|
||||
# Plugin websocket routes
|
||||
location ~ ^/plugins/[^/]+(/[^/]+)?/ws/ {
|
||||
try_files /dev/null @api_websocket;
|
||||
}
|
||||
|
||||
##
|
||||
# Performance optimizations
|
||||
# For extra performance please refer to https://github.com/denji/nginx-tuning
|
||||
@ -130,8 +111,7 @@ http {
|
||||
font/truetype
|
||||
font/opentype
|
||||
application/vnd.ms-fontobject
|
||||
image/svg+xml
|
||||
application/xml;
|
||||
image/svg+xml;
|
||||
gzip_min_length 1000; # default is 20 bytes
|
||||
gzip_buffers 16 8k;
|
||||
gzip_comp_level 2; # default is 1
|
||||
@ -153,8 +133,8 @@ http {
|
||||
|
||||
# Bypass PeerTube for performance reasons. Optional.
|
||||
# Should be consistent with client-overrides assets list in /server/controllers/client.ts
|
||||
location ~ ^/client/(assets/images/(icons/icon-36x36\.png|icons/icon-48x48\.png|icons/icon-72x72\.png|icons/icon-96x96\.png|icons/icon-144x144\.png|icons/icon-192x192\.png|icons/icon-512x512\.png|logo\.svg|favicon\.png))$ {
|
||||
add_header Cache-Control "public, max-age=31536000, immutable"; # Cache 1 year
|
||||
location ~ ^/client/(assets/images/(icons/icon-36x36\.png|icons/icon-48x48\.png|icons/icon-72x72\.png|icons/icon-96x96\.png|icons/icon-144x144\.png|icons/icon-192x192\.png|icons/icon-512x512\.png|logo\.svg|favicon\.png|default-playlist\.jpg|default-avatar-account\.png|default-avatar-video-channel\.png))$ {
|
||||
add_header Cache-Control "public, max-age=31536000, immutable"; # Cache 1 year
|
||||
|
||||
root /var/www/peertube;
|
||||
|
||||
@ -168,28 +148,39 @@ http {
|
||||
alias /var/www/peertube/peertube-latest/client/dist/$1;
|
||||
}
|
||||
|
||||
# Plugin websocket routes
|
||||
location ~ ^/plugins/[^/]+(/[^/]+)?/ws/ {
|
||||
try_files /dev/null @api_websocket;
|
||||
}
|
||||
# Bypass PeerTube for performance reasons. Optional.
|
||||
location ~ ^/static/(thumbnails|avatars)/ {
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header Access-Control-Allow-Origin '*';
|
||||
add_header Access-Control-Allow-Methods 'GET, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
||||
add_header Access-Control-Max-Age 1728000; # Preflight request can be cached 20 days
|
||||
add_header Content-Type 'text/plain charset=UTF-8';
|
||||
add_header Content-Length 0;
|
||||
return 204;
|
||||
}
|
||||
|
||||
location ~ ^(/static/(webseed|web-videos|streaming-playlists)/private/)|^/download {
|
||||
#We can't rate limit a try_files directive, so we need to duplicate @api
|
||||
add_header Access-Control-Allow-Origin '*';
|
||||
add_header Access-Control-Allow-Methods 'GET, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
||||
add_header Cache-Control "public, max-age=7200"; # Cache response 2 hours
|
||||
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
|
||||
proxy_limit_rate 5M;
|
||||
rewrite ^/static/(.*)$ /$1 break;
|
||||
|
||||
proxy_pass http://backend;
|
||||
try_files $uri @api;
|
||||
}
|
||||
|
||||
# Bypass PeerTube for performance reasons. Optional.
|
||||
location ~ ^/static/(webseed|web-videos|redundancy|streaming-playlists)/ {
|
||||
limit_rate_after 5M;
|
||||
location ~ ^/static/(webseed|redundancy|streaming-playlists)/ {
|
||||
limit_rate_after 5M;
|
||||
|
||||
set $peertube_limit_rate 5M;
|
||||
# Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client
|
||||
set $peertube_limit_rate 800k;
|
||||
|
||||
# Increase rate limit in HLS mode, because we don't have multiple simultaneous connections
|
||||
if ($request_uri ~ -fragmented.mp4$) {
|
||||
set $peertube_limit_rate 5M;
|
||||
}
|
||||
|
||||
# Use this line with nginx >= 1.17.0
|
||||
limit_rate $peertube_limit_rate;
|
||||
@ -210,13 +201,23 @@ http {
|
||||
add_header Access-Control-Allow-Origin '*';
|
||||
add_header Access-Control-Allow-Methods 'GET, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
|
||||
add_header X-Cache-Status $upstream_cache_status;
|
||||
add_header X-Cache-Range $slice_range;
|
||||
add_header X-Fuuu ok;
|
||||
|
||||
add_header X-Accel-Expires 604800;
|
||||
|
||||
# Don't spam access log file with byte range requests
|
||||
access_log off;
|
||||
}
|
||||
|
||||
aio threads;
|
||||
|
||||
# Enabling the sendfile directive eliminates the step of copying the data into the buffer
|
||||
# and enables direct copying data from one file descriptor to another.
|
||||
sendfile on;
|
||||
sendfile_max_chunk 1M; # prevent one fast connection from entirely occupying the worker process. should be > 800k.
|
||||
aio threads;
|
||||
sendfile_max_chunk 1M; # prevent one fast connection from entirely occupying the worker process.
|
||||
# should be > 800k.
|
||||
|
||||
{{ if eq (env "NGINX_WEBSEED_PROXY_ENABLED") "1" }}
|
||||
proxy_connect_timeout 70;
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
Redis needs to be ugpraded to >= 6 and you can't downgrade afterwards, so
|
||||
beware!
|
||||
|
||||
-- @decentral1se / Autonomic
|
||||
@ -1,14 +0,0 @@
|
||||
This will break your deployment!
|
||||
You need to add new lines to /config/production.yaml as shown here:
|
||||
https://github.com/Chocobozzz/PeerTube/blob/v5.0.0/config/production.yaml.example#L14
|
||||
https://github.com/Chocobozzz/PeerTube/blob/v5.0.0/config/production.yaml.example#L153
|
||||
|
||||
you can do that from the host as the file is inside a volume. It should be in /var/lib/docker/volumes/<peertube stack name>_app-config/_data/production.yaml on your host machine. It's important to save the secret that you're putting in the file somewhere else, as the container has write access to the file, and it's possible it could overwrite it, causing the secret to disappear. We don't know what happens to your data if you lose that secret.
|
||||
|
||||
You'll also have to run a migration as described in https://github.com/Chocobozzz/PeerTube/releases/tag/v5.0.0
|
||||
|
||||
abra app run <app name> app bash -u peertube
|
||||
and when inside the container:
|
||||
node dist/scripts/migrations/peertube-5.0.js
|
||||
|
||||
knoflook & decentralise @ Autonomic Co-op
|
||||
@ -1,9 +0,0 @@
|
||||
WARNING! ⚠️
|
||||
|
||||
This release includes several major Postgres version updates, please make even more sure to take a database backup than usual
|
||||
|
||||
Also, `PEERTUBE_SECRET `can now be stored in Docker, instead of just in a config file. To enable this behaviour:
|
||||
|
||||
1. Extract the secret from the config file using `abra app run $STACK_NAME app grep peertube: /config/production.yaml | cut -d'"' -f2`
|
||||
2. Run `abra app secret insert $STACK_NAME peertube_secret v1`
|
||||
3. Run `abra app config $STACK_NAME`, and set `COMPOSE_FILE=compose.yml:compose.peertube-secret.yml`
|
||||
@ -1,25 +0,0 @@
|
||||
Before upgrading:
|
||||
|
||||
You might need to migrate some data, depending on your setup:
|
||||
> Important for Docker admins If you enabled the "Keep a version of the input file" configuration, files may have been stored in the container instead of the host volume. To prevent data loss, you must copy the files on the host before upgrading using docker compose cp peertube:/app/storage/original-video-files docker-volume/data
|
||||
|
||||
If you are upgrading from earlier versions, double check the configs `default.yml` and `production.yaml` as new config keys have been added but we are (currently) not tracking that file here (see issue: https://git.coopcloud.tech/coop-cloud/peertube/issues/17).
|
||||
|
||||
You can find the production.yaml.example here:
|
||||
https://github.com/Chocobozzz/PeerTube/blob/v6.3.3/config/production.yaml.example
|
||||
|
||||
After upgrading:
|
||||
You need to manually execute a migration script after your upgrade while PeerTube is running and the database migration is complete (`Migrations finished. New migration version schema: 865` in PeerTube startup logs, this migration script may take a while).
|
||||
|
||||
To search the logs:
|
||||
`abra app logs <app>`
|
||||
|
||||
To execute the migration:
|
||||
|
||||
```abra app run <app> app bash
|
||||
export ARGS="-e NODE_CONFIG_DIR=/config -e NODE_ENV=production"
|
||||
export PEERTUBE_DB_PASSWORD=$(cat /run/secrets/db_password)
|
||||
node dist/scripts/migrations/peertube-6.3.js```
|
||||
|
||||
You can find the full release notes here:
|
||||
https://github.com/Chocobozzz/PeerTube/blob/develop/CHANGELOG.md#important-notes-5
|
||||
@ -1,11 +0,0 @@
|
||||
> Due to a bug in the remote video thumbnail update, we recommend running the prune storage script to clean up the filesystem
|
||||
|
||||
```abra app run <app> app bash
|
||||
export ARGS="-e NODE_CONFIG_DIR=/config -e NODE_ENV=production"
|
||||
export PEERTUBE_DB_PASSWORD=$(cat /run/secrets/db_password)
|
||||
npm run prune-storage```
|
||||
|
||||
> If you are using object storage, you will need to create the captions bucket or configure PeerTube to use an existing one in the configuration file or using environment variables if you use Docker (PEERTUBE_OBJECT_STORAGE_CAPTIONS_BUCKET_NAME, PEERTUBE_OBJECT_STORAGE_CAPTIONS_PREFIX, PEERTUBE_OBJECT_STORAGE_CAPTIONS_BASE_URL)
|
||||
|
||||
See release notes: https://github.com/Chocobozzz/PeerTube/blob/develop/CHANGELOG.md#v710
|
||||
|
||||
Reference in New Issue
Block a user