Merge pull request #428 from padloc/docs/docker-examples

Add examples for setting up self-hosted server and pwa via docker
This commit is contained in:
Martin Kleinschrodt 2022-04-13 10:32:31 +02:00 committed by GitHub
commit 347284f7cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 733 additions and 20 deletions

2
.gitignore vendored
View File

@ -16,7 +16,7 @@ packages/cordova/dist
packages/electron/build
packages/electron/app
packages/electron/dist
*.env
/.env
packages/pwa/dist
packages/server/logs
packages/server/data

View File

@ -1,11 +1,9 @@
FROM node:16
ENV PL_PWA_PORT=8080
ENV PL_PWA_DIR=/pwa
FROM node:16-bullseye
EXPOSE 8080
VOLUME ["/pwa"]
ENV PL_ASSETS_DIR=/assets
ENV PL_PWA_DIR=/pwa
WORKDIR /padloc
@ -33,8 +31,9 @@ COPY packages/core/tsconfig.json ./packages/core/
COPY packages/locale/src ./packages/locale/src
COPY packages/locale/res ./packages/locale/res
COPY packages/locale/tsconfig.json ./packages/locale/
COPY assets /assets
WORKDIR packages/pwa
WORKDIR /padloc/packages/pwa
ENTRYPOINT ["npm", "run"]

View File

@ -1,16 +1,9 @@
FROM node:16
ENV PL_SERVER_PORT=3000
ENV PL_BILLING_PORT=4000
ENV PL_DB_PATH=/data
ENV PL_ATTACHMENTS_PATH=/attachments
ENV PL_LOG_DIR=/logs
ENV PL_REPL_HISTORY=.pl_repl_history
FROM node:16.13.1
EXPOSE 3000
EXPOSE 4000
VOLUME ["/data", "/attachments", "/logs"]
ENV PL_ASSETS_DIR=/assets
ENV PL_ATTACHMENTS_DIR=/attachments
WORKDIR /padloc
@ -34,10 +27,9 @@ COPY packages/core/tsconfig.json ./packages/core/
COPY packages/locale/src ./packages/locale/src
COPY packages/locale/res ./packages/locale/res
COPY packages/locale/tsconfig.json ./packages/locale/
COPY assets /assets
COPY packages/server/do-ca.crt ./packages/server/
WORKDIR packages/server
WORKDIR /padloc/packages/server
ENTRYPOINT ["npm", "run"]

View File

