Installing NOMAD Oasis v1.1.0 without Docker (Base Linux)

I’m trying to update our base installation on nomad.warwick.ac.uk, where Docker is not allowed by ITS.

As far as I see, the base linux instructions have not been touched since the beta version. I have tried to use the changes in the docker sections about nomad.yaml and nginx.conf but I’m not sure if all changes are correct for our case.

Steps

I have tried to start from scratch as far as possible (e.g. deleted indices of earlier attempts from elasticsearch), so we can use this to update the instruction as well:

$ mkdir v1.1
$ cd v1.1
$ virtualenv -p `which python3` nomadpyenv
$ source nomadpyenv/bin/activate
$ curl 'https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/archive/v1.1.0/nomad-FAIR-v1.1.0.tar.gz' -o nomad-lab.tar.gz
$ pip install install --upgrade pip
$ pip install nomad-lab.tar.gz[all]
$ vi nomad.yaml
$ nomad admin ops nginx-conf > nginx.conf
$ vi nginx.conf
$ cp nginx.conf /etc/nginx/default.d/nomad.conf
$ sudo service nginx restart
$ nomad admin ops gui-config
Traceback (most recent call last):
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/bin/nomad", line 8, in <module>
    sys.exit(run_cli())
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/cli/cli.py", line 71, in run_cli
    return cli(obj=POPO())  # pylint: disable=E1120,E1123
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/cli/admin/admin.py", line 241, in gui_config
    shutil.copytree(gui_folder, run_gui_folder)
  File "/home/admin/.pyenv/versions/3.7.9/lib/python3.7/shutil.py", line 318, in copytree
    names = os.listdir(src)
FileNotFoundError: [Errno 2] No such file or directory: '/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/app/flask/static/gui'

Not sure why it’s missing.

The current version of the nomad.yaml:

services:
  api_host: 'nomad.warwick.ac.uk'
  api_base_path: '/nomad-oasis'
  https: True
  https_upload: True
  admin_user_id: 'admin'

oasis:
  is_oasis: true
  uses_central_user_management: true

north:
  jupyterhub_crypt_key: '79f88d1ad2c7d97bbe2df4bbaf7d3977ee3a71a1e6c7759294e30bd44022276f'
  hub_ip_connect: '127.0.0.1'  # 172.17.0.1 is docker-specific?

meta:
  deployment: 'NOMAD Oasis UoW'
  deployment_id: 'nomad.warwick.ac.uk'
  maintainer_email: '[email protected]'

mongo:
  db_name: nomad_v1

elastic:
  entries_index: nomad_v1_entries
  materials_index: nomad_v1_materials

# client.url entry missing in v1.1 docs
# keycloak entries missing in v1.1 docs
# rabbitmq entries missing in v1.1 docs

The current version of /etc/nginx/default.d/nomad.conf (server entry removed, auto-generated hostnames replaced with localhost):


    location / {
         proxy_pass http://localhost:8000;
    }

    location ~ /nomad-oasis\/?(gui)?$ {
        rewrite ^ /nomad-oasis/gui/ permanent;
    }

    location /nomad-oasis/gui/ {
        proxy_intercept_errors on;
        error_page 404 = @redirect_to_index;
        proxy_pass http://localhost:8000;
    }

    location @redirect_to_index {
        rewrite ^ /nomad-oasis/gui/index.html break;
        proxy_pass http://localhost:8000;
    }

    location ~ \/gui\/(service-worker\.js|meta\.json)$ {
        add_header Last-Modified $date_gmt;
        add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
        if_modified_since off;
        expires off;
        etag off;
        proxy_pass http://localhost:8000;
    }

    location ~ /api/v1/uploads(/?$|.*/raw|.*/bundle?$) {
        client_max_body_size 35g;
        proxy_request_buffering off;
        proxy_pass http://localhost:8000;
    }

    location ~ /api/v1/.*/download {
        proxy_buffering off;
        proxy_pass http://localhost:8000;
    }

In the old v0.8 we used a run script:

source /home/admin/$VIRTUALENV/bin/activate
gunicorn "${params[@]}" -b 0.0.0.0:8000 nomad.app:app >> nomad.app.log 2>&1 &
celery worker -l info -A nomad.processing -Q celery,calcs,uploads >> nomad.processing.log 2>&1 &

In the NOMAD tutorial last week, @mscheidgen noted that we should use the UvicornWorker class instead:

gunicorn "${params[@]}" --worker-class=uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 nomad.app.main:app >> nomad.app.log 2>&1 &

But the v1.1 documentation suggests using uvicorn (this was updated even in the bare Linux section :+1:):

python -m nomad.cli admin ops gui-config
python -m uvicorn --host 0.0.0.0 nomad.app.main:app

Since this seems to depend on the failing gui-config command, I didn’t go further.

