diff --git a/Dockerfile.nginx b/Dockerfile.nginx deleted file mode 100644 index bffea40e22b258ea88b3229d3c1486b540881531..0000000000000000000000000000000000000000 --- a/Dockerfile.nginx +++ /dev/null @@ -1,5 +0,0 @@ -FROM nginx:stable-alpine - -COPY etc/nginx/villas.conf /etc/nginx/conf.d/default.conf - -EXPOSE 8080 diff --git a/Dockerfile.node b/Dockerfile.node deleted file mode 100644 index d1c5f4dc0e1d3ac2438defa0733e77a9ce985d88..0000000000000000000000000000000000000000 --- a/Dockerfile.node +++ /dev/null @@ -1,6 +0,0 @@ -FROM villas/node:latest - -COPY etc/node/*.conf /etc/villas/node/ - -EXPOSE 12000-12100/udp -EXPOSE 12000-12100/tcp diff --git a/README.md b/README.md index 6e8c3de37627d4478ffeb15fdefbb11568ba46e2..b3dc6c50e5a1c633b825be84c5d044094363f044 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,16 @@ We are using Docker and Docker Compose in order to make it as easy as possible f 4. Open the Docker CLI and navigate to the location of the demo files. 5. Start demo by running `docker-compose up -d` +## Backup / Restore Database + +We provide a simple shell script to backup and restore the current state of the MongoDB database: + +- Backup: `./sample-data.sh dump backup_2018_08_30.tar` +- Restore: `./sample-data.sh restore backup_2018_08_30.tar` + ## Copyright -2017, Institute for Automation of Complex Power Systems, EONERC +2017-2018, Institute for Automation of Complex Power Systems, EONERC ## License diff --git a/backend b/backend index 421d5f736b8d27186bf29aa540b0397fc97a0b8d..da9279c2a18e711ddfaf5206fc296f50ab87079c 160000 --- a/backend +++ b/backend @@ -1 +1 @@ -Subproject commit 421d5f736b8d27186bf29aa540b0397fc97a0b8d +Subproject commit da9279c2a18e711ddfaf5206fc296f50ab87079c diff --git a/docker-compose.yml b/docker-compose.yml index 3da3468d3177e4ef6b2d201006acbb40dfc529cf..7cb6bad1538a97229d1a1ab2826b34a8cf2ad46d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,7 @@ services: image: villas/web-frontend build: context: frontend + restart: always # The VILLASweb backend backend: @@ -19,19 +20,29 @@ services: build: context: backend environment: - - NODE_ENV=production - restart: always + NODE_ENV: dotenv + DATABASE_URL: mongodb://database:27017/ + AMQP_ENDPOINT: "amqp://villas:s3c0sim4!@broker/%2F" + LOG_LEVEL: info + LOG_FILE: villasweb-backend_log.txt + DEFAULT_ADMIN: "true" volumes: - files:/usr/src/app/public/ depends_on: - broker: - condition: service_healthy + - broker + restart: always # A single reverse proxy for all our services nginx: - build: - context: . - dockerfile: Dockerfile.nginx + image: nginx:stable-alpine + volumes: + - ./etc/nginx/villas.conf:/etc/nginx/conf.d/default.conf + ports: + - 8080:8080 + depends_on: + - backend + - frontend + restart: always # The MongoDB database for the VILLASweb backend database: @@ -39,22 +50,21 @@ services: user: mongodb volumes: - database:/data/db - restart: always user: mongodb + restart: always # VILLASnode, the gateway between UDP and WebSocket traffic node: - build: - context: . - dockerfile: Dockerfile.node + image: villas/node:latest privileged: true - restart: always - command: node /etc/villas/node/websocket-demo.conf + command: node /etc/villas/node/demo.conf volumes: - ./etc/node:/etc/villas/node ports: + - "8081:80" - "12000-12010:12000-12010/udp" - "12000-12010:12000-12010/tcp" + restart: always # Web Interface for MongoDB mongo-express: @@ -63,10 +73,10 @@ services: ME_CONFIG_MONGODB_SERVER: database ME_CONFIG_BASICAUTH_USERNAME: admin ME_CONFIG_BASICAUTH_PASSWORD: mongo-admin + ME_CONFIG_SITE_BASEURL: /mongo-express/ depends_on: - database - ports: - - "8081:8081" + restart: always # AMQP broker for VILLAScontroller broker: @@ -75,10 +85,9 @@ services: RABBITMQ_DEFAULT_USER: "villas" RABBITMQ_DEFAULT_PASS: "s3c0sim4!" ports: - - "8082:15672" + - "8083:15672" - "5672:5672" - healthcheck: - test: rabbitmqctl status + restart: always # A VILLAScontroller for creating some dummy simulators controller: @@ -87,5 +96,5 @@ services: dockerfile: Dockerfile.controller command: villas-ctl -b "amqp://villas:s3c0sim4!@broker/%2F" -c /etc/villas/controller/config.json daemon depends_on: - broker: - condition: service_healthy + - broker + restart: always diff --git a/etc/nginx/villas.conf b/etc/nginx/villas.conf index 67034deecbeece33e9e07ad931664aa712fae2e3..878ddb1c11c0cd9deba272fc702ece81f54662da 100644 --- a/etc/nginx/villas.conf +++ b/etc/nginx/villas.conf @@ -61,7 +61,7 @@ server { proxy_pass http://node/api; } - location /ws { + location /ws/ { proxy_pass http://node/; } @@ -69,6 +69,10 @@ server { location / { proxy_pass http://frontend:5000/; } + + location /mongo-express { + proxy_pass http://mongo-express:8081/mongo-express/; + } } server { diff --git a/etc/node/demo.conf b/etc/node/demo.conf new file mode 100644 index 0000000000000000000000000000000000000000..380bdcc979873fedf69d65f2967e8595b41e53b4 --- /dev/null +++ b/etc/node/demo.conf @@ -0,0 +1,181 @@ +/** Example configuration file for VILLASnode. + * + * The syntax of this file is similar to JSON. + * A detailed description of the format can be found here: + * http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files + * + * @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de> + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + *********************************************************************************/ + +stats = 5; + +hugepages = 1000; + +nodes = { + sig = { + type = "signal", + + signal = "mixed", + values = 5, + rate = 20 + }, + ws_sig = { + type = "websocket", + } + dpsim1 = { + type = "mqtt" + format = "protobuf", + + username = "guest", + password = "guest", + host = "137.226.248.103", + port = 1883, + + publish = "villas-dpsim1", + subscribe = "dpsim1-villas", + }, + dpsim2 = { + type = "mqtt" + format = "protobuf", + + username = "guest", + password = "guest", + host = "137.226.248.103", + port = 1883, + + publish = "villas-dpsim2", + subscribe = "dpsim2-villas", + }, + opal = { + type = "mqtt" + format = "protobuf", + + username = "guest", + password = "guest", + host = "137.226.248.103", + port = 1883, + + publish = "villas-opal", + subscribe = "opal-villas", + }, + lo = { + type = "mqtt" + format = "villas.human", + + username = "guest", + password = "guest", + host = "137.226.248.103", + port = 1883, + + publish = "lo", + subscribe = "lo", + }, + ws_dpsim1 = { + type = "websocket" + + hooks = ( + { type = "stats" } + ) + }, + ws_dpsim2 = { + type = "websocket" + + hooks = ( + { type = "stats" } + ) + }, + ws_opal = { + type = "websocket" + + hooks = ( + { type = "stats" } + ) + }, + ws_lo = { + type = "websocket" + + hooks = ( + { type = "stats" } + ) + }, + ws_rtds = { + type = "websocket" + }, + rtds = { + type = "socket" + layer = "udp" + format = "gtnet" + + local = "*:12000" + remote = "137.226.133.156:12000" + }, + ws_elsa = { + type = "websocket" + }, + elsa = { + type = "socket" + layer = "udp" + format = "gtnet" + local = "*:12001" + remote = "137.226.133.156:12001" + } +}; + +############ List of paths ############ + +paths = ( + { + in = "sig", + out = "ws_sig" + }, + { + in = "ws_lo", + out = "lo" + }, + { + in = "lo", + out = "ws_lo" + }, + { + in = "dpsim1", + out = "ws_dpsim1", + reverse = true + }, + { + in = "dpsim2", + out = "ws_dpsim2", + reverse = true + }, + { + in = "opal", + out = "ws_opal", + reverse = true + }, + { + in = "rtds", + out = "ws_rtds", + reverse = true + }, + { + in = "elsa", + out = "ws_elsa", + reverse = true + } +); diff --git a/frontend b/frontend index 3c31ffb80261ace00adf522f9d609c198f4668af..3f1913dd4934eae3682607e67f63405d70c51ad2 160000 --- a/frontend +++ b/frontend @@ -1 +1 @@ -Subproject commit 3c31ffb80261ace00adf522f9d609c198f4668af +Subproject commit 3f1913dd4934eae3682607e67f63405d70c51ad2 diff --git a/sample-data.sh b/sample-data.sh new file mode 100755 index 0000000000000000000000000000000000000000..e3ea463427a1777257c3beb9c930fd7e1e34a75c --- /dev/null +++ b/sample-data.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +set +e + +ACTION=${1:-restore} +FILE=${2:-VILLAS.zip} + +NAME=$(basename $(pwd)) +VOLUME="${NAME}_files" + +VOLUME_PATH=$(docker volume inspect ${VOLUME} | jq -r .[0].Mountpoint) + +DOCKEROPTS="--interactive --tty --rm --network ${NETWORK} --volume $(pwd):/tmp" + +TEMP_PATH=$(mktemp -d) + +echo "Temp path: ${TEMP_PATH}" +echo "Volume path: ${VOLUME_PATH}" + +case ${ACTION} in + restore) + tar -C ${TEMP_PATH} -x -v -f ${FILE} + docker-compose exec database mongo VILLAS --eval "db.dropDatabase()" + docker-compose exec -T database mongorestore --archive < ${TEMP_PATH}/database.mongoarchive + + if [ -f ${TEMP_PATH}/files.tar.gz ]; then + rm -rf ${VOLUME_PATH}/* + tar -C ${VOLUME_PATH} -x -z -v -f ${TEMP_PATH}/files.tar.gz + fi + ;; + + dump) + # docker exec mangles stdout and stderr output. So we must use --quiet + docker-compose exec -T database mongodump --archive --quiet > ${TEMP_PATH}/database.mongoarchive + tar -C ${VOLUME_PATH} -c -z -v -f ${TEMP_PATH}/files.tar.gz . + tar -C ${TEMP_PATH} -c -v -f ${FILE} . + ;; + + *) + echo "Usage: $0 (restore|dump) [FILE]" + ;; +esac + +#rm -rf ${TMP_PATH}