Skip to content

Commit

Permalink
Merge pull request #361 from tobiasge/nginx-unit
Browse files Browse the repository at this point in the history
Use Nginx Unit to serve the application
  • Loading branch information
tobiasge authored Jan 15, 2021
2 parents 380cb77 + d273391 commit 742560c
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 136 deletions.
10 changes: 0 additions & 10 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,3 @@ If your log is very long, create a Gist instead (and post the link to it): https
```text
LOG LOG LOG
```

The output of `docker-compose logs nginx`:
<!--
Only if you have gotten a 5xx http error, else delete this section.
If your log is very long, create a Gist instead (and post the link to it): https://gist.github.com
-->

```text
LOG LOG LOG
```
2 changes: 1 addition & 1 deletion .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- ./build.sh develop
docker_from:
- '' # use the default of the build script
# - python:3.10-rc-alpine # disable until dependencies work
- alpine:edge
fail-fast: false
runs-on: ubuntu-latest
name: Builds new Netbox Docker Images
Expand Down
48 changes: 20 additions & 28 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,15 @@ RUN apk add --no-cache \
libffi-dev \
libxslt-dev \
openldap-dev \
postgresql-dev

WORKDIR /install

RUN pip install --prefix="/install" --no-warn-script-location \
# gunicorn is used for launching netbox
gunicorn \
greenlet \
eventlet \
# napalm is used for gathering information from network devices
napalm \
# ruamel is used in startup_scripts
'ruamel.yaml>=0.15,<0.16' \
# django_auth_ldap is required for ldap
django_auth_ldap \
# django-storages was introduced in 2.7 and is optional
django-storages
postgresql-dev \
py3-pip \
python3-dev \
&& python3 -m venv /opt/netbox/venv \
&& /opt/netbox/venv/bin/python3 -m pip install --upgrade pip setuptools

ARG NETBOX_PATH
COPY ${NETBOX_PATH}/requirements.txt /
RUN pip install --prefix="/install" --no-warn-script-location -r /requirements.txt
COPY ${NETBOX_PATH}/requirements.txt requirements-container.txt /
RUN /opt/netbox/venv/bin/pip install -r /requirements.txt -r /requirements-container.txt

###
# Main stage
Expand All @@ -44,42 +32,46 @@ FROM ${FROM} as main
RUN apk add --no-cache \
bash \
ca-certificates \
curl \
graphviz \
libevent \
libffi \
libjpeg-turbo \
libressl \
libxslt \
postgresql-libs \
ttf-ubuntu-font-family
python3 \
py3-pip \
ttf-ubuntu-font-family \
unit \
unit-python3

WORKDIR /opt

COPY --from=builder /install /usr/local
COPY --from=builder /opt/netbox/venv /opt/netbox/venv

ARG NETBOX_PATH
COPY ${NETBOX_PATH} /opt/netbox

COPY docker/configuration.docker.py /opt/netbox/netbox/netbox/configuration.py
COPY docker/gunicorn_config.py /etc/netbox/
COPY docker/nginx.conf /etc/netbox-nginx/nginx.conf
COPY docker/docker-entrypoint.sh /opt/netbox/docker-entrypoint.sh
COPY docker/launch-netbox.sh /opt/netbox/launch-netbox.sh
COPY startup_scripts/ /opt/netbox/startup_scripts/
COPY initializers/ /opt/netbox/initializers/
COPY configuration/ /etc/netbox/config/
COPY docker/nginx-unit.json /etc/unit/

WORKDIR /opt/netbox/netbox

# Must set permissions for '/opt/netbox/netbox/static' directory
# to g+w so that `./manage.py collectstatic` can be executed during
# container startup.
# Must set permissions for '/opt/netbox/netbox/media' directory
# to g+w so that pictures can be uploaded to netbox.
RUN mkdir static && chmod -R g+w static media
RUN mkdir -p static /opt/unit/state/ /opt/unit/tmp/ \
&& chmod -R g+w media /opt/unit/ \
&& SECRET_KEY="dummy" /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py collectstatic --no-input

ENTRYPOINT [ "/opt/netbox/docker-entrypoint.sh" ]

CMD ["gunicorn", "-c /etc/netbox/gunicorn_config.py", "netbox.wsgi"]
CMD [ "/opt/netbox/launch-netbox.sh" ]