@ -0,0 +1,307 @@
# =============================================================================
# TRANSPORT
#
# Supported backends: http (default)
# =============================================================================
# -----------------------------------------------------------------------------
# HTTP
# -----------------------------------------------------------------------------
# PL_TRANSPORT_BACKEND=http
# PL_TRANSPORT_HTTP_PORT=3000
# PL_TRANSPORT_HTTP_MAX_REQUEST_SIZE=1e9
# PL_TRANSPORT_HTTP_ALLOW_ORIGIN=*
# =============================================================================
# EMAIL
#
# Supported backends: smtp, console (default)
# =============================================================================
# -----------------------------------------------------------------------------
# CONSOLE
#
# Just prints a text version of all emails to stdout
# -----------------------------------------------------------------------------
# PL_EMAIL_BACKEND=console
# -----------------------------------------------------------------------------
# SMTP
#
# Use smtp protocol for sending emails
# -----------------------------------------------------------------------------
# PL_EMAIL_BACKEND=smtp
# PL_EMAIL_SMTP_HOST=localhost
# PL_EMAIL_SMTP_PORT=1025
# PL_EMAIL_SMTP_SECURE=false
# PL_EMAIL_SMTP_IGNORE_TLS=false
# PL_EMAIL_SMTP_USER=""
# PL_EMAIL_SMTP_PASSWORD=""
# PL_EMAIL_SMTP_TEMPLATE_DIR=""
# PL_EMAIL_SMTP_FROM=""
# =============================================================================
# DATA STORAGE
#
# Supported backends: void, memory, leveldb (default), mongodb, postgres
# =============================================================================
# -----------------------------------------------------------------------------
# VOID
#
# Doesn't store anything. All data goes straight into the void.
# -----------------------------------------------------------------------------
# PL_DATA_BACKEND=void
# -----------------------------------------------------------------------------
# MEMORY
#
# Data is stored in memory only
# -----------------------------------------------------------------------------
# PL_DATA_BACKEND=memory
# -----------------------------------------------------------------------------
# LEVELDB
#
# Use embedded leveldb as storage backend: https://github.com/level/level
# -----------------------------------------------------------------------------
# PL_DATA_BACKEND=leveldb
# PL_DATA_LEVELDB_DIR=./data
# -----------------------------------------------------------------------------
# MONGODB
#
# Use mongodb as storage backend: https://github.com/mongodb/node-mongodb-native
# -----------------------------------------------------------------------------
# PL_DATA_BACKEND=mongodb
# PL_DATA_MONGODB_HOST=localhost
# PL_DATA_MONGODB_PORT=27017
# PL_DATA_MONGODB_PROTOCOL=mongodb
# PL_DATA_MONGODB_USERNAME=""
# PL_DATA_MONGODB_PASSWORD=""
# PL_DATA_MONGODB_DATABASE=padloc
# PL_DATA_MONGODB_AUTH_DATABASE=""
# PL_DATA_MONGODB_TLS=false
# PL_DATA_MONGODB_TLS_CAFILE=""
# PL_DATA_MONGODB_ACKNOWLEDGE_WRITES=true
# PL_DATA_MONGODB_MAX_SIZE=""
# PL_DATA_MONGODB_MAX_DOCUMENTS=""
# -----------------------------------------------------------------------------
# POSTGRES
#
# Use postgresql as storage backend: https://www.npmjs.com/package/pg
# -----------------------------------------------------------------------------
# PL_DATA_BACKEND=postgres
# PL_DATA_POSTGRES_HOST=localhost
# PL_DATA_POSTGRES_PORT=5432
# PL_DATA_POSTGRES_DATABASE=padloc
# PL_DATA_POSTGRES_USER=padloc
# PL_DATA_POSTGRES_PASSWORD=""
# PL_DATA_POSTGRES_TLS=false
# PL_DATA_POSTGRES_TLS_CAFILE=""
# =============================================================================
# ATTACHMENT STORAGE
#
# Supported backends: memory (default), fs, s3
# =============================================================================
# -----------------------------------------------------------------------------
# MEMORY
#
# Attachments are stored in memory only
# -----------------------------------------------------------------------------
# PL_ATTACHMENTS_BACKEND=memory
# -----------------------------------------------------------------------------
# FS
#
# Uses the local file system to store attachments
# -----------------------------------------------------------------------------
# PL_ATTACHMENTS_BACKEND=fs
# PL_ATTACHMENTS_FS_DIR=./attachments
# -----------------------------------------------------------------------------
# S3
#
# Uses a S3-compatible object storage to store attachments
# -----------------------------------------------------------------------------
# PL_ATTACHMENTS_BACKEND=s3
# PL_ATTACHMENTS_S3_ENDPOINT=[required]
# PL_ATTACHMENTS_S3_REGION=[required]
# PL_ATTACHMENTS_S3_ACCESS_KEY_ID=[required]
# PL_ATTACHMENTS_S3_SECRET_ACCESS_KEY=[required]
# PL_ATTACHMENTS_S3_BUCKET=[required]
# =============================================================================
# LOGGING
#
# Supported backends: void (default), mongodb, mixpanel
# =============================================================================
# -----------------------------------------------------------------------------
# VOID
#
# Don't log at all
# -----------------------------------------------------------------------------
# PL_LOGGING_BACKEND=void
# -----------------------------------------------------------------------------
# MONGODB
#
# Use mongodb for log storage
# -----------------------------------------------------------------------------
# PL_LOGGING_BACKEND=mongodb
# PL_LOGGING_MONGODB_HOST=localhost
# PL_LOGGING_MONGODB_PORT=27017
# PL_LOGGING_MONGODB_PROTOCOL=mongodb
# PL_LOGGING_MONGODB_USERNAME=""
# PL_LOGGING_MONGODB_PASSWORD=""
# PL_LOGGING_MONGODB_DATABASE=padloc
# PL_LOGGING_MONGODB_AUTH_DATABASE=""
# PL_LOGGING_MONGODB_TLS=false
# PL_LOGGING_MONGODB_TLS_CAFILE=""
# PL_LOGGING_MONGODB_ACKNOWLEDGE_WRITES=true
# PL_LOGGING_MONGODB_MAX_SIZE=""
# PL_LOGGING_MONGODB_MAX_DOCUMENTS=""
# -----------------------------------------------------------------------------
# MIXPANEL
#
# Send logs to mixpanel
# -----------------------------------------------------------------------------
# PL_LOGGING_BACKEND=mixpanel
# PL_LOGGING_MIXPANEL_TOKEN=[required]
# PL_LOGGING_MIXPANEL_EXCLUDE_EVENTS=""
# =============================================================================
# AUTHENTICATION
#
# Supported types: email, webauthn_platform, webauthn_portable, totp, public_key, openid
# =============================================================================
# PL_AUTH_TYPES=email,totp
# -----------------------------------------------------------------------------
# EMAIL AUTHENTICATION
#
# Send verfication code via email.
# -----------------------------------------------------------------------------
# By default, this uses the config from PL_EMAIL_...
# To use a different configuration, you can use the same environment variables,
# but prefixed with PL_AUTH_EMAIL_... instead of PL_EMAIL
# -----------------------------------------------------------------------------
# WEBAUTHN
#
# Configuration for webautn authentication types. Required for both
# webauthn_portable and webauthn_platform
# -----------------------------------------------------------------------------
# PL_AUTH_WEBAUTHN_RP_NAME=[required]
# PL_AUTH_WEBAUTHN_RP_ID=[required]
# PL_AUTH_WEBAUTHN_ORIGIN=[required]
# -----------------------------------------------------------------------------
# TOTP
#
# Configration for authentication via time-based one-time passwords
# https://datatracker.ietf.org/doc/html/rfc6238
# -----------------------------------------------------------------------------
# PL_AUTH_TOTP_INTERVAL=30
# PL_AUTH_TOTP_DIGITS=6
# PL_AUTH_TOTP_HASH=SHA-1
# PL_AUTH_TOTP_WINDOW=1
# -----------------------------------------------------------------------------
# OPENID
#
# Configration for authentication via Oauth/OpenID
# -----------------------------------------------------------------------------
# PL_AUTH_OPENID_CLIENT_ID=[required]
# PL_AUTH_OPENID_CLIENT_SECRET=[required]
# PL_AUTH_OPENID_AUTHORIZATION_ENDPOING=[required]
# PL_AUTH_OPENID_TOKEN_ENDPOINT=[required]
# PL_AUTH_OPENID_TOKEN_REDIRECT_URI=[required]
# =============================================================================
# PROVISIONING
#
# Supported backends: simple (default), stripe
# =============================================================================
# -----------------------------------------------------------------------------
# SIMPLE PROVISIONING
#
# Manage provisioning through a simple api
# -----------------------------------------------------------------------------
# PL_PROVISIONING_BACKEND=simple
# PL_PROVISIONING_SIMPLE_PORT=4000
# PL_PROVISIONING_SIMPLE_API_KEY=""
# PL_PROVISIONING_SIMPLE_DEFAULT_STATUS=active
# PL_PROVISIONING_SIMPLE_DEFAULT_STATUS_LABEL=""
# PL_PROVISIONING_SIMPLE_DEFAULT_STATUS_MESSAGE=""
# PL_PROVISIONING_SIMPLE_DEFAULT_ACTION_URL=""
# PL_PROVISIONING_SIMPLE_DEFAULT_ACTION_LABEL=""
# PL_PROVISIONING_SIMPLE_DEFAULT_DISABLE_FEATURES=""
# PL_PROVISIONING_SIMPLE_DEFAULT_QUOTA_ORGS=3
# PL_PROVISIONING_SIMPLE_DEFAULT_QUOTA_VAULTS=3
# -----------------------------------------------------------------------------
# SIMPLE PROVISIONING
#
# Manage provisioning via stripe
# -----------------------------------------------------------------------------
# PL_PROVISIONING_BACKEND=stripe
# PL_PROVISIONING_STRIPE_SECRET_KEY=[required]
# PL_PROVISIONING_STRIPE_PUBLIC_KEY=[required]
# PL_PROVISIONING_STRIPE_WEBHOOK_PORT=[required]
# =============================================================================
# SERVER
#
# Basic server config
# =============================================================================
# PL_SERVER_CLIENT_URL=http://localhost:8080
# PL_SERVER_REPORT_ERRORS=webmaster@example.com
# PL_MAX_REQUEST_AGE=3600000
# PL_VERIFY_EMAIL_ON_SIGNUP=true
# PL_DEFAULT_AUTH_TYPES=email
# =============================================================================
# PWA
#
# Config for progressive web app
# =============================================================================
# PL_PWA_PORT=8080
# PL_PWA_DIR=./dist

