A hard transformation has arrived for several classic Ubuntu images on ECR and Docker Hub. The remaining old Docker images –Apache2, Nginx, Bind9, Memcached, and Squid– have been hardened to rocks, signaling a complete evolution of the Ubuntu namespace.
Built on top of Resolute and equipped with Pebble as the service manager, these new rocks are now maintained by the Rockcrafters team and follow the same principles that have guided the broader Rocks initiative: user-focused experience, uniform and opinionated design, and a distroless-like architecture.
By meticulously chiseling each rock down to its bare essentials, we have achieved a significant reduction in image sizes:
A Resolute docker image has been built using traditional techniques to establish a baseline for security analysis. This allowed for a direct comparison against the new rocks using Snyk vulnerability scan to assess the security impact of these updates. The chart below shows the number of CVEs found by Snyk for each image:
Since Pebble now handles service management, it provides several new commands for monitoring services. These allow you to inspect logs for a specific Pebble-managed service, assess container health, or validate configured health checks.
To inspect the logs, run the pebble logs command, as follows:
$ docker exec squid-container pebble logs
2026-06-22T16:27:21.448Z [squid] 2026/06/22 16:27:19| With 1024 file descriptors available
2026-06-22T16:27:21.448Z [squid] 2026/06/22 16:27:19| Initializing IP Cache...
2026-06-22T16:27:21.448Z [squid] 2026/06/22 16:27:19| DNS IPv6 socket created at [::], FD 8
2026-06-22T16:27:21.448Z [squid] 2026/06/22 16:27:19| DNS IPv4 socket created at 0.0.0.0, FD 9
2026-06-22T16:27:21.448Z [squid] 2026/06/22 16:27:19| Adding nameserver 10.255.255.254 from /etc/resolv.conf
2026-06-22T16:27:21.448Z [squid] 2026/06/22 16:27:19| Adding domain home from /etc/resolv.conf
2026-06-22T16:27:21.448Z [squid] 2026/06/22 16:27:19| Logfile: opening log daemon:/var/log/squid/access.log
2026-06-22T16:27:21.448Z [squid] 2026/06/22 16:27:19| Logfile Daemon: opening log /var/log/squid/access.log
...
To assess the health status, run pebble health:
$ docker exec nginx-container pebble health
healthy
To validate configured checks, run pebble checks:
$ docker exec bind9-container pebble checks
Check Level Startup Status Successes Failures Change
config - enabled up 1 0/3 1
Now let’s take a deeper look at what has changed for each one of the new rocks!
Apache2
Repository: canonical/apache2-rock
Pull from: Dockerhub, Amazon ECR.
Contents
Apache2 has undergone one of the most dramatic reductions in size among this batch of rocks. It includes the following Chisel slices:
| Slice | Description |
|---|---|
| base-files_base | Creates an Ubuntu-like file system. |
| base-files_chisel | Adds the Chisel manifest. |
| base-files_release-info | Adds the release information files, like /etc/os-release. |
| base-passwd_data | Adds /etc/passwd and /etc/group. |
| apache2_core | Core functionality of the apache2 package. |
| apache2_index | Adds /var/www/html/index.html. |
| tzdata_zoneinfo | Adds timezone data. |
By installing the apache2_core slice, this rock includes the primary binary at /usr/sbin/apache2 alongside critical modules, configurations, and dependencies.
While the standard slice typically bundles extra data like icons and the apachectl script, these have been excluded to eliminate unnecessary bloat. Instead, a bespoke control script is provided for streamlined server management.
Additionally, to maintain parity with previous image behavior, the apache2_index slice is also included, providing /var/www/html/index.html.
Usage
The result is a significantly smaller rock that still provides the same Apache2 experience without carrying around over 120 MB of unnecessary baggage. It can be run with docker as follows:
$ docker run -d --rm --name apache2-rock -p 8080:80 ubuntu/apache2:2.4-26.04_edge
$ curl -sSI http://127.0.0.1:8080
HTTP/1.1 200 OK
...
Nginx
Repository: canonical/nginx-rock
Pull from: Dockerhub, Amazon ECR.
Contents
Nginx followed a similar path and emerged even leaner. It includes the following slices:
| Slice | Description |
|---|---|
| base-files_base | Creates an Ubuntu-like file system. |
| base-files_chisel | Adds the Chisel manifest. |
| base-files_release-info | Adds the release information files, like /etc/os-release. |
| base-passwd_data | Adds /etc/passwd and /etc/group. |
| nginx_bins | Includes the main nginx binary and its dependencies. |
| nginx-common_index | Adds /var/www/html/index.nginx-debian.html |
| ca-certificates_data-with-certs | Adds ca-certificates data required for SSL. |
| ca-certificates_scripts | Adds script to update ca-certificates data. |
The core of the Nginx rock is built around the nginx_bins slice, which provides the main executable and every necessary shared library required for operation. To ensure consistency and stability across the ecosystem, these slices were carefully forward-ported from the 25.10 base.
Recognizing the critical importance of secure communications, the rock incorporates dedicated ca-certificate slices to fully support SSL/TLS requirements. This inclusion ensures that the new rock not only maintains strict functional parity with previous Nginx images but also remains lightweight and highly secure.
Usage
The resulting rock contains little more than what is needed to start and run Nginx, delivering a substantial reduction in size while preserving expected functionality. It can be used as follows:
$ docker run -d --rm --name nginx-rock -p 8080:80 ubuntu/nginx:1.28-26.04_edge
Similarly to Apache2, a request can be made to Nginx with curl:
$ curl -sSI http://127.0.0.1:8080
HTTP/1.1 200 OK
...
Bind9
Repository: canonical/bind9-rock
Pull from: Dockerhub, Amazon ECR.
Contents
Bind9 presents an interesting case because it is more than just a daemon. It includes these slices:
| Slice | Description |
|---|---|
| base-files_base | Creates an Ubuntu-like file system. |
| base-files_chisel | Adds the Chisel manifest. |
| base-files_release-info | Adds the release information files, like /etc/os-release. |
| base-passwd_data | Adds /etc/passwd and /etc/group. |
| bind9_core | Core functionality of the bind9 package. |
| tzdata_zoneinfo | Adds timezone data. |
While the primary purpose of the image is to run the named DNS server, many users also rely on the accompanying administrative tools. The challenge was therefore not only to reduce the image size but also to preserve the operational workflows people expect.
The new rock includes the named binary together with its essential runtime dependencies, added by the bind9_core slice. This slice also contains several utilities from bind9-utils that were already available in the previous images, including:
-
named-checkzone -
named-compilezone -
named-checkconf
The latter is now used as a Pebble health check, helping verify that the server configuration remains valid, as shown by the pebble plan command:
$ docker exec bind9-rock pebble plan
services:
dns-server:
startup: enabled
override: replace
command: /usr/sbin/named [ -g ]
checks:
config:
override: replace
threshold: 3
exec:
command: /usr/bin/named-checkconf
service-context: dns-server
Besides, in order to support day-to-day DNS administration, the rndc utility is also included in the rock. It is installed by the bind9-utils_rndc slice, which is a dependency of the core slice. As such, rndc commands can be executed through docker exec, providing a familiar management experience for existing users.
Usage
The Bind9 rock now runs rootless, and even after keeping the operational tools, the image size dropped from 131 MB to 37.3 MB uncompressed. It can be used as follows:
$ docker run --rm -d --name bind9-rock ubuntu/bind9:9.20-26.04_edge
The DNS server can be managed using the rndc tool, though it requires initializing the rndc-confgen script beforehand:
$ docker exec bind9-rock rndc-confgen -a
$ docker restart bind9-rock
$ docker exec bind9-rock rndc status
version: BIND 9.20.18-1ubuntu2.1-Ubuntu (Stable Release) <id:>
running on localhost: ...
boot time: Sun, 21 Jun 2026 23:10:23 GMT
last configured: Sun, 21 Jun 2026 23:10:23 GMT
configuration file: /etc/bind/named.conf
CPUs found: 12
worker threads: 12
number of zones: 101 (100 automatic)
debug level: 0
xfers running: 0
xfers deferred: 0
xfers first refresh: 0
soa queries in progress: 0
Memcached
Repository: canonical/memcached-rock
Pull from: Dockerhub, Amazon ECR.
Contents
Memcached received the same treatment as several of the newer rocks in the ecosystem: fewer layers, fewer dependencies, and fewer privileges. It contains the following slices:
| Slice | Description |
|---|---|
| base-files_base | Creates an Ubuntu-like file system. |
| base-files_chisel | Adds the Chisel manifest. |
| base-files_release-info | Adds the release information files, like /etc/os-release. |
| base-passwd_data | Adds /etc/passwd and /etc/group. |
| libsasl2-modules_libs | Modules required by memcached. |
| memcached_bins | Core functionality of the Memcached package. |
| tzdata_zoneinfo | Adds timezone data. |
The memcached_bins slice provides the core memcached binary, necessary libraries, and configuration files. To support specific use cases, the libsasl2-modules_libs slice is also included; it contains a set of modules that extend the libsasl2-2 library. Although these modules are not explicitly defined as dependencies for Memcached, they are required for various advanced functional scenarios.
Usage
For a service that exists to help everything else run faster, it seems only fair that the image itself got a little lighter too. It can be used as follows:
$ docker run --rm -d --name memcached-rock -p 11211:11211 ubuntu/memcached:1.6-26.04_edge
Then once the Memcached server is up, it can store and retrieve data:
$ printf "set my_key 0 60 11\r\nhello world\r\n" | nc -q 1 127.0.0.1 11211
$ printf "get my_key\r\n" | nc -q 1 127.0.0.1 11211 | grep "hello world"
hello world
Squid
Repository: canonical/squid-rock
Pull from: Dockerhub, Amazon ECR.
Contents
As one of the most widely used images under the Ubuntu namespace, compatibility and functionality were key concerns throughout the process. Unlike some services that can be reduced almost entirely to a single daemon and a handful of dependencies, Squid often relies on a broader collection of modules and supporting components.
For that reason, most of Squid’s tentacles were preserved:
| Slice | Description |
|---|---|
| base-files_base | Creates an Ubuntu-like file system. |
| base-files_chisel | Adds the Chisel manifest. |
| base-files_release-info | Adds the release information files, like /etc/os-release. |
| base-passwd_data | Adds /etc/passwd and /etc/group. |
| squid_standard | Standard installation of squid: core functionality plus authentication, cache, external acls and certs capabilities. |
| tzdata_zoneinfo | Adds timezone data. |
| libc-bin_nsswitch | Name service switch. Adds /etc/nsswitch.conf. |
| libpam-modules_libs | Provides PAM authentication capabilities. |
The objective was to remain close to a standard Squid deployment while still applying the principles of chiseling and minimization wherever possible. Each included component was evaluated against a simple rule: if a capability is present, the dependencies required to make it functional should be present too–but nothing more.
Usage
Despite retaining a substantial set of features, the rock is still both baseless and rootless, and its uncompressed size has been reduced from 205 MB to 127 MB. It can be used as follows:
$ docker run --rm -d --name squid-rock -p 3128:3128 ubuntu/squid:7.2-26.04_edge
Using curl, an HTTP request can then be routed through the proxy:
$ curl -4 -sI -x http://127.0.0.1:3128 https://ubuntu.com | grep "HTTP/1.1 200"
HTTP/1.1 200 Connection established
Then you can check that the request was actually routed by the Squid proxy:
$ docker exec squid cat /var/log/squid/access.log | grep -qF "CONNECT ubuntu.com:443"
1782085805.059 15133 172.17.0.1 TCP_TUNNEL/200 7771 CONNECT ubuntu.com:443 - HIER_DIRECT/185.125.190.29 -
Closing Thoughts
These five rocks represent another step toward a broader collection of minimal, secure, and maintainable Ubuntu service images.
Apache2, Nginx, Bind9, Memcached and Squid all emerged from the petrification process smaller than before, with cleaner dependency trees and a reduced runtime footprint. Several now run rootless, with their services being now managed by Pebble, and each has been carefully chiseled to include only the pieces required for its intended purpose.
The rock garden keeps growing!
![]()