LABEL ORIGINAL_TAG="" \
NETBOX_GIT_BRANCH="" \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ cd netbox-docker
tee docker-compose.override.yml <<EOF
version: '3.4'
services:
nginx:
netbox:
ports:
- 8000:8080
EOF
Expand Down
14 changes: 7 additions & 7 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ if [ "${1}x" == "x" ] || [ "${1}" == "--help" ] || [ "${1}" == "-h" ]; then
echo " DOCKERFILE The name of Dockerfile to use."
echo " Default: Dockerfile"
echo " DOCKER_FROM The base image to use."
echo " Default: 'python:3.9-alpine'"
echo " Default: 'alpine:3.13'"
echo " DOCKER_TARGET A specific target to build."
echo " It's currently not possible to pass multiple targets."
echo " Default: main ldap"
Expand Down Expand Up @@ -106,7 +106,7 @@ else
fi

###
# Variables for fetching the source
# Variables for fetching the Netbox source
###
SRC_ORG="${SRC_ORG-netbox-community}"
SRC_REPO="${SRC_REPO-netbox}"
Expand All @@ -115,10 +115,10 @@ URL="${URL-https://github.com/${SRC_ORG}/${SRC_REPO}.git}"
NETBOX_PATH="${NETBOX_PATH-.netbox}"

###
# Fetching the source
# Fetching the Netbox source
###
if [ "${2}" != "--push-only" ] && [ -z "${SKIP_GIT}" ] ; then
echo "🌐 Checking out '${NETBOX_BRANCH}' of netbox from the url '${URL}' into '${NETBOX_PATH}'"
echo "🌐 Checking out '${NETBOX_BRANCH}' of Netbox from the url '${URL}' into '${NETBOX_PATH}'"
if [ ! -d "${NETBOX_PATH}" ]; then
$DRY git clone -q --depth 10 -b "${NETBOX_BRANCH}" "${URL}" "${NETBOX_PATH}"
fi
Expand All @@ -135,7 +135,7 @@ if [ "${2}" != "--push-only" ] && [ -z "${SKIP_GIT}" ] ; then
$DRY git checkout -qf FETCH_HEAD
$DRY git prune
)
echo "✅ Checked out netbox"
echo "✅ Checked out Netbox"
fi

###
Expand All @@ -157,7 +157,7 @@ fi
# Determining the value for DOCKER_FROM
###
if [ -z "$DOCKER_FROM" ]; then
DOCKER_FROM="python:3.9-alpine"
DOCKER_FROM="alpine:3.13"
fi

###
Expand Down Expand Up @@ -271,7 +271,7 @@ for DOCKER_TARGET in "${DOCKER_TARGETS[@]}"; do

if ! printf '%s\n' "${IMAGES_LAYERS_OLD[@]}" | grep -q -P "^${PYTHON_LAST_LAYER}\$"; then
SHOULD_BUILD="true"
BUILD_REASON="${BUILD_REASON} python"
BUILD_REASON="${BUILD_REASON} alpine"
fi
if [ "${NETBOX_GIT_REF}" != "${NETBOX_GIT_REF_OLD}" ]; then
SHOULD_BUILD="true"
Expand Down
14 changes: 0 additions & 14 deletions docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,9 @@ services:
- ./configuration:/etc/netbox/config:z,ro
- ./reports:/etc/netbox/reports:z,ro
- ./scripts:/etc/netbox/scripts:z,ro
- netbox-nginx-config:/etc/netbox-nginx:z
- netbox-static-files:/opt/netbox/netbox/static:z
- netbox-media-files:/opt/netbox/netbox/media:z
nginx:
command: nginx -c /etc/netbox-nginx/nginx.conf
image: nginx:1.19-alpine
depends_on:
- netbox
ports:
- 8080
volumes:
- netbox-static-files:/opt/netbox/netbox/static:ro
- netbox-nginx-config:/etc/netbox-nginx/:ro
postgres:
image: postgres:12-alpine
env_file: env/postgres.env
Expand All @@ -45,9 +35,5 @@ services:
- redis-server --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose
env_file: env/redis-cache.env
volumes:
netbox-static-files:
driver: local
netbox-nginx-config:
driver: local
netbox-media-files:
driver: local
23 changes: 4 additions & 19 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,19 @@ services:
- ./configuration:/etc/netbox/config:z,ro
- ./reports:/etc/netbox/reports:z,ro
- ./scripts:/etc/netbox/scripts:z,ro
- netbox-nginx-config:/etc/netbox-nginx:z
- netbox-static-files:/opt/netbox/netbox/static:z
- netbox-media-files:/opt/netbox/netbox/media:z
ports:
- "8080"
netbox-worker:
<<: *netbox
depends_on:
- redis
entrypoint:
- python3
- /opt/netbox/venv/bin/python
- /opt/netbox/netbox/manage.py
command:
- rqworker