View File

@ -0,0 +1,8 @@
# Docker Examples
This directory contains various examples on hosting the Padloc server and web
app via Docker.
- [Basic Example](basic)
- [Example of using **NGINX** as a reverse proxy](nginx)
- [Advanced Example using **Postgres**, **NGINX** and **Letsencrypt**](postgres-nginx-letsencrypt)

View File

@ -0,0 +1,17 @@
# Basic Docker Example
This is a basic example of running an instance of the Padloc server component
and web app via Docker + Docker Compose.
## Setup Instructions
0. Install [Docker](https://docs.docker.com/get-docker/) and
[Docker Compose](https://docs.docker.com/compose/install/):
1. Clone or download this folder and `cd` into it.
2. Start the server and pwa:
```sh
docker-compose up
```
That's it! The web app is now available at http://localhost:8080.

View File

@ -0,0 +1,34 @@
version: "3.7"
services:
server:
image: padloc/server
build:
context: github.com/padloc/padloc.git#v4
dockerfile: Dockerfile-server
depends_on:
- db
environment:
PL_DATA_BACKEND: leveldb
PL_DATA_LEVELDB_DIR: /data
PL_DATA_ATTACHMENTS_BACKEND: fs
PL_DATA_ATTACHMENTS_DIR: /attachments
PL_SERVER_CLIENT_URL: http://localhost:8080
ports:
- 3000:3000
volumes:
- attachments:/attachments
- data:/data
restart: unless-stopped
pwa:
image: padloc/pwa
build:
context: github.com/padloc/padloc.git#v4
dockerfile: Dockerfile-pwa
environment:
PL_SERVER_URL: http://localhost:3000
ports:
- 8080:8080
restart: on-failure
volumes:
data:
attachments:

View File

@ -0,0 +1,18 @@
# Docker + NGINX
This is a basic example of running an instance of the Padloc server component
and web app with Docker Compose, using [NGINX](https://www.nginx.com/) as a
reverse proxy.
## Setup Instructions
0. Install [Docker](https://docs.docker.com/get-docker/) and
[Docker Compose](https://docs.docker.com/compose/install/)
1. Clone or download this folder and `cd` into it.
2. Start the server and pwa:
```sh
docker-compose up
```
That's it! The web app is now available at http://localhost.

View File

@ -0,0 +1,46 @@
version: "3.7"
services:
server:
image: padloc/server
build:
context: github.com/padloc/padloc.git#v4
dockerfile: Dockerfile-server
depends_on:
- db
environment:
PL_DATA_BACKEND: leveldb
PL_DATA_LEVELDB_DIR: /data
PL_DATA_ATTACHMENTS_BACKEND: fs
PL_DATA_ATTACHMENTS_DIR: /attachments
PL_SERVER_CLIENT_URL: http://localhost
expose:
- 3000
volumes:
- attachments:/attachments
- data:/data
restart: unless-stopped
pwa:
image: padloc/pwa
environment:
PL_SERVER_URL: http://localhost/server
build:
context: github.com/padloc/padloc.git#v4
dockerfile: Dockerfile-pwa
volumes:
- pwa:/pwa
command: ["build"]
restart: on-failure
nginx:
image: nginx
depends_on:
- server
restart: always
volumes:
- pwa:/pwa
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- 80:80
volumes:
data:
attachments:
pwa:

View File

@ -0,0 +1,50 @@
user nginx;
worker_processes auto;
http {
# BASIC SETTINGS
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Required for attachments
client_max_body_size 10m;
# Enable gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
include mime.types;
# Disallow embedding in iFrames
add_header X-Frame-Options deny;
server {
# We don't need a host name here since we're only
# dealing with one domain, but you may insert your domain here.
server_name _;
# Both server and pwa are served over https
listen 80;
# This will resolve to the server instance
location /server {
resolver 127.0.0.11 valid=60s;
set $server "http://server:3000";
proxy_pass $server;
}
# This will resolve to the web app
location / {
root /pwa;
index index.html;
try_files $uri /index.html;
}
}
}
events {
}

View File

@ -0,0 +1,29 @@
# =================================
# Email Settings
# =================================
PL_EMAIL_BACKEND=smtp
PL_EMAIL_SMTP_HOST=smtp.example.com
PL_EMAIL_SMTP_PORT=587
PL_EMAIL_SMTP_USER=smtp_username
PL_EMAIL_SMTP_PASSWORD=*** # <- you may want to pass this directly rather than storing it here
PL_EMAIL_SMTP_FROM=mail@example.com
# =================================
# Database Settings
# =================================
PL_DATA_POSTGRES_DATABASE=padloc
PL_DATA_POSTGRES_USER=padloc
PL_DATA_POSTGRES_PASSWORD=*** # <- you may want to pass this directly rather than storing it here
# =================================
# Other Settings
# =================================
# This is the public domain where you want to reach the web app under
# (The server will be available under https://$PL_HOSTNAME/server
PL_HOSTNAME=test.padloc.app
# This is used for obtaining an TLS certificate via Letsencrypt
# and for notifying you if there is an unexpected error in the backend.
PL_ADMIN_EMAIL=martin@padloc.app

View File

@ -0,0 +1,43 @@
# Docker + Postgres + NGINX + Letsencrypt
This is a more advanced example of running an instance of the Padloc server
component and web app with [Docker](https://www.docker.com/) and
[Docker Compose](https://docs.docker.com/compose/), using:
- [PostgreSQL](https://www.postgresql.org/) as the datababase backend
- [NGINX](https://www.nginx.com/) as a reverse proxy.
- [Letsencrypt](https://letsencrypt.org/) for obtaining a TLS certificate.
## Setup Instructions
0. Install [Docker](https://docs.docker.com/get-docker/) and
[Docker Compose](https://docs.docker.com/compose/install/)
1. Clone or download this folder and `cd` into it.
2. Edit the `.env` file to set your STMP settings, Postgres database name,
username and password, and the host name / domain you want to host the web
app and server under.
3. Obtain an TLS certificate
```sh
docker-compose up cerbot
```
4. Start the server, pwa, database and reverse proxy:
```sh
docker-compose up -d
```
That's it! The web app is now available at `https://$PL_HOSTNAME`
## Renewing the TLS certificate
TLS certificates issued by Letsencrypt are usually valid for 90 days, so you'll
have to regularly renew your certificate. To do so, simply run the following:
```sh
docker-compose down && \
docker-compose up certbot && \
docker-compose up -d
```

View File

@ -0,0 +1,84 @@
version: "3.7"
services:
db:
image: postgres:13
expose:
- 5432
env_file: .env
environment:
- POSTGRES_USER=$PL_DATA_POSTGRES_USER
- POSTGRES_DB=$PL_DATA_POSTGRES_DATABASE
- POSTGRES_PASSWORD=$PL_DATA_POSTGRES_PASSWORD
volumes:
- data:/var/lib/postgresql/data
restart: unless-stopped
server:
image: padloc/server
build:
context: github.com/padloc/padloc.git#v4
dockerfile: Dockerfile-server
depends_on:
- db
env_file: .env
environment:
- PL_DATA_BACKEND=postgres
- PL_DATA_POSTGRES_HOST=db
- PL_DATA_POSTGRES_PORT=5432
- PL_DATA_POSTGRES_DATABASE
- PL_DATA_POSTGRES_USER
- PL_DATA_POSTGRES_PASSWORD
- PL_SERVER_CLIENT_URL=https://$PL_HOSTNAME
- PL_SERVER_REPORT_ERRORS=$PL_ADMIN_EMAIL
- PL_EMAIL_BACKEND
- PL_EMAIL_SMTP_HOST
- PL_EMAIL_SMTP_PORT
- PL_EMAIL_SMTP_USER
- PL_EMAIL_SMTP_PASSWORD
- PL_EMAIL_SMTP_FROM
expose:
- 3000
volumes:
- attachments:/attachments
restart: unless-stopped
pwa:
image: padloc/pwa
env_file: .env
environment:
PL_PWA_DIR: /pwa
PL_SERVER_URL: https://$PL_HOSTNAME/server
build:
context: github.com/padloc/padloc.git#v4
dockerfile: Dockerfile-pwa
volumes:
- pwa:/pwa
command: ["build"]
restart: on-failure
nginx:
env_file: .env
image: nginx
depends_on:
- server
restart: always
volumes:
- pwa:/pwa
- ./nginx.conf:/etc/nginx/nginx.conf
- /etc/letsencrypt/live/$PL_HOSTNAME/fullchain.pem:/tls/cert
- /etc/letsencrypt/live/$PL_HOSTNAME/privkey.pem:/tls/key
ports:
- 80:80
- 443:443
certbot:
env_file: .env
image: certbot/certbot
volumes:
- /etc/letsencrypt:/etc/letsencrypt
- /var/lib/letsencrypt:/var/lib/letsencrypt
command: "certonly --standalone -d $PL_HOSTNAME --expand --non-interactive --agree-tos -m $PL_ADMIN_EMAIL"
ports:
- 80:80
- 443:443
profiles: ["certbot"]
volumes:
data:
attachments:
pwa:

View File

@ -0,0 +1,6 @@
sudo docker run --rm --name certbot -p 80:80 \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
certbot/certbot certonly --standalone \
-d test.padloc.app \
--expand --non-interactive --agree-tos -m martin@pentacode.app

View File

@ -0,0 +1,64 @@
user nginx;
worker_processes auto;
http {
# BASIC SETTINGS
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Required for attachments
client_max_body_size 10m;
# Enable gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
include mime.types;
# Disallow embedding in iFrames
add_header X-Frame-Options deny;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# Redirect all http traffic to https
return 301 https://$host$request_uri;
}
server {
# We don't need a host name here since we're only
# dealing with one domain, but you may insert your domain here.
server_name _;
# Both server and pwa are served over https
listen 443 ssl http2;
# This will resolve to the server instance
location /server {
resolver 127.0.0.11 valid=60s;
set $server "http://server:3000";
proxy_pass $server;
}
# This will resolve to the web app
location / {
root /pwa;
index index.html;
try_files $uri /index.html;
}
# SSL certificate
ssl_certificate /tls/cert;
# SSL private key
ssl_certificate_key /tls/key;
}
}
events {
}

View File

@ -4,6 +4,22 @@ This package contains the Padloc backend server component.
## How to use
### Through Docker
The recommended setup for hosting the Padloc server is through Docker (For v4,
you'll have to build the Docker image from source for now. Official image coming
soon!):
```sh
docker build -t padloc/server github.com/padloc/padloc#v4 -f Dockerfile-server
docker run padloc/server
```
For some examples of a Docker-based setup, check out our
[Docker Examples](../../docs/examples/hosting/docker).
### Directly through Node.js
Currently the `@padloc/server` package is meant to be run from within the
[Padloc monorepo](../../README.md). A standalone npm package is coming soon!