Questions

  1. Are the client, keycloak, and rabbitmq entries still necessary in our case?
  2. Why is …/gui not found?
  3. Should we use uvicorn or gunicorn?

Thanks for your help!

Answers in reverse order.

The released v1.1.0 still relies on gunicorn (but already required the uvicorn worker). This would be the most minimal command to launch the app

gunicorn --worker-class=uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 nomad.app.main:app

The gui folder is created by this command (repeat after you changed the nomad.yaml):

python -m nomad.cli admin ops gui-config

I am not sure what client, keycloak, rabbitmq entries you are referring to. You don’t need them in the nomad.yaml anymore. The file you posted looks good.

Let me know, if these commands could do something for you.

That should effectively be the same as the command I already used, right?

$ nomad admin ops gui-config
Traceback (most recent call last):
…
FileNotFoundError: [Errno 2] No such file or directory: '/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/app/flask/static/gui'

For completeness:

$ python -m nomad.cli admin ops gui-config
Traceback (most recent call last):
  File "/home/admin/.pyenv/versions/3.7.9/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/home/admin/.pyenv/versions/3.7.9/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/cli/__main__.py", line 22, in <module>
    run_cli()  # pylint: disable=E1120,E1123
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/cli/cli.py", line 71, in run_cli
    return cli(obj=POPO())  # pylint: disable=E1120,E1123
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/cli/admin/admin.py", line 241, in gui_config
    shutil.copytree(gui_folder, run_gui_folder)
  File "/home/admin/.pyenv/versions/3.7.9/lib/python3.7/shutil.py", line 318, in copytree
    names = os.listdir(src)
FileNotFoundError: [Errno 2] No such file or directory: '/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/app/flask/static/gui'

I created the directories by hand:

$ mkdir -p /home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/app/flask/static/gui
$ python -m nomad.cli admin ops gui-config

Then there is no error. Git cannot checkin empty directories, as far as I know. Is that the problem? Either way, the command should create them itself.

I am sorry for the confusion. I should have read the box with the error output more carefully. I thought the error was thrown when you run the app. Wasn’t seeing that you were already running the gui-config command. You are totally right, its the missing parent directories.

Could you run the app after this step?

I get another “not found” error at startup, this time for …/nomad/units/default_en.txt:

[2022-05-20 16:15:29 +0100] [6944] [INFO] Starting gunicorn 20.1.0
[2022-05-20 16:15:29 +0100] [6944] [INFO] Listening at: http://0.0.0.0:8000 (6944)
[2022-05-20 16:15:29 +0100] [6944] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2022-05-20 16:15:29 +0100] [6967] [INFO] Booting worker with pid: 6967
[2022-05-20 16:15:30 +0100] [6967] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/pint/registry.py", line 542, in load_definitions
    with open(file, encoding="utf-8") as fp:
