-
Notifications
You must be signed in to change notification settings - Fork 63
Installation with Docker
Installing and running NEMO with Docker is a quick and easy way to run a production version of NEMO. The benefit of using Docker is that you can skip installing the Python interpreter, package dependencies, and setting environment variables. These things are all included with the image. The NEMO Docker image is hosted on Docker Hub, and you can download it using this command:
docker pull nanofab/nemo
NEMO requires certain runtime information to be available before running the container.
Below is a template for NEMO settings that would be suitable for production. The settings must be customized appropriately for your organization. This is the single most important file for NEMO to run properly, and you should take your time to ensure it is correct. Furthermore, it's probably the most likely place where things can go wrong when configured improperly. So grab a coffee, take your time, and be thorough when crafting this file for your organization. In order to make things easier, several methods are described below to test your configuration and ensure it's working properly.
The settings reference particular locations on disk that must exist, and external services that must be available for NEMO to work properly. A single, consolidated directory that contains all NEMO runtime information is recommended. Here is the suggested directory structure and contents:
nemo/
|
|--- logs/ # Optional: store all log files. (Recommended approach: don't store logs locally... instead, send them to a central logging server via syslog so your disk never overflows)
|--- media/ # Images and files uploaded to NEMO are stored here
|--- secrets/ # Contains all passwords, certificates, and keys that NEMO uses
| |--- nemo.example.org.key # Private TLS key used for encryption
| |--- nemo.example.org.crt # Public TLS certificate, signed by a certificate authority
| |--- Other certificates # Other certificates, such as public TLS certs for email or LDAPS authentication
|--- static/ # JavaScript, images, and CSS
|--- settings.py # NEMO settings file
|--- sqlite.db # SQLite database - this is automatically created by NEMO (see deployment instructions)
# -------------------- Django settings for NEMO --------------------
# Customize these to suit your needs. Documentation can be found at:
# https://docs.djangoproject.com/en/1.11/ref/settings/
# Core settings
# DANGER: SETTING "DEBUG = True" ON A PRODUCTION SYSTEM IS EXTREMELY DANGEROUS.
# ONLY SET "DEBUG = True" FOR DEVELOPMENT AND TESTING!!!
DEBUG = False
AUTH_USER_MODEL = 'NEMO.User'
WSGI_APPLICATION = 'NEMO.wsgi.application'
ROOT_URLCONF = 'NEMO.urls'
# Information security
SESSION_COOKIE_AGE = 2419200 # 2419200 seconds == 4 weeks
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_AGE = None
CSRF_USE_SESSIONS = False
X_FRAME_OPTIONS = 'DENY'
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_SECONDS = 15768000
SECURE_SSL_REDIRECT = True
# Authentication
LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'login'
# Date and time formats
DATETIME_FORMAT = "l, F jS, Y @ g:i A"
DATE_FORMAT = "m/d/Y"
TIME_FORMAT = "g:i A"
DATETIME_INPUT_FORMATS = ['%m/%d/%Y %I:%M %p']
DATE_INPUT_FORMATS = ['%m/%d/%Y']
TIME_INPUT_FORMATS = ['%I:%M %p']
USE_I18N = False
USE_L10N = False
USE_TZ = True
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.humanize',
'NEMO',
'rest_framework',
'django_filters',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.common.BrokenLinkEmailsMiddleware',
'NEMO.middleware.DeviceDetectionMiddleware',
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'NEMO.context_processors.hide_logout_button', # Add a 'request context processor' in order to figure out whether to display the logout button. If the site is configured to use the LDAP authentication backend then we want to provide a logoff button (in the menu bar). Otherwise the Kerberos authentication backend is used and no logoff button is necessary.
'NEMO.context_processors.device', # Informs the templating engine whether the template is being rendered for a desktop or mobile device.
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# -------------------- Third party Django addons for NEMO --------------------
# These are third party capabilities that NEMO employs. They are documented on
# the respective project sites. Only customize these if you know what you're doing.
# Django REST framework:
# http://www.django-rest-framework.org/
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('NEMO.permissions.BillingAPI',),
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 1000,
}
# ------------ Organization specific settings (officially supported by Django) ------------
# Customize these to suit your needs. Documentation can be found at:
# https://docs.djangoproject.com/en/1.11/ref/settings/
ALLOWED_HOSTS = [
'nemo.example.org',
]
SERVER_EMAIL = 'NEMO Server Administrator <[email protected]>'
ADMINS = [
('System administrator', '[email protected]'),
]
MANAGERS = ADMINS
EMAIL_HOST = 'mail.example.org'
EMAIL_PORT = 25
TIME_ZONE = 'America/New_York'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'sqlite.db',
}
}
STATIC_ROOT = '/nemo/static/'
STATIC_URL = '/static/'
MEDIA_ROOT = '/nemo/media/'
MEDIA_URL = '/media/'
# Make this unique, and don't share it with anybody.
SECRET_KEY = '' # Generate this for yourself. You can use `nemo generate_secret_key` to help
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'mail_admins': {
'level': 'INFO',
'class': 'django.utils.log.AdminEmailHandler'
},
'error_file': {
'level': 'WARNING',
'class': 'logging.FileHandler',
'filename': '/nemo/logs/django_error.log'
},
'security_file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '/nemo/logs/django_security.log'
},
},
'loggers': {
'django.request': {
'handlers': ['mail_admins', 'error_file'],
'level': 'WARNING',
'propagate': True,
},
'django.security': {
'handlers': ['mail_admins', 'security_file'],
'level': 'WARNING',
'propagate': True,
},
}
}
# ------------ Organization specific settings (NEMO specific; NOT supported by Django) ------------
# Customize these to suit your needs
# When true, all available URLs and NEMO functionality is enabled.
# When false, conditional URLs are removed to reduce the attack surface of NEMO.
# Reduced functionality for NEMO is desirable for the public facing version
# of the site in order to mitigate security risks.
ALLOW_CONDITIONAL_URLS = True
# There are two options to authenticate users:
# 1) A decoupled "REMOTE_USER" method (such as Kerberos authentication from a reverse proxy)
# 2) LDAP authentication from NEMO itself
AUTHENTICATION_BACKENDS = ['NEMO.views.authentication.LDAPAuthenticationBackend']
# Specify your list of LDAP authentication servers only if you choose to use LDAP authentication
LDAP_SERVERS = [
{
'url': 'ldap.another.org',
'domain': 'ANOTHER',
'certificate': '/nemo/secrets/root.crt',
},
{
'url': 'ldap.example.org',
'domain': 'EXAMPLE',
'certificate': '/nemo/secrets/root.crt',
},
]
# NEMO can integrate with a custom Identity Service to manage user accounts on
# related computer systems, which streamlines user onboarding and offboarding.
IDENTITY_SERVICE = {
'available': False,
'url': 'https://identity.example.org/',
'domains': ['EXAMPLE', 'ANOTHER'],
}
NEMO comes with static files, such as JavaScript and CSS, to improve the look and feel of the website. There are also static files included with the Django web framework, used in the /admin/
section of the site. These static files are dispersed throughout the source tree, and can be collected into a single place by specifying STATIC_ROOT
in settings.py
. You will need to specify a location that is exposed as a Docker volume, so that the files can be served by a reverse proxy and static content server. The recommended default location is STATIC_ROOT = '/nemo/static/'
. Then collect the files using this command:
docker run --volume /home/user/nemo:/nemo nanofab/nemo django-admin collectstatic
Now that NEMO has been installed and configured, you'll need to create the database. An SQLite database will be suitable for most organizations. If your organization has hundreds of concurrent NEMO users then consider using PostgreSQL. The procedure to construct the database is the same for SQLite and Postgres:
docker run --volume /home/user/nemo:/nemo nanofab/nemo bash -c "django-admin makemigrations NEMO && django-admin migrate"
If you are using SQLite, the database file should now exist. (Recall that the location of the database file is specified in settings.py
.)
You will need to log in to NEMO in order to access and manage it. Create a "super user" with this command:
docker run --interactive --tty --volume /home/user/nemo:/nemo nanofab/nemo django-admin createsuperuser
You will be prompted for a username, first name, last name, email address, and password. Enter the appropriate information. Note, that even though you enter a password, NEMO is designed to not store passwords in the database, therefore the password you enter is discarded. It will not work when you try to log in. NEMO relies exclusively on external authentication sources (such as LDAP or Kerberos) for authentication. Usernames are stored in NEMO, and these are authenticated against the external authentication source(s). So, your NEMO username must match the username of the external authentication source.
You can run the NEMO Docker container now that the NEMO runtime information exists:
docker run --detach --publish 8000:8000 --volume /home/user/nemo:/nemo nanofab/nemo
The --volume
option mounts your NEMO runtime directory /home/user/nemo/
to the container at /nemo/
; customize this path to suit your needs. Port 8000 is published to the host machine, and you can use a reverse proxy to expose NEMO on HTTPS port 443.