commit
93017f150e
1
.github/workflows/push.yml
vendored
1
.github/workflows/push.yml
vendored
@ -55,6 +55,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
env:
|
env:
|
||||||
GH_ACTION: enable
|
GH_ACTION: enable
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
IMAGE_NAMES: docker.io/netboxcommunity/netbox
|
IMAGE_NAMES: docker.io/netboxcommunity/netbox
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Builds new NetBox Docker Images
|
name: Builds new NetBox Docker Images
|
||||||
|
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@ -25,6 +25,7 @@ jobs:
|
|||||||
name: Builds new NetBox Docker Images
|
name: Builds new NetBox Docker Images
|
||||||
env:
|
env:
|
||||||
GH_ACTION: enable
|
GH_ACTION: enable
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
IMAGE_NAMES: docker.io/netboxcommunity/netbox quay.io/netboxcommunity/netbox ghcr.io/netbox-community/netbox
|
IMAGE_NAMES: docker.io/netboxcommunity/netbox quay.io/netboxcommunity/netbox ghcr.io/netbox-community/netbox
|
||||||
steps:
|
steps:
|
||||||
- id: source-checkout
|
- id: source-checkout
|
||||||
@ -32,7 +33,7 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- id: set-netbox-docker-version
|
- id: set-netbox-docker-version
|
||||||
name: Get Version of NetBox Docker
|
name: Get Version of NetBox Docker
|
||||||
run: echo "::set-output name=version::$(cat VERSION)"
|
run: echo "version=$(cat VERSION)" >>"$GITHUB_OUTPUT"
|
||||||
shell: bash
|
shell: bash
|
||||||
- id: qemu-setup
|
- id: qemu-setup
|
||||||
name: Set up QEMU
|
name: Set up QEMU
|
||||||
|
@ -66,8 +66,8 @@ RUN export DEBIAN_FRONTEND=noninteractive \
|
|||||||
&& apt-get update -qq \
|
&& apt-get update -qq \
|
||||||
&& apt-get install \
|
&& apt-get install \
|
||||||
--yes -qq --no-install-recommends \
|
--yes -qq --no-install-recommends \
|
||||||
unit=1.27.0-1~jammy \
|
unit=1.29.1-1~jammy \
|
||||||
unit-python3.10=1.27.0-1~jammy \
|
unit-python3.10=1.29.1-1~jammy \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY --from=builder /opt/netbox/venv /opt/netbox/venv
|
COPY --from=builder /opt/netbox/venv /opt/netbox/venv
|
||||||
@ -94,7 +94,7 @@ RUN mkdir -p static /opt/unit/state/ /opt/unit/tmp/ \
|
|||||||
--config-file /opt/netbox/mkdocs.yml --site-dir /opt/netbox/netbox/project-static/docs/ \
|
--config-file /opt/netbox/mkdocs.yml --site-dir /opt/netbox/netbox/project-static/docs/ \
|
||||||
&& SECRET_KEY="dummy" /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py collectstatic --no-input
|
&& SECRET_KEY="dummy" /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py collectstatic --no-input
|
||||||
|
|
||||||
ENV LANG=C.UTF-8 PATH=/opt/netbox/venv/bin:$PATH
|
ENV LANG=C.utf8 PATH=/opt/netbox/venv/bin:$PATH
|
||||||
ENTRYPOINT [ "/usr/bin/tini", "--" ]
|
ENTRYPOINT [ "/usr/bin/tini", "--" ]
|
||||||
|
|
||||||
CMD [ "/opt/netbox/docker-entrypoint.sh", "/opt/netbox/launch-netbox.sh" ]
|
CMD [ "/opt/netbox/docker-entrypoint.sh", "/opt/netbox/launch-netbox.sh" ]
|
||||||
|
20
README.md
20
README.md
@ -3,7 +3,7 @@
|
|||||||
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/netbox-community/netbox-docker)][github-release]
|
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/netbox-community/netbox-docker)][github-release]
|
||||||
[![GitHub stars](https://img.shields.io/github/stars/netbox-community/netbox-docker)][github-stargazers]
|
[![GitHub stars](https://img.shields.io/github/stars/netbox-community/netbox-docker)][github-stargazers]
|
||||||
![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed-raw/netbox-community/netbox-docker)
|
![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed-raw/netbox-community/netbox-docker)
|
||||||
![Github release workflow](https://img.shields.io/github/workflow/status/netbox-community/netbox-docker/release)
|
![Github release workflow](https://img.shields.io/github/actions/workflow/status/netbox-community/netbox-docker/release.yml?branch=release)
|
||||||
![Docker Pulls](https://img.shields.io/docker/pulls/netboxcommunity/netbox)
|
![Docker Pulls](https://img.shields.io/docker/pulls/netboxcommunity/netbox)
|
||||||
[![GitHub license](https://img.shields.io/github/license/netbox-community/netbox-docker)][netbox-docker-license]
|
[![GitHub license](https://img.shields.io/github/license/netbox-community/netbox-docker)][netbox-docker-license]
|
||||||
|
|
||||||
@ -40,19 +40,21 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 8000:8080
|
- 8000:8080
|
||||||
EOF
|
EOF
|
||||||
docker-compose pull
|
docker compose pull
|
||||||
docker-compose up
|
docker compose up
|
||||||
```
|
```
|
||||||
|
|
||||||
The whole application will be available after a few minutes.
|
The whole application will be available after a few minutes.
|
||||||
Open the URL `http://0.0.0.0:8000/` in a web-browser.
|
Open the URL `http://0.0.0.0:8000/` in a web-browser.
|
||||||
You should see the NetBox homepage.
|
You should see the NetBox homepage.
|
||||||
In the top-right corner you can login.
|
|
||||||
The default credentials are:
|
|
||||||
|
|
||||||
* Username: **admin**
|
To create the first admin user run this command:
|
||||||
* Password: **admin**
|
|
||||||
* API Token: **0123456789abcdef0123456789abcdef01234567**
|
```bash
|
||||||
|
docker compose exec netbox /opt/netbox/netbox/manage.py createsuperuser
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need to restart Netbox from an empty database often, you can also set the `SUPERUSER_*` variables in your `docker-compose.override.yml` as shown in the example.
|
||||||
|
|
||||||
[wiki-getting-started]: https://github.com/netbox-community/netbox-docker/wiki/Getting-Started
|
[wiki-getting-started]: https://github.com/netbox-community/netbox-docker/wiki/Getting-Started
|
||||||
|
|
||||||
@ -123,7 +125,7 @@ This project relies only on _Docker_ and _docker-compose_ meeting these requirem
|
|||||||
* The _containerd version_ must be at least `1.5.6`.
|
* The _containerd version_ must be at least `1.5.6`.
|
||||||
* The _docker-compose version_ must be at least `1.28.0`.
|
* The _docker-compose version_ must be at least `1.28.0`.
|
||||||
|
|
||||||
To check the version installed on your system run `docker --version` and `docker-compose --version`.
|
To check the version installed on your system run `docker --version` and `docker compose version`.
|
||||||
|
|
||||||
## Updating
|
## Updating
|
||||||
|
|
||||||
|
9
build-functions/check-commands.sh
Normal file
9
build-functions/check-commands.sh
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
NEEDED_COMMANDS="curl jq docker skopeo"
|
||||||
|
for c in $NEEDED_COMMANDS; do
|
||||||
|
if ! command -v "$c" &>/dev/null; then
|
||||||
|
echo "⚠️ '$c' is not installed. Can't proceed with build."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
@ -1,82 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Retrieves image configuration from public images in DockerHub
|
|
||||||
# Functions from https://gist.github.com/cirocosta/17ea17be7ac11594cb0f290b0a3ac0d1
|
|
||||||
# Optimised for our use case
|
|
||||||
|
|
||||||
get_image_label() {
|
get_image_label() {
|
||||||
local label=$1
|
local label=$1
|
||||||
local image=$2
|
local image=$2
|
||||||
local tag=$3
|
skopeo inspect "docker://$image" | jq -r ".Labels[\"$label\"]"
|
||||||
local token
|
|
||||||
token=$(_get_token "$image")
|
|
||||||
local digest
|
|
||||||
digest=$(_get_digest "$image" "$tag" "$token")
|
|
||||||
local retval="null"
|
|
||||||
if [ "$digest" != "null" ]; then
|
|
||||||
retval=$(_get_image_configuration "$image" "$token" "$digest" "$label")
|
|
||||||
fi
|
|
||||||
echo "$retval"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get_image_layers() {
|
get_image_layers() {
|
||||||
local image=$1
|
local image=$1
|
||||||
local tag=$2
|
skopeo inspect "docker://$image" | jq -r ".Layers"
|
||||||
local token
|
|
||||||
token=$(_get_token "$image")
|
|
||||||
_get_layers "$image" "$tag" "$token"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get_image_last_layer() {
|
get_image_last_layer() {
|
||||||
local image=$1
|
local image=$1
|
||||||
local tag=$2
|
skopeo inspect "docker://$image" | jq -r ".Layers | last"
|
||||||
local token
|
|
||||||
token=$(_get_token "$image")
|
|
||||||
local layers
|
|
||||||
mapfile -t layers < <(_get_layers "$image" "$tag" "$token")
|
|
||||||
echo "${layers[-1]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_get_image_configuration() {
|
|
||||||
local image=$1
|
|
||||||
local token=$2
|
|
||||||
local digest=$3
|
|
||||||
local label=$4
|
|
||||||
curl \
|
|
||||||
--silent \
|
|
||||||
--location \
|
|
||||||
--header "Authorization: Bearer $token" \
|
|
||||||
"https://registry-1.docker.io/v2/$image/blobs/$digest" |
|
|
||||||
jq -r ".config.Labels.\"$label\""
|
|
||||||
}
|
|
||||||
|
|
||||||
_get_token() {
|
|
||||||
local image=$1
|
|
||||||
curl \
|
|
||||||
--silent \
|
|
||||||
"https://auth.docker.io/token?scope=repository:$image:pull&service=registry.docker.io" |
|
|
||||||
jq -r '.token'
|
|
||||||
}
|
|
||||||
|
|
||||||
_get_digest() {
|
|
||||||
local image=$1
|
|
||||||
local tag=$2
|
|
||||||
local token=$3
|
|
||||||
curl \
|
|
||||||
--silent \
|
|
||||||
--header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
|
|
||||||
--header "Authorization: Bearer $token" \
|
|
||||||
"https://registry-1.docker.io/v2/$image/manifests/$tag" |
|
|
||||||
jq -r '.config.digest'
|
|
||||||
}
|
|
||||||
|
|
||||||
_get_layers() {
|
|
||||||
local image=$1
|
|
||||||
local tag=$2
|
|
||||||
local token=$3
|
|
||||||
curl \
|
|
||||||
--silent \
|
|
||||||
--header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
|
|
||||||
--header "Authorization: Bearer $token" \
|
|
||||||
"https://registry-1.docker.io/v2/$image/manifests/$tag" |
|
|
||||||
jq -r '.layers[].digest'
|
|
||||||
}
|
}
|
||||||
|
@ -19,3 +19,14 @@ gh_env() {
|
|||||||
echo "${@}" >>"${GITHUB_ENV}"
|
echo "${@}" >>"${GITHUB_ENV}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
# Prints the output to the file defined in ${GITHUB_OUTPUT}.
|
||||||
|
# Only executes if ${GH_ACTION} is defined.
|
||||||
|
# Example Usage: gh_env "FOO_VAR=bar_value"
|
||||||
|
###
|
||||||
|
gh_out() {
|
||||||
|
if [ -n "${GH_ACTION}" ]; then
|
||||||
|
echo "${@}" >>"$GITHUB_OUTPUT"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
@ -1,26 +1,27 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Builds the latest released version
|
# Builds the latest released version
|
||||||
|
|
||||||
|
# Check if we have everything needed for the build
|
||||||
|
source ./build-functions/check-commands.sh
|
||||||
|
|
||||||
|
source ./build-functions/gh-functions.sh
|
||||||
|
|
||||||
echo "▶️ $0 $*"
|
echo "▶️ $0 $*"
|
||||||
|
|
||||||
###
|
CURL_ARGS=(
|
||||||
# Check for the jq library needed for parsing JSON
|
--silent
|
||||||
###
|
)
|
||||||
if ! command -v jq; then
|
|
||||||
echo "⚠️ jq command missing from \$PATH!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
###
|
###
|
||||||
# Checking for the presence of GITHUB_OAUTH_CLIENT_ID
|
# Checking for the presence of GITHUB_TOKEN
|
||||||
# and GITHUB_OAUTH_CLIENT_SECRET
|
|
||||||
###
|
###
|
||||||
if [ -n "${GITHUB_OAUTH_CLIENT_ID}" ] && [ -n "${GITHUB_OAUTH_CLIENT_SECRET}" ]; then
|
if [ -n "${GITHUB_TOKEN}" ]; then
|
||||||
echo "🗝 Performing authenticated Github API calls."
|
echo "🗝 Performing authenticated Github API calls."
|
||||||
GITHUB_OAUTH_PARAMS="client_id=${GITHUB_OAUTH_CLIENT_ID}&client_secret=${GITHUB_OAUTH_CLIENT_SECRET}"
|
CURL_ARGS+=(
|
||||||
|
--header "Authorization: Bearer ${GITHUB_TOKEN}"
|
||||||
|
)
|
||||||
else
|
else
|
||||||
echo "🕶 Performing unauthenticated Github API calls. This might result in lower Github rate limits!"
|
echo "🕶 Performing unauthenticated Github API calls. This might result in lower Github rate limits!"
|
||||||
GITHUB_OAUTH_PARAMS=""
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
###
|
###
|
||||||
@ -42,31 +43,27 @@ fi
|
|||||||
###
|
###
|
||||||
ORIGINAL_GITHUB_REPO="netbox-community/netbox"
|
ORIGINAL_GITHUB_REPO="netbox-community/netbox"
|
||||||
GITHUB_REPO="${GITHUB_REPO-$ORIGINAL_GITHUB_REPO}"
|
GITHUB_REPO="${GITHUB_REPO-$ORIGINAL_GITHUB_REPO}"
|
||||||
URL_RELEASES="https://api.github.com/repos/${GITHUB_REPO}/releases?${GITHUB_OAUTH_PARAMS}"
|
URL_RELEASES="https://api.github.com/repos/${GITHUB_REPO}/releases"
|
||||||
|
|
||||||
# Composing the JQ commans to extract the most recent version number
|
# Composing the JQ commans to extract the most recent version number
|
||||||
JQ_LATEST="group_by(.prerelease) | .[] | sort_by(.published_at) | reverse | .[0] | select(.prerelease==${PRERELEASE-false}) | .tag_name"
|
JQ_LATEST="group_by(.prerelease) | .[] | sort_by(.published_at) | reverse | .[0] | select(.prerelease==${PRERELEASE-false}) | .tag_name"
|
||||||
|
|
||||||
CURL="curl -sS"
|
CURL="curl"
|
||||||
|
|
||||||
# Querying the Github API to fetch the most recent version number
|
# Querying the Github API to fetch the most recent version number
|
||||||
VERSION=$($CURL "${URL_RELEASES}" | jq -r "${JQ_LATEST}")
|
VERSION=$($CURL "${CURL_ARGS[@]}" "${URL_RELEASES}" | jq -r "${JQ_LATEST}" 2>/dev/null)
|
||||||
|
|
||||||
###
|
###
|
||||||
# Check if the prerelease version is actually higher than stable version
|
# Check if the prerelease version is actually higher than stable version
|
||||||
###
|
###
|
||||||
if [ "${PRERELEASE}" == "true" ]; then
|
if [ "${PRERELEASE}" == "true" ]; then
|
||||||
JQ_STABLE="group_by(.prerelease) | .[] | sort_by(.published_at) | reverse | .[0] | select(.prerelease==false) | .tag_name"
|
JQ_STABLE="group_by(.prerelease) | .[] | sort_by(.published_at) | reverse | .[0] | select(.prerelease==false) | .tag_name"
|
||||||
STABLE_VERSION=$($CURL "${URL_RELEASES}" | jq -r "${JQ_STABLE}")
|
STABLE_VERSION=$($CURL "${CURL_ARGS[@]}" "${URL_RELEASES}" | jq -r "${JQ_STABLE}" 2>/dev/null)
|
||||||
|
|
||||||
# shellcheck disable=SC2003
|
MAJOR_STABLE=$(expr "${STABLE_VERSION}" : 'v\([0-9]\+\)')
|
||||||
MAJOR_STABLE=$(expr match "${STABLE_VERSION}" 'v\([0-9]\+\)')
|
MINOR_STABLE=$(expr "${STABLE_VERSION}" : 'v[0-9]\+\.\([0-9]\+\)')
|
||||||
# shellcheck disable=SC2003
|
MAJOR_UNSTABLE=$(expr "${VERSION}" : 'v\([0-9]\+\)')
|
||||||
MINOR_STABLE=$(expr match "${STABLE_VERSION}" 'v[0-9]\+\.\([0-9]\+\)')
|
MINOR_UNSTABLE=$(expr "${VERSION}" : 'v[0-9]\+\.\([0-9]\+\)')
|
||||||
# shellcheck disable=SC2003
|
|
||||||
MAJOR_UNSTABLE=$(expr match "${VERSION}" 'v\([0-9]\+\)')
|
|
||||||
# shellcheck disable=SC2003
|
|
||||||
MINOR_UNSTABLE=$(expr match "${VERSION}" 'v[0-9]\+\.\([0-9]\+\)')
|
|
||||||
|
|
||||||
if {
|
if {
|
||||||
[ "${MAJOR_STABLE}" -eq "${MAJOR_UNSTABLE}" ] &&
|
[ "${MAJOR_STABLE}" -eq "${MAJOR_UNSTABLE}" ] &&
|
||||||
@ -75,10 +72,7 @@ if [ "${PRERELEASE}" == "true" ]; then
|
|||||||
|
|
||||||
echo "❎ Latest unstable version '${VERSION}' is not higher than the latest stable version '$STABLE_VERSION'."
|
echo "❎ Latest unstable version '${VERSION}' is not higher than the latest stable version '$STABLE_VERSION'."
|
||||||
if [ -z "$DEBUG" ]; then
|
if [ -z "$DEBUG" ]; then
|
||||||
if [ -n "${GH_ACTION}" ]; then
|
gh_out "skipped=true"
|
||||||
echo "::set-output name=skipped::true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo "⚠️ Would exit here with code '0', but DEBUG is enabled."
|
echo "⚠️ Would exit here with code '0', but DEBUG is enabled."
|
||||||
|
35
build.sh
35
build.sh
@ -137,6 +137,9 @@ END_OF_HELP
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check if we have everything needed for the build
|
||||||
|
source ./build-functions/check-commands.sh
|
||||||
|
|
||||||
source ./build-functions/gh-functions.sh
|
source ./build-functions/gh-functions.sh
|
||||||
|
|
||||||
IMAGE_NAMES="${IMAGE_NAMES-docker.io/netboxcommunity/netbox}"
|
IMAGE_NAMES="${IMAGE_NAMES-docker.io/netboxcommunity/netbox}"
|
||||||
@ -170,7 +173,7 @@ if [ "${2}" != "--push-only" ] && [ -z "${SKIP_GIT}" ]; then
|
|||||||
REMOTE_EXISTS=$(git ls-remote --heads --tags "${URL}" "${NETBOX_BRANCH}" | wc -l)
|
REMOTE_EXISTS=$(git ls-remote --heads --tags "${URL}" "${NETBOX_BRANCH}" | wc -l)
|
||||||
if [ "${REMOTE_EXISTS}" == "0" ]; then
|
if [ "${REMOTE_EXISTS}" == "0" ]; then
|
||||||
echo "❌ Remote branch '${NETBOX_BRANCH}' not found in '${URL}'; Nothing to do"
|
echo "❌ Remote branch '${NETBOX_BRANCH}' not found in '${URL}'; Nothing to do"
|
||||||
gh_echo "::set-output name=skipped::true"
|
gh_out "skipped=true"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
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}'"
|
||||||
@ -215,7 +218,7 @@ fi
|
|||||||
# Determining the value for DOCKER_FROM
|
# Determining the value for DOCKER_FROM
|
||||||
###
|
###
|
||||||
if [ -z "$DOCKER_FROM" ]; then
|
if [ -z "$DOCKER_FROM" ]; then
|
||||||
DOCKER_FROM="ubuntu:22.04"
|
DOCKER_FROM="docker.io/ubuntu:22.04"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
###
|
###
|
||||||
@ -300,6 +303,7 @@ if [ -n "${TARGET_DOCKER_SHORT_TAG}" ]; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
FINAL_DOCKER_TAG="${IMAGE_NAME_TAGS[0]}"
|
||||||
gh_env "FINAL_DOCKER_TAG=${IMAGE_NAME_TAGS[0]}"
|
gh_env "FINAL_DOCKER_TAG=${IMAGE_NAME_TAGS[0]}"
|
||||||
|
|
||||||
###
|
###
|
||||||
@ -316,23 +320,17 @@ if [ -z "${GH_ACTION}" ]; then
|
|||||||
# Asuming non Github builds should always proceed
|
# Asuming non Github builds should always proceed
|
||||||
SHOULD_BUILD="true"
|
SHOULD_BUILD="true"
|
||||||
BUILD_REASON="${BUILD_REASON} interactive"
|
BUILD_REASON="${BUILD_REASON} interactive"
|
||||||
elif [[ "${IMAGE_NAME_TAGS[0]}" = docker.io* ]]; then
|
else
|
||||||
source ./build-functions/get-public-image-config.sh
|
source ./build-functions/get-public-image-config.sh
|
||||||
IFS=':' read -ra DOCKER_FROM_SPLIT <<<"${DOCKER_FROM}"
|
echo "Checking labels for '${FINAL_DOCKER_TAG}'"
|
||||||
if ! [[ ${DOCKER_FROM_SPLIT[0]} =~ .*/.* ]]; then
|
BASE_LAST_LAYER=$(get_image_last_layer "${DOCKER_FROM}")
|
||||||
# Need to use "library/..." for images the have no two part name
|
mapfile -t IMAGES_LAYERS_OLD < <(get_image_layers "${FINAL_DOCKER_TAG}")
|
||||||
DOCKER_FROM_SPLIT[0]="library/${DOCKER_FROM_SPLIT[0]}"
|
NETBOX_GIT_REF_OLD=$(get_image_label netbox.git-ref "${FINAL_DOCKER_TAG}")
|
||||||
fi
|
GIT_REF_OLD=$(get_image_label org.opencontainers.image.revision "${FINAL_DOCKER_TAG}")
|
||||||
IFS='/' read -ra ORG_REPO <<<"${IMAGE_NAMES[0]}"
|
|
||||||
echo "Checking labels for '${ORG_REPO[1]}' and '${ORG_REPO[2]}'"
|
|
||||||
BASE_LAST_LAYER=$(get_image_last_layer "${DOCKER_FROM_SPLIT[0]}" "${DOCKER_FROM_SPLIT[1]}")
|
|
||||||
mapfile -t IMAGES_LAYERS_OLD < <(get_image_layers "${ORG_REPO[1]}"/"${ORG_REPO[2]}" "${TAG}")
|
|
||||||
NETBOX_GIT_REF_OLD=$(get_image_label netbox.git-ref "${ORG_REPO[1]}"/"${ORG_REPO[2]}" "${TAG}")
|
|
||||||
GIT_REF_OLD=$(get_image_label org.opencontainers.image.revision "${ORG_REPO[1]}"/"${ORG_REPO[2]}" "${TAG}")
|
|
||||||
|
|
||||||
if ! printf '%s\n' "${IMAGES_LAYERS_OLD[@]}" | grep -q -P "^${BASE_LAST_LAYER}\$"; then
|
if ! printf '%s\n' "${IMAGES_LAYERS_OLD[@]}" | grep -q -P "^${BASE_LAST_LAYER}\$"; then
|
||||||
SHOULD_BUILD="true"
|
SHOULD_BUILD="true"
|
||||||
BUILD_REASON="${BUILD_REASON} debian"
|
BUILD_REASON="${BUILD_REASON} ubuntu"
|
||||||
fi
|
fi
|
||||||
if [ "${NETBOX_GIT_REF}" != "${NETBOX_GIT_REF_OLD}" ]; then
|
if [ "${NETBOX_GIT_REF}" != "${NETBOX_GIT_REF_OLD}" ]; then
|
||||||
SHOULD_BUILD="true"
|
SHOULD_BUILD="true"
|
||||||
@ -342,17 +340,14 @@ elif [[ "${IMAGE_NAME_TAGS[0]}" = docker.io* ]]; then
|
|||||||
SHOULD_BUILD="true"
|
SHOULD_BUILD="true"
|
||||||
BUILD_REASON="${BUILD_REASON} netbox-docker"
|
BUILD_REASON="${BUILD_REASON} netbox-docker"
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
SHOULD_BUILD="true"
|
|
||||||
BUILD_REASON="${BUILD_REASON} no-check"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${SHOULD_BUILD}" != "true" ]; then
|
if [ "${SHOULD_BUILD}" != "true" ]; then
|
||||||
echo "Build skipped because sources didn't change"
|
echo "Build skipped because sources didn't change"
|
||||||
echo "::set-output name=skipped::true"
|
gh_out "skipped=true"
|
||||||
exit 0 # Nothing to do -> exit
|
exit 0 # Nothing to do -> exit
|
||||||
else
|
else
|
||||||
gh_echo "::set-output name=skipped::false"
|
gh_out "skipped=false"
|
||||||
fi
|
fi
|
||||||
gh_echo "::endgroup::"
|
gh_echo "::endgroup::"
|
||||||
|
|
||||||
|
@ -58,6 +58,9 @@ _BASE_DIR = dirname(dirname(abspath(__file__)))
|
|||||||
#
|
#
|
||||||
# Example: ALLOWED_HOSTS = ['netbox.example.com', 'netbox.internal.local']
|
# Example: ALLOWED_HOSTS = ['netbox.example.com', 'netbox.internal.local']
|
||||||
ALLOWED_HOSTS = environ.get('ALLOWED_HOSTS', '*').split(' ')
|
ALLOWED_HOSTS = environ.get('ALLOWED_HOSTS', '*').split(' ')
|
||||||
|
# ensure that '*' or 'localhost' is always in ALLOWED_HOSTS (needed for health checks)
|
||||||
|
if '*' not in ALLOWED_HOSTS and 'localhost' not in ALLOWED_HOSTS:
|
||||||
|
ALLOWED_HOSTS.append('localhost')
|
||||||
|
|
||||||
# PostgreSQL database configuration. See the Django documentation for a complete list of available parameters:
|
# PostgreSQL database configuration. See the Django documentation for a complete list of available parameters:
|
||||||
# https://docs.djangoproject.com/en/stable/ref/settings/#databases
|
# https://docs.djangoproject.com/en/stable/ref/settings/#databases
|
||||||
@ -83,6 +86,7 @@ REDIS = {
|
|||||||
'tasks': {
|
'tasks': {
|
||||||
'HOST': environ.get('REDIS_HOST', 'localhost'),
|
'HOST': environ.get('REDIS_HOST', 'localhost'),
|
||||||
'PORT': _environ_get_and_map('REDIS_PORT', 6379, _AS_INT),
|
'PORT': _environ_get_and_map('REDIS_PORT', 6379, _AS_INT),
|
||||||
|
'USERNAME': environ.get('REDIS_USERNAME', ''),
|
||||||
'PASSWORD': _read_secret('redis_password', environ.get('REDIS_PASSWORD', '')),
|
'PASSWORD': _read_secret('redis_password', environ.get('REDIS_PASSWORD', '')),
|
||||||
'DATABASE': _environ_get_and_map('REDIS_DATABASE', 0, _AS_INT),
|
'DATABASE': _environ_get_and_map('REDIS_DATABASE', 0, _AS_INT),
|
||||||
'SSL': _environ_get_and_map('REDIS_SSL', 'False', _AS_BOOL),
|
'SSL': _environ_get_and_map('REDIS_SSL', 'False', _AS_BOOL),
|
||||||
@ -91,6 +95,7 @@ REDIS = {
|
|||||||
'caching': {
|
'caching': {
|
||||||
'HOST': environ.get('REDIS_CACHE_HOST', environ.get('REDIS_HOST', 'localhost')),
|
'HOST': environ.get('REDIS_CACHE_HOST', environ.get('REDIS_HOST', 'localhost')),
|
||||||
'PORT': _environ_get_and_map('REDIS_CACHE_PORT', environ.get('REDIS_PORT', '6379'), _AS_INT),
|
'PORT': _environ_get_and_map('REDIS_CACHE_PORT', environ.get('REDIS_PORT', '6379'), _AS_INT),
|
||||||
|
'USERNAME': environ.get('REDIS_CACHE_USERNAME', environ.get('REDIS_USERNAME', '')),
|
||||||
'PASSWORD': _read_secret('redis_cache_password', environ.get('REDIS_CACHE_PASSWORD', environ.get('REDIS_PASSWORD', ''))),
|
'PASSWORD': _read_secret('redis_cache_password', environ.get('REDIS_CACHE_PASSWORD', environ.get('REDIS_PASSWORD', ''))),
|
||||||
'DATABASE': _environ_get_and_map('REDIS_CACHE_DATABASE', '1', _AS_INT),
|
'DATABASE': _environ_get_and_map('REDIS_CACHE_DATABASE', '1', _AS_INT),
|
||||||
'SSL': _environ_get_and_map('REDIS_CACHE_SSL', environ.get('REDIS_SSL', 'False'), _AS_BOOL),
|
'SSL': _environ_get_and_map('REDIS_CACHE_SSL', environ.get('REDIS_SSL', 'False'), _AS_BOOL),
|
||||||
|
@ -61,18 +61,26 @@ LDAP_CA_CERT_FILE = environ.get('LDAP_CA_CERT_FILE', None)
|
|||||||
|
|
||||||
AUTH_LDAP_USER_SEARCH_BASEDN = environ.get('AUTH_LDAP_USER_SEARCH_BASEDN', '')
|
AUTH_LDAP_USER_SEARCH_BASEDN = environ.get('AUTH_LDAP_USER_SEARCH_BASEDN', '')
|
||||||
AUTH_LDAP_USER_SEARCH_ATTR = environ.get('AUTH_LDAP_USER_SEARCH_ATTR', 'sAMAccountName')
|
AUTH_LDAP_USER_SEARCH_ATTR = environ.get('AUTH_LDAP_USER_SEARCH_ATTR', 'sAMAccountName')
|
||||||
|
AUTH_LDAP_USER_SEARCH_FILTER: str = environ.get(
|
||||||
|
'AUTH_LDAP_USER_SEARCH_FILTER', f'({AUTH_LDAP_USER_SEARCH_ATTR}=%(user)s)'
|
||||||
|
)
|
||||||
|
|
||||||
AUTH_LDAP_USER_SEARCH = LDAPSearch(
|
AUTH_LDAP_USER_SEARCH = LDAPSearch(
|
||||||
AUTH_LDAP_USER_SEARCH_BASEDN,
|
AUTH_LDAP_USER_SEARCH_BASEDN, ldap.SCOPE_SUBTREE, AUTH_LDAP_USER_SEARCH_FILTER
|
||||||
ldap.SCOPE_SUBTREE,
|
|
||||||
"(" + AUTH_LDAP_USER_SEARCH_ATTR + "=%(user)s)"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# This search ought to return all groups to which the user belongs. django_auth_ldap uses this to determine group
|
# This search ought to return all groups to which the user belongs. django_auth_ldap uses this to determine group
|
||||||
# heirarchy.
|
# heirarchy.
|
||||||
|
|
||||||
AUTH_LDAP_GROUP_SEARCH_BASEDN = environ.get('AUTH_LDAP_GROUP_SEARCH_BASEDN', '')
|
AUTH_LDAP_GROUP_SEARCH_BASEDN = environ.get('AUTH_LDAP_GROUP_SEARCH_BASEDN', '')
|
||||||
AUTH_LDAP_GROUP_SEARCH_CLASS = environ.get('AUTH_LDAP_GROUP_SEARCH_CLASS', 'group')
|
AUTH_LDAP_GROUP_SEARCH_CLASS = environ.get('AUTH_LDAP_GROUP_SEARCH_CLASS', 'group')
|
||||||
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(AUTH_LDAP_GROUP_SEARCH_BASEDN, ldap.SCOPE_SUBTREE,
|
|
||||||
"(objectClass=" + AUTH_LDAP_GROUP_SEARCH_CLASS + ")")
|
AUTH_LDAP_GROUP_SEARCH_FILTER: str = environ.get(
|
||||||
|
'AUTH_LDAP_GROUP_SEARCH_FILTER', f'(objectclass={AUTH_LDAP_GROUP_SEARCH_CLASS})'
|
||||||
|
)
|
||||||
|
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
|
||||||
|
AUTH_LDAP_GROUP_SEARCH_BASEDN, ldap.SCOPE_SUBTREE, AUTH_LDAP_GROUP_SEARCH_FILTER
|
||||||
|
)
|
||||||
AUTH_LDAP_GROUP_TYPE = _import_group_type(environ.get('AUTH_LDAP_GROUP_TYPE', 'GroupOfNamesType'))
|
AUTH_LDAP_GROUP_TYPE = _import_group_type(environ.get('AUTH_LDAP_GROUP_TYPE', 'GroupOfNamesType'))
|
||||||
|
|
||||||
# Define a group required to login.
|
# Define a group required to login.
|
||||||
|
@ -2,4 +2,22 @@ version: '3.4'
|
|||||||
services:
|
services:
|
||||||
netbox:
|
netbox:
|
||||||
ports:
|
ports:
|
||||||
- 8000:8080
|
- "8000:8080"
|
||||||
|
# If you want the Nginx unit status page visible from the
|
||||||
|
# outside of the container add the following port mapping:
|
||||||
|
# - "8001:8081"
|
||||||
|
# healthcheck:
|
||||||
|
# Time for which the health check can fail after the container is started.
|
||||||
|
# This depends mostly on the performance of your database. On the first start,
|
||||||
|
# when all tables need to be created the start_period should be higher than on
|
||||||
|
# subsequent starts. For the first start after major version upgrades of NetBox
|
||||||
|
# the start_period might also need to be set higher.
|
||||||
|
# Default value in our docker-compose.yml is 60s
|
||||||
|
# start_period: 90s
|
||||||
|
# environment:
|
||||||
|
# SKIP_SUPERUSER: "false"
|
||||||
|
# SUPERUSER_API_TOKEN: ""
|
||||||
|
# SUPERUSER_EMAIL: ""
|
||||||
|
# SUPERUSER_NAME: ""
|
||||||
|
# SUPERUSER_PASSWORD: ""
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
version: '3.4'
|
version: '3.4'
|
||||||
services:
|
services:
|
||||||
netbox: &netbox
|
netbox: &netbox
|
||||||
image: netboxcommunity/netbox:${VERSION-v3.4-2.4.0}
|
image: docker.io/netboxcommunity/netbox:${VERSION-v3.4-2.5.0}
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
@ -47,14 +47,14 @@ services:
|
|||||||
|
|
||||||
# postgres
|
# postgres
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:15-alpine
|
image: docker.io/postgres:15-alpine
|
||||||
env_file: env/postgres.env
|
env_file: env/postgres.env
|
||||||
volumes:
|
volumes:
|
||||||
- netbox-postgres-data:/var/lib/postgresql/data
|
- netbox-postgres-data:/var/lib/postgresql/data
|
||||||
|
|
||||||
# redis
|
# redis
|
||||||
redis:
|
redis:
|
||||||
image: redis:7-alpine
|
image: docker.io/redis:7-alpine
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c # this is to evaluate the $REDIS_PASSWORD from the env
|
- -c # this is to evaluate the $REDIS_PASSWORD from the env
|
||||||
|
@ -46,6 +46,8 @@ if ! ./manage.py migrate --check >/dev/null 2>&1; then
|
|||||||
./manage.py remove_stale_contenttypes --no-input
|
./manage.py remove_stale_contenttypes --no-input
|
||||||
echo "⚙️ Removing expired user sessions"
|
echo "⚙️ Removing expired user sessions"
|
||||||
./manage.py clearsessions
|
./manage.py clearsessions
|
||||||
|
echo "⚙️ Building search index (lazy)"
|
||||||
|
./manage.py reindex --lazy
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create Superuser if required
|
# Create Superuser if required
|
||||||
@ -80,6 +82,13 @@ END
|
|||||||
echo "💡 Superuser Username: ${SUPERUSER_NAME}, E-Mail: ${SUPERUSER_EMAIL}"
|
echo "💡 Superuser Username: ${SUPERUSER_NAME}, E-Mail: ${SUPERUSER_EMAIL}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
./manage.py shell --interface python <<END
|
||||||
|
from users.models import Token
|
||||||
|
old_default_token = Token.objects.get(key="0123456789abcdef0123456789abcdef01234567")
|
||||||
|
if old_default_token:
|
||||||
|
print("⚠️ Warning: You have the old default admin token in your database. This token is widely known; please remove it.")
|
||||||
|
END
|
||||||
|
|
||||||
echo "✅ Initialisation is done."
|
echo "✅ Initialisation is done."
|
||||||
|
|
||||||
# Launch whatever is passed by docker
|
# Launch whatever is passed by docker
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
UNIT_CONFIG="${UNIT_CONFIG-/etc/unit/nginx-unit.json}"
|
UNIT_CONFIG="${UNIT_CONFIG-/etc/unit/nginx-unit.json}"
|
||||||
|
# Also used in "nginx-unit.json"
|
||||||
UNIT_SOCKET="/opt/unit/unit.sock"
|
UNIT_SOCKET="/opt/unit/unit.sock"
|
||||||
|
|
||||||
load_configuration() {
|
load_configuration() {
|
||||||
|
@ -1,30 +1,45 @@
|
|||||||
{
|
{
|
||||||
"listeners": {
|
"listeners": {
|
||||||
"0.0.0.0:8080": {
|
"0.0.0.0:8080": {
|
||||||
"pass": "routes"
|
"pass": "routes/main"
|
||||||
},
|
},
|
||||||
"[::]:8080": {
|
"[::]:8080": {
|
||||||
"pass": "routes"
|
"pass": "routes/main"
|
||||||
|
},
|
||||||
|
"0.0.0.0:8081": {
|
||||||
|
"pass": "routes/status"
|
||||||
|
},
|
||||||
|
"[::]:8081": {
|
||||||
|
"pass": "routes/status"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"routes": {
|
||||||
"routes": [
|
"main": [
|
||||||
{
|
{
|
||||||
"match": {
|
"match": {
|
||||||
"uri": "/static/*"
|
"uri": "/static/*"
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"share": "/opt/netbox/netbox${uri}"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"action": {
|
{
|
||||||
"share": "/opt/netbox/netbox${uri}"
|
"action": {
|
||||||
|
"pass": "applications/netbox"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
|
"status": [
|
||||||
{
|
{
|
||||||
"action": {
|
"match": {
|
||||||
"pass": "applications/netbox"
|
"uri": "/status/*"
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"proxy": "http://unix:/opt/unit/unit.sock"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
],
|
},
|
||||||
|
|
||||||
"applications": {
|
"applications": {
|
||||||
"netbox": {
|
"netbox": {
|
||||||
"type": "python 3",
|
"type": "python 3",
|
||||||
@ -38,6 +53,5 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"access_log": "/dev/stdout"
|
"access_log": "/dev/stdout"
|
||||||
}
|
}
|
||||||
|
6
env/netbox.env
vendored
6
env/netbox.env
vendored
@ -30,9 +30,5 @@ REDIS_PASSWORD=H733Kdjndks81
|
|||||||
REDIS_SSL=false
|
REDIS_SSL=false
|
||||||
RELEASE_CHECK_URL=https://api.github.com/repos/netbox-community/netbox/releases
|
RELEASE_CHECK_URL=https://api.github.com/repos/netbox-community/netbox/releases
|
||||||
SECRET_KEY=r8OwDznj!!dci#P9ghmRfdu1Ysxm0AiPeDCQhKE+N_rClfWNj
|
SECRET_KEY=r8OwDznj!!dci#P9ghmRfdu1Ysxm0AiPeDCQhKE+N_rClfWNj
|
||||||
SKIP_SUPERUSER=false
|
SKIP_SUPERUSER=true
|
||||||
SUPERUSER_API_TOKEN=0123456789abcdef0123456789abcdef01234567
|
|
||||||
SUPERUSER_EMAIL=admin@example.com
|
|
||||||
SUPERUSER_NAME=admin
|
|
||||||
SUPERUSER_PASSWORD=admin
|
|
||||||
WEBHOOKS_ENABLED=true
|
WEBHOOKS_ENABLED=true
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
django-auth-ldap==4.1.0
|
django-auth-ldap==4.1.0
|
||||||
django-storages[azure,boto3,dropbox,google,libcloud,sftp]==1.13.1
|
django-storages[azure,boto3,dropbox,google,libcloud,sftp]==1.13.2
|
||||||
napalm==4.0.0
|
napalm==4.0.0
|
||||||
psycopg2==2.9.5
|
psycopg2==2.9.5
|
||||||
python3-saml==1.14.0
|
python3-saml==1.15.0
|
||||||
social-auth-core[all]==4.3.0
|
social-auth-core[all]==4.3.0
|
||||||
|
Loading…
Reference in New Issue
Block a user