From 56c6c782b3f1eda11183bc32dbf5113c8a65bec2 Mon Sep 17 00:00:00 2001 From: Andre Lackmann Date: Fri, 17 Jan 2020 04:53:46 +1100 Subject: [PATCH] Fixes docker-compose, adds HTTPS and refactors image builds (fixes #234) (#276) * Feature/automate docker build (#4) * Moved Dockerfile into root * Dockerfile tidying Signed-off-by: Andre Lackmann * Feature/docker compose update (#5) * Moved Dockerfile into root * Dockerfile tidying * moving and updating docker-compose * updated docker configuration and docs Signed-off-by: Andre Lackmann * Updated docker-compose to use official image tag Signed-off-by: Andre Lackmann * updated logging to work in docker using console Signed-off-by: Andre Lackmann --- .../docker/node/Dockerfile => Dockerfile | 19 ++++-- README.md | 56 ++++++---------- config-docker.json | 56 ++++++++++++++++ deployment/docker/docker-compose.yml | 56 ---------------- deployment/docker/nginx/Dockerfile | 8 --- .../docker/nginx/openhabcloud_nginx.conf | 64 ------------------- deployment/docker/traefik.toml | 31 +++++++++ docker-compose.yml | 64 +++++++++++++++++++ logger.js | 10 ++- system/index.js | 11 ++++ 10 files changed, 205 insertions(+), 170 deletions(-) rename deployment/docker/node/Dockerfile => Dockerfile (74%) create mode 100644 config-docker.json delete mode 100644 deployment/docker/docker-compose.yml delete mode 100644 deployment/docker/nginx/Dockerfile delete mode 100644 deployment/docker/nginx/openhabcloud_nginx.conf create mode 100644 deployment/docker/traefik.toml create mode 100644 docker-compose.yml diff --git a/deployment/docker/node/Dockerfile b/Dockerfile similarity index 74% rename from deployment/docker/node/Dockerfile rename to Dockerfile index 3d7d598..52154f7 100644 --- a/deployment/docker/node/Dockerfile +++ b/Dockerfile @@ -28,18 +28,27 @@ RUN rm -rf \ /usr/lib/node_modules/npm/html \ /usr/lib/node_modules/npm/scripts -RUN mkdir -p /opt/openhabcloud -COPY ./package.json ./config.json /opt/openhabcloud/ +RUN mkdir -p /opt/openhabcloud/logs RUN mkdir /data + +COPY ./package.json /opt/openhabcloud/ RUN ln -s /opt/openhabcloud/package.json /data + WORKDIR /data RUN npm install && npm rebuild bcrypt --build-from-source ENV NODE_PATH /data/node_modules -WORKDIR /opt/openhabcloud - -USER openhabcloud ADD . /opt/openhabcloud +RUN rm -Rf /opt/openhabcloud/deployment +RUN rm -Rf /opt/openhabcloud/docs +RUN rm -Rf /opt/openhabcloud/tests +RUN rm /opt/openhabcloud/config-development.json +RUN rm /opt/openhabcloud/config-production.json + +RUN chown openhabcloud: /opt/openhabcloud/logs + +WORKDIR /opt/openhabcloud +USER openhabcloud EXPOSE 3000 CMD ["node", "app.js"] \ No newline at end of file diff --git a/README.md b/README.md index ff87488..df7e048 100644 --- a/README.md +++ b/README.md @@ -233,47 +233,34 @@ to spin up the dockerized openhab-cloud backend. #### Architecture The dockerized openhab-cloud uses a separate docker image and container for each part of the overall system according to the following stack: -* app-1: node.js and express.js (openhab/openhab-cloud/app-1:latest) -* mongodb: MongoDB database (bitnami/mongodb:latest) -* nginx: nginx proxy (openhab/openhab-cloud/nginx:latest) +* app: node.js and express.js (openhab/openhab-cloud/app:latest) +* mongodb: MongoDB database (mongo:4.1.10-bionic) * redis: redis session manager (bitnami/redis:latest) +* traefik: http proxy with LetsEncrypt SSL Certs (traefik:1.7) #### Prerequisites To run openhab-cloud make sure docker, docker-machine and docker-compose are installed on your machine. -More information at [Docker's website](https://docs.docker.com/) +More information at [Docker's website](https://docs.docker.com/). -#### Configuration -You need to modify the ```config.json``` and adjust the hosts of mongodb and redis to match to the corresponding -container services of docker-compose: -``` - "mongodb": { - "hosts": ["mongodb"], - "db": "openhab", - "user": "", - "password": "" - }, - "redis": { - "host": "redis", - "port": "6379", - "password": "password" - }, -``` - -To change the server IP/DNS matching your installation, please refer to [Setting up Nginx](#setupNginx) +The `docker-compose.yml` file assume you have ports 80, 443 and 8080 available on the host you intend to run on. If you don't, you'll need to adjust these. #### Customization -If you want to customize the openhab-cloud app or change e.g. configurations within ```config.json```, -you need to switch to the local build of the node app. Adjust the build stratgy in the ```docker-compose.yml``` -and replace the ```image``` section of ```docker-compose.yml``` with the following lines, to not use the official docker hub images anymore and switch to your local sources as base for the app-1 image: +1. Copy the files `docker-compose.yml`, `config-docker.json` and `deployment/docker/traefik.toml` onto the machine that will be hosting your OpenHAB Cloud, into the same directory. +1. In the `docker-compose.yml` file, update: + - In the `app` container, replace `` with the DNS name you will be using to host OpenHAB Cloud. This helps configure traefik http proxying + - In the `mongodb` container, uncomment the volumes section and supply a local path for the mongo files. This allows your database to have persistence. If you miss this step, anytime you restart the containers, you'll need to setup things again. +1. In the `config-docker.json` file, update: + - the system / host entry to be the same DNS name you entered into the `docker-compose.yml` above (you don't need scheme, so just `myopenhab.domain.com` or similar) + - update the redis password to match what you've entered in `docker-compose.yml` + - update any other settings for OpenHAB Cloud as per the docs +1. In the `traefik.toml` file, update: + - the `domain` entry in the [Docker] section to match the domain you've used above twice already + - enter your email in the [acme] section so LetsEncrypt works properly. -```build: - context: ./ - dockerfile: ./docker/node/Dockerfile -``` #### Run -To create and run the composed application, use the following command: +Having created all the configs, you can fire it all up. To create and run the composed application, use the following command: ``` docker-compose up -d ``` @@ -286,7 +273,7 @@ docker-compose up -d --force-recreate To make sure openhab-cloud is running, check the openhab-cloud app logs: ``` -docker-compose logs app-1 +docker-compose logs app ``` #### Stop & Cleanup @@ -311,12 +298,11 @@ docker system prune #### Access -Navigate your browser to ```http://:``` and log in (e.g. http://localhost:80) +Navigate your browser to ```https://``` and log in (e.g. https://myopenhab.domain.com). -#### Limitations -* Lets Encrypt SSL is missing in the images and will be added soon -* The nginx configuration at /etc/nginx_openhabcloud.conf will be reused +If it's the first time you're starting up, make sure you have `registration_enabled` set to `true` in the `config-docker.yml` file so you can create an initial user login. +Assuming you don't plan to run an open system, switch this back to `false` once you've registered and restart. ## Installing openHAB Cloud on Amazon Web Services (AWS) ## diff --git a/config-docker.json b/config-docker.json new file mode 100644 index 0000000..a9d2ad7 --- /dev/null +++ b/config-docker.json @@ -0,0 +1,56 @@ +{ + "system": { + "host": "localhost", + "port": "443", + "protocol": "https", + "logger" : { + "type": "console" + }, + "subDomainCookies": false + }, + "express":{ + "key" : "" + }, + "apn" : { + "gateway": "gateway.push.apple.com", + "cert": "certs/aps/aps_production_cert.pem", + "key": "certs/aps/aps_production_key.pem", + "passphrase": "passphrase" + }, + "gcm" : { + "jid": "something@gcm.googleapis.com", + "password": "password" + }, + "ifttt" : { + "iftttChannelKey" : "key", + "iftttTestToken" : "token" + }, + "mail": { + "host" : "smtp", + "port" : 465, + "user" : "my@openhab.org", + "pass" : "123_openHAB" + }, + "mongodb": { + "hosts": ["mongodb"], + "db": "openhab" + }, + "redis": { + "host": "redis", + "port": "6379", + "password": "123_openHAB" + }, + "mailer": { + "host" : "smtp.openhab.org", + "port": 465, + "secureConnection": true, + "user": "my@openhab.org", + "password": "123_openHAB", + "from": "My openHAB " + }, + "legal": { + "terms" : "", + "policy": "" + }, + "registration_enabled": false +} \ No newline at end of file diff --git a/deployment/docker/docker-compose.yml b/deployment/docker/docker-compose.yml deleted file mode 100644 index 173869f..0000000 --- a/deployment/docker/docker-compose.yml +++ /dev/null @@ -1,56 +0,0 @@ -version: '3' -services: - app-1: - container_name: app-1 - image: docker.io/openhab/openhabcloud-app - working_dir: /opt/openhabcloud - networks: - - ohcloud-network - links: - - mongodb - - redis - ports: - - "3000" - depends_on: - - mongodb - - redis - restart: always - mongodb: - container_name: mongodb - image: bitnami/mongodb:latest - ports: - - "27017:27017" - command: mongod --smallfiles --bind_ip_all - networks: - - ohcloud-network - volumes: - - /data/db - - /data/configdb - restart: always - redis: - container_name: redis - image: bitnami/redis:latest - networks: - - ohcloud-network - ports: - - "6379" - environment: - - REDIS_PASSWORD=123_openHAB - restart: always - nginx: - container_name: nginx - image: docker.io/openhab/openhabcloud-nginx - volumes: - - app-1:/opt/openhabcloud - networks: - - ohcloud-network - ports: - - "80:8081" - - "443:8443" - links: - - app-1:app-1 -volumes: - app-1: -networks: - ohcloud-network: - driver: bridge \ No newline at end of file diff --git a/deployment/docker/nginx/Dockerfile b/deployment/docker/nginx/Dockerfile deleted file mode 100644 index 3597475..0000000 --- a/deployment/docker/nginx/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -# Set nginx base image -FROM bitnami/nginx - -# File Author / Maintainer -MAINTAINER Mehmet Arziman - -# Copy custom configuration file from the current directory -COPY ./docker/nginx/openhabcloud_nginx.conf /bitnami/nginx/conf/vhosts/my_vhost.conf \ No newline at end of file diff --git a/deployment/docker/nginx/openhabcloud_nginx.conf b/deployment/docker/nginx/openhabcloud_nginx.conf deleted file mode 100644 index 1a042f0..0000000 --- a/deployment/docker/nginx/openhabcloud_nginx.conf +++ /dev/null @@ -1,64 +0,0 @@ -upstream app_server { - server app-1:3000 fail_timeout=5s max_fails=5; - } - -server{ - listen 0.0.0.0:8081; - - charset utf-8; - #include /bitnami/nginx/conf/mime.types; - - access_log "/opt/bitnami/nginx/logs/openhabcloud-access.log"; - error_log "/opt/bitnami/nginx/logs/openhabcloud-error.log"; - client_max_body_size 300m; - - root /var/www/html; - - location ~ /.well-known { - allow all; - } - location /css { - alias /opt/openhabcloud/public/css; - } - location /js { - alias /opt/openhabcloud/public/js; - } - location /img { - alias /opt/openhabcloud/public/img; - } - location /bootstrap { - alias /opt/openhabcloud/public/bootstrap; - } - location /font-icons { - alias /opt/openhabcloud/public/font-icons; - } - location /fonts { - alias /opt/openhabcloud/public/fonts; - } - location /js-plugin { - alias /opt/openhabcloud/public/js-plugin; - } - location /downloads { - alias /opt/openhabcloud/public/downloads; - } - - location ~ ^/(socket.io|rest|images|static|rrdchart.png|chart|openhab.app|WebApp|CMD|cometVisu|proxy|greent|jquery|classicui|ui|basicui|doc|start|icon|habmin|remote|habpanel|ifttt/v1/actions/command){ - proxy_pass http://app_server; - proxy_redirect off; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header X-Real-IP $remote_addr ; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - - location / { - proxy_pass http://app_server; - proxy_redirect off; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr ; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } -} \ No newline at end of file diff --git a/deployment/docker/traefik.toml b/deployment/docker/traefik.toml new file mode 100644 index 0000000..127220e --- /dev/null +++ b/deployment/docker/traefik.toml @@ -0,0 +1,31 @@ +debug = false + +logLevel = "ERROR" +defaultEntryPoints = ["https","http"] + +[entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + +[retry] + +[api] + +[docker] +endpoint = "unix:///var/run/docker.sock" +domain = "yourdomain.com" +watch = true +exposedByDefault = false + +[acme] +email = "your@email.com" +storage = "acme.json" +entryPoint = "https" +onHostRule = true +[acme.httpChallenge] +entryPoint = "http" \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..abd94b2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,64 @@ +version: '2' +services: + app: + container_name: app + image: openhab/openhabcloud-app:latest + working_dir: /opt/openhabcloud + volumes: + - ./config-docker.json:/opt/openhabcloud/config.json + networks: + - ohcloud-network + links: + - mongodb + - redis + ports: + - "3000" + depends_on: + - mongodb + - redis + restart: always + labels: + - "traefik.docker.network=ohcloud-network" + - "traefik.enable=true" + - "traefik.frontend.rule=Host:" + - "traefik.port=3000" + - "traefik.protocol=http" + mongodb: + container_name: mongodb + image: mongo:4.1.10-bionic + ports: + - "27017" + networks: + - ohcloud-network + #volumes: + #- :/data/db + restart: always + redis: + container_name: redis + image: bitnami/redis:latest + networks: + - ohcloud-network + ports: + - "6379" + environment: + - REDIS_PASSWORD=123_openHAB + restart: always + traefik: + container_name: traefik + image: traefik:1.7 + networks: + - internet + - ohcloud-network + ports: + - "443:443" + - "80:80" + - "8080:8080" + volumes: + - ./traefik.toml:/etc/traefik/traefik.toml + - /var/run/docker.sock:/var/run/docker.sock +networks: + internet: + external: + name: internet + ohcloud-network: + driver: bridge \ No newline at end of file diff --git a/logger.js b/logger.js index f99f176..4f8c30b 100644 --- a/logger.js +++ b/logger.js @@ -29,7 +29,7 @@ var logFormat = winston.format.printf(function (info) { return `${info.timestamp} ${info.level}: ${info.message}` }) -var defaultLog = new (winston.transports.DailyRotateFile)({ +var fileLog = new (winston.transports.DailyRotateFile)({ filename: system.getLoggerDir() + 'openhab-cloud-%DATE%-process-' + system.getNodeProcessPort() + '.log', datePattern: 'YYYY-MM-DD', zippedArchive: false, @@ -64,7 +64,7 @@ var auditLog = new (winston.transports.DailyRotateFile)({ var consoleLog = new (winston.transports.Console)({ handleExceptions: true, - level: 'warn', + level: system.getLoggerLevel(), format: winston.format.combine( timeFormat, winston.format.splat(), @@ -72,6 +72,12 @@ var consoleLog = new (winston.transports.Console)({ ) }) +if(system.getLoggerType() == 'console') { + var defaultLog = consoleLog +} else { + var defaultLog = fileLog +} + logger = winston.createLogger({ transports: [ defaultLog, diff --git a/system/index.js b/system/index.js index 6ca8e32..a41f28f 100644 --- a/system/index.js +++ b/system/index.js @@ -374,4 +374,15 @@ System.prototype.getLoggerMorganOption = function() { } }; +/** + * Returns the type of logging used (either file or console). Defaults to file + */ +System.prototype.getLoggerType = function() { + try { + return this.getConfig(['system', 'logger', 'type']); + } catch (e) { + return 'file'; + } +}; + module.exports = new System();