diff --git a/README.md b/README.md index 136f0c4f..7a5f069f 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ A free, user-friendly, extendable application and [API](http://docs.webodm.org) * [Getting Help](#getting-help) * [Support the Project](#support-the-project) * [Become a Contributor](#become-a-contributor) + * [Architecture Overview](#architecture-overview) * [Run the docker version as a Linux Service](#run-the-docker-version-as-a-linux-service) * [Run it natively](#run-it-natively) @@ -85,7 +86,7 @@ You **will not be able to distribute a single job across multiple processing nod If you want to run WebODM in production, make sure to pass the `--no-debug` flag while starting WebODM: ```bash -./webodm.sh down && ./webodm.sh start --no-debug +./webodm.sh restart --no-debug ``` This will disable the `DEBUG` flag from `webodm/settings.py` within the docker container. This is [really important](https://docs.djangoproject.com/en/1.11/ref/settings/#std:setting-DEBUG). @@ -99,7 +100,7 @@ WebODM has the ability to automatically request and install a SSL certificate vi - Run the following: ```bash -./webodm.sh down && ./webodm.sh start --ssl --hostname webodm.myorg.com +./webodm.sh restart --ssl --hostname webodm.myorg.com ``` That's it! The certificate will automatically renew when needed. @@ -111,7 +112,7 @@ If you want to specify your own key/certificate pair, simply pass the `--ssl-key When using Docker, all processing results are stored in a docker volume and are not available on the host filesystem. If you want to store your files on the host filesystem instead of a docker volume, you need to pass a path via the `--media-dir` option: ```bash -./webodm.sh down && ./webodm.sh start --media-dir /home/user/webodm_data +./webodm.sh restart --media-dir /home/user/webodm_data ``` Note that existing task results will not be available after the change. Refer to the [Migrate Data Volumes](https://docs.docker.com/engine/tutorials/dockervolumes/#backup-restore-or-migrate-data-volumes) section of the Docker documentation for information on migrating existing task results. @@ -122,7 +123,7 @@ Sympthoms | Possible Solutions --------- | ------------------ While starting WebODM you get: `from six.moves import _thread as thread ImportError: cannot import name _thread` | Try running: `sudo pip install --ignore-installed six` While starting WebODM you get: `'WaitNamedPipe','The system cannot find the file specified.'` | 1. Make sure you have enabled VT-x virtualization in the BIOS.
2. Try to downgrade your version of Python to 2.7 -While Accessing the WebODM interface you get: `OperationalError at / could not translate host name “db” to address: Name or service not known` or `ProgrammingError at / relation “auth_user” does not exist` | Try restarting your computer, then type: `./webodm.sh down && ./webodm.sh start` +While Accessing the WebODM interface you get: `OperationalError at / could not translate host name “db” to address: Name or service not known` or `ProgrammingError at / relation “auth_user” does not exist` | Try restarting your computer, then type: `./webodm.sh restart` Task output or console shows one of the following: | Make sure that your Docker environment has enough RAM allocated: [MacOS Instructions](http://stackoverflow.com/a/39720010), [Windows Instructions](https://docs.docker.com/docker-for-windows/#advanced) After an update, you get: `django.contrib.auth.models.DoesNotExist: Permission matching query does not exist.` | Try to remove your WebODM folder and start from a fresh git clone Task fails with `Process exited with code null`, no task console output | If the computer running node-opendronemap is using an old or 32bit CPU, you need to compile [OpenDroneMap](https://github.com/OpenDroneMap/OpenDroneMap) from sources and setup node-opendronemap natively. You cannot use docker. Docker images work with CPUs with 64-bit extensions, MMX, SSE, SSE2, SSE3 and SSSE3 instruction set support or higher. @@ -168,7 +169,7 @@ Developer, I'm looking to build an app that will stay behind a firewall and just - [ ] Volumetric Measurements - [X] Cluster management and setup. - [ ] Mission Planner -- [ ] Plugins/Webhooks System +- [X] Plugins/Webhooks System - [X] API - [X] Documentation - [ ] Android Mobile App @@ -204,6 +205,17 @@ There are many ways to contribute back to the project: If you know Python, web technologies (JS, HTML, CSS, etc.) or both, it's easy to make a change to WebODM! Make a fork, clone the repository and run `./devenv.sh start`. That's it! See the [Development Quickstart](http://docs.webodm.org/#development-quickstart) and [Contributing](/CONTRIBUTING.md) documents for more information. All ideas are considered and people of all skill levels are welcome to contribute. +## Architecture Overview + +WebODM is built with scalability and performance in mind. While the default setup places all databases and applications on the same machine, users can separate its components for increased performance (ex. place a Celery worker on a separate machine for running background tasks). + +![Architecture](https://user-images.githubusercontent.com/1951843/36916884-3a269a7a-1e23-11e8-997a-a57cd6ca7950.png) + +A few things to note: + * We use Celery workers to do background tasks such as resizing images and processing task results, but we use an ad-hoc scheduling mechanism to communicate with node-OpenDroneMap (which processes the orthophotos, 3D models, etc.). The choice to use two separate systems for task scheduling is due to the flexibility that an ad-hoc mechanism gives us for certain operations (capture task output, persistent data and ability to restart tasks mid-way, communication via REST calls, etc.). + * If loaded on multiple machines, Celery workers should all share their `app/media` directory with the Django application (via network shares). You can manage workers via `./worker.sh` + + ## Run the docker version as a Linux Service If you wish to run the docker version with auto start/monitoring/stop, etc, as a systemd style Linux Service, a systemd unit file is included in the service folder of the repo. @@ -224,30 +236,24 @@ If all pre-requisites have been met, and repository is checked out to /opt/WebOD First, to install the service, and enable the service to run at startup from now on: ```bash -sudo systemctl enable /opt/WebODM/service/webodm.service +sudo systemctl enable /opt/WebODM/service/webodm-gunicorn.service ``` To manually stop the service: ```bash -sudo systemctl stop webodm +sudo systemctl stop webodm-gunicorn ``` To manually start the service: ```bash -sudo systemctl start webodm +sudo systemctl start webodm-gunicorn ``` To manually check service status: ```bash -sudo systemctl status webodm +sudo systemctl status webodm-gunicorn ``` -The service runs within a screen session, so as the odm user you can easily jump into the screen session by using: -```bash -screen -r webodm -``` -(if you wish to exit the screen session, don't use ctrl+c, that will kill webodm, use `CTRL+A` then hit the `D` key) - ## Run it natively WebODM can run natively on Windows, MacOS and Linux. @@ -261,6 +267,7 @@ To run WebODM, you will need to install: * GDAL (>= 2.1) * Node.js (>= 6.0) * Nginx (Linux/MacOS) - OR - Apache + mod_wsgi (Windows) + * Redis (>= 2.6) On Linux, make sure you have: @@ -302,6 +309,12 @@ ALTER SYSTEM SET postgis.enable_outdb_rasters TO True; ALTER SYSTEM SET postgis.gdal_enabled_drivers TO 'GTiff'; ``` +Start the redis broker: + +```bash +redis-server +``` + Then: ```bash @@ -313,6 +326,12 @@ python manage.py collectstatic --noinput chmod +x start.sh && ./start.sh --no-gunicorn ``` +Finally, start at least one celery worker: + +```bash +./worker.sh start +``` + The `start.sh` script will use Django's built-in server if you pass the `--no-gunicorn` parameter. This is good for testing, but bad for production. In production, if you have nginx installed, modify the configuration file in `nginx/nginx.conf` to match your system's configuration and just run `start.sh` without parameters. @@ -345,5 +364,6 @@ python --version pip --version npm --version gdalinfo --version +redis-server --version ``` Should all work without errors. diff --git a/slate/diagrams/README.md b/slate/diagrams/README.md new file mode 100644 index 00000000..12e02bad --- /dev/null +++ b/slate/diagrams/README.md @@ -0,0 +1,3 @@ +## How To Open Diagrams + +Import the .xml files in this directory to https://www.draw.io \ No newline at end of file diff --git a/slate/diagrams/WebODM.xml b/slate/diagrams/WebODM.xml new file mode 100644 index 00000000..e204143f --- /dev/null +++ b/slate/diagrams/WebODM.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/webodm.sh b/webodm.sh index b8456dbe..99a0fcb2 100755 --- a/webodm.sh +++ b/webodm.sh @@ -25,6 +25,7 @@ DEFAULT_HOST="$WO_HOST" DEFAULT_MEDIA_DIR="$WO_MEDIA_DIR" DEFAULT_SSL="$WO_SSL" DEFAULT_SSL_INSECURE_PORT_REDIRECT="$WO_SSL_INSECURE_PORT_REDIRECT" +DEFAULT_BROKER="$WO_BROKER" # Parse args for overrides POSITIONAL=() @@ -70,6 +71,11 @@ case $key in --no-debug) export WO_DEBUG=NO shift # past argument + ;; + --broker) + export WO_BROKER="$2" + shift # past argument + shift # past value ;; *) # unknown option POSITIONAL+=("$1") # save it in an array for later @@ -103,6 +109,7 @@ usage(){ echo " --ssl-cert Manually specify a path to the certificate file (.pem) to use with nginx to enable SSL (default: None)" echo " --ssl-insecure-port-redirect Insecure port number to redirect from when SSL is enabled (default: $DEFAULT_SSL_INSECURE_PORT_REDIRECT)" echo " --no-debug Disable debug for production environments (default: disabled)" + echo " --broker Set the URL used to connect to the celery broker (default: $DEFAULT_BROKER)" exit } @@ -146,6 +153,22 @@ run(){ } start(){ + echo "Starting WebODM..." + echo "" + echo "Using the following environment:" + echo "================================" + echo "Host: $WO_HOST" + echo "Port: $WO_PORT" + echo "Media directory: $WO_MEDIA_DIR" + echo "SSL: $WO_SSL" + echo "SSL key: $WO_SSL_KEY" + echo "SSL certificate: $WO_SSL_CERT" + echo "SSL insecure port redirect: $WO_SSL_INSECURE_PORT_REDIRECT" + echo "Celery Broker: $WO_BROKER" + echo "================================" + echo "Make sure to issue a $0 down if you decide to change the environment." + echo "" + command="docker-compose -f docker-compose.yml -f docker-compose.nodeodm.yml" if [ "$WO_SSL" = "YES" ]; then @@ -189,6 +212,10 @@ start(){ run "$command start || $command up" } +down(){ + run "docker-compose -f docker-compose.yml -f docker-compose.nodeodm.yml down" +} + rebuild(){ run "docker-compose down --remove-orphans" run "rm -fr node_modules/ || sudo rm -fr node_modules/" @@ -232,30 +259,20 @@ resetpassword(){ if [[ $1 = "start" ]]; then environment_check - echo "Starting WebODM..." - echo "" - echo "Using the following environment:" - echo "================================" - echo "Host: $WO_HOST" - echo "Port: $WO_PORT" - echo "Media directory: $WO_MEDIA_DIR" - echo "SSL: $WO_SSL" - echo "SSL key: $WO_SSL_KEY" - echo "SSL certificate: $WO_SSL_CERT" - echo "SSL insecure port redirect: $WO_SSL_INSECURE_PORT_REDIRECT" - echo "================================" - echo "Make sure to issue a $0 down if you decide to change the environment." - echo "" - start elif [[ $1 = "stop" ]]; then environment_check echo "Stopping WebODM..." run "docker-compose -f docker-compose.yml -f docker-compose.nodeodm.yml stop" +elif [[ $1 = "restart" ]]; then + environment_check + echo "Restarting WebODM..." + down + start elif [[ $1 = "down" ]]; then environment_check echo "Tearing down WebODM..." - run "docker-compose -f docker-compose.yml -f docker-compose.nodeodm.yml down" + down elif [[ $1 = "rebuild" ]]; then environment_check echo "Rebuilding WebODM..."