FileNotFoundError: [Errno 2] No such file or directory: '/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/units/default_en.txt'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/gunicorn/arbiter.py", line 589, in spawn_worker
    worker.init_process()
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/uvicorn/workers.py", line 63, in init_process
    super(UvicornWorker, self).init_process()
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/gunicorn/workers/base.py", line 134, in init_process
    self.load_wsgi()
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
    return self.load_wsgiapp()
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/gunicorn/util.py", line 359, in import_app
    mod = importlib.import_module(module)
  File "/home/admin/.pyenv/versions/3.7.9/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/app/main.py", line 28, in <module>
    from nomad import config, infrastructure
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/infrastructure.py", line 48, in <module>
    from nomad.parsing import parsers  # pylint: disable=unused-import
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/parsing/__init__.py", line 75, in <module>
    from nomad.parsing.parser import Parser, BrokenParser, MissingParser, MatchingParser, MatchingParserInterface
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/parsing/parser.py", line 28, in <module>
    from nomad.datamodel import EntryArchive, EntryMetadata
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/datamodel/__init__.py", line 74, in <module>
    from nomad.metainfo import Environment
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/metainfo/__init__.py", line 33, in <module>
    from .metainfo import (
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/metainfo/metainfo.py", line 41, in <module>
    from nomad.units import ureg as units
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/units/__init__.py", line 22, in <module>
    ureg = UnitRegistry(os.path.join(os.path.dirname(__file__), 'default_en.txt'))
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/pint/registry.py", line 112, in __call__
    obj._after_init()
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/pint/registry.py", line 1889, in _after_init
    super()._after_init()
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/pint/registry.py", line 270, in _after_init
    self.load_definitions(self._filename)
  File "/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/pint/registry.py", line 550, in load_definitions
    raise ValueError("While opening {}\n{}".format(file, msg))
ValueError: While opening /home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/units/default_en.txt
[Errno 2] No such file or directory: '/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/units/default_en.txt'
[2022-05-20 16:15:30 +0100] [6967] [INFO] Worker exiting (pid: 6967)
[2022-05-20 16:15:31 +0100] [6944] [INFO] Shutting down: Master
[2022-05-20 16:15:31 +0100] [6944] [INFO] Reason: Worker failed to boot.

The mentioned file is in the package. It should have been copied to the specified path upon pip install nomad-lab.tar.gz[all]. Can you verify that the file exists at '/home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/units/default_en.txt'?

The directory exists but there is no default_en.txt:

$ ls /home/admin/nomad-oasis/v1.1/nomadpyenv/lib/python3.7/site-packages/nomad/units
__init__.py  __pycache__

I tried it again in a new directory in case the install nomad-lab.tar.gz[all] had not worked correctly but the result was the same.

I am not sure where you found this line:

curl 'https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR/-/archive/v1.1.0/nomad-FAIR-v1.1.0.tar.gz' -o nomad-lab.tar.gz

However, this is not our pypi/pip package. I guess this is an automated .tar.gz that gitlab is creating when we create a tag/release of your repo. I am surprised that pip can do something with that.

Can you install version 1.1.0 like this:

pip install nomad-lab==v1.1.0 --extra-index-url https://gitlab.mpcdf.mpg.de/api/v4/projects/2187/packages/pypi/simple

This will pull a pre-release of 1.1.0 from our gitlab pypi registry. The official pypi only contains our current stable release 1.0.9. You need to uninstall the wrong nomad-lab from your virtualenv before doing this. This should give you the missing files.

Oh, my bad. I assumed the tar.gz from the Gitlab releases were pypi ones but I suppose they are just bare sources. Sorry for the confusion.

I had to adjust your command to include [all] to install all dependencies:

pip install nomad-lab[all]==v1.1.0 --extra-index-url https://gitlab.mpcdf.mpg.de/api/v4/projects/2187/packages/pypi/simple

Now there is no “not found” anymore but a timeout:

[2022-05-23 14:51:39 +0100] [29592] [INFO] Starting gunicorn 20.1.0
[2022-05-23 14:51:39 +0100] [29592] [INFO] Listening at: http://0.0.0.0:8000 (29592)
[2022-05-23 14:51:39 +0100] [29592] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2022-05-23 14:51:39 +0100] [29616] [INFO] Booting worker with pid: 29616
[2022-05-23 14:51:50 +0100] [29616] [INFO] Started server process [29616]
[2022-05-23 14:51:50 +0100] [29616] [INFO] Waiting for application startup.
[2022-05-23 14:52:09 +0100] [29592] [CRITICAL] WORKER TIMEOUT (pid:29616)
[2022-05-23 14:52:09 +0100] [29592] [WARNING] Worker with pid 29616 was terminated due to signal 6
[2022-05-23 14:52:09 +0100] [29884] [INFO] Booting worker with pid: 29884
… # repeats

Any ideas?

I guess the server needs more than 30s to start. The startup is slow (lots of imports and initialisation). Usually 30s is enough, but depending on the server, it is imaginable that it would need more time. The timeout is probably configurable. Are you using uvicorn or gunicorn now?

gunicorn

source /home/admin/nomad-oasis/v1.1/$VIRTUALENV/bin/activate
gunicorn "${params[@]}" --worker-class=uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 nomad.app.main:app >> nomad.app.log 2>&1 &
celery worker -l info -A nomad.processing -Q celery,calcs,uploads >> nomad.processing.log 2>&1 &

Edit: Trying out --timeout=120 now.

Increasing timeout worked.

Page https://nomad.warwick.ac.uk/ shows:

info
version: 1.1.0
commit: cc6fb73f
…

API pages work alright.

https://nomad.warwick.ac.uk/nomad-oasis/gui/ gives status code 404. I’m not quite sure if nomad admin ops gui-config worked; it does not throw an error but I also don’t see what files it creates.

Edit: Same for https://nomad.warwick.ac.uk/nomad-oasis/gui/index.html.

I have to check the nomad-lab python package. I don’t think that the gui was build and added there in version 1.1.0. I let you know when I find something.

1 Like

I added in fix in the version 1.1.1 of the python package. You can install this with:

pip install nomad-lab[all]==v1.1.1 --extra-index-url https://gitlab.mpcdf.mpg.de/api/v4/projects/2187/packages/pypi/simple

This should now actually contain the GUI code. At least the index.html should be loadable. You will still need the nginx proxy to use it effectively (the redirect rule to index.html after a 404 is especially important to make most of the gui routes work). If the generated nginx config (described in the old docs) does not work, you can try to adapt the nginx config from the docker-compose parts of the docs.

With 1.1.1 you can also use uvicorn directly (python -m uvicorn --host 0.0.0.0 nomad.app.main:app).

1 Like

Worked and I could log in without any further changes. Thanks for your help!