deployment: add example deployment config and readme
This commit is contained in:
parent
59651d3cb9
commit
4eb504d719
100
deployment/README.md
Normal file
100
deployment/README.md
Normal file
|
@ -0,0 +1,100 @@
|
|||
# Deploying an OpenBikeSensor Portal with Docker
|
||||
|
||||
## Introduction
|
||||
|
||||
The main idea of this document is to provide an easy docker-based
|
||||
production-ready setup of the openbikesensor portal. It uses the [the traefik
|
||||
proxy](https://doc.traefik.io/traefik/) as a reverse proxy, which listens
|
||||
on port 80 and 443. Based on some labels, traefik routes the domains to the
|
||||
corresponding docker containers.
|
||||
|
||||
## Before Getting Started
|
||||
|
||||
The guide and example configuration assumes one domain, which points to the
|
||||
server's IP address. This documentation uses `portal.example.com` as an
|
||||
example. The API is hosted at `https://portal.example.com/api`, while the main
|
||||
frontend is reachable at the domain root.
|
||||
|
||||
## Steps
|
||||
|
||||
### Clone the repo
|
||||
|
||||
Create a folder somewhere in your system, we'll name it `$ROOT` from now on.
|
||||
|
||||
Clone the repository to `$ROOT/source`. Ensure you also cloned the submodules,
|
||||
as described in the main [README](../README.md).
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/openbikesensor
|
||||
cd /opt/openbikesensor
|
||||
git clone https://github.com/openbikesensor/portal source/
|
||||
```
|
||||
|
||||
### Configure `traefik.toml`
|
||||
|
||||
```bash
|
||||
mkdir -p config/
|
||||
cp source/deployment/examples/traefik.toml config/traefik.toml
|
||||
vim config/traefik.toml
|
||||
```
|
||||
|
||||
Configure your email in the `config/traefik.toml`. This email is uses by
|
||||
Let's Encrypt to send you some mails regarding your certificates.
|
||||
|
||||
### Configure `docker-compose.yaml`
|
||||
|
||||
```bash
|
||||
cp source/deployment/examples/docker-compose.yaml docker-compose.yaml
|
||||
vim docker-compose.yaml
|
||||
```
|
||||
|
||||
Change the domain where it occurs, such as in `Host()` rules.
|
||||
|
||||
### Configure frontend
|
||||
|
||||
```bash
|
||||
cp source/frontend/config.json.example config/frontend.json
|
||||
vim frontend/src/config.json
|
||||
```
|
||||
|
||||
* Change all URLs to your domain
|
||||
* Create a UUID by using `uuidgen` and set the `clientId`
|
||||
|
||||
### Configure API
|
||||
|
||||
```bash
|
||||
cp source/api/config.json.example config/api.json
|
||||
vim config/api.json
|
||||
```
|
||||
|
||||
* Change all URLs to your domain
|
||||
* Generate and set a random `cookieSecret` (for example with `uuidgen`)
|
||||
* Generate and set a random `jwtSecret` (for example with `uuidgen`)
|
||||
* Configure you SMTP mail server
|
||||
* Set the `clientId` for the `oAuth2Client` of the portal (from step 3)
|
||||
|
||||
### Build container and run them
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
The services are being built the first time this is run. It can take some
|
||||
minutes.
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
### Logs
|
||||
|
||||
To read logs, run
|
||||
|
||||
```bash
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
If something went wrong, you can reconfigure your config files and rerun:
|
||||
|
||||
```bash
|
||||
docker-compose build
|
||||
docker-compose up -d
|
||||
```
|
125
deployment/examples/docker-compose.yaml
Normal file
125
deployment/examples/docker-compose.yaml
Normal file
|
@ -0,0 +1,125 @@
|
|||
version: '3'
|
||||
|
||||
networks:
|
||||
gateway:
|
||||
external: true
|
||||
name: gateway
|
||||
backend:
|
||||
internal: true
|
||||
|
||||
services:
|
||||
mongo:
|
||||
image: mongo
|
||||
tty: true
|
||||
volumes:
|
||||
- ./data/mongo:/data/db
|
||||
restart: on-failure
|
||||
networks:
|
||||
- backend
|
||||
|
||||
redis:
|
||||
image: redis
|
||||
volumes:
|
||||
- ./data/redis:/data
|
||||
command: redis-server --appendonly yes
|
||||
restart: on-failure
|
||||
networks:
|
||||
- backend
|
||||
|
||||
api:
|
||||
image: obs-api
|
||||
build:
|
||||
context: ./source/api
|
||||
volumes:
|
||||
- ./data/api-data:/data
|
||||
- ./config/api-config.json:/opt/obs/api/config.json
|
||||
environment:
|
||||
- MONGODB_URL=mongo://mongo/obs
|
||||
restart: on-failure
|
||||
labels:
|
||||
- traefik.http.middlewares.obsapi-prefix.stripprefix.prefixes=/api
|
||||
- traefik.http.middlewares.obsapi-wellknown.replacepathregex.regex=^/\.well-known/oauth-authorization-server/api$$
|
||||
- traefik.http.middlewares.obsapi-wellknown.replacepathregex.replacement=/.well-known/oauth-authorization-server
|
||||
- traefik.http.routers.obsapi.rule=Host(`portal.example.com`) && (PathPrefix(`/api/`) || Path(`/.well-known/oauth-authorization-server/api`))
|
||||
- traefik.http.routers.obsapi.entrypoints=websecure
|
||||
- traefik.http.routers.obsapi.tls=true
|
||||
- traefik.http.routers.obsapi.tls.certresolver=leresolver
|
||||
- traefik.http.routers.obsapi.middlewares=obsapi-prefix@docker,obsapi-wellknown@docker
|
||||
- traefik.docker.network=gateway
|
||||
networks:
|
||||
- gateway
|
||||
- backend
|
||||
|
||||
worker:
|
||||
image: obs-api
|
||||
build:
|
||||
context: ./source/api
|
||||
volumes:
|
||||
- ./data/api-data:/data
|
||||
- ./config/api-config.json:/opt/obs/api/config.json
|
||||
links:
|
||||
- mongo
|
||||
- redis
|
||||
restart: on-failure
|
||||
command:
|
||||
- npm
|
||||
- run
|
||||
- start:worker
|
||||
networks:
|
||||
- backend
|
||||
# Not requred for traefik, but to reach overpass-api.de
|
||||
- gateway
|
||||
|
||||
frontend:
|
||||
image: obs-frontend
|
||||
build:
|
||||
context: ./source/frontend
|
||||
dockerfile: Dockerfile-prod
|
||||
links:
|
||||
- api
|
||||
restart: on-failure
|
||||
labels:
|
||||
- traefik.http.routers.obsfrontend.rule=Host(`portal.example.com`)
|
||||
- traefik.http.routers.obsfrontend.entrypoints=websecure
|
||||
- traefik.http.routers.obsfrontend.tls=true
|
||||
- traefik.http.routers.obsfrontend.tls.certresolver=leresolver
|
||||
- traefik.docker.network=gateway
|
||||
networks:
|
||||
- gateway
|
||||
- backend
|
||||
|
||||
traefik:
|
||||
image: traefik:2.4.8
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
# The Web UI (enabled by [api] in traefik.toml)
|
||||
# - "8080:8080"
|
||||
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./config/traefik.toml:/traefik.toml
|
||||
- ./config/usersfile:/usersfile
|
||||
- ./data/acme.json:/acme.json
|
||||
|
||||
networks:
|
||||
- gateway
|
||||
|
||||
labels:
|
||||
# global redirect from http to https
|
||||
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
|
||||
- "traefik.http.routers.http-catchall.entrypoints=web"
|
||||
# Define middlewares to be used
|
||||
- "traefik.http.routers.http-catchall.middlewares=redirect-http-to-https"
|
||||
# Configure middlewares
|
||||
- "traefik.http.middlewares.redirect-http-to-https.redirectscheme.scheme=https"
|
||||
|
||||
# Show Traefik Dashboard. Enable the dashboard in traefik.toml if you use these.
|
||||
# - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
|
||||
# - "traefik.http.routers.traefik.service=api@internal"
|
||||
# - "traefik.http.routers.traefik.tls=true"
|
||||
# - "traefik.http.routers.traefik.entrypoints=websecure"
|
||||
# - "traefik.http.routers.traefik.tls.certresolver=leresolver"
|
||||
# - "traefik.http.routers.traefik.middlewares=basic-auth"
|
||||
# - "traefik.http.middlewares.basic-auth.basicauth.usersfile=/usersfile"
|
29
deployment/examples/traefik.toml
Normal file
29
deployment/examples/traefik.toml
Normal file
|
@ -0,0 +1,29 @@
|
|||
# https://doc.traefik.io/traefik/v2.4/routing/entrypoints/
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.web.http]
|
||||
[entryPoints.web.http.redirections]
|
||||
[entryPoints.web.http.redirections.entryPoint]
|
||||
to = "websecure"
|
||||
scheme = "https"
|
||||
|
||||
[entryPoints.websecure]
|
||||
address = ":443"
|
||||
|
||||
# Enable API
|
||||
[api]
|
||||
dashboard = false
|
||||
|
||||
# Enable docker backend
|
||||
[providers.docker]
|
||||
network = "gateway"
|
||||
|
||||
# https://doc.traefik.io/traefik/v2.4/https/acme/#configuration-examples
|
||||
[certificatesResolvers.leresolver.acme]
|
||||
email = "info@example.com"
|
||||
storage = "acme.json"
|
||||
[certificatesResolvers.leresolver.acme.httpChallenge]
|
||||
# used during the challenge
|
||||
entryPoint = "web"
|
Loading…
Reference in a new issue