Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nginx unit #361

Merged
merged 1 commit into from
Jan 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 /
cimnine marked this conversation as resolved.
Show resolved Hide resolved
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 \
tobiasge marked this conversation as resolved.
Show resolved Hide resolved
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