From e8395f027b6c3e3f757c740e35b20e76c51b03bd Mon Sep 17 00:00:00 2001 From: kaiyou Date: Mon, 29 Jan 2018 08:52:20 +0100 Subject: [PATCH] Add production Alpine and Debian Stretch Docker images (#225) * First pass at a (swarm-compatible) docker image Uses an existing traefik server as a https reverse proxy. * Add example config for a Docker swarm deployment * Point to traefik config for docker compose setup * Clarify that traefik is needed for the example config * Use node:8-stretch base image and don't install yarn (The base image already contains yarn.) * Initial commit for an Alpine Docker image * Fix docker volume path * Merge #213 and #225 and move files around * Remove unnecessary dependencies from the alpine build * Update Dockerfiles to match install path, config path, etc. * Update the configuration in the example compose file * Update the configuration in the example swarm file * Remove the declared networks and volumes from the compose example, which are not strictly required * Update attachment path in the documentation * Display traefik as a suggestion and not a required dependency * Update the Docker ignored files * Fix typos reported in #225 * Move production Dockerfiles to a production directory * Add the redis configuration settings * Add Docker files to the dockerignore * Make the signup limit configurable --- .dockerignore | 10 +++ README.md | 24 ++++++- support/doc/production.md | 18 ++++++ support/docker/production/Dockerfile.alpine | 24 +++++++ support/docker/production/Dockerfile.stretch | 25 ++++++++ .../config/custom-environment-variables.yaml | 40 ++++++++++++ .../docker/production/config/production.yaml | 64 +++++++++++++++++++ support/docker/production/docker-compose.yml | 35 ++++++++++ .../docker/production/swarm-stack.sample.yml | 52 +++++++++++++++ 9 files changed, 290 insertions(+), 2 deletions(-) create mode 100644 .dockerignore create mode 100644 support/docker/production/Dockerfile.alpine create mode 100644 support/docker/production/Dockerfile.stretch create mode 100644 support/docker/production/config/custom-environment-variables.yaml create mode 100644 support/docker/production/config/production.yaml create mode 100644 support/docker/production/docker-compose.yml create mode 100644 support/docker/production/swarm-stack.sample.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..1d1cf894a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +*.swp +*.md +.git +.github +config +support/doc +support/nginx +support/systemd +support/docker/*/Dockerfile.* +support/docker/*/*.yml diff --git a/README.md b/README.md index 4d9cc298f..202d6680d 100644 --- a/README.md +++ b/README.md @@ -65,8 +65,8 @@ donating to them](https://soutenir.framasoft.org/en/).** Want to see it in action? * Demonstration servers: - * [peertube.cpy.re](http://peertube.cpy.re) - * [peertube2.cpy.re](http://peertube2.cpy.re) + * [peertube.cpy.re](http://peertube.cpy.re) + * [peertube2.cpy.re](http://peertube2.cpy.re) * [peertube3.cpy.re](http://peertube3.cpy.re) * [Video](https://peertube.cpy.re/videos/watch/f78a97f8-a142-4ce1-a5bd-154bf9386504) to see what the "decentralization feature" looks like @@ -139,6 +139,26 @@ BitTorrent) inside the web browser, as of today. * OpenSSL (cli) * FFmpeg +## Run using Docker + +You can quickly get a server running using Docker. You need to have [docker](https://www.docker.com/community-edition) and [docker-compose](https://docs.docker.com/compose/install/) installed. + +For this example configuration, you should also run a reverse proxy. The example +Docker Compose file provides example labels for the Traefik load balancer, +though any HTTP reverse proxy is compatible. + +Example for running a peertube server locally: + +```bash +sudo \ + PEERTUBE_HOSTNAME=peertube.lvh.me \ + PEERTUBE_ADMIN_EMAIL=test@example.com \ + PEERTUBE_TRANSCODING_ENABLED=true \ + docker-compose up app +``` + +(Get the initial root user password from the program output.) + ## Production See the [production guide](support/doc/production.md). diff --git a/support/doc/production.md b/support/doc/production.md index c18b4ead0..ae7f3e0f6 100644 --- a/support/doc/production.md +++ b/support/doc/production.md @@ -315,3 +315,21 @@ $ OLD_VERSION="v0.42.42" && SQL_BACKUP_PATH="backup/sql-peertube_prod-2018-01-19 pg_restore -U peertube -c -d peertube_prod "$SQL_BACKUP_PATH" sudo systemctl restart peertube ``` + +## Installation on Docker Swarm + +There is an example configuration for deploying peertube and a postgres database as a Docker swarm stack. It works like this: + +(_Note_: You need to make sure to set `traefik` and `peertube` labels on the target node(s) for this configuration to work.) + +1. Install a traefik loadbalancer stack (including Let's Encrypt) on your docker swarm. [Here](https://gist.github.com/djmaze/2684fbf147d775c8ee441b4302554823) is an example configuration. + +2. Copy the [example stack file](support/docker/production/docker-stack.example.yml) for peertube: + + scp support/docker/production/docker-stack.example.yml root@your-server:/path/to/your/swarm-config/peertube.yml + +2. Have a look at the file and adjust the variables to your need. + +3. Deploy the stack: + + docker stack deploy -c peertube.yml peertube diff --git a/support/docker/production/Dockerfile.alpine b/support/docker/production/Dockerfile.alpine new file mode 100644 index 000000000..939b2d23b --- /dev/null +++ b/support/docker/production/Dockerfile.alpine @@ -0,0 +1,24 @@ +FROM node:8-alpine + +# Install dependencies +RUN apk add --no-cache ffmpeg openssl bash make g++ git \ + && apk add --no-cache --repository https://dl-3.alpinelinux.org/alpine/edge/testing/ vips-dev fftw-dev + +# Install the application +WORKDIR /app + +COPY . ./ +RUN bash -c 'yarn install --pure-lockfile && npm run build' + +# Configure the application +RUN addgroup -g 991 peertube \ + && adduser -D -u 991 -G peertube -h /data peertube +USER peertube + +ENV NODE_ENV production +ENV NODE_CONFIG_DIR /app/support/docker/production/config/ + +# Run the application +CMD ["npm", "start"] +VOLUME ["/data"] +EXPOSE 9000 diff --git a/support/docker/production/Dockerfile.stretch b/support/docker/production/Dockerfile.stretch new file mode 100644 index 000000000..c739247a6 --- /dev/null +++ b/support/docker/production/Dockerfile.stretch @@ -0,0 +1,25 @@ +FROM node:8-stretch + +# Install dependencies +RUN apt-get update \ + && apt-get -y install ffmpeg \ + && rm /var/lib/apt/lists/* -fR + +# Install the application +WORKDIR /app + +COPY . ./ +RUN yarn install --pure-lockfile && npm run build + +# Configure the application +RUN groupadd -g 991 peertube \ + && useradd -u 991 -g peertube -d /data -m peertube +USER peertube + +ENV NODE_ENV production +ENV NODE_CONFIG_DIR /app/support/docker/production/config + +# Run the application +CMD ["npm", "start"] +VOLUME ["/data"] +EXPOSE 9000 diff --git a/support/docker/production/config/custom-environment-variables.yaml b/support/docker/production/config/custom-environment-variables.yaml new file mode 100644 index 000000000..5226e1742 --- /dev/null +++ b/support/docker/production/config/custom-environment-variables.yaml @@ -0,0 +1,40 @@ +webserver: + hostname: "PEERTUBE_HOSTNAME" + port: + __name: "PEERTUBE_PORT" + __format: "json" + https: + __name: "PEERTUBE_HTTPS" + __format: "json" + +database: + hostname: "PEERTUBE_DB_HOSTNAME" + port: + __name: "PEERTUBE_DB_PORT" + __format: "json" + suffix: "PEERTUBE_DB_SUFFIX" + username: "PEERTUBE_DB_USERNAME" + password: "PEERTUBE_DB_PASSWORD" + +redis: + hostname: "PEERTUBE_REDIS_HOSTNAME" + port: + __name: "PEERTUBE_REDIS_PORT" + __format: "json" + auth: "PEERTUBE_REDIS_AUTH" + +admin: + email: "PEERTUBE_ADMIN_EMAIL" + +signup: + enabled: + __name: "PEERTUBE_SIGNUP_ENABLED" + __format: "json" + limit: + __name: "PEETUBE_SIGNUP_LIMIT" + __format: "json" + +transcoding: + enabled: + __name: "PEERTUBE_TRANSCODING_ENABLED" + __format: "json" diff --git a/support/docker/production/config/production.yaml b/support/docker/production/config/production.yaml new file mode 100644 index 000000000..4666ea2ed --- /dev/null +++ b/support/docker/production/config/production.yaml @@ -0,0 +1,64 @@ +listen: + port: 9000 + +# Correspond to your reverse proxy "listen" configuration +webserver: + https: true + hostname: undefined + port: 443 + +# Your database name will be "peertube"+database.suffix +database: + hostname: 'db' + port: 5432 + suffix: '' + username: 'postgres' + password: 'postgres' + +# Redis server for short time storage +redis: + hostname: 'redis' + port: 6379 + auth: null + +# From the project root directory +storage: + avatars: '../data/avatars/' + certs: '../data/certs/' + videos: '../data/videos/' + logs: '../data/logs/' + previews: '../data/previews/' + thumbnails: '../data/thumbnails/' + torrents: '../data/torrents/' + cache: '../data/cache/' + +log: + level: 'info' # debug/info/warning/error + +cache: + previews: + size: 100 # Max number of previews you want to cache + +admin: + email: undefined + +signup: + enabled: false + limit: -1 + +user: + # Default value of maximum video BYTES the user can upload (does not take into account transcoded files). + # -1 == unlimited + video_quota: -1 + +# If enabled, the video will be transcoded to mp4 (x264) with "faststart" flag +# Uses a lot of CPU! +transcoding: + enabled: false + threads: 2 + resolutions: # Only created if the original video has a higher resolution + 240p: true + 360p: true + 480p: true + 720p: true + 1080p: true diff --git a/support/docker/production/docker-compose.yml b/support/docker/production/docker-compose.yml new file mode 100644 index 000000000..db1c7d587 --- /dev/null +++ b/support/docker/production/docker-compose.yml @@ -0,0 +1,35 @@ +version: "3.3" + +services: + peertube: + + build: . + image: peertube:stretch + environment: + PEERTUBE_HOSTNAME: my.domain.tld + PEERTUBE_PORT: 443 + PEERTUBE_HTTPS: true + PEERTUBE_ADMIN_EMAIL: admin@domain.tld + PEERTUBE_DB_USERNAME: user + PEERTUBE_DB_PASSWORD: password + PEERTUBE_SIGNUP_ENABLED: true + PEERTUBE_TRANSCODING_ENABLED: true + # Traefik labels are suggested as an example for people using Traefik, + # remove them if you are using another reverse proxy. + labels: + traefik.enable: "true" + traefik.frontend.rule: "Host:${PEERTUBE_HOSTNAME}" + traefik.port: "9000" + volumes: + - ./data:/usr/src/app/data + depends_on: + - db + + db: + image: postgres:10 + environment: + POSTGRES_USERNAME: user + POSTGRES_PASSWORD: password + POSTGRES_DB: peertube_prod + volumes: + - ./db:/var/lib/postgresql/data diff --git a/support/docker/production/swarm-stack.sample.yml b/support/docker/production/swarm-stack.sample.yml new file mode 100644 index 000000000..794f44753 --- /dev/null +++ b/support/docker/production/swarm-stack.sample.yml @@ -0,0 +1,52 @@ +version: "3.3" + +services: + app: + image: peertube:stretch + environment: + PEERTUBE_HOSTNAME: my.domain.tld + PEERTUBE_PORT: 443 + PEERTUBE_HTTPS: true + PEERTUBE_ADMIN_EMAIL: admin@domain.tld + PEERTUBE_DB_USERNAME: user + PEERTUBE_DB_PASSWORD: password + PEERTUBE_SIGNUP_ENABLED: true + PEERTUBE_TRANSCODING_ENABLED: true + labels: &labels + traefik.frontend.rule: "Host:my.domain.tld" + traefik.docker.network: traefik + traefik.port: "9000" + volumes: + - app_data:/usr/src/app/data + networks: + - traefik + - backend + depends_on: + - db + deploy: + labels: *labels + placement: + constraints: + - node.labels.peertube == 1 + + db: + image: postgres:10 + environment: + POSTGRES_DB: peertube_prod + volumes: + - db_data:/var/lib/postgresql/data + networks: + - backend + deploy: + placement: + constraints: + - node.labels.peertube == 1 + +volumes: + app_data: + db_data: + +networks: + backend: + traefik: + external: true -- 2.25.1