diff options
| -rw-r--r-- | .editorconfig | 4 | ||||
| -rwxr-xr-x | api/main.py | 36 | ||||
| -rw-r--r-- | docker-compose.yml | 61 | ||||
| -rw-r--r-- | frontend/Dockerfile | 19 | ||||
| -rw-r--r-- | frontend/nginx.conf | 32 | ||||
| -rw-r--r-- | frontend/src/api/socket.js | 8 | ||||
| -rw-r--r-- | frontend/yarn.lock | 2 |
7 files changed, 100 insertions, 62 deletions
diff --git a/.editorconfig b/.editorconfig index 508cb765..b0ec2ebd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,3 +14,7 @@ insert_final_newline = true [*.md] trim_trailing_whitespace = false + +# Ensure YAML formatting is according to standard +[*.{yml,yaml}] +indent_size = 2 diff --git a/api/main.py b/api/main.py index a2481269..7544333a 100755 --- a/api/main.py +++ b/api/main.py @@ -1,15 +1,16 @@ #!/usr/bin/env python3 -import flask_socketio import json import os import sys import traceback import urllib.request -from flask import Flask, request, send_from_directory, jsonify + +import flask_socketio +from dotenv import load_dotenv +from flask import Flask, request, jsonify from flask_compress import Compress -from oauth2client import client, crypt from flask_cors import CORS -from dotenv import load_dotenv +from oauth2client import client, crypt from opendc.models.user import User from opendc.util import rest, path_parser, database @@ -19,12 +20,6 @@ load_dotenv() TEST_MODE = "OPENDC_FLASK_TESTING" in os.environ -# Specify the directory of static assets -if TEST_MODE: - STATIC_ROOT = os.curdir -else: - STATIC_ROOT = os.path.join(os.environ['OPENDC_ROOT_DIR'], 'frontend', 'build') - # Set up database if not testing if not TEST_MODE: database.DB.initialize_database( @@ -34,7 +29,7 @@ if not TEST_MODE: host=os.environ['OPENDC_DB_HOST'] if 'OPENDC_DB_HOST' in os.environ else 'localhost') # Set up the core app -FLASK_CORE_APP = Flask(__name__, static_url_path='', static_folder=STATIC_ROOT) +FLASK_CORE_APP = Flask(__name__) FLASK_CORE_APP.config['SECRET_KEY'] = os.environ['OPENDC_FLASK_SECRET'] # Set up CORS support for local setups @@ -50,11 +45,6 @@ else: SOCKET_IO_CORE = flask_socketio.SocketIO(FLASK_CORE_APP) -@FLASK_CORE_APP.errorhandler(404) -def page_not_found(e): - return send_from_directory(STATIC_ROOT, 'index.html') - - @FLASK_CORE_APP.route('/tokensignin', methods=['POST']) def sign_in(): """Authenticate a user with Google sign in""" @@ -132,20 +122,6 @@ def api_call(version, endpoint_path): return flask_response -@FLASK_CORE_APP.route('/my-auth-token') -def serve_web_server_test(): - """Serve the web server test.""" - return send_from_directory(STATIC_ROOT, 'index.html') - - -@FLASK_CORE_APP.route('/') -@FLASK_CORE_APP.route('/projects') -@FLASK_CORE_APP.route('/projects/<path:project_id>') -@FLASK_CORE_APP.route('/profile') -def serve_index(project_id=None): - return send_from_directory(STATIC_ROOT, 'index.html') - - @SOCKET_IO_CORE.on('request') def receive_message(message): """"Receive a SocketIO request""" diff --git a/docker-compose.yml b/docker-compose.yml index 6dc01f67..837f9019 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,21 @@ version: "3" services: + frontend: + build: + context: ./frontend + args: + - REACT_APP_OAUTH_CLIENT_ID=${OPENDC_OAUTH_CLIENT_ID} + image: frontend + restart: on-failure + ports: + - "8081:80" + networks: + - backend + api: build: ./api image: api restart: on-failure - ports: - - "8081:8081" networks: - backend depends_on: @@ -20,34 +30,33 @@ services: - OPENDC_DB_HOST=mongo - OPENDC_FLASK_SECRET - OPENDC_OAUTH_CLIENT_ID - - REACT_APP_OAUTH_CLIENT_ID=${OPENDC_OAUTH_CLIENT_ID} - OPENDC_ROOT_DIR - OPENDC_SERVER_BASE_URL -# TODO: Implement new database interaction on the simulator side -# simulator: -# build: -# context: ./opendc-simulator -# dockerfile: opendc-model-odc/setup/Dockerfile -# image: simulator -# restart: on-failure -# links: -# - mongo -# depends_on: -# - mongo -# environment: -# - PERSISTENCE_URL=jdbc:mysql://mariadb:3306/opendc -# - PERSISTENCE_USER=opendc -# - PERSISTENCE_PASSWORD=opendcpassword -# - COLLECT_MACHINE_STATES=ON -# - COLLECT_TASK_STATES=ON -# - COLLECT_STAGE_MEASUREMENTS=OFF -# - COLLECT_TASK_METRICS=OFF -# - COLLECT_JOB_METRICS=OFF + # TODO: Implement new database interaction on the simulator side + # simulator: + # build: + # context: ./opendc-simulator + # dockerfile: opendc-model-odc/setup/Dockerfile + # image: simulator + # restart: on-failure + # links: + # - mongo + # depends_on: + # - mongo + # environment: + # - PERSISTENCE_URL=jdbc:mysql://mariadb:3306/opendc + # - PERSISTENCE_USER=opendc + # - PERSISTENCE_PASSWORD=opendcpassword + # - COLLECT_MACHINE_STATES=ON + # - COLLECT_TASK_STATES=ON + # - COLLECT_STAGE_MEASUREMENTS=OFF + # - COLLECT_TASK_METRICS=OFF + # - COLLECT_JOB_METRICS=OFF mongo: build: - context: database + context: database restart: on-failure environment: - MONGO_INITDB_ROOT_USERNAME @@ -79,8 +88,8 @@ services: ME_CONFIG_MONGODB_ADMINPASSWORD: "${MONGO_INITDB_ROOT_PASSWORD}" volumes: - mongo-volume: - external: false + mongo-volume: + external: false networks: backend: {} diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 00000000..36e3c20b --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,19 @@ +FROM node:14 +MAINTAINER OpenDC Maintainers <opendc@atlarge-research.com> + +ARG REACT_APP_OAUTH_CLIENT_ID + +# Copy OpenDC directory +COPY ./ /opendc + +# Build frontend +RUN cd /opendc/ \ + && rm -rf ./build \ + && yarn \ + && export REACT_APP_OAUTH_CLIENT_ID=$REACT_APP_OAUTH_CLIENT_ID \ + && yarn build + +# Setup nginx to serve the frontend +FROM nginx:1.19 +COPY --from=0 /opendc/build /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 00000000..ed7e5cfe --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,32 @@ +server { + listen 80; + server_name opendc.org; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } + + location /socket.io { + proxy_http_version 1.1; + + proxy_buffering off; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_pass http://api:8081/socket.io; + } + + location /tokensignin { + proxy_pass http://api:8081/tokensignin; + } + + location /api { + proxy_pass http://api:8081/api; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/frontend/src/api/socket.js b/frontend/src/api/socket.js index 93ce8fa8..759c119e 100644 --- a/frontend/src/api/socket.js +++ b/frontend/src/api/socket.js @@ -6,11 +6,9 @@ let requestIdCounter = 0 const callbacks = {} export function setupSocketConnection(onConnect) { - let port = window.location.port - if (process.env.NODE_ENV !== 'production') { - port = 8081 - } - socket = io.connect(window.location.protocol + '//' + window.location.hostname + ':' + port) + const apiUrl = process.env.REACT_APP_API_URL || window.location.hostname + ':' + window.location.port; + + socket = io.connect(window.location.protocol + '//' + apiUrl); socket.on('connect', onConnect) socket.on('response', onSocketResponse) } diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 00c6e441..2859e4e0 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -11527,7 +11527,7 @@ uuid@^3.0.1, uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuidv4@^6.1.1: +uuidv4@~6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/uuidv4/-/uuidv4-6.1.1.tgz#6565b4f2be7d6f841c14106f420fdb701eae5c81" integrity sha512-ZplGb1SHFMVH3l7PUQl2Uwo+FpJQV6IPOoU+MjjbqrNYQolqbGwv+/sn9F+AGMsMOgGz3r9JN3ztGUi0VzMxmw== |
