@@ -473,6 +473,173 @@ environment:
473473` ` `
474474
475475
476+ # # Running from source
477+
478+ To run the Mage server directly from your _built_ source tree, build the `service`, `web-app`, and any plugin packages
479+ you want to run as described in the above section. Then, from the `instance` directory, run
480+ ` ` ` shell
481+ npm run start:dev
482+ ` ` `
483+ That [NPM script](./instance/package.json) will run the `mage.service` script from your working tree using the
484+ [configuration](./instance/config.js) from the instance directory. You can modify that configuration to suit
485+ your needs.
486+
487+ # ## Local runtime issues
488+
489+ You may run into some problems running the Mage instance from your working tree due to NPM's dependency installation
490+ behavior and/or Node's module resolution algorithm. For example, if you are working on a plugin within this core
491+ Mage repository, you may see errors as plugins initialize. This is usually a null reference error that looks something
492+ like
493+ ```
494+ 2024-08-23T02:42:52.783Z - [ mage.image] intializing image plugin ...
495+ ...
496+ /<...>/mage-server/plugins/image/service/lib/processor.js:53
497+ return yield stateRepo.get().then(x => !!x ? x : stateRepo.put(exports.defaultImagePluginConfig));
498+ ^
499+
500+ TypeError: Cannot read properties of undefined (reading 'get')
501+ at /<...>/mage-server/plugins/image/service/lib/processor.js:53:36
502+ ```
503+ This is usually because the plugin package has a peer depedency on `@ngageoint/mage.service`, which NPM pulls from the
504+ public [registry](https://www.npmjs.com/package/@ngageoint/mage.service) and installs into the plugin's `node_modules`
505+ directory. However, your local Mage instance references `@ngageoint/mage.service` package from the local relative
506+ path. This results in your instance having two copies of `@ngageoint/mage.service` - one from your local build linked
507+ in the top-level `instance/node_modules` directory, and one from the registry in the plugin's `node_modules` directory.
508+ In the case of the error above, this results in a discrepancy during dependency injection because the Mage service
509+ defines unique `Symbol` constants for plugins to indicate which elements they need from their host Mage service. In
510+ the plugin's modules, Node resolves these symbol constants and any other core `@ngageoint/mage.service` modules from
511+ the plugin's copy of the package, as opposed to the relative package installed at the instance level. This is why you
512+ must ensure that you link the working tree core Mage service package in your plugin working tree, as the above
513+ instructions state.
514+ ```shell
515+ ~/my_plugin % npm ci
516+ ~/my_plugin % npm link <relative path to mage server repo>/service
517+ ```
518+ Be aware that NPM's dependency resolution will delete this symbolic link every time you run ` npm install ` ,
519+ ` npm install <dependency> ` , or ` npm ci ` for the plugin, so always ` npm link ` your relative Mage service
520+ dependency again after those commands.
521+
522+ If you encounter other unexpected issues running locally with plugins, especially reference errors, or other
523+ discrepancies in values the core modules define, check that the core service package is still linked properly
524+ in your plugin working tree. You can check using the ` npm ls ` command as follows.
525+ ``` shell
526+ % npm ls @ngageoint/mage.service
527+ @ngageoint/mage.image.service@1.1.0-beta.1 /< ...> /mage-server/plugins/image/service
528+ └── @ngageoint/mage.service@6.3.0-beta.6 -> ./../../../service
529+ ```
530+
531+ ## Docker Setup
532+ The docker directory includes documentation and dockerfiles for building using the release npm packages. The root Dockerfile and docker-compose.yml are used for building and running a dockerfile from the source/local code. Simply run ` docker compose up ` to spin up a local mongo db database along with the web server. After it starts up, navitage to localhost:4242 to view the web server.
533+
534+ By default, the Dockerfile includes additional plugins. Should you want to add/remove any plugins, you will need to modify the Entrypoint command. Simply uncomment the ` entrypoint ` section of the docker compose to specify what plugins you would like to include, or exlude
535+
536+ ### HTTPS/TLS reverse proxy
537+
538+ Then ` mage-web-proxy ` service is optional when developing and running on
539+ localhost, but highly recommended when running MAGE Server on publicly
540+ accessible servers. The service in ` docker-compose.yml ` uses the official
541+ nginx docker image with an appropriate [ configuration] ( web/nginx.conf ) . This
542+ is an example of setting up a reverse proxy in front of the Node server to
543+ enforce HTTPS/TLS connections to the server. Of course, you could use any
544+ reverse proxy you see fit, such as [ Apache HTTP Server] ( https://httpd.apache.org/ )
545+ or an AWS [ Application Load Balancer] ( https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html ) . To run your MAGE server behind the TLS
546+ reverse proxy, peform the following modifications to ` docker-compose.yml ` .
547+ 1 . Comment the ` ports ` block for the ` mage-server ` service to disallow
548+ connections directly to the Node.js server.
549+ 1 . Uncomment the block with the ` mage-web-proxy ` service key.
550+
551+ For testing in a development environment, you can create a self-signed server
552+ certificate for nginx to use. The following OpenSSL command, run from the
553+ directory of this README, will create a self-signed server certificate and
554+ private key in the ` web ` directory that should allow the MAGE mobile app to
555+ connect to nginx. Replace the values of the ` SUBJ_* ` variables at the
556+ beginning of the command with your own values.
557+ ```
558+ SUBJ_C="XX" \
559+ SUBJ_ST="State" \
560+ SUBJ_L="Locality" \
561+ SUBJ_O="Organization" \
562+ SUBJ_OU="Organizational_Unit" \
563+ SUBJ_CN="HOST_NAME_OR_IP"; \
564+ openssl req -new -nodes -x509 -newkey rsa:4096 -sha256 -days 1095 \
565+ -out web/mage-web.crt -keyout web/mage-web.key \
566+ -config <(cat /etc/ssl/openssl.cnf <(printf "[mage]\n \
567+ subjectAltName=DNS:$SUBJ_CN\n \
568+ basicConstraints=CA:true")) \
569+ -subj "/C=$SUBJ_C/ST=$SUBJ_ST/L=$SUBJ_L/O=$SUBJ_O/OU=$SUBJ_OU/CN=$SUBJ_CN" \
570+ -extensions mage; \
571+ unset SUBJ_C SUBJ_ST SUBJ_L SUBJ_O SUBJ_OU SUBJ_CN
572+ ```
573+ The preceding command creates ` web/mage-web.crt ` and ` web/mage-web.key ` , which
574+ the nginx configuration file references. The ` <(...) ` operator is Unix process
575+ substitution and allows treating the enclosed command output as a file. The
576+ ` subjectAltName ` and ` basicConstraints ` arguments are necessary to install the
577+ public certificate, ` mage-web.crt ` , as a trusted authority on a mobile device.
578+
579+ ** IMPORTANT** If you intend to connect to your reverse proxy from a mobile
580+ device or simulator/emulator running the MAGE mobile app, make sure that the
581+ value of the ` SUBJ_CN ` variable matches the IP address of your MAGE Server
582+ host on your network, or the resolvable host name of the host. TLS connections
583+ will not succeed if Common Name and Subject Alternative Name fields in the
584+ public certificate do not match the host name.
585+
586+ When running with the reverse proxy and default port settings in the Compose
587+ file, your server will be available at https://localhost:5443 . If you are
588+ connecting from a mobile device on the same network.
589+
590+ ### Bind mounts
591+
592+ The Compose file uses [ bind mounts] ( https://docs.docker.com/storage/bind-mounts/ )
593+ for the MongoDB database directory, database log path, and MAGE server
594+ [ resources] ( ../README.md#mage-local-media-directory ) . By default, the source
595+ paths of those bind mounts are ` database/data ` , ` database/log ` , and
596+ ` server/resources ` , respectively. You can change the source paths according to
597+ your environment and needs.
598+
599+ With these bind mounts, the MAGE server will retain its data on your host file
600+ system in directories you can explore and manage yourself. For example, this
601+ setup allows you to mount a directory into the MAGE server container from a
602+ [ FUSE-based] ( https://github.com/libfuse/libfuse ) file system, which might
603+ provide extra functionality like [ encryption] ( https://www.veracrypt.fr ) or
604+ [ remote mounting] ( https://github.com/libfuse/sshfs ) transparently to the
605+ Docker container and MAGE application. If you don't have any requirements of
606+ that sort, you can modify the Compose file to use [ Docker-managed volumes] ( https://docs.docker.com/storage/volumes/ ) instead of bind mounts.
607+
608+ ### Ports
609+ The only port the Compose file exposes to the host by default is 4242 on the
610+ ` mage-server ` service to allow HTTP connections from your host web browser to
611+ the MAGE server running in the Docker container. In a production environment,
612+ you could add another service in the Compose file to run an
613+ [ nginx] ( https://hub.docker.com/_/nginx/ ) or [ httpd] ( https://hub.docker.com/_/httpd/ )
614+ reverse proxy with TLS or other security measures in front of the MAGE Server
615+ Node application. In that case you would remove the
616+ ``` yaml
617+ ports :
618+ - 4242:4242
619+ ` ` `
620+ lines from the Compose file under the ` mage-server` service entry. You would
621+ then most likely add the mapping
622+ ` ` ` yaml
623+ ports:
624+ - 443:443
625+ ` ` `
626+ to the reverse proxy's service definition.
627+
628+ You can also allow connections from your host to the MongoDB database container
629+ by uncommenting the `ports` block of the `mage-db` service. You would then be
630+ able to connect directly to the MongoDB database using the `mongo` client on
631+ your host machine to examine or modify the database contents.
632+
633+ # ## Environment settings
634+
635+ You can configure the MAGE server Docker app using [environment variables](../README.md#mage-environment-settings).
636+ The Compose file does this by necessity to configure the MongoDB URL for the MAGE server.
637+ ` ` ` yaml
638+ environment:
639+ MAGE_MONGO_URL: mongodb://mage-db:27017/magedb
640+ ` ` `
641+
642+
476643# # ReST API
477644
478645The MAGE ReSTful API is documented using [OpenAPI](https://swagger.io/specification/). A MAGE server instance includes
0 commit comments