diff --git a/example/docker-compose-prod-certificate/README.md b/example/docker-compose-prod-certificate/README.md new file mode 100644 index 00000000..9db99800 --- /dev/null +++ b/example/docker-compose-prod-certificate/README.md @@ -0,0 +1,51 @@ +# Deploy in production! + +## :dvd: Software requirements + +- [Docker](https://www.docker.com/) : packages `docker` and `docker-compose` + +## :desktop_computer: Network Requirements + +You will need a DNS domain name pointing to your server with a [wildcard DNS record](https://en.wikipedia.org/wiki/Wildcard_DNS_record) +> **Note** +> For free DNS names you can use [Dynu DNS](https://www.dynu.com/) + +You will need the used port to be opened on your router and forwarded to your server : +- Port 80 for HTTP +- Port 443 for HTTPS +- Port 9000 for PeerJs + +## :globe_with_meridians: Setup reverse proxy + +You need to set up a reverse proxy in a docker container to : + - Redirect `${YOUR_DOMAIN_NAME}` to `app.${YOUR_DOMAIN_NAME}` + - Redirect HTTP to HTTPS + - Forward `app.${YOUR_DOMIN_NAME}` to the docker container adding certificates + - Forward `peer.${YOUR_DOMIN_NAME}` to the docker container adding certificates + +you can use (NGINX)[https://www.nginx.com/] and the exemple inside `exemple/docker-compose-prod-certificate/reverse-proxy`, replacing all occurrences of `${YOUR_DOMAIN_NAME}` + +## :page_with_curl: Set-up certificates + +You will need a SSL certifcate for each subdomain : +- `${YOUR_DOMAIN_NAME}` +- `app.${YOUR_DOMAIN_NAME}` +- `peer.${YOUR_DOMAIN_NAME}` +> **Note** +> You can manage your cerificates with [Certbot](https://certbot.eff.org/), which uses [Let's Encrypt](https://letsencrypt.org/fr/getting-started/) + +Once you have created you certificates and have a path for them you need to : +- Mount a volume containing the certificates to the reverse-proxy : update `docker-compose.yml` (change only if your path differs from the exemple) +- Point to the certificates in the reverse-proxy configuration: update : `nginx.comf` (change only if your path differs from the exemple) + + +## :runner: Run lemverse in production + +export your settings.json in the environment variable METEOR_SETTINGS + +`export METEOR_SETTINGS="$(cat path/to/settings.json)"` + +then execute docker-compose from this folder : + +`docker-compose up -d` + diff --git a/example/docker-compose-prod-certificate/docker-compose.yml b/example/docker-compose-prod-certificate/docker-compose.yml new file mode 100644 index 00000000..6605d31c --- /dev/null +++ b/example/docker-compose-prod-certificate/docker-compose.yml @@ -0,0 +1,62 @@ +version: "3.8" +services: + reverseproxy: + build: + context: . + dockerfile: reverse-proxy/nginx.Dockerfile + ports: + - "443:443" + - "80:80" + volumes: + # update here with the the paths to your certificate folders if necessary + - /etc/letsencrypt:/etc/letsencrypt:ro + networks: + - net_lemverse + depends_on: + - mongodb + - lemverse + restart: always + mongodb: + image: mongo:5.0.3 + environment: + - PUID=1000 + - PGID=1000 + volumes: + - db:/data/db # Volume to keep database data between restarts + restart: unless-stopped + networks: + - net_lemverse + lemverse: + image: lempire/lemverse:latest + container_name: lemverse + restart: unless-stopped + networks: + - net_lemverse + depends_on: + - mongodb + ports: + - "3000:3000" + volumes: + - lemverse:/var/tmp/lemverse # Volume for upload tileset and keep them between restart + environment: + ROOT_URL: ${APP_ROOT_URL:-http://localhost} + MONGO_URL: mongodb://mongodb:27017/meteor + PORT: 3000 + METEOR_SETTINGS: ${METEOR_SETTINGS} + peer: + image: peerjs/peerjs-server:0.6.1 + container_name: peer + restart: unless-stopped + networks: + - net_lemverse + command: [ "--port", "9000", "--path", "/peer" ] +volumes: + lemverse: + driver: local + db: + driver: local +# Custom network so all services can communicate using a FQDN +networks: + net_lemverse: + driver: bridge + name: net_lemverse diff --git a/example/docker-compose-prod-certificate/reverse-proxy/config/nginx.conf b/example/docker-compose-prod-certificate/reverse-proxy/config/nginx.conf new file mode 100644 index 00000000..e25eeed8 --- /dev/null +++ b/example/docker-compose-prod-certificate/reverse-proxy/config/nginx.conf @@ -0,0 +1,81 @@ +upstream lemverse { + server lemverse:3000; +} + +upstream peer { + server peer:9000; +} + +# Redirect ${YOUR_DOMAIN_NAME} to app.${YOUR_DOMAIN_NAME} +server { + listen 80; + listen [::]:80; + listen 443 ssl; + listen [::]:443 ssl http2; + server_name ${YOUR_DOMAIN_NAME}; + ssl_certificate /etc/letsencrypt/live/${YOUR_DOMAIN_NAME}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/${YOUR_DOMAIN_NAME}/privkey.pem; + + location / { + return 301 https://app.${YOUR_DOMAIN_NAME}$request_uri; + } +} + +# Redirect any HTTP to HTTPS +server { + listen 80; + listen [::]:80; + server_name *.${YOUR_DOMAIN_NAME}; + + location / { + return 301 https://$host$request_uri; + } + + location ~ /.well-known/acme-challenge { + allow all; + root /tmp/acme_challenge; + } +} + +# Certificates and redirect to container on https://app.${YOUR_DOMAIN_NAME} +server { + listen 443 ssl; + listen [::]:443 ssl http2; + server_name app.${YOUR_DOMAIN_NAME}; + ssl_certificate /etc/letsencrypt/live/app.${YOUR_DOMAIN_NAME}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/app.${YOUR_DOMAIN_NAME}/privkey.pem; + + location / { + proxy_pass http://lemverse; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_redirect off; + } + location /static/ { + alias /static/; + } +} + +# Certificates and redirect to container on https://peer.${YOUR_DOMAIN_NAME} +server { + listen 443 ssl; + listen [::]:443 ssl http2; + server_name peer.${YOUR_DOMAIN_NAME}; + ssl_certificate /etc/letsencrypt/live/peer.${YOUR_DOMAIN_NAME}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/peer.${YOUR_DOMAIN_NAME}/privkey.pem; + + location / { + proxy_pass http://peer; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_redirect off; + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + location /static/ { + alias /static/; + } + +} diff --git a/example/docker-compose-prod-certificate/reverse-proxy/nginx.Dockerfile b/example/docker-compose-prod-certificate/reverse-proxy/nginx.Dockerfile new file mode 100644 index 00000000..4b456c1c --- /dev/null +++ b/example/docker-compose-prod-certificate/reverse-proxy/nginx.Dockerfile @@ -0,0 +1,3 @@ +FROM nginx:latest +RUN rm /etc/nginx/conf.d/default.conf +COPY reverse-proxy/config/nginx.conf /etc/nginx/conf.d/default.conf