diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 617e694..0000000 --- a/.dockerignore +++ /dev/null @@ -1,13 +0,0 @@ -/.dev -/.idea -/*.iml - -/.git -/.res -/examples -/.editorconfig -/.gitignore -/.travis.yml -/CHANGELOG.md -/LICENSE -/README.md diff --git a/.editorconfig b/.editorconfig index acb43f7..10ec7fc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,16 +3,13 @@ root = true [*] indent_style = space -indent_size = 4 +indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -[{Dockerfile,*.sh,*.yml}] -indent_size = 2 - -[assets/**] +[rootfs/**] insert_final_newline = false [*.md] diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..eb8909a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/*.sh linguist-detectable=false +/rootfs/** linguist-detectable=false diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..f7b8e1d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @crazy-max diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..04c13b5 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: crazy-max +custom: https://www.paypal.me/crazyws diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000..2013f88 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,91 @@ +# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema +name: Bug Report +description: Report a bug +labels: + - kind/bug + - status/triage + +body: + - type: checkboxes + attributes: + label: Support guidelines + description: Please read the support guidelines before proceeding. + options: + - label: I've read the [support guidelines](https://github.com/librenms/docker/blob/master/.github/SUPPORT.md) + required: true + + - type: checkboxes + attributes: + label: I've found a bug and checked that ... + description: | + Make sure that your request fulfills all of the following requirements. If one requirement cannot be satisfied, explain in detail why. + options: + - label: ... the documentation does not mention anything about my problem + - label: ... there are no open or closed issues that are related to my problem + + - type: textarea + attributes: + label: Description + description: | + Please provide a brief description of the bug in 1-2 sentences. + validations: + required: true + + - type: textarea + attributes: + label: Expected behaviour + description: | + Please describe precisely what you'd expect to happen. + validations: + required: true + + - type: textarea + attributes: + label: Actual behaviour + description: | + Please describe precisely what is actually happening. + validations: + required: true + + - type: textarea + attributes: + label: Steps to reproduce + description: | + Please describe the steps to reproduce the bug. + placeholder: | + 1. ... + 2. ... + 3. ... + validations: + required: true + + - type: textarea + attributes: + label: Docker info + description: | + Output of `docker info` command. + render: text + validations: + required: true + + - type: textarea + attributes: + label: Docker Compose config + description: | + Output of `docker compose config` command. + render: yaml + + - type: textarea + attributes: + label: Logs + description: | + Please provide the container logs (set `LOG_LEVEL=debug` if applicable). + render: text + validations: + required: true + + - type: textarea + attributes: + label: Additional info + description: | + Please provide any additional information that seem useful. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..8f929f1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,6 @@ +# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser +blank_issues_enabled: true +contact_links: + - name: Questions and Discussions + url: https://github.com/librenms/docker/discussions/new + about: Use Github Discussions to ask questions and/or open discussion topics. diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml new file mode 100644 index 0000000..6ab7568 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -0,0 +1,15 @@ +# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema +name: Feature request +description: Missing functionality? Come tell us about it! +labels: + - kind/enhancement + - status/triage + +body: + - type: textarea + id: description + attributes: + label: Description + description: What is the feature you want to see? + validations: + required: true diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 0000000..43fac54 --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,29 @@ +# Support [![](https://isitmaintained.com/badge/resolution/librenms/docker.svg)](https://isitmaintained.com/project/librenms/docker) + +## Reporting an issue + +Please do a search in [open issues](https://github.com/librenms/docker/issues?utf8=%E2%9C%93&q=) to see if the issue or feature request has already been filed. + +If you find your issue already exists, make relevant comments and add your [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments). Use a reaction in place of a "+1" comment. + +:+1: - upvote + +:-1: - downvote + +If you cannot find an existing issue that describes your bug or feature, submit an issue using the guidelines below. + +## Writing good bug reports and feature requests + +File a single issue per problem and feature request. + +* Do not enumerate multiple bugs or feature requests in the same issue. +* Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar, but have different causes. + +The more information you can provide, the more likely someone will be successful reproducing the issue and finding a fix. + +You are now ready to [create a new issue](https://github.com/librenms/docker/issues/new/choose)! + +## Closure policy + +* Issues that don't have the information requested above (when applicable) will be closed immediately and the poster directed to the support guidelines. +* Issues that go a week without a response from original poster are subject to closure at my discretion. diff --git a/.res/docker-librenms.jpg b/.github/docker-librenms.jpg similarity index 100% rename from .res/docker-librenms.jpg rename to .github/docker-librenms.jpg diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 0000000..b5d2b8c --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,73 @@ +## more info https://github.com/crazy-max/ghaction-github-labeler +- + name: "bot" + color: "69cde9" + description: "" +- + name: "good first issue" + color: "7057ff" + description: "" +- + name: "help wanted" + color: "4caf50" + description: "" +- + name: "area/ci" + color: "ed9ca9" + description: "" +- + name: "area/dockerfile" + color: "03a9f4" + description: "" +- + name: "kind/bug" + color: "b60205" + description: "" +- + name: "kind/dependencies" + color: "0366d6" + description: "" +- + name: "kind/docs" + color: "c5def5" + description: "" +- + name: "kind/duplicate" + color: "cccccc" + description: "" +- + name: "kind/enhancement" + color: "0054ca" + description: "" +- + name: "kind/invalid" + color: "e6e6e6" + description: "" +- + name: "kind/upstream" + color: "fbca04" + description: "" +- + name: "kind/wontfix" + color: "ffffff" + description: "" +- + name: "status/automerge" + color: "8f4fbc" + description: "" +- + name: "status/needs-investigation" + color: "e6625b" + description: "" +- + name: "status/needs-more-info" + color: "795548" + description: "" +- + name: "status/stale" + color: "237da0" + description: "" +- + name: "status/triage" + color: "dde4b7" + description: "" diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..67a8c1f --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ], + "customManagers": [ + { + "customType": "regex", + "description": "Update _VERSION variables in Dockerfiles", + "fileMatch": ["(^|/|\\.)Dockerfile$", "(^|/)Dockerfile\\.[^/]*$"], + "matchStrings": [ + "# renovate: datasource=(?[a-z-]+?)(?: depName=(?.+?))? packageName=(?.+?)(?: versioning=(?[a-z-]+?))?\\s(?:ENV|ARG) .+?_VERSION=\"(?.+?)\"\\s" + ] + } + ] +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f824740 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,77 @@ +name: build + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + contents: read + +on: + push: + branches: + - 'master' + tags: + - '*' + paths-ignore: + - '**.md' + pull_request: + paths-ignore: + - '**.md' + +env: + DOCKERHUB_SLUG: librenms/librenms + +jobs: + build: + runs-on: ubuntu-latest + steps: + - + name: Login to DockerHub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - + name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ env.DOCKERHUB_SLUG }} + tags: | + type=match,pattern=(.*)-r,group=1 + type=ref,event=pr + type=edge + labels: | + org.opencontainers.image.title=LibreNMS + org.opencontainers.image.description=Fully featured network monitoring system + org.opencontainers.image.vendor=LibreNMS + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Build + uses: docker/bake-action@v6 + with: + files: | + ./docker-bake.hcl + cwd://${{ steps.meta.outputs.bake-file }} + targets: image-all + push: ${{ github.event_name != 'pull_request' }} + - + name: Check manifest + if: github.event_name != 'pull_request' + run: | + docker buildx imagetools inspect ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.version }} + - + name: Inspect + if: github.event_name != 'pull_request' + run: | + docker pull ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.version }} + docker image inspect ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml new file mode 100644 index 0000000..00c6675 --- /dev/null +++ b/.github/workflows/labels.yml @@ -0,0 +1,39 @@ +name: labels + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + contents: read + +on: + push: + branches: + - 'master' + paths: + - '.github/labels.yml' + - '.github/workflows/labels.yml' + pull_request: + paths: + - '.github/labels.yml' + - '.github/workflows/labels.yml' + +jobs: + labeler: + runs-on: ubuntu-latest + permissions: + # same as global permissions + contents: read + # required to update labels + issues: write + steps: + - + name: Checkout + uses: actions/checkout@v6 + - + name: Run Labeler + uses: crazy-max/ghaction-github-labeler@v5 + with: + dry-run: ${{ github.event_name == 'pull_request' }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..40a0e32 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,81 @@ +name: test + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + contents: read + +on: + push: + branches: + - 'master' + paths-ignore: + - '**.md' + pull_request: + paths-ignore: + - '**.md' + +env: + BUILD_TAG: librenms:test + CONTAINER_NAME: librenms + +jobs: + test: + runs-on: ubuntu-latest + continue-on-error: ${{ matrix.version == 'master' }} + strategy: + fail-fast: false + matrix: + version: + - '' + - master + steps: + - + name: Prepare + if: matrix.version != '' + run: | + echo "LIBRENMS_VERSION=${{ matrix.version }}" >> $GITHUB_ENV + - + name: Checkout + uses: actions/checkout@v6 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Build + uses: docker/bake-action@v6 + with: + source: . + targets: image-local + env: + DEFAULT_TAG: ${{ env.BUILD_TAG }} + - + name: Start + run: | + docker compose up -d + working-directory: test + env: + LIBRENMS_IMAGE: ${{ env.BUILD_TAG }} + LIBRENMS_CONTAINER: ${{ env.CONTAINER_NAME }} + - + name: Check container logs + uses: crazy-max/.github/.github/actions/container-logs-check@main + with: + container_name: ${{ env.CONTAINER_NAME }} + log_check: "ready to handle connections" + timeout: 120 + - + name: Logs + if: always() + run: | + docker compose logs + working-directory: test + env: + LIBRENMS_IMAGE: ${{ env.BUILD_TAG }} + LIBRENMS_CONTAINER: ${{ env.CONTAINER_NAME }} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 83a80f2..0000000 --- a/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Jetbrains -/.idea -/*.iml - -# Visual Studio Code -/.vscode - -# App -/.dev \ No newline at end of file diff --git a/.res/paypal.png b/.res/paypal.png deleted file mode 100644 index 76842ea..0000000 Binary files a/.res/paypal.png and /dev/null differ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0b99854..0000000 --- a/.travis.yml +++ /dev/null @@ -1,62 +0,0 @@ -sudo: required - -services: - - docker - -env: - global: - - VERSION=1.43 - - GITHUB_REPO=crazy-max/docker-librenms - - DOCKER_USERNAME=crazymax - - DOCKER_REPONAME=librenms - - QUAY_USERNAME=crazymax - - QUAY_REPONAME=librenms - - MICROBADGER_HOOK=https://hooks.microbadger.com/images/crazymax/librenms/-iJon04e52FswWvLC-zkB6yi2vo= - - secure: GMYFptO3rWVVITjC0Wz8g9uccBjSMBvVt3aFC3Y08/3Hw9CoA/SS51X/2lh0bRn+y49X0742QC7b2LtSWa3eERM1HbzlS1ODK75+P0lGYdtW2Ng5JutI+GRt8xTouY7+iP4qSAbOYMUdM5e61PkRepJvZWVeBkPtAtcGpxZO75h+snFxuzFVZXWLoSKjByKIqy9VXzT2P0Wx+zuUWpeo2qA62ONRJf5RjIKCDxHmWEwhXKmmDjeqo+Db/zsUwGYSwKpKRGBhyPVP0MnKFA2HQ/+dG1NyikXhae5dhjaZvgG9tSpbYdOWCHCunbxm6VWozt/kvkqkbizn+S3aoeeZyco40ZFIUinpypxw/nZpVvfDkwBIhw3nOS4giMKHLLBtnkSZw2szP6zfdLX6MLKWSjcDsBbtqj8aNe8Z1ViEKc2uW+yqJvd6GNnDL+AINe5rJ/cjeseh1ancOaGG8tlGsg/80dhOV3l+E4nINn+1uj354ncH/lv14e4giDNMGRw8gq7HFWxIE1X8SLetK9Hz5kLyMIPlSCO2fL73adrqfJFFluTQ0CbzsOEHSuScHT8i9UJWrqcu25BQ4pKidmDAt0gT7x6cz7zziuTY0hTO05txIP0FCop0qCFoLuAGM/bQg8r6FnfIZu4NbUxutjLiAN5aMB1D3znnymxKdeX/HOc= # DOCKER_PASSWORD - - secure: XMkF9Nz6FjKVB52vv7rZ+fa7vDDRXG7/nDm5Wio4eljYU/+cIZwdbBv2hU2IEmherZBn2jO9V64LYR9yTLALOGMEjqE/0E8KNiibj7VRjeRmtQrTHbUj7XpBmqAVyNek2GxkmtS4meOIcUUxBOfCAiIu2b++iuR70rAHvr+dL8skX7FNG77ZgTRsP9VkCylyfw0qb+50pD+2ukOFHxZ4tSi89F8ZU4UQOiNTBre4NUPCN5DZmglSt4nUYt3iofKs9p4ZjPP0cTBpHhArn37VZJyo1tOcl1jP8x18PVvgxrHO8Z0FQCasnZ6O269FR8lF28yM4CwHxk6ufCuieCCj5f0ez6S8IEv82a8ljmw+a75Gb6+pAmYB8nY49VkrWmA6KoDY+F+Ob30QOOtLCGumGBLZ1++6MOtwFjN5BzAyVl3Qhl+9heUMM3ULkbEV0IGJHL1M3zEBqxkQO6urdgf6cPEf3uldd+T6Ochn2DZ42Ge+yiZiIrgF/p0R3l1vDbyBG6OcnmaEoQWdIgqa6DUV48MBkYHF9Sp0idUbsrOaoVNsZZ4h0P72fRci/rElvoDGJIAdFEEE1ZW/y3a6hJihxvYQM9+S+HvzluI+5SKzdFUJ4hRpaGfIvclKdyaCNSE1B0VrwGXn7pBt5tem0IZnE5BQ9d/6TgVFc+L2Eyf7Mck= # QUAY_PASSWORD - - secure: mLY2C4Ggmg/VUdWoYc8vqYQb7lLSSB/YMvKUzY+z8VGAi5A8J1A6oTgeeThiKPWaNp9GgU1hdHA5WqoSCuOk2SzJoIEhnPU0j3GkDknuXmbhU1UXsuefMF++v2J9RarmC2CkyGiBDzJCrcs9srcS6RjmbK7hQv5EsbkjjyQHQwZlMG+q2aUwNcNxhAeD0+gn8j6eZ6myxt/SJ3LZRLCb+ZpP1NITc6aHjC9glc6ZO7bTy6WG6SVg0SREdxbht+cUrTNQvAcIkoEZQ4vOJBi3kAo6aZz6QYglofaYpTCdmiSSFGHseJ7k1Dl+khCL8OqeOnVCOkcu8SgPV7tI6WId8Dky/YPUsFtjivJqekjs/ctAekOHTzJW9UeOLkCOiqeLmQTDQ01JDLno1znzMOTC3T96I5d2LUnob3QOu32chdzqw0LfcawcuNnLwLdbK4AwPcDuIUl6b1FjU6I8DckHjtvL9Mr9xLhIkNrhdPW0vAj8yZkvGCxvGXh+qK6ejNDt/RdH6wWojh1yTbJSCAQLo1WnJ5YpqLxtu5++/4PfiTLkt7u8QMnau5m+8wZ4ju2RfFrwmEaKkrZSkq7ViQ+RsI/y0bNxUzk3Bb02Wgh9MfpPUXLA+4llYWIPnbgL17N5zhsROp9u0YSbzc3cWJm+0TQZZ0hAjyXBDoT2UCsDNqE= # GITHUB_TOKEN - -before_install: - - sudo apt-get update - - docker --version - - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi) - - export DOCKER_TAG=$(if [ "$BRANCH" == "master" ]; then echo "latest"; else echo $BRANCH; fi) - - echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH, DOCKER_TAG=$DOCKER_TAG" - -install: - - | - docker build --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ - --build-arg VCS_REF=${TRAVIS_COMMIT::8} \ - --build-arg VERSION=${VERSION} \ - -t docker_build . - -before_script: - - docker network create -d bridge $DOCKER_REPONAME - - docker run -d --network=$DOCKER_REPONAME --name db mariadb:10.2 - - docker run -d --network=$DOCKER_REPONAME --link db -p 8000:80 -e "DB_HOST=db" -e "DB_PASSWORD=asupersecretpassword" --name $DOCKER_REPONAME docker_build - - sleep 20 - - docker logs $DOCKER_REPONAME - -script: - - docker ps | grep $DOCKER_REPONAME - -after_success: - - | - test $TRAVIS_PULL_REQUEST = false \ - && echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin \ - && docker tag docker_build $DOCKER_USERNAME/$DOCKER_REPONAME:$DOCKER_TAG \ - && docker tag docker_build $DOCKER_USERNAME/$DOCKER_REPONAME:$VERSION \ - && docker push $DOCKER_USERNAME/$DOCKER_REPONAME \ - && echo "$QUAY_PASSWORD" | docker login quay.io --username "$QUAY_USERNAME" --password-stdin \ - && docker tag docker_build quay.io/$DOCKER_USERNAME/$DOCKER_REPONAME:$DOCKER_TAG \ - && docker tag docker_build quay.io/$DOCKER_USERNAME/$DOCKER_REPONAME:$VERSION \ - && docker push quay.io/$QUAY_USERNAME/$QUAY_REPONAME \ - && curl -X POST $MICROBADGER_HOOK - -branches: - except: - - /^[0-9]/ - -notifications: - webhooks: - secure: qy/lFOFGeP0IMvDTJZmPemOtHjkpnYq4sm734rTjBsKFNA8MU4TyWCnx24hljRd4YazAkH6j2Uav3XfmnR+UGfutXRsmktzZoDTlygiJLP/026gvD+VuT8GZIFXRpYhNlfPemFoN2/wO5sf91JGQL4cxVcF9r1A0aUQUtAzvl9UKwk+DRc9Y78oCKRmIaeoFrvKE1SCGPf/drNYeLKJiRiq7VV5jL+1tmZUjYKWVYnWU3yYSyg3OdAvXAVEDagzvAQ0ors9UJeXxAsAls0kTQc8c2+uWfEH411sRrPuqTYYkXIPQpJszLeDhG0ISU5xs5UCJSi7QzTRxD5lWgn8C2QfGS8x3eQK8fHEfN1Q0frqGdCYJcEC2izs91bwZDmFmDj9B0mkuOyHDjWmTIo+HPkb/ryATFD3Bk2pekHWBkuq+KKTQzvgtgokp4V7xRumDh7htyYzr88uk1EQFR7VY05aWFGFsoZ13oKa4UQ4uglH2xmWVW3X9cyf5NCj/t4mUt5223ZM7Q+LKDONSPz/VEDlSOkPapjC4rpn6mn/k6FNN3UyC4hL9+HXSFyCOJZDy3P6lagCWWlzLxt0R4DnptZG+cShW0+bzcecEaGPjyEidACctKl3hfDCiblg05Js0lvW454C4TPnzZ/tDAE6VE8mCFtU/K1ur+wneZuOv2pA= diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 6d2ad66..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,44 +0,0 @@ -# Changelog - -## 1.43-RC5 (2018/09/29) - -* Ability to add custom Monitoring plugins through `/data/monitoring-plugins` -* Install [Monitoring Plugins](https://www.monitoring-plugins.org/) package -* Services enabled by default - -## 1.43-RC4 (2018/09/26) - -* Add `ttf-dejavu` package - -## 1.43-RC3 (2018/09/24) - -* Set default port for `MEMCACHED_PORT` and `RRDCACHED_PORT` - -## 1.43-RC2 (2018/09/24) - -* Add CAP_NET_RAW on nmap and fping -* Fixes for `validate.php` nologin errors and missing setfacl binaries -* Add fping6 support -* Add `rrdtool_version` -* Ability to configure distributed polling -* Adding python-memcached module required for distributed poller setup -* Configurable DB_TIMEOUT -* Allow setting sensible variables through files -* Ability to override Memcached and RRD ports - -## 1.43-RC1 (2018/09/10) - -* Upgrade to LibreNMS 1.43 - -## 1.42.01-RC1 (2018/08/05) - -* Upgrade to LibreNMS 1.42.01 - -## 1.42-RC1 (2018/08/02) - -* Upgrade to LibreNMS 1.42 -* Add syslog-ng support - -## 1.41-RC1 (2018/07/07) - -* Initial version based on LibreNMS 1.41 diff --git a/Dockerfile b/Dockerfile index 452073c..623e097 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,114 +1,147 @@ -FROM alpine:3.8 +# syntax=docker/dockerfile:1 -ARG BUILD_DATE -ARG VCS_REF -ARG VERSION - -LABEL maintainer="CrazyMax" \ - org.label-schema.build-date=$BUILD_DATE \ - org.label-schema.name="librenms" \ - org.label-schema.description="LibreNMS based on Alpine Linux and Nginx" \ - org.label-schema.version=$VERSION \ - org.label-schema.url="https://github.com/crazy-max/docker-librenms" \ - org.label-schema.vcs-ref=$VCS_REF \ - org.label-schema.vcs-url="https://github.com/crazy-max/docker-librenms" \ - org.label-schema.vendor="CrazyMax" \ - org.label-schema.schema-version="1.0" +# renovate: datasource=github-releases packageName=librenms/librenms versioning=semver +ARG LIBRENMS_VERSION="26.1.1" +ARG ALPINE_VERSION="3.22" +ARG SYSLOGNG_VERSION="4.8.3-r1" +FROM crazymax/yasu:latest AS yasu +FROM crazymax/alpine-s6:${ALPINE_VERSION}-2.2.0.3 +COPY --from=yasu / / RUN apk --update --no-cache add \ + busybox-extras \ acl \ bash \ + bind-tools \ binutils \ ca-certificates \ coreutils \ curl \ + file \ fping \ git \ graphviz \ imagemagick \ + ipmitool \ + iputils \ + libcap-utils \ + mariadb-client \ monitoring-plugins \ mtr \ - mysql-client \ net-snmp \ net-snmp-tools \ nginx \ nmap \ openssl \ + openssh-client \ perl \ - php7 \ - php7-cli \ - php7-ctype \ - php7-curl \ - php7-fpm \ - php7-gd \ - php7-json \ - php7-mbstring \ - php7-mcrypt \ - php7-memcached \ - php7-mysqli \ - php7-opcache \ - php7-openssl \ - php7-pdo \ - php7-pdo_mysql \ - php7-phar \ - php7-posix \ - php7-session \ - php7-simplexml \ - php7-snmp \ - php7-tokenizer \ - php7-xml \ - php7-zip \ - py-mysqldb \ - py2-pip \ - python2 \ + php83 \ + php83-cli \ + php83-ctype \ + php83-curl \ + php83-dom \ + php83-fileinfo \ + php83-fpm \ + php83-gd \ + php83-gmp \ + php83-iconv \ + php83-json \ + php83-ldap \ + php83-mbstring \ + php83-mysqlnd \ + php83-opcache \ + php83-openssl \ + php83-pdo \ + php83-pdo_mysql \ + php83-pecl-memcached \ + php83-pear \ + php83-phar \ + php83-posix \ + php83-session \ + php83-simplexml \ + php83-snmp \ + php83-sockets \ + php83-tokenizer \ + php83-xml \ + php83-xmlwriter \ + php83-zip \ + python3 \ + py3-pip \ rrdtool \ runit \ + sed \ shadow \ - supervisor \ - syslog-ng \ ttf-dejavu \ - tzdata \ + tzdata \ util-linux \ whois \ - && pip install python-memcached \ - && sed -i -e "s/;date\.timezone.*/date\.timezone = UTC/" /etc/php7/php.ini \ - && rm -rf /var/cache/apk/* /var/www/* /tmp/* \ + && apk --update --no-cache add -t build-dependencies \ + build-base \ + make \ + mariadb-dev \ + musl-dev \ + python3-dev \ + && pip3 install --upgrade --break-system-packages pip \ + && pip3 install python-memcached mysqlclient --upgrade --break-system-packages \ + && curl -sSL https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer \ + && apk del build-dependencies \ + && rm -rf /var/www/* /tmp/* \ + && echo "/usr/sbin/fping -6 \$@" > /usr/sbin/fping6 \ + && chmod +x /usr/sbin/fping6 \ + && chmod u+s,g+s \ + /bin/ping \ + /bin/ping6 \ + /usr/lib/monitoring-plugins/check_icmp \ && setcap cap_net_raw+ep /usr/bin/nmap \ - && setcap cap_net_raw+ep /usr/sbin/fping + && setcap cap_net_raw+ep /usr/sbin/fping \ + && setcap cap_net_raw+ep /usr/sbin/fping6 \ + && setcap cap_net_raw+ep /usr/lib/monitoring-plugins/check_icmp \ + && setcap cap_net_raw+ep /usr/lib/monitoring-plugins/check_ping -ENV LIBRENMS_VERSION="1.43" \ +ARG SYSLOGNG_VERSION +RUN apk --update --no-cache add syslog-ng=${SYSLOGNG_VERSION} + +ENV S6_BEHAVIOUR_IF_STAGE2_FAILS="2" \ LIBRENMS_PATH="/opt/librenms" \ - DATA_PATH="/data" \ - CRONTAB_PATH="/var/spool/cron/crontabs" + LIBRENMS_DOCKER="1" \ + TZ="UTC" \ + PUID="1000" \ + PGID="1000" -RUN mkdir -p /opt \ - && addgroup -g 1000 librenms \ - && adduser -u 1000 -G librenms -h ${LIBRENMS_PATH} -s /bin/sh -D librenms \ - && passwd -l librenms \ - && usermod -a -G librenms nginx \ - && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer \ - && git clone --branch ${LIBRENMS_VERSION} https://github.com/librenms/librenms.git ${LIBRENMS_PATH} \ - && chown -R librenms. ${LIBRENMS_PATH} \ - && su - librenms -c "composer install --no-dev --no-interaction --no-ansi --working-dir=${LIBRENMS_PATH}" \ - && wget -q https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro -O /usr/bin/distro \ - && chmod +x /usr/bin/distro \ - && rm -rf /tmp/* +RUN addgroup -g ${PGID} librenms \ + && adduser -D -h /home/librenms -u ${PUID} -G librenms -s /bin/sh -D librenms \ + && curl -sSLk -q https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro -o /usr/bin/distro \ + && chmod +x /usr/bin/distro -COPY entrypoint.sh /entrypoint.sh -COPY assets / - -RUN mkdir -p /data ${LIBRENMS_PATH}/config.d /var/log/supervisord \ - && chmod a+x /entrypoint.sh /usr/local/bin/* \ - && cp ${LIBRENMS_PATH}/snmpd.conf.example /etc/snmp/snmpd.conf \ - && cp ${LIBRENMS_PATH}/config.php.default ${LIBRENMS_PATH}/config.php \ - && echo "foreach (glob(\"${DATA_PATH}/config/*.php\") as \$filename) include \$filename;" >> ${LIBRENMS_PATH}/config.php \ - && echo "foreach (glob(\"${LIBRENMS_PATH}/config.d/*.php\") as \$filename) include \$filename;" >> ${LIBRENMS_PATH}/config.php \ - && chown -R librenms. ${DATA_PATH} ${LIBRENMS_PATH} \ - && chown -R nginx. /var/lib/nginx /var/log/nginx /var/log/php7 /var/tmp/nginx - -EXPOSE 80 514 514/udp WORKDIR ${LIBRENMS_PATH} -VOLUME [ "${DATA_PATH}" ] +ARG LIBRENMS_VERSION +ARG WEATHERMAP_PLUGIN_COMMIT +RUN apk --update --no-cache add -t build-dependencies \ + build-base \ + linux-headers \ + musl-dev \ + python3-dev \ + && echo "Installing LibreNMS https://github.com/librenms/librenms.git#${LIBRENMS_VERSION}..." \ + && git clone --depth=1 --branch ${LIBRENMS_VERSION} https://github.com/librenms/librenms.git . \ + && pip3 install --ignore-installed -r requirements.txt --upgrade --break-system-packages \ + && mkdir config.d \ + && cp config.php.default config.php \ + && cp snmpd.conf.example /etc/snmp/snmpd.conf \ + && sed -i '/runningUser/d' lnms \ + && echo "foreach (glob(\"/data/config/*.php\") as \$filename) include \$filename;" >> config.php \ + && echo "foreach (glob(\"${LIBRENMS_PATH}/config.d/*.php\") as \$filename) include \$filename;" >> config.php \ + && chown -R librenms:librenms ${LIBRENMS_PATH} \ + && su librenms -s /bin/sh -c "COMPOSER_CACHE_DIR=/tmp composer install --no-dev --no-interaction --no-ansi" \ + && apk del build-dependencies \ + && rm -rf .git \ + html/plugins/Test \ + doc/ \ + tests/ \ + /tmp/* -ENTRYPOINT [ "/entrypoint.sh" ] -CMD [ "/usr/bin/supervisord", "-c", "/etc/supervisord.conf" ] +COPY rootfs / + +EXPOSE 8000 514 514/udp 162 162/udp +VOLUME [ "/data" ] + +ENTRYPOINT [ "/init" ] diff --git a/LICENSE b/LICENSE index 29b1e96..4bc99d2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 CrazyMax +Copyright (c) 2018-2025 CrazyMax Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 13ef046..39f06e0 100644 --- a/README.md +++ b/README.md @@ -1,130 +1,294 @@ -

+

- Version - Build Status - Docker Stars - Docker Pulls - Docker Repository on Quay - Donate Paypal + Latest Version + Build Status + Docker Stars + Docker Pulls +
Become a sponsor + Donate Paypal

## About -🐳 [LibreNMS](https://www.librenms.org/) Docker image based on Alpine Linux and Nginx.
-If you are interested, [check out](https://hub.docker.com/r/crazymax/) my other 🐳 Docker images! +Docker image for [LibreNMS](https://www.librenms.org/), a fully featured network +monitoring system that provides a wealth of features and device support. + +> [!TIP] +> Want to be notified of new releases? Check out 🔔 [Diun (Docker Image Update Notifier)](https://github.com/crazy-max/diun) +> project! + +___ + +* [Features](#features) +* [Demo](#demo) +* [Build locally](#build-locally) +* [Image](#image) +* [Environment variables](#environment-variables) + * [General](#general) + * [Redis](#redis) + * [Dispatcher service](#dispatcher-service) + * [Syslog-ng](#syslog-ng) + * [Snmptrapd](#snmptrapd) + * [Database](#database) + * [Misc](#misc) +* [Volumes](#volumes) +* [Ports](#ports) +* [Usage](#usage) + * [Docker Compose](#docker-compose) + * [Command line](#command-line) + * [First launch](#first-launch) +* [Upgrade](#upgrade) +* [Configuration Management](#configuration-management) + * [Initial Configuration](#initial-configuration) + * [Live Configuration](#live-configuration) + * [Re-Apply YAML Config](#re-apply-yaml-config) + * [Live Config](#live-config) +* [Notes](#notes) + * [LNMS command](#lnms-command) + * [Validate](#validate) + * [Dispatcher service container](#dispatcher-service-container) + * [Syslog-ng container](#syslog-ng-container) + * [Snmptrapd container](#snmptrapd-container) + * [Add a LibreNMS plugin](#add-a-librenms-plugin) + * [Additional Monitoring plugins](#additional-monitoring-plugins) + * [Custom alert templates](#custom-alert-templates) +* [Contributing](#contributing) +* [License](#license) ## Features -### Included - -* Alpine Linux 3.8, Nginx, PHP 7.2 -* Cron tasks as a ["sidecar" container](#cron) +* Run as non-root user +* Multi-platform image +* [Dispatcher service](#dispatcher-service) as "sidecar" container * Syslog-ng support through a ["sidecar" container](#syslog-ng) -* Ability to configure [distributed polling](https://docs.librenms.org/#Extensions/Distributed-Poller/#distributed-poller) -* Ability to add custom Monitoring plugins (Nagios) +* Snmp-trap support through a ["sidecar" container](#snmptrapd) +* Ability to add custom Monitoring plugins +* Ability to add custom alert templates * OPCache enabled to store precompiled script bytecode in shared memory - -### From docker-compose - -* [Traefik](https://github.com/containous/traefik-library-image) as reverse proxy and creation/renewal of Let's Encrypt certificates -* [Memcached](https://github.com/docker-library/memcached) image ready to use for better scalability -* [RRDcached](https://github.com/crazy-max/docker-rrdcached) image ready to use for better scalability -* [Postfix SMTP relay](https://github.com/juanluisbaptiste/docker-postfix) image to send emails +* [s6-overlay](https://github.com/just-containers/s6-overlay/) as process supervisor +* [Traefik](https://github.com/containous/traefik-library-image) as reverse proxy and creation/renewal of Let's Encrypt certificates (see [this template](examples/traefik)) +* [Redis](https://github.com/docker-library/redis) image ready to use for better scalability +* [RRDcached](https://github.com/crazy-max/docker-rrdcached) image ready to use for data caching and graphs +* [msmtpd SMTP relay](https://github.com/crazy-max/docker-msmtpd) image to send emails * [MariaDB](https://github.com/docker-library/mariadb) image as database instance -* Cron jobs as a ["sidecar" container](#cron) -* Syslog-ng support through a ["sidecar" container](#syslog-ng) -## Docker +## Demo -### Environment variables +[![Try in PWD](https://raw.githubusercontent.com/play-with-docker/stacks/master/assets/images/button.png)](https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/librenms/docker/master/examples/pwd/librenms.yml) -#### General +## Build locally -* `TZ` : The timezone assigned to the container (default `UTC`) -* `PUID` : LibreNMS user id (default `1000`) +```console +$ git clone https://github.com/librenms/docker.git docker-librenms +$ cd docker-librenms + +# Build image and output to docker (default) +$ docker buildx bake + +# Build multi-platform image +$ docker buildx bake image-all +``` + +## Image + +Following platforms for this image are available: + +``` +$ docker buildx imagetools inspect librenms/librenms --format "{{json .Manifest}}" | \ + jq -r '.manifests[] | select(.platform.os != null and .platform.os != "unknown") | .platform | "\(.os)/\(.architecture)\(if .variant then "/" + .variant else "" end)"' + +linux/386 +linux/amd64 +linux/arm/v7 +linux/arm64 +linux/ppc64le +linux/s390x +``` + +## Environment variables + +### General + +* `TZ`: The timezone assigned to the container (default `UTC`) +* `PUID`: LibreNMS user id (default `1000`) * `PGID`: LibreNMS group id (default `1000`) -* `MEMORY_LIMIT` : PHP memory limit (default `256M`) -* `UPLOAD_MAX_SIZE` : Upload max size (default `16M`) -* `OPCACHE_MEM_SIZE` : PHP OpCache memory consumption (default `128`) +* `MEMORY_LIMIT`: PHP memory limit (default `256M`) +* `MAX_INPUT_VARS`: PHP max input vars (default `1000`) +* `UPLOAD_MAX_SIZE`: Upload max size (default `16M`) +* `CLEAR_ENV`: Clear environment in FPM workers (default `yes`) +* `FPM_PM_MAX_CHILDREN`: FPM max Children (default: `15`) +* `FPM_PM_START_SERVERS`: FPM start servers (default: `2`) +* `FPM_PM_MIN_SPARE_SERVERS`: FPM min spare servers (default: `1`) +* `FPM_PM_MAX_SPARE_SERVERS`: FPM max spare servers (default: `6`) +* `OPCACHE_MEM_SIZE`: PHP OpCache memory consumption (default `128`) +* `LISTEN_IPV6`: Enable IPv6 for Nginx (default `true`) +* `REAL_IP_FROM`: Trusted addresses that are known to send correct replacement addresses (default `0.0.0.0/32`) +* `REAL_IP_HEADER`: Request header field whose value will be used to replace the client address (default `X-Forwarded-For`) +* `LOG_IP_VAR`: Use another variable to retrieve the remote IP address for access [log_format](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format) on Nginx. (default `remote_addr`) +* `SESSION_DRIVER`: [Driver to use for session storage](https://github.com/librenms/librenms/blob/master/config/session.php) (default `file`) +* `CACHE_DRIVER`: [Driver to use for cache and locks](https://github.com/librenms/librenms/blob/master/config/cache.php) (default `database`) -#### (Distributed) Poller +### Redis -* `LIBRENMS_POLLER_THREADS` : Threads that `poller-wrapper.py` runs (default `16`) -* `LIBRENMS_POLLER_INTERVAL` : Interval in minutes at which `poller-wrapper.py` runs (defaults to `5`) [docs](https://docs.librenms.org/#Support/1-Minute-Polling/) -* `LIBRENMS_DISTRIBUTED_POLLER_ENABLE` : Enable distributed poller functionality -* `LIBRENMS_DISTRIBUTED_POLLER_NAME` : Optional name of poller (defaults to hostname) -* `LIBRENMS_DISTRIBUTED_POLLER_GROUP` : By default, all hosts are shared and have the poller_group = 0. To pin a device to a poller, set it to a value greater than 0 and set the same value here. One can also specify a comma separated string of poller groups. The poller will then poll devices from any of the groups listed. [docs](https://docs.librenms.org/#Extensions/Distributed-Poller/#distributed-poller) -* `LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_HOST` : Memcached server for poller synchronization (Defaults to `$MEMCACHED_HOST`) -* `LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_PORT` : Port of memcached server (Defaults to `$MEMCACHED_PORT`) +> [!NOTE] +> Redis variables should be set on all containers and are required when running +> more than one dispatcher. -#### Cron +* `REDIS_HOST`: Redis host for poller synchronization +* `REDIS_SENTINEL`: Redis Sentinel host for high availability Redis cluster +* `REDIS_SENTINEL_SERVICE`: Redis Sentinel service name (default `librenms`) +* `REDIS_SCHEME`: Redis scheme (default `tcp`) +* `REDIS_PORT`: Redis port (default `6379`) +* `REDIS_PASSWORD`: Redis password +* `REDIS_DB`: Redis database (default `0`) +* `REDIS_CACHE_DB`: Redis cache database (default `1`) -* `LIBRENMS_CRON_DISCOVERY_ENABLE` : Enable LibreNMS discovery for this container cronjobs (default `true`) -* `LIBRENMS_CRON_DAILY_ENABLE` : Enable LibreNMS daily script for this container cronjobs (default `true`) -* `LIBRENMS_CRON_ALERTS_ENABLE` : Enable LibreNMS alerts generation for this container cronjobs (default `true`) -* `LIBRENMS_CRON_BILLING_ENABLE` : Enable LibreNMS billing polling for this container cronjobs (default `true`) -* `LIBRENMS_CRON_BILLING_CALCULATE_ENABLE` : Enable LibreNMS billing for this container cronjobs (default `true`) -* `LIBRENMS_CRON_CHECK_SERVICES_ENABLE` : Enable LibreNMS service checks for this container cronjobs (default `true`) -* `LIBRENMS_CRON_POLLER_ENABLE` : Enable LibreNMS polling for this container cronjobs (default `true`) +### Dispatcher service -#### Database +> [!WARNING] +> You need at least one dispatcher sidecar, otherwise poller will not run [sidecar dispatcher container](#dispatcher-service-container). -* `DB_HOST` : MySQL database hostname / IP address -* `DB_PORT` : MySQL database port (default `3306`) -* `DB_NAME` : MySQL database name (default `librenms`) -* `DB_USER` : MySQL user (default `librenms`) -* `DB_PASSWORD` : MySQL password (default `librenms`) -* `DB_TIMEOUT` : Time in seconds after which we stop trying to reach the MySQL server (useful for clusters, default `30`) +* `SIDECAR_DISPATCHER`: Set to `1` to enable sidecar dispatcher mode for this container (default `0`) +* `DISPATCHER_NODE_ID`: Unique node ID for your dispatcher service +* `DISPATCHER_ARGS`: Additional args to pass to the [dispatcher service](https://github.com/librenms/librenms/blob/master/librenms-service.py) -#### Misc +### Syslog-ng -* `LIBRENMS_SNMP_COMMUNITY` : This container's SNMP v2c community string (default `librenmsdocker`) -* `MEMCACHED_HOST` : Hostname / IP address of a Memcached server -* `MEMCACHED_PORT` : Port of the Memcached server (default `11211`) -* `RRDCACHED_HOST` : Hostname / IP address of a RRDcached server -* `RRDCACHED_PORT` : Port of the RRDcached server (default `42217`) +> [!WARNING] +> Only used if you enable and run a [sidecar syslog-ng container](#syslog-ng-container). -### Volumes +* `SIDECAR_SYSLOGNG`: Set to `1` to enable sidecar syslog-ng mode for this container (default `0`) -* `/data` : Contains configuration, rrd database, logs, additional Monitoring plugins, additional syslog-ng config files +### Snmptrapd -### Ports +> [!WARNING] +> Only used if you enable and run a [sidecar snmptrapd container](#snmptrapd-container). -* `80` : HTTP port +* `SIDECAR_SNMPTRAPD`: Set to `1` to enable sidecar snmptrapd mode for this container (default `0`) +* `SNMP_PROCESSING_TYPE`: Sets which type of processing (`log`, `execute`, and/or `net`) to use with the SNMP trap (default `log,execute,net`) +* `SNMP_USER`: Defines what username to authenticate with (default `librenms_user`) +* `SNMP_AUTH`: Defines what password to authenticate with (default `auth_pass` should not be used, but will work) +* `SNMP_PRIV`: Defines what password to encrypt packages with (default `priv_pass` should not be used, but will work) +* `SNMP_AUTH_PROTO`: Sets what protocol (`MD5`|`SHA`) to use for authentication (default `SHA`) +* `SNMP_PRIV_PROTO`: Sets what protocol (`DES`|`AES`) to use for encryption of packages (default `AES`) +* `SNMP_SECURITY_LEVEL`: Sets what security level (`noauth`|`priv`) to use (default `priv`) +* `SNMP_ENGINEID`: Defines what SNMP EngineID to use (default `1234567890`) +* `SNMP_DISABLE_AUTHORIZATION`: Will disable the above access control checks, and revert to the previous behaviour of accepting all incoming notifications. (default `yes`) +* `SNMP_EXTRA_MIB_DIRS`: [Additional directories where MIB files are for SNMP Traps](https://docs.librenms.org/Extensions/SNMP-Trap-Handler/#option-2) (example `/opt/librenms/mibs/veeam`) -## Use this image +### Database + +* `DB_HOST`: MySQL database hostname / IP address +* `DB_PORT`: MySQL database port (default `3306`) +* `DB_NAME`: MySQL database name (default `librenms`) +* `DB_USER`: MySQL user (default `librenms`) +* `DB_PASSWORD`: MySQL password (default `librenms`) +* `DB_TIMEOUT`: Time in seconds after which we stop trying to reach the MySQL server (useful for clusters, default `60`) + +### Misc + +* `LIBRENMS_BASE_URL`: URL of your LibreNMS instance (default `/`) +* `LIBRENMS_SNMP_COMMUNITY`: This container's SNMP v2c community string (default `librenmsdocker`) +* `MEMCACHED_HOST`: Hostname / IP address of a Memcached server +* `MEMCACHED_PORT`: Port of the Memcached server (default `11211`) +* `RRDCACHED_SERVER`: RRDcached server (eg. `rrdcached:42217`) + +## Volumes + +* `/data`: Contains configuration, plugins, rrd database, logs, additional Monitoring plugins, additional syslog-ng config files + +> [!WARNING] +> Note that the volume should be owned by the user/group with the specified +> `PUID` and `PGID`. If you don't give the volume correct permissions, the +> container may not start. + +## Ports + +* `8000`: HTTP port +* `514 514/udp`: Syslog ports (only used if you enable and run a [sidecar syslog-ng container](#syslog-ng-container)) +* `162 162/udp`: Snmptrapd ports (only used if you enable and run a [sidecar snmptrapd container](#snmptrapd-container)) + +## Usage ### Docker Compose -Docker compose is the recommended way to run this image. Copy the content of folder [examples/compose](examples/compose) in `/var/librenms/` on your host for example. Edit the compose and env files with your preferences and run the following commands : +Docker compose is the recommended way to run this image. Copy the content of +folder [examples/compose](examples/compose) in `/var/librenms/` on your host +for example. Edit the compose and env files with your preferences and run the +following commands: -```bash -touch acme.json -chmod 600 acme.json -docker-compose up -d -docker-compose logs -f +```console +$ docker compose up -d +$ docker compose logs -f ``` ### Command line -You can also use the following minimal command : +You can also use the following minimal command: -```bash -docker run -d -p 80:80 --name librenms \ +```console +$ docker run -d -p 8000:8000 --name librenms \ -v $(pwd)/data:/data \ -e "DB_HOST=db" \ - crazymax/librenms:latest + librenms/librenms:latest ``` -> `-e "DB_HOST=db"`
-> :warning: `db` must be a running MySQL instance +> [!WARNING] +> `db` must be a running MySQL instance. -## Notes +### First launch -### Edit configuration +When you first access the webui, you will be prompted to create an admin user. -You can edit configuration of LibreNMS by placing `*.php` files inside `/data/config` folder. Let's say you want to edit the [WebUI config](https://docs.librenms.org/#Support/Configuration/#webui-settings). Create a file called for example `/data/config/webui.php` with this content : +> [!NOTE] +> If you lose access, you can create another one using the [`lnms` command](#lnms-command). + +## Upgrade + +To upgrade to the latest version of LibreNMS, pull the newer image and launch +the container. LibreNMS will upgrade automatically: + +```console +$ docker compose down +$ docker compose pull +$ docker compose up -d +``` + +## Configuration Management + +### Initial Configuration + +You can set the initial configuration of LibreNMS by placing `*.yaml` files inside `/data/config` folder. Let's say you want to edit the [WebUI config](https://docs.librenms.org/Support/Configuration/#webui-settings). +Create a file called for example `/data/config/webui.yaml` with this content : + +```yaml +page_refresh: 300 +webui.default_dashboard_id: 0 +``` + +This configuration will be seeded into the LibreNMS database when it is first deployed +and will override the default values. + +### Live Configuration + +You can edit the running configuration via the LibreNMS web UI or `lnms config:set` + +```bash +docker compose exec librenms lnms config:set page_refresh 300 +``` + +### Re-Apply YAML Config + +Set `REAPPLY_YAML_CONFIG=1` to overwrite any settings that are set during initial config +or via user config back to their initial values every time the container is deployed. + +### Live Config + +Using this config method, configuration changes will be reflected live on the containers, BUT +you will be unable to edit the configured settings from within the LibreNMS web UI or lnms config:set. + +The same example using PHP `/data/config/webui.php` ```php 10 +```console +$ docker compose exec librenms lnms ``` -> :warning: Substitute your desired username ``, password `` and email address `` - ### Validate -If you want to validate your installation from the CLI, type the following command : +If you want to validate your installation from the CLI, type the following +command: -```text -$ docker exec -it --user librenms librenms php validate.php +```console +$ docker compose exec --user librenms librenms php validate.php ==================================== Component | Version --------- | ------- -LibreNMS | 1.41 -DB Schema | 253 -PHP | 7.2.7 -MySQL | 10.2.16-MariaDB-10.2.16+maria~jessie -RRDTool | 1.7.0 -SNMP | NET-SNMP 5.7.3 +LibreNMS | 1.64 +DB Schema | 2020_04_19_010532_eventlog_sensor_reference_cleanup (165) +PHP | 7.3.18 +Python | 3.8.2 +MySQL | 10.4.13-MariaDB-1:10.4.13+maria~bionic +RRDTool | 1.7.2 +SNMP | NET-SNMP 5.8 ==================================== -[OK] Composer Version: 1.6.5 -[OK] Dependencies up-to-date. +[OK] Installed from the official Docker image; no Composer required [OK] Database connection successful [OK] Database schema correct -[WARN] You have not added any devices yet. - [FIX] You can add a device in the webui or with ./addhost.php -[WARN] Your install is over 24 hours out of date, last update: Sat, 30 Jun 2018 21:37:37 +0000 - [FIX] Make sure your daily.sh cron is running and run ./daily.sh by hand to see if there are any errors. -[WARN] Your local git branch is not master, this will prevent automatic updates. - [FIX] You can switch back to master with git checkout master +[WARN] IPv6 is disabled on your server, you will not be able to add IPv6 devices. +[WARN] Updates are managed through the official Docker image ``` -### Update database +### Dispatcher service container -To update the database manually, type the following command : +If you want to enable the new [Dispatcher service](https://docs.librenms.org/Extensions/Dispatcher-Service/), +you have to run a "sidecar" container (see dispatcher service in +[compose.yml](examples/compose/compose.yml) example) or run a simple container +like this: -```bash -$ docker exec -it --user librenms librenms php build-base.php -``` - -### Cron - -If you want to enable the cron job, you have to run a "sidecar" container like in the [docker-compose file](examples/compose/docker-compose.yml) or run a simple container like this : - -```bash -docker run -d --name librenms-cron \ +```console +$ docker run -d --name librenms_dispatcher \ --env-file $(pwd)/librenms.env \ + -e SIDECAR_DISPATCHER=1 \ + -e DISPATCHER_NODE_ID=dispatcher1 \ -v librenms:/data \ - crazymax/librenms:latest /usr/local/bin/cron + librenms/librenms:latest ``` -> `-v librenms:/data`
-> :warning: `librenms` must be a valid volume already attached to a LibreNMS container +> [!WARNING] +> `librenms` must be a valid volume already attached to a LibreNMS container. -### Syslog-ng +### Syslog-ng container -If you want to enable syslog-ng, you have to run a "sidecar" container like in the [docker-compose file](examples/compose/docker-compose.yml) or run a simple container like this : +If you want to enable syslog-ng, you have to run a "sidecar" container (see +syslog-ng service in [compose.yml](examples/compose/compose.yml) example) or +run a simple container like this: -```bash -docker run -d --name librenms-syslog-ng \ +```console +$ docker run -d --name librenms_syslog \ --env-file $(pwd)/librenms.env \ + -e SIDECAR_SYSLOGNG=1 \ -p 514 -p 514/udp \ -v librenms:/data \ - crazymax/librenms:latest /usr/sbin/syslog-ng -F + librenms/librenms:latest ``` -You have to create a configuration file to enable syslog in LibreNMS too. Create a file called for example `/data/config/syslog.php` with this content : +> [!WARNING] +> `librenms` must be a valid volume already attached to a LibreNMS container. -```php - ⚠️ Container has to be restarted to propagate changes - -## Upgrade - -To upgrade to the latest version of LibreNMS, pull the newer image and launch the container. LibreNMS will upgrade automatically : - -```bash -docker-compose pull -docker-compose up -d +```console +$ docker run -d --name librenms_snmptrapd \ + --env-file $(pwd)/librenms.env \ + -e SIDECAR_SNMPTRAPD=1 \ + -p 162 -p 162/udp \ + -v librenms:/data \ + librenms/librenms:latest ``` -## How can I help ? +> [!WARNING] +> `librenms` must be a valid volume already attached to a LibreNMS container. -All kinds of contributions are welcome :raised_hands:!
-The most basic way to show your support is to star :star2: the project, or to raise issues :speech_balloon:
-But we're not gonna lie to each other, I'd rather you buy me a beer or two :beers:! +### Add a LibreNMS plugin -[![Paypal](.res/paypal.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=962TPYQKMQ2UE) +You can add [plugins for LibreNMS](https://docs.librenms.org/Extensions/Plugin-System/) +in `/data/plugins/`. If you add a plugin that already exists in LibreNMS, it +will be removed and yours will be used. + +> [!WARNING] +> Container has to be restarted to propagate changes. + +### Additional Monitoring plugins + +You can add a custom Monitoring plugin in `/data/monitoring-plugins/`. + +Some plugins can be found in the [Monitoring Plugins](https://github.com/monitoring-plugins/monitoring-plugins#readme) +repo, or in the [unofficial fork for Nagios](https://github.com/nagios-plugins/nagios-plugins#readme). + +> [!WARNING] +> Container has to be restarted to propagate changes. + +### Custom alert templates + +You can add [Laravel alert templates](https://docs.librenms.org/Alerting/Templates/#base-templates) +in `/data/alert-templates/`. + +> [!WARNING] +> Container has to be restarted to propagate changes. + +## Contributing + +Want to contribute? Awesome! The most basic way to show your support is to star +the project, or to raise issues. You can also support this project by [**becoming a sponsor on GitHub**](https://github.com/sponsors/crazy-max) +or by making a [PayPal donation](https://www.paypal.me/crazyws) to ensure this +journey continues indefinitely! + +Thanks again for your support, it is much appreciated! :pray: ## License diff --git a/assets/etc/supervisord.conf b/assets/etc/supervisord.conf deleted file mode 100644 index 90df761..0000000 --- a/assets/etc/supervisord.conf +++ /dev/null @@ -1,21 +0,0 @@ -[supervisord] -nodaemon = true -user = root -logfile = /var/log/supervisord/supervisord.log -pidfile = /var/run/supervisord.pid -childlogdir = /var/log/supervisord/ -logfile_maxbytes = 50MB -logfile_backups = 10 -loglevel = info - -[supervisorctl] -serverurl = unix:///var/run/supervisor.sock - -[unix_http_server] -file = /var/run/supervisor.sock - -[rpcinterface:supervisor] -supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface - -[include] -files = /etc/supervisord/*.conf diff --git a/assets/etc/supervisord/nginx.conf b/assets/etc/supervisord/nginx.conf deleted file mode 100644 index 70a8762..0000000 --- a/assets/etc/supervisord/nginx.conf +++ /dev/null @@ -1,8 +0,0 @@ -[program:nginx] -command = /usr/sbin/nginx -stdout_logfile = /dev/stdout -stdout_logfile_maxbytes = 0 -stderr_logfile = /dev/stderr -stderr_logfile_maxbytes = 0 -autorestart = false -startentries = 0 diff --git a/assets/etc/supervisord/php.conf b/assets/etc/supervisord/php.conf deleted file mode 100644 index 8ef3a3b..0000000 --- a/assets/etc/supervisord/php.conf +++ /dev/null @@ -1,8 +0,0 @@ -[program:php] -command = /usr/sbin/php-fpm7 -stdout_logfile = /dev/stdout -stdout_logfile_maxbytes = 0 -stderr_logfile = /dev/stderr -stderr_logfile_maxbytes = 0 -autorestart = false -startentries = 0 diff --git a/assets/etc/supervisord/snmpd.conf b/assets/etc/supervisord/snmpd.conf deleted file mode 100644 index d3a1ef4..0000000 --- a/assets/etc/supervisord/snmpd.conf +++ /dev/null @@ -1,7 +0,0 @@ -[program:snmpd] -command = /usr/sbin/snmpd -f -c /etc/snmpd.conf -startentries = 0 -stdout_logfile = /proc/1/fd/1 -stdout_logfile_maxbytes = 0 -stderr_logfile = /proc/1/fd/2 -stderr_logfile_maxbytes = 0 \ No newline at end of file diff --git a/assets/tpls/etc/php7/php-fpm.d/www.conf b/assets/tpls/etc/php7/php-fpm.d/www.conf deleted file mode 100644 index ef857fe..0000000 --- a/assets/tpls/etc/php7/php-fpm.d/www.conf +++ /dev/null @@ -1,28 +0,0 @@ -[global] -daemonize = no -error_log = /proc/self/fd/2 - -[www] -user = librenms -group = librenms - -listen = /run/php-fpm7.sock -listen.owner = librenms -listen.group = librenms - -pm = dynamic -pm.max_children = 15 -pm.start_servers = 2 -pm.min_spare_servers = 1 -pm.max_spare_servers = 6 -request_terminate_timeout = 0 - -; if we send this to /proc/self/fd/1, it never appears -access.log = /proc/self/fd/2 - -php_admin_value[post_max_size] = @UPLOAD_MAX_SIZE@ -php_admin_value[upload_max_filesize] = @UPLOAD_MAX_SIZE@ -php_admin_value[max_execution_time] = 10800 -php_admin_value[max_input_time] = 3600 -php_admin_value[expose_php] = Off -php_admin_value[memory_limit] = @MEMORY_LIMIT@ \ No newline at end of file diff --git a/assets/usr/local/bin/cron b/assets/usr/local/bin/cron deleted file mode 100644 index 53d6c2c..0000000 --- a/assets/usr/local/bin/cron +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -set -e - -exec busybox crond -f -L /dev/stdout diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 0000000..4c10aa3 --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,40 @@ +variable "DEFAULT_TAG" { + default = "librenms:local" +} + +variable "LIBRENMS_VERSION" { + default = null +} + +// Special target: https://github.com/docker/metadata-action#bake-definition +target "docker-metadata-action" { + tags = ["${DEFAULT_TAG}"] + args = { + LIBRENMS_VERSION = LIBRENMS_VERSION + } +} + +// Default target if none specified +group "default" { + targets = ["image-local"] +} + +target "image" { + inherits = ["docker-metadata-action"] +} + +target "image-local" { + inherits = ["image"] + output = ["type=docker"] +} + +target "image-all" { + inherits = ["image"] + platforms = [ + "linux/amd64", + "linux/arm/v7", + "linux/arm64", + "linux/386", + "linux/s390x" + ] +} diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100644 index b064968..0000000 --- a/entrypoint.sh +++ /dev/null @@ -1,318 +0,0 @@ -#!/bin/bash - -function runas_librenms() { - su - librenms -s /bin/sh -c "$1" -} - -TZ=${TZ:-"UTC"} -PUID=${PUID:-1000} -PGID=${PGID:-1000} - -MEMORY_LIMIT=${MEMORY_LIMIT:-"256M"} -UPLOAD_MAX_SIZE=${UPLOAD_MAX_SIZE:-"16M"} -OPCACHE_MEM_SIZE=${OPCACHE_MEM_SIZE:-"128"} - -MEMCACHED_PORT=${MEMCACHED_PORT:-"11211"} -RRDCACHED_PORT=${RRDCACHED_PORT:-"42217"} - -LIBRENMS_POLLER_THREADS=${LIBRENMS_POLLER_THREADS:-"16"} -LIBRENMS_POLLER_INTERVAL=${LIBRENMS_POLLER_INTERVAL:-"5"} - -LIBRENMS_DISTRIBUTED_POLLER_ENABLE=${LIBRENMS_DISTRIBUTED_POLLER_ENABLE:-false} -LIBRENMS_DISTRIBUTED_POLLER_NAME=${LIBRENMS_DISTRIBUTED_POLLER_NAME:-$(hostname -f)} -LIBRENMS_DISTRIBUTED_POLLER_GROUP=${LIBRENMS_DISTRIBUTED_POLLER_GROUP:-'0'} -LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_HOST=${LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_HOST:-"${MEMCACHED_HOST}"} -LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_PORT=${LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_PORT:-"${MEMCACHED_PORT}"} - -LIBRENMS_CRON_DISCOVERY_ENABLE=${LIBRENMS_CRON_DISCOVERY_ENABLE:-true} -LIBRENMS_CRON_DAILY_ENABLE=${LIBRENMS_CRON_DAILY_ENABLE:-true} -LIBRENMS_CRON_ALERTS_ENABLE=${LIBRENMS_CRON_ALERTS_ENABLE:-true} -LIBRENMS_CRON_BILLING_ENABLE=${LIBRENMS_CRON_BILLING_ENABLE:-true} -LIBRENMS_CRON_BILLING_CALCULATE_ENABLE=${LIBRENMS_CRON_BILLING_CALCULATE_ENABLE:-true} -LIBRENMS_CRON_CHECK_SERVICES_ENABLE=${LIBRENMS_CRON_CHECK_SERVICES_ENABLE:-true} -LIBRENMS_CRON_POLLER_ENABLE=${LIBRENMS_CRON_POLLER_ENABLE:-true} - -DB_PORT=${DB_PORT:-"3306"} -DB_NAME=${DB_NAME:-"librenms"} -DB_USER=${DB_USER:-"librenms"} -DB_TIMEOUT=${DB_TIMEOUT:-"30"} - -MEMCACHED_PORT=${MEMCACHED_PORT:-"11211"} -RRDCACHED_PORT=${RRDCACHED_PORT:-"42217"} - -# From https://github.com/docker-library/mariadb/blob/master/docker-entrypoint.sh#L21-L41 -# usage: file_env VAR [DEFAULT] -# ie: file_env 'XYZ_DB_PASSWORD' 'example' -# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of -# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) -file_env() { - local var="$1" - local fileVar="${var}_FILE" - local def="${2:-}" - if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then - echo >&2 "error: both $var and $fileVar are set (but are exclusive)" - exit 1 - fi - local val="$def" - if [ "${!var:-}" ]; then - val="${!var}" - elif [ "${!fileVar:-}" ]; then - val="$(< "${!fileVar}")" - fi - export "$var"="$val" - unset "$fileVar" -} - -# Timezone -echo "Setting timezone to ${TZ}..." -ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime -echo ${TZ} > /etc/timezone -sed -i -e "s|date\.timezone.*|date\.timezone = ${TZ}|" /etc/php7/php.ini \ - -# Change librenms UID / GID -echo "Checking if librenms UID / GID has changed..." -if [ $(id -u librenms) != ${PUID} ]; then - usermod -u ${PUID} librenms -fi -if [ $(id -g librenms) != ${PGID} ]; then - groupmod -g ${PGID} librenms -fi - -# PHP -echo "Setting PHP-FPM configuration..." -sed -e "s/@MEMORY_LIMIT@/$MEMORY_LIMIT/g" \ - -e "s/@UPLOAD_MAX_SIZE@/$UPLOAD_MAX_SIZE/g" \ - /tpls/etc/php7/php-fpm.d/www.conf > /etc/php7/php-fpm.d/www.conf - -# OpCache -echo "Setting OpCache configuration..." -sed -e "s/@OPCACHE_MEM_SIZE@/$OPCACHE_MEM_SIZE/g" \ - /tpls/etc/php7/conf.d/opcache.ini > /etc/php7/conf.d/opcache.ini - -# Nginx -echo "Setting Nginx configuration..." -sed -e "s/@UPLOAD_MAX_SIZE@/$UPLOAD_MAX_SIZE/g" \ - /tpls/etc/nginx/nginx.conf > /etc/nginx/nginx.conf - -# SNMP -echo "Updating SNMP community..." -file_env 'LIBRENMS_SNMP_COMMUNITY' 'librenmsdocker' -sed -i -e "s/RANDOMSTRINGGOESHERE/${LIBRENMS_SNMP_COMMUNITY}/" /etc/snmp/snmpd.conf - -# Init files and folders -echo "Initializing LibreNMS files / folders..." -mkdir -p ${DATA_PATH}/config \ - ${DATA_PATH}/logs \ - ${DATA_PATH}/monitoring-plugins \ - ${DATA_PATH}/rrd -rm -f ${LIBRENMS_PATH}/config.d/* - -echo "Setting LibreNMS configuration..." - -# Config : Directories - cat > ${LIBRENMS_PATH}/config.d/directories.php <&2 echo "ERROR: DB_HOST must be defined" - exit 1 -fi -file_env 'DB_PASSWORD' -if [ -z "$DB_PASSWORD" ]; then - >&2 echo "ERROR: Either DB_PASSWORD or DB_PASSWORD_FILE must be defined" - exit 1 -fi -cat > ${LIBRENMS_PATH}/config.d/database.php < ${LIBRENMS_PATH}/config.d/user.php < /usr/sbin/fping6 -chmod +x /usr/sbin/fping6 -cat > ${LIBRENMS_PATH}/config.d/fping.php < ${LIBRENMS_PATH}/config.d/autoupdate.php < ${LIBRENMS_PATH}/config.d/services.php < ${LIBRENMS_PATH}/config.d/memcached.php < ${LIBRENMS_PATH}/config.d/rrdcached.php < ${LIBRENMS_PATH}/config.d/distributed_poller.php <>" - echo ">> Sidecar cron container detected" - echo ">>" - - # Init - if [ -z "$CRONTAB_PATH" ]; then - >&2 echo "ERROR: CRONTAB_PATH must be defined" - exit 1 - fi - - rm -rf ${CRONTAB_PATH} - mkdir -m 0644 -p ${CRONTAB_PATH} - touch ${CRONTAB_PATH}/librenms - - # Add crontab - cat ${LIBRENMS_PATH}/librenms.nonroot.cron > ${CRONTAB_PATH}/librenms - sed -i -e "s/ librenms //" ${CRONTAB_PATH}/librenms - - if [ $LIBRENMS_CRON_DISCOVERY_ENABLE != true ]; then - sed -i "/discovery.php/d" ${CRONTAB_PATH}/librenms - fi - - if [ $LIBRENMS_CRON_DAILY_ENABLE != true ]; then - sed -i "/daily.sh/d" ${CRONTAB_PATH}/librenms - fi - - if [ $LIBRENMS_CRON_ALERTS_ENABLE != true ]; then - sed -i "/alerts.php/d" ${CRONTAB_PATH}/librenms - fi - - if [ $LIBRENMS_CRON_BILLING_ENABLE != true ]; then - sed -i "/poll-billing.php/d" ${CRONTAB_PATH}/librenms - fi - - if [ $LIBRENMS_CRON_BILLING_CALCULATE_ENABLE != true ]; then - sed -i "/billing-calculate.php/d" ${CRONTAB_PATH}/librenms - fi - - if [ $LIBRENMS_CRON_CHECK_SERVICES_ENABLE != true ]; then - sed -i "/check-services.php/d" ${CRONTAB_PATH}/librenms - fi - - sed -i "/poller-wrapper.py/d" ${CRONTAB_PATH}/librenms - if [ $LIBRENMS_CRON_POLLER_ENABLE = true ]; then - cat >> ${CRONTAB_PATH}/librenms <>" - echo ">> Sidecar syslog-ng container detected" - echo ">>" - - # Init - mkdir -p ${DATA_PATH}/syslog-ng /run/syslog-ng - chown -R librenms. ${DATA_PATH}/syslog-ng /run/syslog-ng -else - echo "Waiting ${DB_TIMEOUT}s for database to be ready..." - counter=1 - while ! ${dbcmd} -e "show databases;" > /dev/null 2>&1; do - sleep 1 - counter=`expr $counter + 1` - if [ ${counter} -gt ${DB_TIMEOUT} ]; then - >&2 echo "ERROR: Failed to connect to database on $DB_HOST" - exit 1 - fi; - done - echo "Database ready!" - - counttables=$(echo 'SHOW TABLES' | ${dbcmd} "$DB_NAME" | wc -l) - - echo "Updating database schema..." - runas_librenms "php build-base.php" - - if [ "${counttables}" -eq "0" ]; then - echo "Creating admin user..." - runas_librenms "php adduser.php librenms librenms 10 librenms@librenms.docker" - fi -fi - -exec "$@" diff --git a/examples/compose/.env b/examples/compose/.env new file mode 100644 index 0000000..d6c0aed --- /dev/null +++ b/examples/compose/.env @@ -0,0 +1,7 @@ +TZ=Europe/Paris +PUID=1000 +PGID=1000 + +MYSQL_DATABASE=librenms +MYSQL_USER=librenms +MYSQL_PASSWORD=asupersecretpassword diff --git a/examples/compose/compose.yml b/examples/compose/compose.yml new file mode 100644 index 0000000..c090df4 --- /dev/null +++ b/examples/compose/compose.yml @@ -0,0 +1,158 @@ +name: librenms + +services: + db: + image: mariadb:10 + container_name: librenms_db + command: + - "mysqld" + - "--innodb-file-per-table=1" + - "--lower-case-table-names=0" + - "--character-set-server=utf8mb4" + - "--collation-server=utf8mb4_unicode_ci" + volumes: + - "./db:/var/lib/mysql" + environment: + - "TZ=${TZ}" + - "MARIADB_RANDOM_ROOT_PASSWORD=yes" + - "MYSQL_DATABASE=${MYSQL_DATABASE}" + - "MYSQL_USER=${MYSQL_USER}" + - "MYSQL_PASSWORD=${MYSQL_PASSWORD}" + restart: always + + redis: + image: redis:7.2-alpine + container_name: librenms_redis + environment: + - "TZ=${TZ}" + restart: always + + msmtpd: + image: crazymax/msmtpd:latest + container_name: librenms_msmtpd + env_file: + - "./msmtpd.env" + restart: always + + librenms: + image: librenms/librenms:latest + container_name: librenms + hostname: librenms + cap_add: + - NET_ADMIN + - NET_RAW + ports: + - target: 8000 + published: 8000 + protocol: tcp + depends_on: + - db + - redis + - msmtpd + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + restart: always + + dispatcher: + image: librenms/librenms:latest + container_name: librenms_dispatcher + hostname: librenms-dispatcher + cap_add: + - NET_ADMIN + - NET_RAW + depends_on: + - librenms + - redis + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + - "DISPATCHER_NODE_ID=dispatcher1" + - "SIDECAR_DISPATCHER=1" + restart: always + + syslogng: + image: librenms/librenms:latest + container_name: librenms_syslogng + hostname: librenms-syslogng + cap_add: + - NET_ADMIN + - NET_RAW + depends_on: + - librenms + - redis + ports: + - target: 514 + published: 514 + protocol: tcp + - target: 514 + published: 514 + protocol: udp + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + - "SIDECAR_SYSLOGNG=1" + restart: always + + snmptrapd: + image: librenms/librenms:latest + container_name: librenms_snmptrapd + hostname: librenms-snmptrapd + cap_add: + - NET_ADMIN + - NET_RAW + depends_on: + - librenms + - redis + ports: + - target: 162 + published: 162 + protocol: tcp + - target: 162 + published: 162 + protocol: udp + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + - "SIDECAR_SNMPTRAPD=1" + restart: always diff --git a/examples/compose/docker-compose.yml b/examples/compose/docker-compose.yml deleted file mode 100644 index 1dbddc8..0000000 --- a/examples/compose/docker-compose.yml +++ /dev/null @@ -1,136 +0,0 @@ -version: "3.2" - -services: - traefik: - image: traefik:1.6-alpine - command: - - "--logLevel=INFO" - - "--defaultentrypoints=http,https" - - "--entryPoints=Name:http Address::80 Redirect.EntryPoint:https" - - "--entryPoints=Name:https Address::443 TLS" - - "--docker" - - "--docker.exposedbydefault=false" - - "--docker.domain=example.com" - - "--acme=true" - - "--acme.acmelogging=true" - - "--acme.email=webmaster@example.com" - - "--acme.storage=acme.json" - - "--acme.entryPoint=https" - - "--acme.onhostrule=true" - - "--acme.httpchallenge=true" - - "--acme.httpchallenge.entrypoint=http" - ports: - - target: 80 - published: 80 - protocol: tcp - mode: host - - target: 443 - published: 443 - protocol: tcp - mode: host - volumes: - - "./acme.json:/acme.json" - - "/var/run/docker.sock:/var/run/docker.sock" - restart: always - - db: - image: mariadb:10.2 - command: - - "mysqld" - - "--sql-mode=" - - "--innodb-file-per-table=1" - - "--lower-case-table-names=0" - volumes: - - "./db:/var/lib/mysql" - environment: - - "TZ=Europe/Paris" - - "MYSQL_ALLOW_EMPTY_PASSWORD=yes" - - "MYSQL_DATABASE=librenms" - - "MYSQL_USER=librenms" - - "MYSQL_PASSWORD=asupersecretpassword" - restart: always - - memcached: - image: memcached:alpine - environment: - - "TZ=Europe/Paris" - restart: always - - rrdcached: - image: crazymax/rrdcached - volumes: - - "./librenms/rrd:/data/db" - - "./rrd-journal:/data/journal" - environment: - - "TZ=Europe/Paris" - - "PUID=1000" - - "PGID=1000" - - "LOG_LEVEL=LOG_INFO" - - "WRITE_TIMEOUT=1800" - - "WRITE_JITTER=1800" - - "WRITE_THREADS=4" - - "FLUSH_DEAD_DATA_INTERVAL=3600" - restart: always - - smtp: - image: juanluisbaptiste/postfix - volumes: - - "/etc/localtime:/etc/localtime:ro" - environment: - - "SERVER_HOSTNAME=librenms.example.com" - - "SMTP_SERVER=smtp.example.com" - - "SMTP_USERNAME=smtp@example.com" - - "SMTP_PASSWORD=" - restart: always - - app: - image: crazymax/librenms:latest - domainname: example.com - hostname: librenms - depends_on: - - db - - memcached - - rrdcached - - smtp - volumes: - - "./librenms:/data" - labels: - - "traefik.enable=true" - - "traefik.backend=librenms" - - "traefik.port=80" - - "traefik.frontend.rule=Host:librenms.example.com" - env_file: - - "./librenms.env" - restart: always - - cron: - image: crazymax/librenms:latest - command: - - "/usr/local/bin/cron" - depends_on: - - app - volumes: - - "./librenms:/data" - env_file: - - "./librenms.env" - restart: always - - syslog-ng: - image: crazymax/librenms:latest - command: - - "/usr/sbin/syslog-ng" - - "-F" - depends_on: - - app - ports: - - target: 514 - published: 514 - protocol: tcp - - target: 514 - published: 514 - protocol: udp - volumes: - - "./librenms:/data" - env_file: - - "./librenms.env" - restart: always diff --git a/examples/compose/librenms.env b/examples/compose/librenms.env index eda0f4f..a1d0492 100644 --- a/examples/compose/librenms.env +++ b/examples/compose/librenms.env @@ -1,29 +1,16 @@ -TZ=Europe/Paris -PUID=1000 -PGID=1000 MEMORY_LIMIT=256M +MAX_INPUT_VARS=1000 UPLOAD_MAX_SIZE=16M OPCACHE_MEM_SIZE=128 +REAL_IP_FROM=0.0.0.0/32 +REAL_IP_HEADER=X-Forwarded-For +LOG_IP_VAR=remote_addr -LIBRENMS_POLLER_THREADS=16 -LIBRENMS_POLLER_INTERVAL=5 - -LIBRENMS_CRON_DISCOVERY_ENABLE=true -LIBRENMS_CRON_DAILY_ENABLE=true -LIBRENMS_CRON_ALERTS_ENABLE=true -LIBRENMS_CRON_BILLING_ENABLE=true -LIBRENMS_CRON_BILLING_CALCULATE_ENABLE=true -LIBRENMS_CRON_CHECK_SERVICES_ENABLE=true -LIBRENMS_CRON_POLLER_ENABLE=true - -DB_HOST=db -DB_NAME=librenms -DB_USER=librenms -DB_PASSWORD=asupersecretpassword -DB_TIMEOUT=30 +CACHE_DRIVER=redis +SESSION_DRIVER=redis +REDIS_HOST=redis LIBRENMS_SNMP_COMMUNITY=librenmsdocker -MEMCACHED_HOST=memcached -MEMCACHED_PORT=11211 -RRDCACHED_HOST=rrdcached -RRDCACHED_PORT=42217 + +LIBRENMS_WEATHERMAP=false +LIBRENMS_WEATHERMAP_SCHEDULE=*/5 * * * * diff --git a/examples/compose/msmtpd.env b/examples/compose/msmtpd.env new file mode 100644 index 0000000..170bec9 --- /dev/null +++ b/examples/compose/msmtpd.env @@ -0,0 +1,10 @@ +# https://github.com/crazy-max/docker-msmtpd +SMTP_HOST=smtp.gmail.com +SMTP_PORT=587 +SMTP_TLS=on +SMTP_STARTTLS=on +SMTP_TLS_CHECKCERT=on +SMTP_AUTH=on +SMTP_USER=foo +SMTP_PASSWORD=bar +SMTP_FROM=foo@gmail.com diff --git a/examples/pwd/librenms.yml b/examples/pwd/librenms.yml new file mode 100644 index 0000000..07abe40 --- /dev/null +++ b/examples/pwd/librenms.yml @@ -0,0 +1,152 @@ +version: "3.5" + +x-env-global: &env-global + - &MYSQL_DATABASE "librenms" + - &MYSQL_USER "librenms" + - &MYSQL_PASSWORD "asupersecretpassword" + - &TZ "UTC" + - &PUID "1000" + - &PGID "1000" + +x-envlibrenms: &envlibrenms + MEMORY_LIMIT: "256M" + MAX_INPUT_VARS: "1000" + UPLOAD_MAX_SIZE: "16M" + OPCACHE_MEM_SIZE: "128" + REAL_IP_FROM: "0.0.0.0/32" + REAL_IP_HEADER: "X-Forwarded-For" + LOG_IP_VAR: "remote_addr" + CACHE_DRIVER: "redis" + SESSION_DRIVER: "redis" + REDIS_HOST: "redis" + LIBRENMS_SNMP_COMMUNITY: "librenmsdocker" + LIBRENMS_WEATHERMAP: "true" + LIBRENMS_WEATHERMAP_SCHEDULE: "*/5 * * * *" + +services: + db: + image: mariadb:10.11 + command: + - "mysqld" + - "--innodb-file-per-table=1" + - "--lower-case-table-names=0" + - "--character-set-server=utf8mb4" + - "--collation-server=utf8mb4_unicode_ci" + volumes: + - "db:/var/lib/mysql" + environment: + TZ: *TZ + MARIADB_RANDOM_ROOT_PASSWORD: "yes" + MYSQL_DATABASE: *MYSQL_DATABASE + MYSQL_USER: *MYSQL_USER + MYSQL_PASSWORD: *MYSQL_PASSWORD + restart: always + + redis: + image: redis:7.2-alpine + environment: + TZ: *TZ + restart: always + + librenms: + image: librenms/librenms:edge + hostname: librenms + cap_add: + - NET_ADMIN + - NET_RAW + ports: + - "8000:8000" + depends_on: + - db + - redis + volumes: + - "librenms:/data" + environment: + <<: *envlibrenms + TZ: *TZ + PUID: *PUID + PGID: *PGID + DB_HOST: "db" + DB_NAME: *MYSQL_DATABASE + DB_USER: *MYSQL_USER + DB_PASSWORD: *MYSQL_PASSWORD + DB_TIMEOUT: "60" + restart: always + + dispatcher: + image: librenms/librenms:edge + hostname: librenms-dispatcher-1234 + cap_add: + - NET_ADMIN + - NET_RAW + depends_on: + - librenms + - redis + volumes: + - "librenms:/data" + environment: + <<: *envlibrenms + TZ: *TZ + PUID: *PUID + PGID: *PGID + DB_HOST: "db" + DB_NAME: *MYSQL_DATABASE + DB_USER: *MYSQL_USER + DB_PASSWORD: *MYSQL_PASSWORD + DB_TIMEOUT: "60" + DISPATCHER_NODE_ID: "dispatcher1234" + SIDECAR_DISPATCHER: "1" + restart: always + + dispatcher2: + image: librenms/librenms:edge + hostname: librenms-dispatcher-5678 + cap_add: + - NET_ADMIN + - NET_RAW + depends_on: + - librenms + - redis + volumes: + - "librenms:/data" + environment: + <<: *envlibrenms + TZ: *TZ + PUID: *PUID + PGID: *PGID + DB_HOST: "db" + DB_NAME: *MYSQL_DATABASE + DB_USER: *MYSQL_USER + DB_PASSWORD: *MYSQL_PASSWORD + DB_TIMEOUT: "60" + DISPATCHER_NODE_ID: "dispatcher5678" + SIDECAR_DISPATCHER: "1" + restart: always + + syslogng: + image: librenms/librenms:edge + hostname: librenms-syslogng + cap_add: + - NET_ADMIN + - NET_RAW + depends_on: + - librenms + - redis + volumes: + - "librenms:/data" + environment: + <<: *envlibrenms + TZ: *TZ + PUID: *PUID + PGID: *PGID + DB_HOST: "db" + DB_NAME: *MYSQL_DATABASE + DB_USER: *MYSQL_USER + DB_PASSWORD: *MYSQL_PASSWORD + DB_TIMEOUT: "60" + SIDECAR_SYSLOGNG: "1" + restart: always + +volumes: + db: + librenms: diff --git a/examples/rrdcached-server/.env b/examples/rrdcached-server/.env new file mode 100644 index 0000000..d6c0aed --- /dev/null +++ b/examples/rrdcached-server/.env @@ -0,0 +1,7 @@ +TZ=Europe/Paris +PUID=1000 +PGID=1000 + +MYSQL_DATABASE=librenms +MYSQL_USER=librenms +MYSQL_PASSWORD=asupersecretpassword diff --git a/examples/rrdcached-server/compose.yml b/examples/rrdcached-server/compose.yml new file mode 100644 index 0000000..dc8891a --- /dev/null +++ b/examples/rrdcached-server/compose.yml @@ -0,0 +1,176 @@ +name: librenms + +services: + db: + image: mariadb:10 + container_name: librenms_db + command: + - "mysqld" + - "--innodb-file-per-table=1" + - "--lower-case-table-names=0" + - "--character-set-server=utf8mb4" + - "--collation-server=utf8mb4_unicode_ci" + volumes: + - "./db:/var/lib/mysql" + environment: + - "TZ=${TZ}" + - "MARIADB_RANDOM_ROOT_PASSWORD=yes" + - "MYSQL_DATABASE=${MYSQL_DATABASE}" + - "MYSQL_USER=${MYSQL_USER}" + - "MYSQL_PASSWORD=${MYSQL_PASSWORD}" + restart: always + + redis: + image: redis:7.2-alpine + container_name: librenms_redis + environment: + - "TZ=${TZ}" + restart: always + + rrdcached: + image: crazymax/rrdcached + container_name: librenms_rrdcached + volumes: + - "./rrd/db:/data/db" + - "./rrd/journal:/data/journal" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "LOG_LEVEL=LOG_INFO" + - "WRITE_TIMEOUT=1800" + - "WRITE_JITTER=1800" + - "WRITE_THREADS=4" + - "FLUSH_DEAD_DATA_INTERVAL=3600" + restart: always + + msmtpd: + image: crazymax/msmtpd:latest + container_name: librenms_msmtpd + env_file: + - "./msmtpd.env" + restart: always + + librenms: + image: librenms/librenms:latest + container_name: librenms + hostname: librenms + cap_add: + - NET_ADMIN + - NET_RAW + ports: + - target: 8000 + published: 8000 + protocol: tcp + depends_on: + - db + - redis + - rrdcached + - msmtpd + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + restart: always + + dispatcher: + image: librenms/librenms:latest + container_name: librenms_dispatcher + hostname: librenms-dispatcher + cap_add: + - NET_ADMIN + - NET_RAW + depends_on: + - librenms + - redis + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + - "DISPATCHER_NODE_ID=dispatcher1" + - "SIDECAR_DISPATCHER=1" + restart: always + + syslogng: + image: librenms/librenms:latest + container_name: librenms_syslogng + hostname: librenms-syslogng + cap_add: + - NET_ADMIN + - NET_RAW + depends_on: + - librenms + - redis + ports: + - target: 514 + published: 514 + protocol: tcp + - target: 514 + published: 514 + protocol: udp + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + - "SIDECAR_SYSLOGNG=1" + restart: always + + snmptrapd: + image: librenms/librenms:latest + container_name: librenms_snmptrapd + hostname: librenms-snmptrapd + cap_add: + - NET_ADMIN + - NET_RAW + depends_on: + - librenms + - redis + ports: + - target: 162 + published: 162 + protocol: tcp + - target: 162 + published: 162 + protocol: udp + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + - "SIDECAR_SNMPTRAPD=1" + restart: always diff --git a/examples/rrdcached-server/librenms.env b/examples/rrdcached-server/librenms.env new file mode 100644 index 0000000..44da1f5 --- /dev/null +++ b/examples/rrdcached-server/librenms.env @@ -0,0 +1,17 @@ +MEMORY_LIMIT=256M +MAX_INPUT_VARS=1000 +UPLOAD_MAX_SIZE=16M +OPCACHE_MEM_SIZE=128 +REAL_IP_FROM=0.0.0.0/32 +REAL_IP_HEADER=X-Forwarded-For +LOG_IP_VAR=remote_addr + +CACHE_DRIVER=redis +SESSION_DRIVER=redis +REDIS_HOST=redis + +LIBRENMS_SNMP_COMMUNITY=librenmsdocker +RRDCACHED_SERVER=rrdcached:42217 + +LIBRENMS_WEATHERMAP=false +LIBRENMS_WEATHERMAP_SCHEDULE=*/5 * * * * diff --git a/examples/rrdcached-server/msmtpd.env b/examples/rrdcached-server/msmtpd.env new file mode 100644 index 0000000..170bec9 --- /dev/null +++ b/examples/rrdcached-server/msmtpd.env @@ -0,0 +1,10 @@ +# https://github.com/crazy-max/docker-msmtpd +SMTP_HOST=smtp.gmail.com +SMTP_PORT=587 +SMTP_TLS=on +SMTP_STARTTLS=on +SMTP_TLS_CHECKCERT=on +SMTP_AUTH=on +SMTP_USER=foo +SMTP_PASSWORD=bar +SMTP_FROM=foo@gmail.com diff --git a/examples/traefik/.env b/examples/traefik/.env new file mode 100644 index 0000000..d6c0aed --- /dev/null +++ b/examples/traefik/.env @@ -0,0 +1,7 @@ +TZ=Europe/Paris +PUID=1000 +PGID=1000 + +MYSQL_DATABASE=librenms +MYSQL_USER=librenms +MYSQL_PASSWORD=asupersecretpassword diff --git a/examples/traefik/compose.yml b/examples/traefik/compose.yml new file mode 100644 index 0000000..3b3a4fc --- /dev/null +++ b/examples/traefik/compose.yml @@ -0,0 +1,184 @@ +name: librenms + +services: + traefik: + image: traefik:2.5 + container_name: traefik + command: + - "--global.checknewversion=false" + - "--global.sendanonymoususage=false" + - "--log=true" + - "--log.level=INFO" + - "--entrypoints.http=true" + - "--entrypoints.http.address=:80" + - "--entrypoints.http.http.redirections.entrypoint.to=https" + - "--entrypoints.http.http.redirections.entrypoint.scheme=https" + - "--entrypoints.https=true" + - "--entrypoints.https.address=:443" + - "--certificatesresolvers.letsencrypt" + - "--certificatesresolvers.letsencrypt.acme.storage=acme.json" + - "--certificatesresolvers.letsencrypt.acme.email=webmaster@example.com" + - "--certificatesresolvers.letsencrypt.acme.httpchallenge" + - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http" + - "--providers.docker" + - "--providers.docker.watch=true" + - "--providers.docker.exposedbydefault=false" + ports: + - target: 80 + published: 80 + protocol: tcp + - target: 443 + published: 443 + protocol: tcp + volumes: + - "./acme.json:/acme.json" + - "/var/run/docker.sock:/var/run/docker.sock" + restart: always + + db: + image: mariadb:10 + container_name: librenms_db + command: + - "mysqld" + - "--innodb-file-per-table=1" + - "--lower-case-table-names=0" + - "--character-set-server=utf8mb4" + - "--collation-server=utf8mb4_unicode_ci" + volumes: + - "./db:/var/lib/mysql" + environment: + - "TZ=${TZ}" + - "MARIADB_RANDOM_ROOT_PASSWORD=yes" + - "MYSQL_DATABASE=${MYSQL_DATABASE}" + - "MYSQL_USER=${MYSQL_USER}" + - "MYSQL_PASSWORD=${MYSQL_PASSWORD}" + restart: always + + redis: + image: redis:7.2-alpine + container_name: librenms_redis + environment: + - "TZ=${TZ}" + restart: always + + msmtpd: + image: crazymax/msmtpd:latest + container_name: librenms_msmtpd + env_file: + - "./msmtpd.env" + restart: always + + librenms: + image: librenms/librenms:latest + container_name: librenms + hostname: librenms + depends_on: + - db + - redis + - msmtpd + volumes: + - "./librenms:/data" + labels: + - "traefik.enable=true" + - "traefik.http.routers.librenms.entrypoints=https" + - "traefik.http.routers.librenms.rule=Host(`librenms.example.com`)" + - "traefik.http.routers.librenms.tls=true" + - "traefik.http.routers.librenms.tls.certresolver=letsencrypt" + - "traefik.http.routers.librenms.tls.domains[0].main=librenms.example.com" + - "traefik.http.services.librenms.loadbalancer.server.port=8000" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + restart: always + + dispatcher: + image: librenms/librenms:latest + container_name: librenms_dispatcher + hostname: librenms-dispatcher + depends_on: + - librenms + - redis + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + - "DISPATCHER_NODE_ID=dispatcher1" + - "SIDECAR_DISPATCHER=1" + restart: always + + syslogng: + image: librenms/librenms:latest + container_name: librenms_syslog + hostname: librenms-syslogng + depends_on: + - librenms + - redis + ports: + - target: 514 + published: 514 + protocol: tcp + - target: 514 + published: 514 + protocol: udp + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + - "SIDECAR_SYSLOGNG=1" + restart: always + + snmptrapd: + image: librenms/librenms:latest + container_name: librenms_snmptrapd + hostname: librenms-snmptrapd + depends_on: + - librenms + - redis + ports: + - target: 162 + published: 162 + protocol: tcp + - target: 162 + published: 162 + protocol: udp + volumes: + - "./librenms:/data" + env_file: + - "./librenms.env" + environment: + - "TZ=${TZ}" + - "PUID=${PUID}" + - "PGID=${PGID}" + - "DB_HOST=db" + - "DB_NAME=${MYSQL_DATABASE}" + - "DB_USER=${MYSQL_USER}" + - "DB_PASSWORD=${MYSQL_PASSWORD}" + - "DB_TIMEOUT=60" + - "SIDECAR_SNMPTRAPD=1" + restart: always diff --git a/examples/traefik/librenms.env b/examples/traefik/librenms.env new file mode 100644 index 0000000..d650129 --- /dev/null +++ b/examples/traefik/librenms.env @@ -0,0 +1,16 @@ +MEMORY_LIMIT=256M +MAX_INPUT_VARS=1000 +UPLOAD_MAX_SIZE=16M +OPCACHE_MEM_SIZE=128 +REAL_IP_FROM=0.0.0.0/32 +REAL_IP_HEADER=X-Forwarded-For +LOG_IP_VAR=http_x_forwarded_for + +CACHE_DRIVER=redis +SESSION_DRIVER=redis +REDIS_HOST=redis + +LIBRENMS_SNMP_COMMUNITY=librenmsdocker + +LIBRENMS_WEATHERMAP=false +LIBRENMS_WEATHERMAP_SCHEDULE=*/5 * * * * diff --git a/examples/traefik/msmtpd.env b/examples/traefik/msmtpd.env new file mode 100644 index 0000000..170bec9 --- /dev/null +++ b/examples/traefik/msmtpd.env @@ -0,0 +1,10 @@ +# https://github.com/crazy-max/docker-msmtpd +SMTP_HOST=smtp.gmail.com +SMTP_PORT=587 +SMTP_TLS=on +SMTP_STARTTLS=on +SMTP_TLS_CHECKCERT=on +SMTP_AUTH=on +SMTP_USER=foo +SMTP_PASSWORD=bar +SMTP_FROM=foo@gmail.com diff --git a/rootfs/etc/cont-init.d/00-fix-logs.sh b/rootfs/etc/cont-init.d/00-fix-logs.sh new file mode 100644 index 0000000..d83c6af --- /dev/null +++ b/rootfs/etc/cont-init.d/00-fix-logs.sh @@ -0,0 +1,5 @@ +#!/usr/bin/with-contenv sh +# shellcheck shell=sh + +# Fix access rights to stdout and stderr +chown ${PUID}:${PGID} /proc/self/fd/1 /proc/self/fd/2 || true diff --git a/rootfs/etc/cont-init.d/01-fix-uidgid.sh b/rootfs/etc/cont-init.d/01-fix-uidgid.sh new file mode 100644 index 0000000..44e7ab0 --- /dev/null +++ b/rootfs/etc/cont-init.d/01-fix-uidgid.sh @@ -0,0 +1,13 @@ +#!/usr/bin/with-contenv sh +# shellcheck shell=sh +set -e + +if [ -n "${PGID}" ] && [ "${PGID}" != "$(id -g librenms)" ]; then + echo "Switching to PGID ${PGID}..." + sed -i -e "s/^librenms:\([^:]*\):[0-9]*/librenms:\1:${PGID}/" /etc/group + sed -i -e "s/^librenms:\([^:]*\):\([0-9]*\):[0-9]*/librenms:\1:\2:${PGID}/" /etc/passwd +fi +if [ -n "${PUID}" ] && [ "${PUID}" != "$(id -u librenms)" ]; then + echo "Switching to PUID ${PUID}..." + sed -i -e "s/^librenms:\([^:]*\):[0-9]*:\([0-9]*\)/librenms:\1:${PUID}:\2/" /etc/passwd +fi diff --git a/rootfs/etc/cont-init.d/02-fix-perms.sh b/rootfs/etc/cont-init.d/02-fix-perms.sh new file mode 100644 index 0000000..93203df --- /dev/null +++ b/rootfs/etc/cont-init.d/02-fix-perms.sh @@ -0,0 +1,22 @@ +#!/usr/bin/with-contenv sh +# shellcheck shell=sh +set -e + +echo "Fixing perms..." +mkdir -p /data \ + /var/run/nginx \ + /var/run/php-fpm +chown librenms:librenms \ + /data \ + "${LIBRENMS_PATH}" \ + "${LIBRENMS_PATH}/.env" \ + "${LIBRENMS_PATH}/cache" \ + "${LIBRENMS_PATH}/rrd" +chown -R librenms:librenms \ + /home/librenms \ + /tpls \ + /var/lib/nginx \ + /var/log/nginx \ + /var/log/php83 \ + /var/run/nginx \ + /var/run/php-fpm diff --git a/rootfs/etc/cont-init.d/03-config.sh b/rootfs/etc/cont-init.d/03-config.sh new file mode 100644 index 0000000..013c15c --- /dev/null +++ b/rootfs/etc/cont-init.d/03-config.sh @@ -0,0 +1,259 @@ +#!/usr/bin/with-contenv bash +# shellcheck shell=bash +set -e + +# From https://github.com/docker-library/mariadb/blob/master/docker-entrypoint.sh#L21-L41 +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(<"${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +TZ=${TZ:-UTC} + +MEMORY_LIMIT=${MEMORY_LIMIT:-256M} +UPLOAD_MAX_SIZE=${UPLOAD_MAX_SIZE:-16M} +CLEAR_ENV=${CLEAR_ENV:-yes} +FPM_PM_MAX_CHILDREN=${FPM_PM_MAX_CHILDREN:-15} +FPM_PM_START_SERVERS=${FPM_PM_START_SERVERS:-2} +FPM_PM_MIN_SPARE_SERVERS=${FPM_PM_MIN_SPARE_SERVERS:-1} +FPM_PM_MAX_SPARE_SERVERS=${FPM_PM_MAX_SPARE_SERVERS:-6} +OPCACHE_MEM_SIZE=${OPCACHE_MEM_SIZE:-128} +LISTEN_IPV6=${LISTEN_IPV6:-true} +REAL_IP_FROM=${REAL_IP_FROM:-"0.0.0.0/32"} +REAL_IP_HEADER=${REAL_IP_HEADER:-"X-Forwarded-For"} +LOG_IP_VAR=${LOG_IP_VAR:-remote_addr} +MAX_INPUT_VARS=${MAX_INPUT_VARS:-1000} + +MEMCACHED_PORT=${MEMCACHED_PORT:-11211} + +DB_PORT=${DB_PORT:-3306} +DB_NAME=${DB_NAME:-librenms} +DB_USER=${DB_USER:-librenms} +DB_TIMEOUT=${DB_TIMEOUT:-30} + +LIBRENMS_BASE_URL=${LIBRENMS_BASE_URL:-/} + +# Timezone +echo "Setting timezone to ${TZ}..." +ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime +echo ${TZ} >/etc/timezone + +# PHP +echo "Setting PHP-FPM configuration..." +sed -e "s/@MEMORY_LIMIT@/$MEMORY_LIMIT/g" \ + -e "s/@UPLOAD_MAX_SIZE@/$UPLOAD_MAX_SIZE/g" \ + -e "s/@CLEAR_ENV@/$CLEAR_ENV/g" \ + -e "s/@FPM_PM_MAX_CHILDREN@/$FPM_PM_MAX_CHILDREN/g" \ + -e "s/@FPM_PM_START_SERVERS@/$FPM_PM_START_SERVERS/g" \ + -e "s/@FPM_PM_MIN_SPARE_SERVERS@/$FPM_PM_MIN_SPARE_SERVERS/g" \ + -e "s/@FPM_PM_MAX_SPARE_SERVERS@/$FPM_PM_MAX_SPARE_SERVERS/g" \ + /tpls/etc/php83/php-fpm.d/www.conf >/etc/php83/php-fpm.d/www.conf + +echo "Setting PHP INI configuration..." +sed -i "s|memory_limit.*|memory_limit = ${MEMORY_LIMIT}|g" /etc/php83/php.ini +sed -i "s|;date\.timezone.*|date\.timezone = ${TZ}|g" /etc/php83/php.ini +sed -i "s|;max_input_vars.*|max_input_vars = ${MAX_INPUT_VARS}|g" /etc/php83/php.ini + +# OpCache +echo "Setting OpCache configuration..." +sed -e "s/@OPCACHE_MEM_SIZE@/$OPCACHE_MEM_SIZE/g" \ + /tpls/etc/php83/conf.d/opcache.ini >/etc/php83/conf.d/opcache.ini + +# Nginx +echo "Setting Nginx configuration..." +sed -e "s#@UPLOAD_MAX_SIZE@#$UPLOAD_MAX_SIZE#g" \ + -e "s#@REAL_IP_FROM@#$REAL_IP_FROM#g" \ + -e "s#@REAL_IP_HEADER@#$REAL_IP_HEADER#g" \ + -e "s#@LOG_IP_VAR@#$LOG_IP_VAR#g" \ + /tpls/etc/nginx/nginx.conf >/etc/nginx/nginx.conf + +if [ "$LISTEN_IPV6" != "true" ]; then + sed -e '/listen \[::\]:/d' -i /etc/nginx/nginx.conf +fi + +# SNMP +echo "Updating SNMP community..." +file_env 'LIBRENMS_SNMP_COMMUNITY' 'librenmsdocker' +sed -i -e "s/RANDOMSTRINGGOESHERE/${LIBRENMS_SNMP_COMMUNITY}/" /etc/snmp/snmpd.conf + +# Init files and folders +echo "Initializing LibreNMS files / folders..." +mkdir -p /data/config /data/logs /data/monitoring-plugins /data/plugins /data/rrd /data/weathermap /data/alert-templates + +if [ -d "${LIBRENMS_PATH}/html/plugins/Weathermap" ]; then + if [ -d "${LIBRENMS_PATH}/html/plugins/Weathermap/configs" ] && [ ! -L "${LIBRENMS_PATH}/html/plugins/Weathermap/configs" ]; then + rm -rf ${LIBRENMS_PATH}/html/plugins/Weathermap/configs + fi + if [ ! -L "${LIBRENMS_PATH}/html/plugins/Weathermap/configs" ]; then + ln -sf /data/weathermap ${LIBRENMS_PATH}/html/plugins/Weathermap/configs + fi + chown -h librenms:librenms ${LIBRENMS_PATH}/html/plugins/Weathermap/configs + find /data/weathermap ${LIBRENMS_PATH}/html/plugins/Weathermap/output \( ! -user librenms -o ! -group librenms \) -exec chown librenms:librenms {} + +fi + +# cleanup bad symlink: https://github.com/librenms/docker/issues/294#issuecomment-1190389960 +if [ -L "/data/weathermap/weathermap" ]; then + rm /data/weathermap/weathermap +fi + +touch /data/logs/librenms.log +rm -rf ${LIBRENMS_PATH}/logs +rm -f ${LIBRENMS_PATH}/config.d/* +mkdir -p /etc/logrotate.d +touch /etc/logrotate.d/librenms + +echo "Setting LibreNMS configuration..." + +# Env file +if [ -z "$DB_HOST" ]; then + echo >&2 "ERROR: DB_HOST must be defined" + exit 1 +fi +file_env 'DB_PASSWORD' +if [ -z "$DB_PASSWORD" ]; then + echo >&2 "ERROR: Either DB_PASSWORD or DB_PASSWORD_FILE must be defined" + exit 1 +fi +cat >${LIBRENMS_PATH}/.env <${LIBRENMS_PATH}/database/seeders/config/directories.yaml <${LIBRENMS_PATH}/database/seeders/config/server.yaml <${LIBRENMS_PATH}/database/seeders/config/user.yaml <${LIBRENMS_PATH}/database/seeders/config/fping.yaml <${LIBRENMS_PATH}/database/seeders/config/ipmitool.yaml <${LIBRENMS_PATH}/config.d/autoupdate.php <${LIBRENMS_PATH}/database/seeders/config/services.yaml <${LIBRENMS_PATH}/config.d/rrdcached.php <${LIBRENMS_PATH}/database/seeders/config/rrdtool.yaml <${LIBRENMS_PATH}/database/seeders/config/dispatcher.yaml <&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(<"${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +DB_PORT=${DB_PORT:-3306} +DB_NAME=${DB_NAME:-librenms} +DB_USER=${DB_USER:-librenms} +DB_TIMEOUT=${DB_TIMEOUT:-60} + +SIDECAR_DISPATCHER=${SIDECAR_DISPATCHER:-0} +SIDECAR_SYSLOGNG=${SIDECAR_SYSLOGNG:-0} +SIDECAR_SNMPTRAPD=${SIDECAR_SNMPTRAPD:-0} + +if [ "$SIDECAR_DISPATCHER" = "1" ] || [ "$SIDECAR_SYSLOGNG" = "1" ] || [ "$SIDECAR_SNMPTRAPD" = "1" ]; then + exit 0 +fi + +# Handle .env +if [ ! -f "/data/.env" ]; then + echo "Generating APP_KEY and unique NODE_ID" + cat >"/data/.env" <>"${LIBRENMS_PATH}/.env" +chown librenms:librenms /data/.env "${LIBRENMS_PATH}/.env" + +file_env 'DB_PASSWORD' +if [ -z "$DB_PASSWORD" ]; then + echo >&2 "ERROR: Either DB_PASSWORD or DB_PASSWORD_FILE must be defined" + exit 1 +fi + +dbcmd="mariadb -h ${DB_HOST} -P ${DB_PORT} -u "${DB_USER}" "-p${DB_PASSWORD}"" +unset DB_PASSWORD + +echo "Waiting ${DB_TIMEOUT}s for database to be ready..." +counter=1 +while ! ${dbcmd} -e "show databases;" >/dev/null 2>&1; do + sleep 1 + counter=$((counter + 1)) + if [ ${counter} -gt ${DB_TIMEOUT} ]; then + echo >&2 "ERROR: Failed to connect to database on $DB_HOST" + exit 1 + fi +done +echo "Database ready!" + +# Enable first run wizard if db is empty +counttables=$(echo 'SHOW TABLES' | ${dbcmd} "$DB_NAME" | wc -l) +if [ "${counttables}" -eq "0" ]; then + echo "Enabling First Run Wizard..." + echo "INSTALL=user,finish" >>${LIBRENMS_PATH}/.env +fi + +echo "Updating database schema..." +lnms migrate --force --no-ansi --no-interaction +artisan db:seed --force --no-ansi --no-interaction + +echo "Clear cache" +artisan cache:clear --no-interaction +artisan config:cache --no-interaction + +mkdir -p /etc/services.d/nginx +cat >/etc/services.d/nginx/run </etc/services.d/php-fpm/run </etc/services.d/snmpd/run <&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(<"${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +DB_PORT=${DB_PORT:-3306} +DB_NAME=${DB_NAME:-librenms} +DB_USER=${DB_USER:-librenms} +DB_TIMEOUT=${DB_TIMEOUT:-60} + +SIDECAR_DISPATCHER=${SIDECAR_DISPATCHER:-0} +#DISPATCHER_NODE_ID=${DISPATCHER_NODE_ID:-dispatcher1} + +#REDIS_HOST=${REDIS_HOST:-localhost} +REDIS_SCHEME=${REDIS_SCHEME:-tcp} +REDIS_PORT=${REDIS_PORT:-6379} +#REDIS_SENTINEL=${REDIS_SENTINEL:-localhost} +REDIS_SENTINEL_SERVICE=${REDIS_SENTINEL_SERVICE:-librenms} +file_env 'REDIS_PASSWORD' +REDIS_DB=${REDIS_DB:-0} + +# Continue only if sidecar dispatcher container +if [ "$SIDECAR_DISPATCHER" != "1" ]; then + exit 0 +fi + +echo ">>" +echo ">> Sidecar dispatcher container detected" +echo ">>" + +file_env 'DB_PASSWORD' +if [ -z "$DB_PASSWORD" ]; then + echo >&2 "ERROR: Either DB_PASSWORD or DB_PASSWORD_FILE must be defined" + exit 1 +fi + +dbcmd="mariadb -h ${DB_HOST} -P ${DB_PORT} -u "${DB_USER}" "-p${DB_PASSWORD}"" +unset DB_PASSWORD + +echo "Waiting ${DB_TIMEOUT}s for database to be ready..." +counter=1 +while ! ${dbcmd} -e "show databases;" >/dev/null 2>&1; do + sleep 1 + counter=$((counter + 1)) + if [ ${counter} -gt ${DB_TIMEOUT} ]; then + echo >&2 "ERROR: Failed to connect to database on $DB_HOST" + exit 1 + fi +done +echo "Database ready!" +while ! ${dbcmd} -e "desc $DB_NAME.poller_cluster;" >/dev/null 2>&1; do + sleep 1 + counter=$((counter + 1)) + if [ ${counter} -gt ${DB_TIMEOUT} ]; then + echo >&2 "ERROR: Table $DB_NAME.poller_cluster does not exist on $DB_HOST" + exit 1 + fi +done + +# Node ID +if [ ! -f "/data/.env" ]; then + echo >&2 "ERROR: /data/.env file does not exist. Please run the main container first" + exit 1 +fi +cat "/data/.env" >>"${LIBRENMS_PATH}/.env" +if [ -n "$DISPATCHER_NODE_ID" ]; then + echo "NODE_ID: $DISPATCHER_NODE_ID" + sed -i "s|^NODE_ID=.*|NODE_ID=$DISPATCHER_NODE_ID|g" "${LIBRENMS_PATH}/.env" +fi + +# Redis +if [ -z "$REDIS_HOST" ] && [ -z "$REDIS_SENTINEL" ]; then + echo >&2 "ERROR: REDIS_HOST or REDIS_SENTINEL must be defined" + exit 1 +elif [ -n "$REDIS_SENTINEL" ]; then + echo "Setting Redis Sentinel" + cat >>${LIBRENMS_PATH}/.env <>${LIBRENMS_PATH}/.env </etc/services.d/dispatcher/run <>" +echo ">> Sidecar syslog-ng container detected" +echo ">>" + +mkdir -p /data/syslog-ng /run/syslog-ng +chown librenms:librenms /data/syslog-ng +chown -R librenms:librenms /run/syslog-ng + +# Create service +mkdir -p /etc/services.d/syslogng +cat >/etc/services.d/syslogng/run <>${CRONTAB_PATH}/librenms + +if [ "$LIBRENMS_WEATHERMAP" = "true" ] && [ -n "$LIBRENMS_WEATHERMAP_SCHEDULE" ]; then + echo "Creating LibreNMS Weathermap cron task with the following period fields: $LIBRENMS_WEATHERMAP_SCHEDULE" + echo "${LIBRENMS_WEATHERMAP_SCHEDULE} php -f /opt/librenms/html/plugins/Weathermap/map-poller.php" >>${CRONTAB_PATH}/librenms +fi + +echo "Creating LibreNMS cron artisan schedule:run" +echo "* * * * * php /opt/librenms/artisan schedule:run --no-ansi --no-interaction > /dev/null 2>&1" >>${CRONTAB_PATH}/librenms + +# Fix perms +echo "Fixing crontabs permissions..." +chmod -R 0644 ${CRONTAB_PATH} + +# Create service +mkdir -p /etc/services.d/cron +cat >/etc/services.d/cron/run <>" +echo ">> Sidecar snmptrapd container detected" +echo ">>" + +mkdir -p /run/snmptrapd +chown -R librenms:librenms /run/snmptrapd + +sed -ie "s/@LIBRENMS_SNMP_COMMUNITY@/${LIBRENMS_SNMP_COMMUNITY}/" /etc/snmp/snmptrapd.conf +sed -ie "s/@SNMP_PROCESSING_TYPE@/${SNMP_PROCESSING_TYPE}/" /etc/snmp/snmptrapd.conf +sed -ie "s/@SNMP_USER@/${SNMP_USER}/" /etc/snmp/snmptrapd.conf +sed -ie "s/@SNMP_AUTH@/${SNMP_AUTH}/" /etc/snmp/snmptrapd.conf +sed -ie "s/@SNMP_PRIV@/${SNMP_PRIV}/" /etc/snmp/snmptrapd.conf +sed -ie "s/@SNMP_AUTH_PROTO@/${SNMP_AUTH_PROTO}/" /etc/snmp/snmptrapd.conf +sed -ie "s/@SNMP_PRIV_PROTO@/${SNMP_PRIV_PROTO}/" /etc/snmp/snmptrapd.conf +sed -ie "s/@SNMP_SECURITY_LEVEL@/${SNMP_SECURITY_LEVEL}/" /etc/snmp/snmptrapd.conf +sed -ie "s/@SNMP_ENGINEID@/${SNMP_ENGINEID}/" /etc/snmp/snmptrapd.conf +sed -ie "s/@SNMP_DISABLE_AUTHORIZATION@/${SNMP_DISABLE_AUTHORIZATION}/" /etc/snmp/snmptrapd.conf + +# Create service +mkdir -p /etc/services.d/snmptrapd +cat >/etc/services.d/snmptrapd/run <