nomad-FAIR issueshttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues2022-12-19T10:17:38Zhttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/1206Switching to src layout2022-12-19T10:17:38ZAdam FeketeSwitching to src layouthttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/1205Refactor metainfo Packages and references2023-12-21T15:39:15ZMarkus ScheidgenRefactor metainfo Packages and referencesMetainfo packages are either defined in Python or in custom schemas. Packages in custom schemas are linked to the archive of the entry that they are defined in. To create references towards definitions in a Package, the archive needs to ...Metainfo packages are either defined in Python or in custom schemas. Packages in custom schemas are linked to the archive of the entry that they are defined in. To create references towards definitions in a Package, the archive needs to be connected to the Package.
- Packages loaded from mongo are not liked to the respective archive. The qualified_name (with `entry_id:...`) is preserved, but the upload_id is not. Instead of storing the qualified name, we should rather store upload_id and entry_id in mongo
- `metainfo.py` is couples to entry_ids, archives, etc. But the `metainfo.py` is supposed to be independent and such aspects should be moved to `datamodel`.
- we should replace `entry_id:...` style qualified names with actual referencesTheodore ChangTheodore Changhttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/1184Use CLI to start nomad services in docker-compose2023-12-21T15:38:47ZMarkus ScheidgenUse CLI to start nomad services in docker-composeThe docker-compose using different scripts and commands to start the services (app, worker, north). Instead, it should simply use `python -m nomad.cli admin run ...`. This would give us more control and flexibility to change how the serv...The docker-compose using different scripts and commands to start the services (app, worker, north). Instead, it should simply use `python -m nomad.cli admin run ...`. This would give us more control and flexibility to change how the services are started without needing to update installations. Would also be more consistent with how we run services in development and the bare-metal installation.https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/1180Graph-style API2023-12-21T15:39:16ZMarkus ScheidgenGraph-style API**tltr**: We might want an API that returns all necessary information "full-picture" for a given section ref.
Assume a client (e.g. our GUI) looks at a particular archive section (e.g. via the `entry/<id>/archive/query` [API](https://no...**tltr**: We might want an API that returns all necessary information "full-picture" for a given section ref.
Assume a client (e.g. our GUI) looks at a particular archive section (e.g. via the `entry/<id>/archive/query` [API](https://nomad-lab.eu/prod/v1/staging/api/v1/extensions/docs#/entries%2Farchive/post_entry_archive_query_entries__entry_id__archive_query_post). To get the full picture, the client still needs to look at the global metainfo, potentially used custom schemas, potentially resolve references, get basic entry metadata, and more.
With our GUI as an example, this leads to additional requests, duplication of code in JS, unnecessary GUI artifacts in the image, etc. The GUI is too complex as it is and we already have loads of troubles testing it. We should move more of this responsibility into the API where it is easier to test and maintain. We should do this at the expanse of client side caching and more server load. This is somewhat opposite to the GUI "store" concept.
This aligns with other efforts. E.g., we need to create upload "bundles" that localize all context information (schemas, etc.) about an upload. Here would aim for a single-request full-picture API for sections instead of uploads.
I could imagine an api that takes a reference-style url `server.de/nomad/api/v1/uploads/raw/my.archive.yaml/archive#/path/to/section` and returns:
```json
{
"upload_id": "...",
"entry_id": "...",
"path": "/path/to/section",
"link": "https://server.de/nomad/api/v1/uploads/<id>/entry/<id>/archive#/path/to/section",
"data": {
"entry": {
"is_author": true,
"is_reviewer": true,
"can_edit": true
},
"archive": {
"m_ref_archives": {
// e.g. other archives that contain the necessary schema
// this should include "global schemas" somehow
// ...
},
"metadata": {
// includes authors, ids, references, existing sections/quantities, etc.
// we could also add client friendly urls to stuff like the reference records
...
},
"path": {
"m_def": "/local/path/to/definition",
"m_reference": "../uploads/<id>/entry/<id>/archive#/path",
"m_link": "https://server.de/nomad/api/v1/uploads/<id>/entry/<id>/archive#/path",
"to": {
"m_def": "/local/path/to/definition",
"m_reference": "../uploads/<id>/entry/<id>/archive#/path/to",
"m_link": "https://server.de/nomad/api/v1/uploads/<id>/entry/<id>/archive#/path/to",
"section": {
...
}
}
}
}
}
}
```
This is very similar to what you can already do with the archive API, but
- the necessary "required" record is created from the path `/path/to/section` automatically
- we add `m_reference`, `m_link` so that the client does not need to create these itself
- we add necessary schemas via `m_ref_archives` in the same way we would add referenced data, makes it easy for the client to resolve
- we add derived user specific entry metadata (can_edit, etc.) so that the client does not have to make these decisions
You might think this is more and more a graphql style API. I would like to think, it is more like an API with the one predefined graph that you always need. I guess simple feature-toggle parameters (`include_schema`, `include_references`, etc.) should be enough.Theodore ChangTheodore Changhttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/1111Revise and formalize annotations2023-02-22T10:04:52ZMarkus ScheidgenRevise and formalize annotationsThere are lots of annotations that are just dictionary types key-value pairs. Often without checks or documentation. Many of those have questionable or incomplete functionality.
- [x] eln
- [x] hide
- [x] table, tabular
- [x] plot
For...There are lots of annotations that are just dictionary types key-value pairs. Often without checks or documentation. Many of those have questionable or incomplete functionality.
- [x] eln
- [x] hide
- [x] table, tabular
- [x] plot
For these we should:
- establish proper classes that can be used in python and that check yaml definitions
- these classes should by pydantic models ... with documentation
- find a way to include the documentation in our docs.Markus ScheidgenMarkus Scheidgenhttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/1088Simplify the data store's caching strategy2022-09-29T07:31:41ZDavid SikterSimplify the data store's caching strategyTo simplify the code and reduce the overhead, we should try a simplified cache strategy in the store. Instead of requiring everyone who is interested in a piece of data to subscribe to it, and clearing elements out when there are no subs...To simplify the code and reduce the overhead, we should try a simplified cache strategy in the store. Instead of requiring everyone who is interested in a piece of data to subscribe to it, and clearing elements out when there are no subscribers left (after a timeout), we should make a simple reset function, which clears everything when navigating to a new upload page or entry page.
This is more similar to the old context approach, and should require less overhead and simpler code. The data store becomes more of a global cache. Subscriptions are still there to get notifications of updates, but are not required for keeping the data in the store.David SikterDavid Sikterhttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/1083Recoil memory leak2022-09-27T12:30:33ZLauri HimanenRecoil memory leakWe are using an old version of recoil (0.3.1), which seems to have a memory leak according to an investigation done by @dsikter. Updating to the newest version (0.7.5) should fix this. There are, however, some compatibility issues in the...We are using an old version of recoil (0.3.1), which seems to have a memory leak according to an investigation done by @dsikter. Updating to the newest version (0.7.5) should fix this. There are, however, some compatibility issues in the way our search uses recoil that need to be fixed first.Lauri HimanenLauri Himanenhttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/1009Metainfo data type improvements2023-12-21T15:38:46ZLauri HimanenMetainfo data type improvementsOur metainfo has some inconsistencies in how the different data types are handled. Here are some observations which could be broken down into separate issues if we decide to act on them:
- Units are ignored for primitive python numeric ...Our metainfo has some inconsistencies in how the different data types are handled. Here are some observations which could be broken down into separate issues if we decide to act on them:
- Units are ignored for primitive python numeric types (#1006).
- Units cannot be assigned to non-numpy 1D arrays (`pint` does not allow assigning units to regular python 1D lists).
- Units can be assigned to non-numeric quantities (maybe a `@constraint` would help here).
- Possible precision loss in downcasting is not handled consistently. For primitive types, one cannot assign values whose values do not match the target data type. This ensures that no precision is lost, but is too strict (cannot assign int to float). For numpy data types, there is no check for precision loss, and values can be casted freely. E.g. storing a float array to an int array does not raise any errors.
- The differences between some of the data types are quite vague. We do support both 32 and 64 bit `int` and `float` numbers, but is this difference realized when we are saving the archive to disk? How does the fact that Javascript only deals with one numeric 64 bit numeric type (`Number`) affect things when reading/saving data in an ELN?
- Arrays with dimensions > 1 can only be created for quantities that have a numpy data type. This is causing some confusion especially for people who do not know what numpy is.
My gut feeling would be that many of these issues would if we used numpy internally when storing all numeric values, no matter what shape (0D, 1D, ND). This way our metainfo would have one "normalized" form for all numeric data, but the user could use any compatible data type in assignments (we would check the compatibility automatically). This would also mean that upon accessing numeric data, the user would always get a numpy data back. Whether this is confusing or not is hard to say. This change would also mean that we could simplify the supported numeric data types. How far we simplify them is an open question. One extreme is to only support two numeric types: `int` (64 bit integer) and `float` (64 bit float). Another option would be to keep support for different variants (`int32`, `int64`, `float32`, `float64`, `uint32`, `uint64` etc.) but maybe use simple strings instead of the actual numpy data type objects, as it may be confusing for ELN users.
All of this is open for discussion and any comments are welcome.https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/1005Fine-tuning develop and dev deployments2022-09-12T14:56:28ZAdam FeketeFine-tuning develop and dev deploymentshttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/990domain attribute for MatchingParser2022-09-01T07:16:00ZJose Pizarrodomain attribute for MatchingParserBy default, domain is set to 'dft' in order to differentiate between computation and experiments.
I think a simple name change for the default value (`domain='computation'`) will set things more clear.By default, domain is set to 'dft' in order to differentiate between computation and experiments.
I think a simple name change for the default value (`domain='computation'`) will set things more clear.https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/971List of supported codes (connected to https://nomad-lab.eu/prod/v1/staging/gu...2022-09-14T12:24:49ZLuca Massimiliano GhiringhelliList of supported codes (connected to https://nomad-lab.eu/prod/v1/staging/gui/about/information )The list of supported codes (i..e., existing parsers) at https://nomad-lab.eu/prod/v1/staging/gui/about/information needs some polishing.
There are two issues:
- One, trivial, is to use the correct spelling (in particular capitalization)...The list of supported codes (i..e., existing parsers) at https://nomad-lab.eu/prod/v1/staging/gui/about/information needs some polishing.
There are two issues:
- One, trivial, is to use the correct spelling (in particular capitalization) for each code. This should be in the mentioned webpage (at some point in production, not only staging) put also in the results.method.simulation.program_name allowed values. Code developers are typically picky about the exact spelling of their code, ant also users would regard a list with essentially all non-standard spelling as of amateurish.
- The second, more involved, is to distinguish between the atomistic codes from the "workflow codes". A third category seems to be "database", e.g., for AFLOW and openKIM. For this second aspect, we may briefly meet asap to decide how to do it in terms of metadata.
Yes, it is not so clean cut to distinguish between atomistic and workflow codes, but here I invoke the community consensus (obviously single assignments done by me so far are open for discussion). In any case, having all this heterogeneous list looks untidy and may suggest lack of understanding of the parsed data from the NOMAD side. So, I would split the list in atomistic codes / workflow codes / and databases. NeXus seems a category on its own. In fact, I assume we do not really have "a nexus parser" not in the sense of the other parsers, as nexus files are coming with their own schema which is simply 1-to-1'ed by the parser (correct me if I am wrong). So, I would put NeXus in a 4th category.
Not sure who should be assigned, here. I mean, for the capitalization correction, I guess @ladinesa is the obvious choice. In any case, this issue should be of interest for @ndaelman , @jrudz , and @pizarroj .
Below is the detailed correction list (codes without a re-assignment in bold are intended as "atomistic")
- abinit: wrong spelling/capitalization -> Abinit
- aflow -> AFLOW . **This is not a code, category database?**
- amber: wrong spelling/capitalization -> Amber
- asap: wrong spelling/capitalization -> ASAP
- asr -> ASR. **Workflow code**
- atk: wrong spelling/capitalization -> QuantumATK
- band -> BAND. **Workflow code (it is a postprocessing on DFT codes)**
- bigdft: wrong spelling/capitalization -> BigDFT
- bopfox: wrong spelling/capitalization -> BOPfox
- castep: wrong spelling/capitalization -> CASTEP
- charmm: wrong spelling/capitalization -> CHARMM. Note that the link / https://www.charmm.org/charmm/ does not work -> https://www.charmm.org/
- cp2k: wrong spelling/capitalization -> CP2K
- cpmd: wrong spelling/capitalization -> CPMD
- crystal: wrong spelling/capitalization -> CRYSTAL
- dftbplus: wrong spelling/capitalization -> DFTB+ (ideally + is a superscript)
- dlpoly: wrong spelling/capitalization -> DL_POLY
- dmol3: wrong spelling/capitalization -> DMol3 (ideally 3 is a superscript)
- eelsdb, EELS DB. **This is not a code, category db?**
- elastic"correct spelling but broken link-> http://exciting.wikidot.com/elastic . **Workflow code**
- elk: wrong spelling/capitalization -> Elk
- _example -> ?? probably a forgotten test? To be removed_
- exciting: this one is correct as is!
- fhiaims: wrong spelling/capitalization -> FHI-aims
- fhivibes: wrong spelling/capitalization -> FHI-vibes . **Workflow code**
- fleur: wrong spelling/capitalization -> FLEUR
- fplo: wrong spelling/capitalization -> FPLO
- gamess: wrong spelling/capitalization -> GAMESS
- gaussian: wrong spelling/capitalization -> Gaussian
- gpaw: wrong spelling/capitalization -> GPAW
- gromacs: wrong spelling/capitalization -> GROMACS
- gromos: wrong spelling/capitalization -> GROMOS
- gulp: wrong spelling/capitalization -> GULP
- lammps: wrong spelling/capitalization -> LAMMPS
- libatoms: wrong spelling/capitalization -> libAtoms
- lobster: wrong spelling/capitalization -> LOBSTER . **Workflow code (it is a postprocessing on DFT codes)**
- molcas: wrong spelling/capitalization -> Molcas
- mopac: wrong spelling/capitalization -> MOPAC
- mp: the abbreviation mp or MP is not official, it should be called "The Materials Project". Still, **this is not a code. Either db category or name the actual workflow code used.**
- namd: wrong spelling/capitalization -> NAMD
- nexus: wrong spelling/capitalization -> NeXus. **This is not a code, not sure which category to put in**. Furthermore, the link is not correct -> https://www.nexusformat.org/ ?
- nwchem: wrong spelling/capitalization -> NWChem
- octopus: this is ambiguous, it is "octopus" in the logo, but typically "Octopus" in text. Can be left as "octopus"
- onetep: wrong spelling/capitalization -> ONETEP
- openkim: wrong spelling/capitalization -> OpenKIM. **this is not a code, category db?**
- openmx: wrong spelling/capitalization -> OpenMX
- orca: wrong spelling/capitalization -> ORCA
- phonopy: correct spelling&capitalization. **Workflow code**
- psi4: wrong spelling/capitalization -> PSI4
- qball: wrong spelling/capitalization -> Qball (or qb@ll)
- qbox: wrong spelling/capitalization -> Qbox
- quantumespresso: wrong spelling/capitalization -> QuantumESPRESSO
- siesta: wrong spelling/capitalization -> SIESTA. Also, the actual link is https://siesta-project.org/siesta/ .
- tinker: wrong spelling/capitalization -> Tinker
- turbomole: wrong spelling/capitalization -> TURBOMOLE
- vasp: wrong spelling/capitalization -> VASP
- wien2k: wrong spelling/capitalization -> WIEN2k
- xtb : correct
- yambo: wrong spelling/capitalization -> YAMBOAlvin Noe LadinesAlvin Noe Ladineshttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/955Harmonizing internal references to always include a "#"2023-12-21T15:39:08ZDavid SikterHarmonizing internal references to always include a "#"Currently, references are sometimes given on the form "/packages/20/category_definitions/0" etc. But to be more consistent with how we use urls, it would be desirable to have these with an initial "#", i.e. "#/packages/20/category_defini...Currently, references are sometimes given on the form "/packages/20/category_definitions/0" etc. But to be more consistent with how we use urls, it would be desirable to have these with an initial "#", i.e. "#/packages/20/category_definitions/0".
These references starting with '/' is for example right now the case with the `metainfo.json` generated by the `generate_gui_artifacts.sh` script.
Question, do these kind of links without "#" ever occur in archives? In which case we need to think about backward compatibility or reprocessing.Theodore ChangTheodore Changhttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/856Revise version information2022-12-19T11:42:42ZMarkus ScheidgenRevise version information- The current NOMAD version is stated a many places throughout the source code. This is annoying to change.
- The documentation has no version statement
- The GUI could have a more prominent statement
- The API does not give any metadata...- The current NOMAD version is stated a many places throughout the source code. This is annoying to change.
- The documentation has no version statement
- The GUI could have a more prominent statement
- The API does not give any metadata with its responsesAdam FeketeAdam Feketehttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/828Refactor the relationship between FileBrowser, various entry/upload views and...2022-09-15T08:57:39ZMarkus ScheidgenRefactor the relationship between FileBrowser, various entry/upload views and their contextsThe FileBrowser should rely on the upload context for any reprocessing and not do its own. Firsts, its a lot of code duplications. Secondly, processing on the FileBrowser does not refresh the Upload/Entry view and vice versa.The FileBrowser should rely on the upload context for any reprocessing and not do its own. Firsts, its a lot of code duplications. Secondly, processing on the FileBrowser does not refresh the Upload/Entry view and vice versa.David SikterDavid Sikterhttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/751Optimize ArchiveReader read disk performance2022-02-23T12:53:41ZTheodore ChangOptimize ArchiveReader read disk performanceThe current implementation that uses blocks receives the entry id from external and uses binary search to search blocks to locate if the target entry is in the archive.
The _load_toc_block() method performs the following steps.
1. compu...The current implementation that uses blocks receives the entry id from external and uses binary search to search blocks to locate if the target entry is in the archive.
The _load_toc_block() method performs the following steps.
1. compute the block number of the target entry
2. load the corresponding block from the disk
3. unpack entries and populate then into the self._toc dict
Consider an archive of n entries and, for simplicity, assume 1 entry per block so that entry and block are interchangable in the following context.
When search for each entry, the binary search requires O(log(n)) operations with O(log(n)) disk reads. Assume to read all n entries, then O(n*log(n)) disk reads are required. However, O(n) disk reads are required to read all entries.
To fix:
Maintain an internal list to record if the block has been read. If so, skip reading the block from disk. Reduce disk opeartion from O(n*log(n)) to O(n).Theodore ChangTheodore Changhttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/749Create utility for getting the signature token, caching the value to reduce a...2022-03-30T08:12:24ZDavid SikterCreate utility for getting the signature token, caching the value to reduce api callsDavid SikterDavid Sikterhttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/730Flawed EditMetadataDialog design2022-03-03T08:21:16ZMarkus ScheidgenFlawed EditMetadataDialog designThe EditMetadataDialog uses some bad implementation patterns that lead to bugs and unpredicted behaviour.
- remove the use of contexts
- hoist all state to the topmost component EditMetadataDialog
- reduce the state: you basically only...The EditMetadataDialog uses some bad implementation patterns that lead to bugs and unpredicted behaviour.
- remove the use of contexts
- hoist all state to the topmost component EditMetadataDialog
- reduce the state: you basically only need a list of edit actions as state
- translate user actions directly to edit actions. Never infer actions from existing values. This information is incomplete. This is where the bugs and hard to predict behaviour comes from.
The interface of all components should be much simpler:
```
EditMetadataDialog(query, uploadId, entryData, onCommit())
EditDatasets(datasets, onAddNew(string), onRemove(dataset), onAdd(dataset))
EditReferences(references, onAdd(string), onRemove(string))
EditComment(comment, onChange(string))
```
The top-level EditMetadataDialog keeps a list of edit actions. That is basically the only state you need. The rest is derived from that.
Values for the comment, datasets, references to show are computed from entryData and the current list of edit actions. The list of edit actions is modified via the onAdd, onRemove, etc. callbacks that are passed down to the other components. EditReferences, EditComment, EditDatasets are basically completely stateless.
All validation is handled by EditMetadataDialog. Where necessary errors are pushed down to children via props.Mohammad NakhaeeMohammad Nakhaeehttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/671Edit entry metadata GUI (from Upload page)2022-01-21T12:24:01ZMarkus ScheidgenEdit entry metadata GUI (from Upload page)This should be a single dialog.
The edits include: **comment**, **references**, and **datasets**.
Users can edit either all entries in an upload or a selected few entries (e.g. by id). (Later we might want to execute the same edits fr...This should be a single dialog.
The edits include: **comment**, **references**, and **datasets**.
Users can edit either all entries in an upload or a selected few entries (e.g. by id). (Later we might want to execute the same edits from another page and allow to edit entries by query)
Since you edit potentially many entries and each entry can have different values, the entries that a user edits might already have different values for comment, references, or datasets. So it is unavoidable that the user might change data, she cannot see. Therefore, the GUI has to clarify to the user that
- she is overriding existing comments with the new one
- she is either adding references or replacing all the possible existing references
- she is either adding datasets or replacing all existing datasets
To show some existing values (e.g. to have something to remove/replace), values could be taken from one example entry. The assumption here is that in many cases all entries will have the same value.
In the old system, the user was implicitly creating datasets. Ideally, we would do this more explicit. Similar to the invite user dialog, we could have a create dataset dialog. When you select a dataset, the user should be presented with all "her" datasets. "Her" meaning datasets that she created.
Related to the edit dialog:
- [x] When changing the name of an upload, the upload edit API should be used and the deprecated `PUT uploads/{upload_id}/metadata` should be removed from the API.
- [x] Under publish we need a lift embargo button for published uploads that have `embargo_length > 0`
- [x] The `EditMembersDialog` sources should be moved to `src/components/uploads`
- [x] As long as we only offer the `EditUserMetadataDialog` only for the UploadPage, we should also move it to `src/components/uploads`Mohammad NakhaeeMohammad Nakhaeehttps://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/666Refactor "owner"2023-12-21T15:39:03ZDavid SikterRefactor "owner"The "owner" field, used in many api calls, uses terminology that doesn't fit so well after the changes done to the permission structure. A suggestion for improvement would be to call it "scope", rather than "owner" and change some of the...The "owner" field, used in many api calls, uses terminology that doesn't fit so well after the changes done to the permission structure. A suggestion for improvement would be to call it "scope", rather than "owner" and change some of the values, for example something like this:
|old name |suggested new name |
|---------|-------------------|
| public | public |
| staging | staging |
| all | **visible** |
| visible | **fully_visible** |
| user | **main_author** |
| | **writer** |
| shared | **viewer** |
| admin | admin |
The new values could first be introduced as synonyms for the existing values, to make the transition in steps.https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/issues/634Refactor config "api" keys2023-12-21T15:38:38ZMarkus ScheidgenRefactor config "api" keysThe configuration of API related keys is very confusing. The path is always the same, but host/port have three different meanings that need to be supported by three different keys:
- to use by nomad client
- to return for external use
- ...The configuration of API related keys is very confusing. The path is always the same, but host/port have three different meanings that need to be supported by three different keys:
- to use by nomad client
- to return for external use
- to access the API via the internal server side network between different app container
Another thing is GUI vs API (which makes a difference in dev mode).
Similar internal vs external distinction is necessary for files (inside container, outside container).