diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..ad73acce3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM ubuntu:14.04 + +RUN apt-get update && apt-get install -y \ + python2.7 \ + python-dev \ + git \ + python-pip \ + libxml2-dev \ + libxslt1-dev \ + libffi-dev \ + graphviz \ + libpq-dev \ + build-essential \ + gunicorn \ + --no-install-recommends \ + && rm -rf /var/lib/apt/lists/* \ + && mkdir -p /opt/netbox \ + && cd /opt/netbox \ + && git clone --depth 1 https://github.com/digitalocean/netbox.git -b master . \ + && pip install -r requirements.txt \ + && apt-get purge -y --auto-remove git build-essential + +ADD docker/docker-entrypoint.sh /docker-entrypoint.sh + +ENTRYPOINT [ "/docker-entrypoint.sh" ] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..e280b95ff --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,55 @@ +version: '2' + +services: + postgres: + image: postgres:9.6 + container_name: postgres + environment: + POSTGRES_USER: netbox + POSTGRES_PASSWORD: J5brHrAXFLQSif0K + POSTGRES_DB: netbox + netbox: + build: . + links: + - postgres + container_name: netbox + depends_on: + - postgres + environment: + SUPERUSER_NAME: admin + SUPERUSER_EMAIL: admin@example.com + SUPERUSER_PASSWORD: admin + ALLOWED_HOSTS: localhost + DB_NAME: netbox + DB_USER: netbox + DB_PASSWORD: J5brHrAXFLQSif0K + DB_HOST: postgres + SECRET_KEY: r8OwDznj!!dci#P9ghmRfdu1Ysxm0AiPeDCQhKE+N_rClfWNj + EMAIL_SERVER: localhost + EMAIL_PORT: 25 + EMAIL_USERNAME: foo + EMAIL_PASSWORD: bar + EMAIL_TIMEOUT: 10 + EMAIL_FROM: netbox@bar.com + NETBOX_USERNAME: guest + NETBOX_PASSWORD: guest + volumes: + - $PWD/netbox/netbox/configuration.docker.py:/opt/netbox/netbox/netbox/configuration.py:ro + - $PWD/docker/gunicorn_config.py:/opt/netbox/gunicorn_config.py:ro + - netbox-static-files:/opt/netbox/netbox/static + nginx: + image: nginx:1.11.1-alpine + links: + - netbox + container_name: nginx + depends_on: + - netbox + ports: + - 80:80 + volumes: + - $PWD/docker/nginx.conf:/etc/nginx/nginx.conf:ro + volumes_from: + - netbox +volumes: + netbox-static-files: + driver: local diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh new file mode 100755 index 000000000..53e52ef04 --- /dev/null +++ b/docker/docker-entrypoint.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -e + +# run db migrations (retry on error) +while ! /opt/netbox/netbox/manage.py migrate 2>&1; do + sleep 5 +done + +# create superuser silently +if [[ -z ${SUPERUSER_NAME} || -z ${SUPERUSER_EMAIL} || -z ${SUPERUSER_PASSWORD} ]]; then + SUPERUSER_NAME='admin' + SUPERUSER_EMAIL='admin@example.com' + SUPERUSER_PASSWORD='admin' + echo "Using defaults: Username: ${SUPERUSER_NAME}, E-Mail: ${SUPERUSER_EMAIL}, Password: ${SUPERUSER_PASSWORD}" +fi +echo "from django.contrib.auth.models import User; User.objects.create_superuser('${SUPERUSER_NAME}', '${SUPERUSER_EMAIL}', '${SUPERUSER_PASSWORD}')" | python /opt/netbox/netbox/manage.py shell + +# copy static files +/opt/netbox/netbox/manage.py collectstatic --no-input + +# start unicorn +gunicorn --log-level debug --debug --error-logfile /dev/stderr --log-file /dev/stdout -c /opt/netbox/gunicorn_config.py netbox.wsgi diff --git a/docker/gunicorn_config.py b/docker/gunicorn_config.py new file mode 100644 index 000000000..878841ac0 --- /dev/null +++ b/docker/gunicorn_config.py @@ -0,0 +1,5 @@ +command = '/usr/bin/gunicorn' +pythonpath = '/opt/netbox/netbox' +bind = '0.0.0.0:8001' +workers = 3 +user = 'root' diff --git a/docker/nginx.conf b/docker/nginx.conf new file mode 100644 index 000000000..2a794f314 --- /dev/null +++ b/docker/nginx.conf @@ -0,0 +1,35 @@ +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + sendfile on; + tcp_nopush on; + keepalive_timeout 65; + gzip on; + server_tokens off; + + server { + listen 80; + + server_name localhost; + + access_log off; + + location /static/ { + alias /opt/netbox/netbox/static/; + } + + location / { + proxy_pass http://netbox:8001; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"'; + } + } +} diff --git a/docs/getting-started-docker.md b/docs/getting-started-docker.md new file mode 100644 index 000000000..c5de5bbf1 --- /dev/null +++ b/docs/getting-started-docker.md @@ -0,0 +1,54 @@ +

Getting Started with NetBox and Docker

+ +This guide assumes that the latest versions of [Docker](https://www.docker.com/) and [docker-compose](https://docs.docker.com/compose/) are already installed in your host. + +# Quickstart + +To get NetBox up and running: + +``` +git clone https://github.com/digitalocean/netbox.git +cd netbox +docker-compose up -d +``` + +The application will be available on http://localhost/ after a few minutes. + +Default credentials: +* user: admin +* password: admin + +# Configuration +You can configure the app at runtime using variables (see docker-compose.yml). + +Possible environment variables: + +* SUPERUSER_NAME +* SUPERUSER_EMAIL +* SUPERUSER_PASSWORD +* ALLOWED_HOSTS +* DB_NAME +* DB_USER +* DB_PASSWORD +* DB_HOST +* DB_PORT +* SECRET_KEY +* EMAIL_SERVER +* EMAIL_PORT +* EMAIL_USERNAME +* EMAIL_PASSWORD +* EMAIL_TIMEOUT +* EMAIL_FROM +* LOGIN_REQUIRED +* MAINTENANCE_MODE +* NETBOX_USERNAME +* NETBOX_PASSWORD +* PAGINATE_COUNT +* TIME_ZONE +* DATE_FORMAT +* SHORT_DATE_FORMAT +* TIME_FORMAT +* SHORT_TIME_FORMAT +* DATETIME_FORMAT +* SHORT_DATETIME_FORMAT + diff --git a/netbox/netbox/configuration.docker.py b/netbox/netbox/configuration.docker.py new file mode 100644 index 000000000..6906ab1b4 --- /dev/null +++ b/netbox/netbox/configuration.docker.py @@ -0,0 +1,75 @@ +import os +######################### +# # +# Required settings # +# # +######################### + +# This is a list of valid fully-qualified domain names (FQDNs) for the NetBox server. NetBox will not permit write +# access to the server via any other hostnames. The first FQDN in the list will be treated as the preferred name. +# +# Example: ALLOWED_HOSTS = ['netbox.example.com', 'netbox.internal.local'] +ALLOWED_HOSTS = [os.environ.get('ALLOWED_HOSTS', '')] + +# PostgreSQL database configuration. +DATABASE = { + 'NAME': os.environ.get('DB_NAME', 'netbox'), # Database name + 'USER': os.environ.get('DB_USER', ''), # PostgreSQL username + 'PASSWORD': os.environ.get('DB_PASSWORD', ''), # PostgreSQL password + 'HOST': os.environ.get('DB_HOST', 'localhost'), # Database server + 'PORT': os.environ.get('DB_PORT', ''), # Database port (leave blank for default) +} + +# This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file. +# For optimal security, SECRET_KEY should be at least 50 characters in length and contain a mix of letters, numbers, and +# symbols. NetBox will not run without this defined. For more information, see +# https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-SECRET_KEY +SECRET_KEY = os.environ.get('SECRET_KEY', '') + +######################### +# # +# Optional settings # +# # +######################### + +# Specify one or more name and email address tuples representing NetBox administrators. These people will be notified of +# application errors (assuming correct email settings are provided). +ADMINS = [ + # ['John Doe', 'jdoe@example.com'], +] + +# Email settings +EMAIL = { + 'SERVER': os.environ.get('EMAIL_SERVER', 'localhost'), + 'PORT': os.environ.get('EMAIL_PORT', 25), + 'USERNAME': os.environ.get('EMAIL_USERNAME', ''), + 'PASSWORD': os.environ.get('EMAIL_PASSWORD', ''), + 'TIMEOUT': os.environ.get('EMAIL_TIMEOUT', 10), # seconds + 'FROM_EMAIL': os.environ.get('EMAIL_FROM', ''), +} + +# Setting this to True will permit only authenticated users to access any part of NetBox. By default, anonymous users +# are permitted to access most data in NetBox (excluding secrets) but not make any changes. +LOGIN_REQUIRED = os.environ.get('LOGIN_REQUIRED', False) + +# Setting this to True will display a "maintenance mode" banner at the top of every page. +MAINTENANCE_MODE = os.environ.get('MAINTENANCE_MODE', False) + +# Credentials that NetBox will use to access live devices. +NETBOX_USERNAME = os.environ.get('NETBOX_USERNAME', '') +NETBOX_PASSWORD = os.environ.get('NETBOX_PASSWORD', '') + +# Determine how many objects to display per page within a list. (Default: 50) +PAGINATE_COUNT = os.environ.get('PAGINATE_COUNT', 50) + +# Time zone (default: UTC) +TIME_ZONE = os.environ.get('TIME_ZONE', 'UTC') + +# Date/time formatting. See the following link for supported formats: +# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date +DATE_FORMAT = os.environ.get('DATE_FORMAT', 'N j, Y') +SHORT_DATE_FORMAT = os.environ.get('SHORT_DATE_FORMAT', 'Y-m-d') +TIME_FORMAT = os.environ.get('TIME_FORMAT', 'g:i a') +SHORT_TIME_FORMAT = os.environ.get('SHORT_TIME_FORMAT', 'H:i:s') +DATETIME_FORMAT = os.environ.get('DATETIME_FORMAT', 'N j, Y g:i a') +SHORT_DATETIME_FORMAT = os.environ.get('SHORT_DATETIME_FORMAT', 'Y-m-d H:i')