Specifics in Packaging Icinga Go Applications

by | Jul 29, 2026

Today’s post provides insights into packaging Icinga Go applications and explains why there are seven Icinga DB version 1.5.1 packages.

# apt-cache show icingadb | grep 'Version: 1.5.1'
Version: 1.5.1-7+debian13
Version: 1.5.1-6+debian13
Version: 1.5.1-5+debian13
Version: 1.5.1-4+debian13
Version: 1.5.1-3+debian13
Version: 1.5.1-2+debian13
Version: 1.5.1-1+debian13

Three Categories of Icinga Packages

To start with a simplification, one can put Icinga packages in three categories:

  • There are compiled binary packages relying on multiple other system libraries. Those are dynamically linked, and Icinga 2 is the most prominent.
  • There are other compiled binaries, but those do not rely on other libraries and are mostly self-contained. This is the case for most Go applications such as Icinga DB, Icinga for Kubernetes, or Icinga Notifications.
  • And lastly, there are scripts to be interpreted during runtime. While there might be a shell script or two within the Icinga 2 package, I am talking about all the PHP stuff, Icinga Web and its modules.

Both the dynamic Icinga 2 program and all web modules require other libraries or runtimes. For Icinga Web, these dependencies are obviously PHP and some PHP libraries.

# apt-cache show icingaweb2 | grep '^Depends' | head -1
Depends: apache2 | httpd, php, icingacli (= 2.14.0-2+debian13), icingaweb2-common (= 2.14.0-2+debian13), php-icinga (= 2.14.0-2+debian13), icinga-l10n (>= 1.1.0)

However, this output for Icinga Web 2 already foreshadows that there are more dependencies, transitive ones. Let’s count all dependencies down the tree with apt-rdepends(1):

# apt-rdepends icingaweb2 2>/dev/null | awk '/Depends:/ { print $2 }' | sort | uniq | wc -l
199

Since Icinga Web 2 was grouped together with Icinga 2, what’s the deal with this dynamically linked binary?

# apt-rdepends icinga2 2>/dev/null | awk '/Depends:/ { print $2 }' | sort | uniq | wc -l
50

Within this list, there are lots of libraries, starting from the C++ standard library, libstdc++, to multiple C++ Boost libraries. This results in Icinga 2 loading those libraries during startup, using the latest version the operating system provides. If there is, for example, a security issue in a depending library, the OS package manager ships a new version, and after an Icinga 2 daemon restart, all is fine. These are the obvious advantages of dynamically linked programs: There is no need for a new Icinga 2 package just because something got bumped down the road.

Go Package Insights

To get back to the opening question: What’s different with our Go packages?

# apt-rdepends icingadb 2>/dev/null | awk '/Depends:/ { print $2 }' | sort | uniq
gcc-14-base
libc6
libgcc-s1

This list contains three items, not nearly 200, not 50, only three. The Icinga DB package only requires an essential C runtime. Everything else is baked into the binary itself, including the Go standard library.

$ icingadb --version | grep 'Go version'
  Go version: go1.26.5 (linux, amd64)

This is not runtime information but built into the binary itself, as the Go tooling might reveal with additional information.

$ go version -m "$(which icingadb)"
/usr/sbin/icingadb: go1.26.5
        path    github.com/icinga/icingadb/cmd/icingadb
        mod     github.com/icinga/icingadb      (devel)
        dep     filippo.io/edwards25519 v1.1.0  h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
        dep     github.com/caarlos0/env/v11     v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA=
        dep     github.com/cespare/xxhash/v2    v2.3.0  h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
        dep     github.com/creasty/defaults     v1.8.0  h1:z27FJxCAa0JKt3utc0sCImAEb+spPucmKoOdLHvHYKk=
        dep     github.com/dgryski/go-rendezvous        v0.0.0-20200823014737-9f7001d12a5f      h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
        dep     github.com/fatih/color  v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
        dep     github.com/go-sql-driver/mysql  v1.9.3  h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
        dep     github.com/goccy/go-yaml        v1.13.0 h1:0Wtp0FZLd7Sm8gERmR9S6Iczzb3vItJj7NaHmFg8pTs=
        dep     github.com/google/go-cmp        v0.7.0  h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
        dep     github.com/google/uuid  v1.6.0  h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
        dep     github.com/icinga/icinga-go-library     v0.8.2  h1:/TwrRotn0QZl/2Vo1jCUaZs1isH5uve9lTnkRYTIHnI=
        dep     github.com/jessevdk/go-flags    v1.6.1  h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4=
        dep     github.com/jmoiron/sqlx v1.4.0  h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
        dep     github.com/lib/pq       v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
        dep     github.com/mattn/go-colorable   v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
        dep     github.com/mattn/go-isatty      v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
        dep     github.com/okzk/sdnotify        v0.0.0-20180710141335-d9becc38acbd      h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs=
        dep     github.com/pkg/errors   v0.9.1  h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
        dep     github.com/redis/go-redis/v9    v9.17.2 h1:P2EGsA4qVIM3Pp+aPocCJ7DguDHhqrXNhVcEp4ViluI=
        dep     github.com/ssgreg/journald      v1.0.0  h1:0YmTDPJXxcWDPba12qNMdO6TxvfkFSYpFIJ31CwmLcU=
        dep     go.uber.org/multierr    v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
        dep     go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
        dep     golang.org/x/exp        v0.0.0-20240506185415-9bf2ced13842      h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
        dep     golang.org/x/sync       v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
        dep     golang.org/x/sys        v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
        build   -buildmode=exe
        build   -compiler=gc
        build   -trimpath=true
        build   DefaultGODEBUG=containermaxprocs=0,cryptocustomrand=1,decoratemappings=0,tlssecpmlkem=0,tlssha1=1,updatemaxprocs=0,urlstrictcolons=0,x509sha256skid=0
        build   CGO_ENABLED=1
        build   GOARCH=amd64
        build   GOOS=linux
        build   GOAMD64=v1

While we can guarantee that the package contains exactly those dependencies we need, it is now our – read, Icinga – responsibility to update them as well. Thus, if there are security issues in this list, including the Go standard library, we need to bump those and draft a new release. Every time a new Go security release was published, fixing a security vulnerability that might or might not affect one of our packages, we considered creating a new release. This release still contains the same code of ours but now references the fixed dependencies. And that’s why there are seven Icinga DB 1.5.1 releases at the time of writing.

However, one might ask themselves: Why even bother? Why draft a new release containing a fix for something Icinga DB never uses? Security scanners are the answer, especially the less capable ones.

Go Vulnerability Scanning

By the way, when scanning Go projects for security issues, I would highly recommend Go’s govulncheck, which excludes unreachable code based on the call-graph.

$ basename $(pwd); ~/go/bin/govulncheck ./...
icingadb
No vulnerabilities found.

 

You May Also Like…

 

Password Policies in Icinga Web

Password Policies in Icinga Web

Icinga Web 2 now ships a PasswordPolicyHook that gives administrators and module developers full control over what...

Subscribe to our Newsletter

A monthly digest of the latest Icinga news, releases, articles and community topics.