# nginx
nginx:
command: nginx -c /etc/netbox-nginx/nginx.conf
image: nginx:1.19-alpine
depends_on:
- netbox
ports:
- 8080
volumes:
- netbox-static-files:/opt/netbox/netbox/static:ro
- netbox-nginx-config:/etc/netbox-nginx/:ro
ports: []

# postgres
postgres:
Expand Down Expand Up @@ -66,10 +55,6 @@ services:
env_file: env/redis-cache.env

volumes:
netbox-static-files:
driver: local
netbox-nginx-config:
driver: local
netbox-media-files:
driver: local
netbox-postgres-data:
Expand Down
1 change: 1 addition & 0 deletions docker/configuration.docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import importlib.util
import sys


def _filename(f):
return f.name

Expand Down
6 changes: 3 additions & 3 deletions docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ set -e
# Allows Netbox to be run as non-root users
umask 002

# Load correct Python3 env
source /opt/netbox/venv/bin/activate

# Try to connect to the DB
DB_WAIT_TIMEOUT=${DB_WAIT_TIMEOUT-3}
MAX_DB_WAIT_TIME=${MAX_DB_WAIT_TIME-30}
Expand Down Expand Up @@ -60,9 +63,6 @@ else
echo "import runpy; runpy.run_path('../startup_scripts')" | ./manage.py shell --interface python
fi

# Copy static files
./manage.py collectstatic --no-input

echo "✅ Initialisation is done."

# Launch whatever is passed by docker
Expand Down
8 changes: 0 additions & 8 deletions docker/gunicorn_config.py

This file was deleted.

53 changes: 53 additions & 0 deletions docker/launch-netbox.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash

UNIT_CONFIG="${UNIT_CONFIG-/etc/unit/nginx-unit.json}"
UNIT_SOCKET="/opt/unit/unit.sock"

load_configuration() {
MAX_WAIT=10
WAIT_COUNT=0
while [ ! -S $UNIT_SOCKET ]; do
if [ $WAIT_COUNT -gte $MAX_WAIT ]; then
echo "⚠️ No control socket found; configuration will not be loaded."
return 1
fi

WAIT_COUNT=$((WAIT_COUNT + 1))
echo "⏳ Waiting for control socket to be created... (${WAIT_COUNT}/${MAX_WAIT})"

sleep 1
done

# even when the control socket exists, it does not mean unit has finished initialisation
# this curl call will get a reply once unit is fully launched
curl --silent --output /dev/null --request GET --unix-socket $UNIT_SOCKET http://localhost/

echo "⚙️ Applying configuration from $UNIT_CONFIG";

RESP_CODE=$(curl \
--silent \
--output /dev/null \
--write-out '%{http_code}' \
--request PUT \
--data-binary "@${UNIT_CONFIG}" \
--unix-socket $UNIT_SOCKET \
http://localhost/config
)
if [ "$RESP_CODE" != "200" ]; then
echo "⚠️ Could no load Unit configuration"
kill "$(cat /opt/unit/unit.pid)"
return 1
fi

echo "✅ Unit configuration loaded successfully"
}

load_configuration &

exec unitd \
--no-daemon \
--control unix:$UNIT_SOCKET \
--pid /opt/unit/unit.pid \
--log /dev/stdout \
--state /opt/unit/state/ \
--tmp /opt/unit/tmp/
40 changes: 40 additions & 0 deletions docker/nginx-unit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"listeners": {
"*:8080": {
"pass": "routes"
}
},

"routes": [
{
"match": {
"uri": "/static/*"
},
"action": {
"share": "/opt/netbox/netbox"
}
},

{
"action": {
"pass": "applications/netbox"
}
}
],

"applications": {
"netbox": {
"type": "python 3",
"path": "/opt/netbox/netbox/",
"module": "netbox.wsgi",
"home": "/opt/netbox/venv",
"processes": {
"max": 4,
"spare": 1,
"idle_timeout": 120
}
}
},

"access_log": "/dev/stdout"
}
Loading

0 comments on commit 742560c

Please sign in to comment.