Skip to content

Conversation

@thresheek
Copy link
Contributor

Notable Dockerfile changes include:

  • renamed configure arguments and changed build paths
  • added njs support for image builds
  • added loadable js modules to entrypoint
  • made curl fail with non-zero exit code on server errors
  • added a way to generate multiple versions of a language-based image
  • tagged minimal variant as latest
  • added a default "welcome" configuration

Notable Dockerfile changes include:
 - renamed configure arguments and changed build paths
 - added njs support for image builds
 - added loadable js modules to entrypoint
 - made curl fail with non-zero exit code on server errors
 - added a way to generate multiple versions of a language-based image
 - tagged minimal variant as latest
 - added a default "welcome" configuration
@github-actions
Copy link

Diff for b2cfd0c:
diff --git a/_bashbrew-cat b/_bashbrew-cat
index 5d4f86a..aa27e60 100644
--- a/_bashbrew-cat
+++ b/_bashbrew-cat
@@ -1,58 +1,58 @@
 Maintainers: Unit Docker Maintainers <[email protected]> (@nginx)
 GitRepo: https://github.com/nginx/unit.git
 
-Tags: 1.29.1-go1.20, go1.20, go1, go
+Tags: 1.30.0-go1.20, go1.20, go1, go
 Architectures: amd64, arm64v8
 GitFetch: refs/heads/branches/packaging
-GitCommit: b9bc222021e77bbdfb12576b3e315b962cf6b399
+GitCommit: 92ffcb89f8e145299e837438f0a0de93d73ffede
 Directory: pkg/docker
 File: Dockerfile.go1.20
 
-Tags: 1.29.1-jsc11, jsc11, jsc
+Tags: 1.30.0-jsc11, jsc11, jsc
 Architectures: amd64, arm64v8
 GitFetch: refs/heads/branches/packaging
-GitCommit: b9bc222021e77bbdfb12576b3e315b962cf6b399
+GitCommit: 92ffcb89f8e145299e837438f0a0de93d73ffede
 Directory: pkg/docker
 File: Dockerfile.jsc11
 
-Tags: 1.29.1-minimal, minimal
+Tags: 1.30.0-minimal, minimal, latest
 Architectures: amd64, arm64v8
 GitFetch: refs/heads/branches/packaging
-GitCommit: b9bc222021e77bbdfb12576b3e315b962cf6b399
+GitCommit: 92ffcb89f8e145299e837438f0a0de93d73ffede
 Directory: pkg/docker
 File: Dockerfile.minimal
 
-Tags: 1.29.1-node18, node18, node
+Tags: 1.30.0-node18, node18, node
 Architectures: amd64, arm64v8
 GitFetch: refs/heads/branches/packaging
-GitCommit: b9bc222021e77bbdfb12576b3e315b962cf6b399
+GitCommit: 92ffcb89f8e145299e837438f0a0de93d73ffede
 Directory: pkg/docker
 File: Dockerfile.node18
 
-Tags: 1.29.1-perl5.36, perl5.36, perl5, perl
+Tags: 1.30.0-perl5.36, perl5.36, perl5, perl
 Architectures: amd64, arm64v8
 GitFetch: refs/heads/branches/packaging
-GitCommit: b9bc222021e77bbdfb12576b3e315b962cf6b399
+GitCommit: 92ffcb89f8e145299e837438f0a0de93d73ffede
 Directory: pkg/docker
 File: Dockerfile.perl5.36
 
-Tags: 1.29.1-php8.2, php8.2, php8, php
+Tags: 1.30.0-php8.2, php8.2, php8, php
 Architectures: amd64, arm64v8
 GitFetch: refs/heads/branches/packaging
-GitCommit: b9bc222021e77bbdfb12576b3e315b962cf6b399
+GitCommit: 92ffcb89f8e145299e837438f0a0de93d73ffede
 Directory: pkg/docker
 File: Dockerfile.php8.2
 
-Tags: 1.29.1-python3.11, python3.11, python3, python
+Tags: 1.30.0-python3.11, python3.11, python3, python
 Architectures: amd64, arm64v8
 GitFetch: refs/heads/branches/packaging
-GitCommit: b9bc222021e77bbdfb12576b3e315b962cf6b399
+GitCommit: 92ffcb89f8e145299e837438f0a0de93d73ffede
 Directory: pkg/docker
 File: Dockerfile.python3.11
 
-Tags: 1.29.1-ruby3.2, ruby3.2, ruby3, ruby
+Tags: 1.30.0-ruby3.2, ruby3.2, ruby3, ruby
 Architectures: amd64, arm64v8
 GitFetch: refs/heads/branches/packaging
-GitCommit: b9bc222021e77bbdfb12576b3e315b962cf6b399
+GitCommit: 92ffcb89f8e145299e837438f0a0de93d73ffede
 Directory: pkg/docker
 File: Dockerfile.ruby3.2
diff --git a/_bashbrew-list b/_bashbrew-list
index 1f3384f..5352663 100644
--- a/_bashbrew-list
+++ b/_bashbrew-list
@@ -1,16 +1,17 @@
-unit:1.29.1-go1.20
-unit:1.29.1-jsc11
-unit:1.29.1-minimal
-unit:1.29.1-node18
-unit:1.29.1-perl5.36
-unit:1.29.1-php8.2
-unit:1.29.1-python3.11
-unit:1.29.1-ruby3.2
+unit:1.30.0-go1.20
+unit:1.30.0-jsc11
+unit:1.30.0-minimal
+unit:1.30.0-node18
+unit:1.30.0-perl5.36
+unit:1.30.0-php8.2
+unit:1.30.0-python3.11
+unit:1.30.0-ruby3.2
 unit:go
 unit:go1
 unit:go1.20
 unit:jsc
 unit:jsc11
+unit:latest
 unit:minimal
 unit:node
 unit:node18
diff --git a/_bashbrew-list-build-order b/_bashbrew-list-build-order
index d08fa46..3adff97 100644
--- a/_bashbrew-list-build-order
+++ b/_bashbrew-list-build-order
@@ -1,6 +1,6 @@
 unit:go
 unit:jsc
-unit:minimal
+unit:latest
 unit:node
 unit:perl
 unit:php
diff --git a/unit_go/Dockerfile.go1.20 b/unit_go/Dockerfile.go1.20
index 408e0d2..50b4d5b 100644
--- a/unit_go/Dockerfile.go1.20
+++ b/unit_go/Dockerfile.go1.20
@@ -6,42 +6,46 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org"
 LABEL org.opencontainers.image.source="https://github.com/nginx/unit"
 LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images"
 LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers <[email protected]>"
-LABEL org.opencontainers.image.version="1.29.1"
+LABEL org.opencontainers.image.version="1.30.0"
 
 RUN set -ex \
     && savedAptMark="$(apt-mark showmanual)" \
     && apt-get update \
-    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \
+    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \
     && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \
-    && hg clone -u 1.29.1-1 https://hg.nginx.org/unit \
+    && hg clone -u 1.30.0-1 https://hg.nginx.org/unit \
     && cd unit \
     && NCPU="$(getconf _NPROCESSORS_ONLN)" \
     && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \
     && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \
     && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \
-    && CONFIGURE_ARGS="--prefix=/usr \
-                --state=/var/lib/unit \
+    && CONFIGURE_ARGS_MODULES="--prefix=/usr \
+                --statedir=/var/lib/unit \
                 --control=unix:/var/run/control.unit.sock \
                 --pid=/var/run/unit.pid \
                 --log=/var/log/unit.log \
-                --tmp=/var/tmp \
+                --tmpdir=/var/tmp \
                 --user=unit \
                 --group=unit \
                 --openssl \
                 --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \
+                --njs" \
+    && make -j $NCPU -C pkg/contrib .njs \
+    && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd-debug \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && ./configure go --go-path=$GOPATH \
     && make -j $NCPU go-install-src libunit-install \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \
     && ./configure go --go-path=$GOPATH \
     && make -j $NCPU go-install-src libunit-install \
     && cd \
@@ -71,9 +75,10 @@ RUN set -ex \
     && ln -sf /dev/stdout /var/log/unit.log
 
 COPY docker-entrypoint.sh /usr/local/bin/
+COPY welcome.* /usr/share/unit/welcome/
 
 STOPSIGNAL SIGTERM
 
 ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
-
+EXPOSE 80
 CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
diff --git a/unit_go/docker-entrypoint.sh b/unit_go/docker-entrypoint.sh
index e0afd7e..4646409 100755
--- a/unit_go/docker-entrypoint.sh
+++ b/unit_go/docker-entrypoint.sh
@@ -25,8 +25,7 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
     if /usr/bin/find "/var/lib/unit/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
         echo "$0: /var/lib/unit/ is not empty, skipping initial configuration..."
     else
-        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
-            echo "$0: /docker-entrypoint.d/ is not empty, launching Unit daemon to perform initial configuration..."
+        echo "$0: Launching Unit daemon to perform initial configuration..."
         /usr/sbin/$1 --control unix:/var/run/control.unit.sock
 
         for i in $(/usr/bin/seq $WAITLOOPS); do
@@ -41,12 +40,21 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         # this curl call will get a reply once unit is fully launched
         /usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
 
+        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
+            echo "$0: /docker-entrypoint.d/ is not empty, applying initial configuration..."
+
             echo "$0: Looking for certificate bundles in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.pem"); do
                 echo "$0: Uploading certificates bundle: $f"
                 curl_put $f "certificates/$(basename $f .pem)"
             done
 
+            echo "$0: Looking for JavaScript modules in /docker-entrypoint.d/..."
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.js"); do
+                echo "$0: Uploading JavaScript module: $f"
+                curl_put $f "js_modules/$(basename $f .js)"
+            done
+
             echo "$0: Looking for configuration snippets in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.json"); do
                 echo "$0: Applying configuration $f";
@@ -60,9 +68,13 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
             done
 
             # warn on filetypes we don't know what to do with
-            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem"); do
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
                 echo "$0: Ignoring $f";
             done
+        else
+            echo "$0: /docker-entrypoint.d/ is empty, creating 'welcome' configuration..."
+            curl_put /usr/share/unit/welcome/welcome.json "config"
+        fi
 
         echo "$0: Stopping Unit daemon after initial configuration..."
         kill -TERM $(/bin/cat /var/run/unit.pid)
@@ -83,9 +95,6 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         echo
         echo "$0: Unit initial configuration complete; ready for start up..."
         echo
-        else
-            echo "$0: /docker-entrypoint.d/ is empty, skipping initial configuration..."
-        fi
     fi
 fi
 
diff --git a/unit_go/welcome.html b/unit_go/welcome.html
new file mode 100644
index 0000000..9c4f828
--- /dev/null
+++ b/unit_go/welcome.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Welcome to NGINX Unit</title>
+        <style type="text/css">
+            body { background: white; color: black; font-family: sans-serif; margin: 2em; line-height: 1.5; }
+            h1,h2 { color: #00974d; }
+            li { margin-bottom: 0.5em; }
+            pre { background-color: beige; padding: 0.4em; }
+            hr { margin-top: 2em; border: 1px solid #00974d; }
+            .indent { margin-left: 1.5em; }
+        </style>
+    </head>
+    <body>
+        <h1>Welcome to NGINX Unit</h1>
+        <p>Congratulations! NGINX Unit is installed and running.</p>
+        <h3>Useful Links</h3>
+        <ul>
+            <li><b><a href="https://unit.nginx.org/configuration/?referer=welcome&platform=docker">https://unit.nginx.org/configuration/</a></b><br>
+                To get started with Unit, see the <em>Configuration</em> docs, starting with
+                the <em>Quick Start</em> guide.</li>
+            <li><b><a href="https://unit.nginx.org/howto/docker/?referer=welcome&platform=docker">https://unit.nginx.org/howto/docker/</a></b><br>
+                For guidance about running <em>Unit in Docker</em> and tips for containerized
+                applications.
+            <li><b><a href="https://github.com/nginx/unit">https://github.com/nginx/unit</a></b><br>
+                See our GitHub repo to browse the code, contribute, or seek help from the
+                <a href="https://github.com/nginx/unit#community">community</a>.</li>
+        </ul>
+
+        <h2>Next steps</h2>
+
+        <h3>Check Current Configuration</h3>
+        <div class="indent">
+        <p>Unit's control API is currently listening for configuration changes
+           on the <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix socket</a> at
+           <b>/var/run/control.unit.sock</b> inside the container.<br>
+           To see the current configuration run:</p>
+        <pre>docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config</pre>
+        </div>
+
+        <hr>
+        <p><a href="https://unit.nginx.org/?referer=welcome&platform=docker">NGINX Unit &mdash; the universal web app server</a><br>
+        NGINX, Inc. &copy; 2023</p>
+    </body>
+</html>
diff --git a/unit_go/welcome.json b/unit_go/welcome.json
new file mode 100644
index 0000000..2a148da
--- /dev/null
+++ b/unit_go/welcome.json
@@ -0,0 +1,25 @@
+{
+    "listeners": {
+        "*:80": {
+            "pass": "routes"
+        }
+    },
+
+    "routes": [
+        {
+            "match": {
+                "headers": {
+                    "accept": "*text/html*"
+                }
+            },
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.html"
+            }
+        },
+        {
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.md"
+            }
+        }
+    ]
+}
diff --git a/unit_go/welcome.md b/unit_go/welcome.md
new file mode 100644
index 0000000..fef3d15
--- /dev/null
+++ b/unit_go/welcome.md
@@ -0,0 +1,29 @@
+Welcome to NGINX Unit
+=====================
+
+Congratulations! NGINX Unit is installed and running.
+
+Useful Links
+------------
+
+ * https://unit.nginx.org/
+   - Get started with the 'Configuration' docs, starting with the 'Quick Start' guide.
+
+ * https://unit.nginx.org/howto/docker/
+   - Guidance for running Unit in a container and tips for containerized applications.
+
+ * https://github.com/nginx/unit
+   - See our GitHub repo to browse the code, contribute, or seek help from the community.
+
+Current Configuration
+---------------------
+Unit's control API is currently listening for configuration changes on the Unix socket at
+`/var/run/control.unit.sock` inside the container.
+
+Read the current configuration with
+```
+docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config
+```
+
+---
+NGINX Unit - the universal web app server
diff --git a/unit_jsc/Dockerfile.jsc11 b/unit_jsc/Dockerfile.jsc11
index dcadeef..bd987ae 100644
--- a/unit_jsc/Dockerfile.jsc11
+++ b/unit_jsc/Dockerfile.jsc11
@@ -6,42 +6,46 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org"
 LABEL org.opencontainers.image.source="https://github.com/nginx/unit"
 LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images"
 LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers <[email protected]>"
-LABEL org.opencontainers.image.version="1.29.1"
+LABEL org.opencontainers.image.version="1.30.0"
 
 RUN set -ex \
     && savedAptMark="$(apt-mark showmanual)" \
     && apt-get update \
-    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \
+    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \
     && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \
-    && hg clone -u 1.29.1-1 https://hg.nginx.org/unit \
+    && hg clone -u 1.30.0-1 https://hg.nginx.org/unit \
     && cd unit \
     && NCPU="$(getconf _NPROCESSORS_ONLN)" \
     && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \
     && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \
     && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \
-    && CONFIGURE_ARGS="--prefix=/usr \
-                --state=/var/lib/unit \
+    && CONFIGURE_ARGS_MODULES="--prefix=/usr \
+                --statedir=/var/lib/unit \
                 --control=unix:/var/run/control.unit.sock \
                 --pid=/var/run/unit.pid \
                 --log=/var/log/unit.log \
-                --tmp=/var/tmp \
+                --tmpdir=/var/tmp \
                 --user=unit \
                 --group=unit \
                 --openssl \
                 --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \
+                --njs" \
+    && make -j $NCPU -C pkg/contrib .njs \
+    && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd-debug \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && ./configure java --jars=/usr/share/unit-jsc-common/ \
     && make -j $NCPU java-shared-install java-install \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \
     && ./configure java --jars=/usr/share/unit-jsc-common/ \
     && make -j $NCPU java-shared-install java-install \
     && cd \
@@ -71,9 +75,10 @@ RUN set -ex \
     && ln -sf /dev/stdout /var/log/unit.log
 
 COPY docker-entrypoint.sh /usr/local/bin/
+COPY welcome.* /usr/share/unit/welcome/
 
 STOPSIGNAL SIGTERM
 
 ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
-
+EXPOSE 80
 CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
diff --git a/unit_jsc/docker-entrypoint.sh b/unit_jsc/docker-entrypoint.sh
index e0afd7e..4646409 100755
--- a/unit_jsc/docker-entrypoint.sh
+++ b/unit_jsc/docker-entrypoint.sh
@@ -25,8 +25,7 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
     if /usr/bin/find "/var/lib/unit/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
         echo "$0: /var/lib/unit/ is not empty, skipping initial configuration..."
     else
-        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
-            echo "$0: /docker-entrypoint.d/ is not empty, launching Unit daemon to perform initial configuration..."
+        echo "$0: Launching Unit daemon to perform initial configuration..."
         /usr/sbin/$1 --control unix:/var/run/control.unit.sock
 
         for i in $(/usr/bin/seq $WAITLOOPS); do
@@ -41,12 +40,21 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         # this curl call will get a reply once unit is fully launched
         /usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
 
+        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
+            echo "$0: /docker-entrypoint.d/ is not empty, applying initial configuration..."
+
             echo "$0: Looking for certificate bundles in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.pem"); do
                 echo "$0: Uploading certificates bundle: $f"
                 curl_put $f "certificates/$(basename $f .pem)"
             done
 
+            echo "$0: Looking for JavaScript modules in /docker-entrypoint.d/..."
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.js"); do
+                echo "$0: Uploading JavaScript module: $f"
+                curl_put $f "js_modules/$(basename $f .js)"
+            done
+
             echo "$0: Looking for configuration snippets in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.json"); do
                 echo "$0: Applying configuration $f";
@@ -60,9 +68,13 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
             done
 
             # warn on filetypes we don't know what to do with
-            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem"); do
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
                 echo "$0: Ignoring $f";
             done
+        else
+            echo "$0: /docker-entrypoint.d/ is empty, creating 'welcome' configuration..."
+            curl_put /usr/share/unit/welcome/welcome.json "config"
+        fi
 
         echo "$0: Stopping Unit daemon after initial configuration..."
         kill -TERM $(/bin/cat /var/run/unit.pid)
@@ -83,9 +95,6 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         echo
         echo "$0: Unit initial configuration complete; ready for start up..."
         echo
-        else
-            echo "$0: /docker-entrypoint.d/ is empty, skipping initial configuration..."
-        fi
     fi
 fi
 
diff --git a/unit_jsc/welcome.html b/unit_jsc/welcome.html
new file mode 100644
index 0000000..9c4f828
--- /dev/null
+++ b/unit_jsc/welcome.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Welcome to NGINX Unit</title>
+        <style type="text/css">
+            body { background: white; color: black; font-family: sans-serif; margin: 2em; line-height: 1.5; }
+            h1,h2 { color: #00974d; }
+            li { margin-bottom: 0.5em; }
+            pre { background-color: beige; padding: 0.4em; }
+            hr { margin-top: 2em; border: 1px solid #00974d; }
+            .indent { margin-left: 1.5em; }
+        </style>
+    </head>
+    <body>
+        <h1>Welcome to NGINX Unit</h1>
+        <p>Congratulations! NGINX Unit is installed and running.</p>
+        <h3>Useful Links</h3>
+        <ul>
+            <li><b><a href="https://unit.nginx.org/configuration/?referer=welcome&platform=docker">https://unit.nginx.org/configuration/</a></b><br>
+                To get started with Unit, see the <em>Configuration</em> docs, starting with
+                the <em>Quick Start</em> guide.</li>
+            <li><b><a href="https://unit.nginx.org/howto/docker/?referer=welcome&platform=docker">https://unit.nginx.org/howto/docker/</a></b><br>
+                For guidance about running <em>Unit in Docker</em> and tips for containerized
+                applications.
+            <li><b><a href="https://github.com/nginx/unit">https://github.com/nginx/unit</a></b><br>
+                See our GitHub repo to browse the code, contribute, or seek help from the
+                <a href="https://github.com/nginx/unit#community">community</a>.</li>
+        </ul>
+
+        <h2>Next steps</h2>
+
+        <h3>Check Current Configuration</h3>
+        <div class="indent">
+        <p>Unit's control API is currently listening for configuration changes
+           on the <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix socket</a> at
+           <b>/var/run/control.unit.sock</b> inside the container.<br>
+           To see the current configuration run:</p>
+        <pre>docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config</pre>
+        </div>
+
+        <hr>
+        <p><a href="https://unit.nginx.org/?referer=welcome&platform=docker">NGINX Unit &mdash; the universal web app server</a><br>
+        NGINX, Inc. &copy; 2023</p>
+    </body>
+</html>
diff --git a/unit_jsc/welcome.json b/unit_jsc/welcome.json
new file mode 100644
index 0000000..2a148da
--- /dev/null
+++ b/unit_jsc/welcome.json
@@ -0,0 +1,25 @@
+{
+    "listeners": {
+        "*:80": {
+            "pass": "routes"
+        }
+    },
+
+    "routes": [
+        {
+            "match": {
+                "headers": {
+                    "accept": "*text/html*"
+                }
+            },
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.html"
+            }
+        },
+        {
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.md"
+            }
+        }
+    ]
+}
diff --git a/unit_jsc/welcome.md b/unit_jsc/welcome.md
new file mode 100644
index 0000000..fef3d15
--- /dev/null
+++ b/unit_jsc/welcome.md
@@ -0,0 +1,29 @@
+Welcome to NGINX Unit
+=====================
+
+Congratulations! NGINX Unit is installed and running.
+
+Useful Links
+------------
+
+ * https://unit.nginx.org/
+   - Get started with the 'Configuration' docs, starting with the 'Quick Start' guide.
+
+ * https://unit.nginx.org/howto/docker/
+   - Guidance for running Unit in a container and tips for containerized applications.
+
+ * https://github.com/nginx/unit
+   - See our GitHub repo to browse the code, contribute, or seek help from the community.
+
+Current Configuration
+---------------------
+Unit's control API is currently listening for configuration changes on the Unix socket at
+`/var/run/control.unit.sock` inside the container.
+
+Read the current configuration with
+```
+docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config
+```
+
+---
+NGINX Unit - the universal web app server
diff --git a/unit_minimal/Dockerfile.minimal b/unit_latest/Dockerfile.minimal
similarity index 76%
rename from unit_minimal/Dockerfile.minimal
rename to unit_latest/Dockerfile.minimal
index 2a2d275..06a85b2 100644
--- a/unit_minimal/Dockerfile.minimal
+++ b/unit_latest/Dockerfile.minimal
@@ -6,42 +6,46 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org"
 LABEL org.opencontainers.image.source="https://github.com/nginx/unit"
 LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images"
 LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers <[email protected]>"
-LABEL org.opencontainers.image.version="1.29.1"
+LABEL org.opencontainers.image.version="1.30.0"
 
 RUN set -ex \
     && savedAptMark="$(apt-mark showmanual)" \
     && apt-get update \
-    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \
+    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \
     && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \
-    && hg clone -u 1.29.1-1 https://hg.nginx.org/unit \
+    && hg clone -u 1.30.0-1 https://hg.nginx.org/unit \
     && cd unit \
     && NCPU="$(getconf _NPROCESSORS_ONLN)" \
     && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \
     && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \
     && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \
-    && CONFIGURE_ARGS="--prefix=/usr \
-                --state=/var/lib/unit \
+    && CONFIGURE_ARGS_MODULES="--prefix=/usr \
+                --statedir=/var/lib/unit \
                 --control=unix:/var/run/control.unit.sock \
                 --pid=/var/run/unit.pid \
                 --log=/var/log/unit.log \
-                --tmp=/var/tmp \
+                --tmpdir=/var/tmp \
                 --user=unit \
                 --group=unit \
                 --openssl \
                 --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \
+                --njs" \
+    && make -j $NCPU -C pkg/contrib .njs \
+    && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd-debug \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && ./configure  \
     && make -j $NCPU version \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \
     && ./configure  \
     && make -j $NCPU version \
     && cd \
@@ -71,9 +75,10 @@ RUN set -ex \
     && ln -sf /dev/stdout /var/log/unit.log
 
 COPY docker-entrypoint.sh /usr/local/bin/
+COPY welcome.* /usr/share/unit/welcome/
 
 STOPSIGNAL SIGTERM
 
 ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
-
+EXPOSE 80
 CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
diff --git a/unit_minimal/docker-entrypoint.sh b/unit_latest/docker-entrypoint.sh
similarity index 52%
rename from unit_minimal/docker-entrypoint.sh
rename to unit_latest/docker-entrypoint.sh
index e0afd7e..4646409 100755
--- a/unit_minimal/docker-entrypoint.sh
+++ b/unit_latest/docker-entrypoint.sh
@@ -25,8 +25,7 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
     if /usr/bin/find "/var/lib/unit/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
         echo "$0: /var/lib/unit/ is not empty, skipping initial configuration..."
     else
-        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
-            echo "$0: /docker-entrypoint.d/ is not empty, launching Unit daemon to perform initial configuration..."
+        echo "$0: Launching Unit daemon to perform initial configuration..."
         /usr/sbin/$1 --control unix:/var/run/control.unit.sock
 
         for i in $(/usr/bin/seq $WAITLOOPS); do
@@ -41,12 +40,21 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         # this curl call will get a reply once unit is fully launched
         /usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
 
+        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
+            echo "$0: /docker-entrypoint.d/ is not empty, applying initial configuration..."
+
             echo "$0: Looking for certificate bundles in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.pem"); do
                 echo "$0: Uploading certificates bundle: $f"
                 curl_put $f "certificates/$(basename $f .pem)"
             done
 
+            echo "$0: Looking for JavaScript modules in /docker-entrypoint.d/..."
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.js"); do
+                echo "$0: Uploading JavaScript module: $f"
+                curl_put $f "js_modules/$(basename $f .js)"
+            done
+
             echo "$0: Looking for configuration snippets in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.json"); do
                 echo "$0: Applying configuration $f";
@@ -60,9 +68,13 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
             done
 
             # warn on filetypes we don't know what to do with
-            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem"); do
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
                 echo "$0: Ignoring $f";
             done
+        else
+            echo "$0: /docker-entrypoint.d/ is empty, creating 'welcome' configuration..."
+            curl_put /usr/share/unit/welcome/welcome.json "config"
+        fi
 
         echo "$0: Stopping Unit daemon after initial configuration..."
         kill -TERM $(/bin/cat /var/run/unit.pid)
@@ -83,9 +95,6 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         echo
         echo "$0: Unit initial configuration complete; ready for start up..."
         echo
-        else
-            echo "$0: /docker-entrypoint.d/ is empty, skipping initial configuration..."
-        fi
     fi
 fi
 
diff --git a/unit_latest/welcome.html b/unit_latest/welcome.html
new file mode 100644
index 0000000..9c4f828
--- /dev/null
+++ b/unit_latest/welcome.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Welcome to NGINX Unit</title>
+        <style type="text/css">
+            body { background: white; color: black; font-family: sans-serif; margin: 2em; line-height: 1.5; }
+            h1,h2 { color: #00974d; }
+            li { margin-bottom: 0.5em; }
+            pre { background-color: beige; padding: 0.4em; }
+            hr { margin-top: 2em; border: 1px solid #00974d; }
+            .indent { margin-left: 1.5em; }
+        </style>
+    </head>
+    <body>
+        <h1>Welcome to NGINX Unit</h1>
+        <p>Congratulations! NGINX Unit is installed and running.</p>
+        <h3>Useful Links</h3>
+        <ul>
+            <li><b><a href="https://unit.nginx.org/configuration/?referer=welcome&platform=docker">https://unit.nginx.org/configuration/</a></b><br>
+                To get started with Unit, see the <em>Configuration</em> docs, starting with
+                the <em>Quick Start</em> guide.</li>
+            <li><b><a href="https://unit.nginx.org/howto/docker/?referer=welcome&platform=docker">https://unit.nginx.org/howto/docker/</a></b><br>
+                For guidance about running <em>Unit in Docker</em> and tips for containerized
+                applications.
+            <li><b><a href="https://github.com/nginx/unit">https://github.com/nginx/unit</a></b><br>
+                See our GitHub repo to browse the code, contribute, or seek help from the
+                <a href="https://github.com/nginx/unit#community">community</a>.</li>
+        </ul>
+
+        <h2>Next steps</h2>
+
+        <h3>Check Current Configuration</h3>
+        <div class="indent">
+        <p>Unit's control API is currently listening for configuration changes
+           on the <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix socket</a> at
+           <b>/var/run/control.unit.sock</b> inside the container.<br>
+           To see the current configuration run:</p>
+        <pre>docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config</pre>
+        </div>
+
+        <hr>
+        <p><a href="https://unit.nginx.org/?referer=welcome&platform=docker">NGINX Unit &mdash; the universal web app server</a><br>
+        NGINX, Inc. &copy; 2023</p>
+    </body>
+</html>
diff --git a/unit_latest/welcome.json b/unit_latest/welcome.json
new file mode 100644
index 0000000..2a148da
--- /dev/null
+++ b/unit_latest/welcome.json
@@ -0,0 +1,25 @@
+{
+    "listeners": {
+        "*:80": {
+            "pass": "routes"
+        }
+    },
+
+    "routes": [
+        {
+            "match": {
+                "headers": {
+                    "accept": "*text/html*"
+                }
+            },
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.html"
+            }
+        },
+        {
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.md"
+            }
+        }
+    ]
+}
diff --git a/unit_latest/welcome.md b/unit_latest/welcome.md
new file mode 100644
index 0000000..fef3d15
--- /dev/null
+++ b/unit_latest/welcome.md
@@ -0,0 +1,29 @@
+Welcome to NGINX Unit
+=====================
+
+Congratulations! NGINX Unit is installed and running.
+
+Useful Links
+------------
+
+ * https://unit.nginx.org/
+   - Get started with the 'Configuration' docs, starting with the 'Quick Start' guide.
+
+ * https://unit.nginx.org/howto/docker/
+   - Guidance for running Unit in a container and tips for containerized applications.
+
+ * https://github.com/nginx/unit
+   - See our GitHub repo to browse the code, contribute, or seek help from the community.
+
+Current Configuration
+---------------------
+Unit's control API is currently listening for configuration changes on the Unix socket at
+`/var/run/control.unit.sock` inside the container.
+
+Read the current configuration with
+```
+docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config
+```
+
+---
+NGINX Unit - the universal web app server
diff --git a/unit_node/Dockerfile.node18 b/unit_node/Dockerfile.node18
index b782b60..b3fb46d 100644
--- a/unit_node/Dockerfile.node18
+++ b/unit_node/Dockerfile.node18
@@ -6,42 +6,46 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org"
 LABEL org.opencontainers.image.source="https://github.com/nginx/unit"
 LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images"
 LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers <[email protected]>"
-LABEL org.opencontainers.image.version="1.29.1"
+LABEL org.opencontainers.image.version="1.30.0"
 
 RUN set -ex \
     && savedAptMark="$(apt-mark showmanual)" \
     && apt-get update \
-    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \
+    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \
     && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \
-    && hg clone -u 1.29.1-1 https://hg.nginx.org/unit \
+    && hg clone -u 1.30.0-1 https://hg.nginx.org/unit \
     && cd unit \
     && NCPU="$(getconf _NPROCESSORS_ONLN)" \
     && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \
     && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \
     && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \
-    && CONFIGURE_ARGS="--prefix=/usr \
-                --state=/var/lib/unit \
+    && CONFIGURE_ARGS_MODULES="--prefix=/usr \
+                --statedir=/var/lib/unit \
                 --control=unix:/var/run/control.unit.sock \
                 --pid=/var/run/unit.pid \
                 --log=/var/log/unit.log \
-                --tmp=/var/tmp \
+                --tmpdir=/var/tmp \
                 --user=unit \
                 --group=unit \
                 --openssl \
                 --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \
+                --njs" \
+    && make -j $NCPU -C pkg/contrib .njs \
+    && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd-debug \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && ./configure nodejs --node-gyp=/usr/local/lib/node_modules/npm/bin/node-gyp-bin/node-gyp \
     && make -j $NCPU node node-install libunit-install \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \
     && ./configure nodejs --node-gyp=/usr/local/lib/node_modules/npm/bin/node-gyp-bin/node-gyp \
     && make -j $NCPU node node-install libunit-install \
     && cd \
@@ -71,9 +75,10 @@ RUN set -ex \
     && ln -sf /dev/stdout /var/log/unit.log
 
 COPY docker-entrypoint.sh /usr/local/bin/
+COPY welcome.* /usr/share/unit/welcome/
 
 STOPSIGNAL SIGTERM
 
 ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
-
+EXPOSE 80
 CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
diff --git a/unit_node/docker-entrypoint.sh b/unit_node/docker-entrypoint.sh
index e0afd7e..4646409 100755
--- a/unit_node/docker-entrypoint.sh
+++ b/unit_node/docker-entrypoint.sh
@@ -25,8 +25,7 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
     if /usr/bin/find "/var/lib/unit/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
         echo "$0: /var/lib/unit/ is not empty, skipping initial configuration..."
     else
-        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
-            echo "$0: /docker-entrypoint.d/ is not empty, launching Unit daemon to perform initial configuration..."
+        echo "$0: Launching Unit daemon to perform initial configuration..."
         /usr/sbin/$1 --control unix:/var/run/control.unit.sock
 
         for i in $(/usr/bin/seq $WAITLOOPS); do
@@ -41,12 +40,21 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         # this curl call will get a reply once unit is fully launched
         /usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
 
+        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
+            echo "$0: /docker-entrypoint.d/ is not empty, applying initial configuration..."
+
             echo "$0: Looking for certificate bundles in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.pem"); do
                 echo "$0: Uploading certificates bundle: $f"
                 curl_put $f "certificates/$(basename $f .pem)"
             done
 
+            echo "$0: Looking for JavaScript modules in /docker-entrypoint.d/..."
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.js"); do
+                echo "$0: Uploading JavaScript module: $f"
+                curl_put $f "js_modules/$(basename $f .js)"
+            done
+
             echo "$0: Looking for configuration snippets in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.json"); do
                 echo "$0: Applying configuration $f";
@@ -60,9 +68,13 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
             done
 
             # warn on filetypes we don't know what to do with
-            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem"); do
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
                 echo "$0: Ignoring $f";
             done
+        else
+            echo "$0: /docker-entrypoint.d/ is empty, creating 'welcome' configuration..."
+            curl_put /usr/share/unit/welcome/welcome.json "config"
+        fi
 
         echo "$0: Stopping Unit daemon after initial configuration..."
         kill -TERM $(/bin/cat /var/run/unit.pid)
@@ -83,9 +95,6 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         echo
         echo "$0: Unit initial configuration complete; ready for start up..."
         echo
-        else
-            echo "$0: /docker-entrypoint.d/ is empty, skipping initial configuration..."
-        fi
     fi
 fi
 
diff --git a/unit_node/welcome.html b/unit_node/welcome.html
new file mode 100644
index 0000000..9c4f828
--- /dev/null
+++ b/unit_node/welcome.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Welcome to NGINX Unit</title>
+        <style type="text/css">
+            body { background: white; color: black; font-family: sans-serif; margin: 2em; line-height: 1.5; }
+            h1,h2 { color: #00974d; }
+            li { margin-bottom: 0.5em; }
+            pre { background-color: beige; padding: 0.4em; }
+            hr { margin-top: 2em; border: 1px solid #00974d; }
+            .indent { margin-left: 1.5em; }
+        </style>
+    </head>
+    <body>
+        <h1>Welcome to NGINX Unit</h1>
+        <p>Congratulations! NGINX Unit is installed and running.</p>
+        <h3>Useful Links</h3>
+        <ul>
+            <li><b><a href="https://unit.nginx.org/configuration/?referer=welcome&platform=docker">https://unit.nginx.org/configuration/</a></b><br>
+                To get started with Unit, see the <em>Configuration</em> docs, starting with
+                the <em>Quick Start</em> guide.</li>
+            <li><b><a href="https://unit.nginx.org/howto/docker/?referer=welcome&platform=docker">https://unit.nginx.org/howto/docker/</a></b><br>
+                For guidance about running <em>Unit in Docker</em> and tips for containerized
+                applications.
+            <li><b><a href="https://github.com/nginx/unit">https://github.com/nginx/unit</a></b><br>
+                See our GitHub repo to browse the code, contribute, or seek help from the
+                <a href="https://github.com/nginx/unit#community">community</a>.</li>
+        </ul>
+
+        <h2>Next steps</h2>
+
+        <h3>Check Current Configuration</h3>
+        <div class="indent">
+        <p>Unit's control API is currently listening for configuration changes
+           on the <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix socket</a> at
+           <b>/var/run/control.unit.sock</b> inside the container.<br>
+           To see the current configuration run:</p>
+        <pre>docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config</pre>
+        </div>
+
+        <hr>
+        <p><a href="https://unit.nginx.org/?referer=welcome&platform=docker">NGINX Unit &mdash; the universal web app server</a><br>
+        NGINX, Inc. &copy; 2023</p>
+    </body>
+</html>
diff --git a/unit_node/welcome.json b/unit_node/welcome.json
new file mode 100644
index 0000000..2a148da
--- /dev/null
+++ b/unit_node/welcome.json
@@ -0,0 +1,25 @@
+{
+    "listeners": {
+        "*:80": {
+            "pass": "routes"
+        }
+    },
+
+    "routes": [
+        {
+            "match": {
+                "headers": {
+                    "accept": "*text/html*"
+                }
+            },
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.html"
+            }
+        },
+        {
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.md"
+            }
+        }
+    ]
+}
diff --git a/unit_node/welcome.md b/unit_node/welcome.md
new file mode 100644
index 0000000..fef3d15
--- /dev/null
+++ b/unit_node/welcome.md
@@ -0,0 +1,29 @@
+Welcome to NGINX Unit
+=====================
+
+Congratulations! NGINX Unit is installed and running.
+
+Useful Links
+------------
+
+ * https://unit.nginx.org/
+   - Get started with the 'Configuration' docs, starting with the 'Quick Start' guide.
+
+ * https://unit.nginx.org/howto/docker/
+   - Guidance for running Unit in a container and tips for containerized applications.
+
+ * https://github.com/nginx/unit
+   - See our GitHub repo to browse the code, contribute, or seek help from the community.
+
+Current Configuration
+---------------------
+Unit's control API is currently listening for configuration changes on the Unix socket at
+`/var/run/control.unit.sock` inside the container.
+
+Read the current configuration with
+```
+docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config
+```
+
+---
+NGINX Unit - the universal web app server
diff --git a/unit_perl/Dockerfile.perl5.36 b/unit_perl/Dockerfile.perl5.36
index c265bd3..2dc31e5 100644
--- a/unit_perl/Dockerfile.perl5.36
+++ b/unit_perl/Dockerfile.perl5.36
@@ -6,42 +6,46 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org"
 LABEL org.opencontainers.image.source="https://github.com/nginx/unit"
 LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images"
 LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers <[email protected]>"
-LABEL org.opencontainers.image.version="1.29.1"
+LABEL org.opencontainers.image.version="1.30.0"
 
 RUN set -ex \
     && savedAptMark="$(apt-mark showmanual)" \
     && apt-get update \
-    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \
+    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \
     && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \
-    && hg clone -u 1.29.1-1 https://hg.nginx.org/unit \
+    && hg clone -u 1.30.0-1 https://hg.nginx.org/unit \
     && cd unit \
     && NCPU="$(getconf _NPROCESSORS_ONLN)" \
     && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \
     && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \
     && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \
-    && CONFIGURE_ARGS="--prefix=/usr \
-                --state=/var/lib/unit \
+    && CONFIGURE_ARGS_MODULES="--prefix=/usr \
+                --statedir=/var/lib/unit \
                 --control=unix:/var/run/control.unit.sock \
                 --pid=/var/run/unit.pid \
                 --log=/var/log/unit.log \
-                --tmp=/var/tmp \
+                --tmpdir=/var/tmp \
                 --user=unit \
                 --group=unit \
                 --openssl \
                 --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \
+                --njs" \
+    && make -j $NCPU -C pkg/contrib .njs \
+    && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd-debug \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && ./configure perl \
     && make -j $NCPU perl-install \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \
     && ./configure perl \
     && make -j $NCPU perl-install \
     && cd \
@@ -71,9 +75,10 @@ RUN set -ex \
     && ln -sf /dev/stdout /var/log/unit.log
 
 COPY docker-entrypoint.sh /usr/local/bin/
+COPY welcome.* /usr/share/unit/welcome/
 
 STOPSIGNAL SIGTERM
 
 ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
-
+EXPOSE 80
 CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
diff --git a/unit_perl/docker-entrypoint.sh b/unit_perl/docker-entrypoint.sh
index e0afd7e..4646409 100755
--- a/unit_perl/docker-entrypoint.sh
+++ b/unit_perl/docker-entrypoint.sh
@@ -25,8 +25,7 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
     if /usr/bin/find "/var/lib/unit/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
         echo "$0: /var/lib/unit/ is not empty, skipping initial configuration..."
     else
-        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
-            echo "$0: /docker-entrypoint.d/ is not empty, launching Unit daemon to perform initial configuration..."
+        echo "$0: Launching Unit daemon to perform initial configuration..."
         /usr/sbin/$1 --control unix:/var/run/control.unit.sock
 
         for i in $(/usr/bin/seq $WAITLOOPS); do
@@ -41,12 +40,21 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         # this curl call will get a reply once unit is fully launched
         /usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
 
+        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
+            echo "$0: /docker-entrypoint.d/ is not empty, applying initial configuration..."
+
             echo "$0: Looking for certificate bundles in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.pem"); do
                 echo "$0: Uploading certificates bundle: $f"
                 curl_put $f "certificates/$(basename $f .pem)"
             done
 
+            echo "$0: Looking for JavaScript modules in /docker-entrypoint.d/..."
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.js"); do
+                echo "$0: Uploading JavaScript module: $f"
+                curl_put $f "js_modules/$(basename $f .js)"
+            done
+
             echo "$0: Looking for configuration snippets in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.json"); do
                 echo "$0: Applying configuration $f";
@@ -60,9 +68,13 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
             done
 
             # warn on filetypes we don't know what to do with
-            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem"); do
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
                 echo "$0: Ignoring $f";
             done
+        else
+            echo "$0: /docker-entrypoint.d/ is empty, creating 'welcome' configuration..."
+            curl_put /usr/share/unit/welcome/welcome.json "config"
+        fi
 
         echo "$0: Stopping Unit daemon after initial configuration..."
         kill -TERM $(/bin/cat /var/run/unit.pid)
@@ -83,9 +95,6 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         echo
         echo "$0: Unit initial configuration complete; ready for start up..."
         echo
-        else
-            echo "$0: /docker-entrypoint.d/ is empty, skipping initial configuration..."
-        fi
     fi
 fi
 
diff --git a/unit_perl/welcome.html b/unit_perl/welcome.html
new file mode 100644
index 0000000..9c4f828
--- /dev/null
+++ b/unit_perl/welcome.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Welcome to NGINX Unit</title>
+        <style type="text/css">
+            body { background: white; color: black; font-family: sans-serif; margin: 2em; line-height: 1.5; }
+            h1,h2 { color: #00974d; }
+            li { margin-bottom: 0.5em; }
+            pre { background-color: beige; padding: 0.4em; }
+            hr { margin-top: 2em; border: 1px solid #00974d; }
+            .indent { margin-left: 1.5em; }
+        </style>
+    </head>
+    <body>
+        <h1>Welcome to NGINX Unit</h1>
+        <p>Congratulations! NGINX Unit is installed and running.</p>
+        <h3>Useful Links</h3>
+        <ul>
+            <li><b><a href="https://unit.nginx.org/configuration/?referer=welcome&platform=docker">https://unit.nginx.org/configuration/</a></b><br>
+                To get started with Unit, see the <em>Configuration</em> docs, starting with
+                the <em>Quick Start</em> guide.</li>
+            <li><b><a href="https://unit.nginx.org/howto/docker/?referer=welcome&platform=docker">https://unit.nginx.org/howto/docker/</a></b><br>
+                For guidance about running <em>Unit in Docker</em> and tips for containerized
+                applications.
+            <li><b><a href="https://github.com/nginx/unit">https://github.com/nginx/unit</a></b><br>
+                See our GitHub repo to browse the code, contribute, or seek help from the
+                <a href="https://github.com/nginx/unit#community">community</a>.</li>
+        </ul>
+
+        <h2>Next steps</h2>
+
+        <h3>Check Current Configuration</h3>
+        <div class="indent">
+        <p>Unit's control API is currently listening for configuration changes
+           on the <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix socket</a> at
+           <b>/var/run/control.unit.sock</b> inside the container.<br>
+           To see the current configuration run:</p>
+        <pre>docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config</pre>
+        </div>
+
+        <hr>
+        <p><a href="https://unit.nginx.org/?referer=welcome&platform=docker">NGINX Unit &mdash; the universal web app server</a><br>
+        NGINX, Inc. &copy; 2023</p>
+    </body>
+</html>
diff --git a/unit_perl/welcome.json b/unit_perl/welcome.json
new file mode 100644
index 0000000..2a148da
--- /dev/null
+++ b/unit_perl/welcome.json
@@ -0,0 +1,25 @@
+{
+    "listeners": {
+        "*:80": {
+            "pass": "routes"
+        }
+    },
+
+    "routes": [
+        {
+            "match": {
+                "headers": {
+                    "accept": "*text/html*"
+                }
+            },
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.html"
+            }
+        },
+        {
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.md"
+            }
+        }
+    ]
+}
diff --git a/unit_perl/welcome.md b/unit_perl/welcome.md
new file mode 100644
index 0000000..fef3d15
--- /dev/null
+++ b/unit_perl/welcome.md
@@ -0,0 +1,29 @@
+Welcome to NGINX Unit
+=====================
+
+Congratulations! NGINX Unit is installed and running.
+
+Useful Links
+------------
+
+ * https://unit.nginx.org/
+   - Get started with the 'Configuration' docs, starting with the 'Quick Start' guide.
+
+ * https://unit.nginx.org/howto/docker/
+   - Guidance for running Unit in a container and tips for containerized applications.
+
+ * https://github.com/nginx/unit
+   - See our GitHub repo to browse the code, contribute, or seek help from the community.
+
+Current Configuration
+---------------------
+Unit's control API is currently listening for configuration changes on the Unix socket at
+`/var/run/control.unit.sock` inside the container.
+
+Read the current configuration with
+```
+docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config
+```
+
+---
+NGINX Unit - the universal web app server
diff --git a/unit_php/Dockerfile.php8.2 b/unit_php/Dockerfile.php8.2
index 660cb2b..fcf3f59 100644
--- a/unit_php/Dockerfile.php8.2
+++ b/unit_php/Dockerfile.php8.2
@@ -6,42 +6,46 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org"
 LABEL org.opencontainers.image.source="https://github.com/nginx/unit"
 LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images"
 LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers <[email protected]>"
-LABEL org.opencontainers.image.version="1.29.1"
+LABEL org.opencontainers.image.version="1.30.0"
 
 RUN set -ex \
     && savedAptMark="$(apt-mark showmanual)" \
     && apt-get update \
-    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \
+    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \
     && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \
-    && hg clone -u 1.29.1-1 https://hg.nginx.org/unit \
+    && hg clone -u 1.30.0-1 https://hg.nginx.org/unit \
     && cd unit \
     && NCPU="$(getconf _NPROCESSORS_ONLN)" \
     && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \
     && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \
     && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \
-    && CONFIGURE_ARGS="--prefix=/usr \
-                --state=/var/lib/unit \
+    && CONFIGURE_ARGS_MODULES="--prefix=/usr \
+                --statedir=/var/lib/unit \
                 --control=unix:/var/run/control.unit.sock \
                 --pid=/var/run/unit.pid \
                 --log=/var/log/unit.log \
-                --tmp=/var/tmp \
+                --tmpdir=/var/tmp \
                 --user=unit \
                 --group=unit \
                 --openssl \
                 --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \
+                --njs" \
+    && make -j $NCPU -C pkg/contrib .njs \
+    && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd-debug \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && ./configure php \
     && make -j $NCPU php-install \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \
     && ./configure php \
     && make -j $NCPU php-install \
     && cd \
@@ -71,9 +75,10 @@ RUN set -ex \
     && ln -sf /dev/stdout /var/log/unit.log
 
 COPY docker-entrypoint.sh /usr/local/bin/
+COPY welcome.* /usr/share/unit/welcome/
 
 STOPSIGNAL SIGTERM
 
 ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
-
+EXPOSE 80
 CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
diff --git a/unit_php/docker-entrypoint.sh b/unit_php/docker-entrypoint.sh
index e0afd7e..4646409 100755
--- a/unit_php/docker-entrypoint.sh
+++ b/unit_php/docker-entrypoint.sh
@@ -25,8 +25,7 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
     if /usr/bin/find "/var/lib/unit/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
         echo "$0: /var/lib/unit/ is not empty, skipping initial configuration..."
     else
-        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
-            echo "$0: /docker-entrypoint.d/ is not empty, launching Unit daemon to perform initial configuration..."
+        echo "$0: Launching Unit daemon to perform initial configuration..."
         /usr/sbin/$1 --control unix:/var/run/control.unit.sock
 
         for i in $(/usr/bin/seq $WAITLOOPS); do
@@ -41,12 +40,21 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         # this curl call will get a reply once unit is fully launched
         /usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
 
+        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
+            echo "$0: /docker-entrypoint.d/ is not empty, applying initial configuration..."
+
             echo "$0: Looking for certificate bundles in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.pem"); do
                 echo "$0: Uploading certificates bundle: $f"
                 curl_put $f "certificates/$(basename $f .pem)"
             done
 
+            echo "$0: Looking for JavaScript modules in /docker-entrypoint.d/..."
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.js"); do
+                echo "$0: Uploading JavaScript module: $f"
+                curl_put $f "js_modules/$(basename $f .js)"
+            done
+
             echo "$0: Looking for configuration snippets in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.json"); do
                 echo "$0: Applying configuration $f";
@@ -60,9 +68,13 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
             done
 
             # warn on filetypes we don't know what to do with
-            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem"); do
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
                 echo "$0: Ignoring $f";
             done
+        else
+            echo "$0: /docker-entrypoint.d/ is empty, creating 'welcome' configuration..."
+            curl_put /usr/share/unit/welcome/welcome.json "config"
+        fi
 
         echo "$0: Stopping Unit daemon after initial configuration..."
         kill -TERM $(/bin/cat /var/run/unit.pid)
@@ -83,9 +95,6 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         echo
         echo "$0: Unit initial configuration complete; ready for start up..."
         echo
-        else
-            echo "$0: /docker-entrypoint.d/ is empty, skipping initial configuration..."
-        fi
     fi
 fi
 
diff --git a/unit_php/welcome.html b/unit_php/welcome.html
new file mode 100644
index 0000000..9c4f828
--- /dev/null
+++ b/unit_php/welcome.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Welcome to NGINX Unit</title>
+        <style type="text/css">
+            body { background: white; color: black; font-family: sans-serif; margin: 2em; line-height: 1.5; }
+            h1,h2 { color: #00974d; }
+            li { margin-bottom: 0.5em; }
+            pre { background-color: beige; padding: 0.4em; }
+            hr { margin-top: 2em; border: 1px solid #00974d; }
+            .indent { margin-left: 1.5em; }
+        </style>
+    </head>
+    <body>
+        <h1>Welcome to NGINX Unit</h1>
+        <p>Congratulations! NGINX Unit is installed and running.</p>
+        <h3>Useful Links</h3>
+        <ul>
+            <li><b><a href="https://unit.nginx.org/configuration/?referer=welcome&platform=docker">https://unit.nginx.org/configuration/</a></b><br>
+                To get started with Unit, see the <em>Configuration</em> docs, starting with
+                the <em>Quick Start</em> guide.</li>
+            <li><b><a href="https://unit.nginx.org/howto/docker/?referer=welcome&platform=docker">https://unit.nginx.org/howto/docker/</a></b><br>
+                For guidance about running <em>Unit in Docker</em> and tips for containerized
+                applications.
+            <li><b><a href="https://github.com/nginx/unit">https://github.com/nginx/unit</a></b><br>
+                See our GitHub repo to browse the code, contribute, or seek help from the
+                <a href="https://github.com/nginx/unit#community">community</a>.</li>
+        </ul>
+
+        <h2>Next steps</h2>
+
+        <h3>Check Current Configuration</h3>
+        <div class="indent">
+        <p>Unit's control API is currently listening for configuration changes
+           on the <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix socket</a> at
+           <b>/var/run/control.unit.sock</b> inside the container.<br>
+           To see the current configuration run:</p>
+        <pre>docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config</pre>
+        </div>
+
+        <hr>
+        <p><a href="https://unit.nginx.org/?referer=welcome&platform=docker">NGINX Unit &mdash; the universal web app server</a><br>
+        NGINX, Inc. &copy; 2023</p>
+    </body>
+</html>
diff --git a/unit_php/welcome.json b/unit_php/welcome.json
new file mode 100644
index 0000000..2a148da
--- /dev/null
+++ b/unit_php/welcome.json
@@ -0,0 +1,25 @@
+{
+    "listeners": {
+        "*:80": {
+            "pass": "routes"
+        }
+    },
+
+    "routes": [
+        {
+            "match": {
+                "headers": {
+                    "accept": "*text/html*"
+                }
+            },
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.html"
+            }
+        },
+        {
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.md"
+            }
+        }
+    ]
+}
diff --git a/unit_php/welcome.md b/unit_php/welcome.md
new file mode 100644
index 0000000..fef3d15
--- /dev/null
+++ b/unit_php/welcome.md
@@ -0,0 +1,29 @@
+Welcome to NGINX Unit
+=====================
+
+Congratulations! NGINX Unit is installed and running.
+
+Useful Links
+------------
+
+ * https://unit.nginx.org/
+   - Get started with the 'Configuration' docs, starting with the 'Quick Start' guide.
+
+ * https://unit.nginx.org/howto/docker/
+   - Guidance for running Unit in a container and tips for containerized applications.
+
+ * https://github.com/nginx/unit
+   - See our GitHub repo to browse the code, contribute, or seek help from the community.
+
+Current Configuration
+---------------------
+Unit's control API is currently listening for configuration changes on the Unix socket at
+`/var/run/control.unit.sock` inside the container.
+
+Read the current configuration with
+```
+docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config
+```
+
+---
+NGINX Unit - the universal web app server
diff --git a/unit_python/Dockerfile.python3.11 b/unit_python/Dockerfile.python3.11
index 10ec651..89cd315 100644
--- a/unit_python/Dockerfile.python3.11
+++ b/unit_python/Dockerfile.python3.11
@@ -6,42 +6,46 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org"
 LABEL org.opencontainers.image.source="https://github.com/nginx/unit"
 LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images"
 LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers <[email protected]>"
-LABEL org.opencontainers.image.version="1.29.1"
+LABEL org.opencontainers.image.version="1.30.0"
 
 RUN set -ex \
     && savedAptMark="$(apt-mark showmanual)" \
     && apt-get update \
-    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \
+    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \
     && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \
-    && hg clone -u 1.29.1-1 https://hg.nginx.org/unit \
+    && hg clone -u 1.30.0-1 https://hg.nginx.org/unit \
     && cd unit \
     && NCPU="$(getconf _NPROCESSORS_ONLN)" \
     && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \
     && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \
     && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \
-    && CONFIGURE_ARGS="--prefix=/usr \
-                --state=/var/lib/unit \
+    && CONFIGURE_ARGS_MODULES="--prefix=/usr \
+                --statedir=/var/lib/unit \
                 --control=unix:/var/run/control.unit.sock \
                 --pid=/var/run/unit.pid \
                 --log=/var/log/unit.log \
-                --tmp=/var/tmp \
+                --tmpdir=/var/tmp \
                 --user=unit \
                 --group=unit \
                 --openssl \
                 --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \
+                --njs" \
+    && make -j $NCPU -C pkg/contrib .njs \
+    && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd-debug \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && ./configure python --config=/usr/local/bin/python3-config \
     && make -j $NCPU python3-install \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \
     && ./configure python --config=/usr/local/bin/python3-config \
     && make -j $NCPU python3-install \
     && cd \
@@ -71,9 +75,10 @@ RUN set -ex \
     && ln -sf /dev/stdout /var/log/unit.log
 
 COPY docker-entrypoint.sh /usr/local/bin/
+COPY welcome.* /usr/share/unit/welcome/
 
 STOPSIGNAL SIGTERM
 
 ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
-
+EXPOSE 80
 CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
diff --git a/unit_python/docker-entrypoint.sh b/unit_python/docker-entrypoint.sh
index e0afd7e..4646409 100755
--- a/unit_python/docker-entrypoint.sh
+++ b/unit_python/docker-entrypoint.sh
@@ -25,8 +25,7 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
     if /usr/bin/find "/var/lib/unit/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
         echo "$0: /var/lib/unit/ is not empty, skipping initial configuration..."
     else
-        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
-            echo "$0: /docker-entrypoint.d/ is not empty, launching Unit daemon to perform initial configuration..."
+        echo "$0: Launching Unit daemon to perform initial configuration..."
         /usr/sbin/$1 --control unix:/var/run/control.unit.sock
 
         for i in $(/usr/bin/seq $WAITLOOPS); do
@@ -41,12 +40,21 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         # this curl call will get a reply once unit is fully launched
         /usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
 
+        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
+            echo "$0: /docker-entrypoint.d/ is not empty, applying initial configuration..."
+
             echo "$0: Looking for certificate bundles in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.pem"); do
                 echo "$0: Uploading certificates bundle: $f"
                 curl_put $f "certificates/$(basename $f .pem)"
             done
 
+            echo "$0: Looking for JavaScript modules in /docker-entrypoint.d/..."
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.js"); do
+                echo "$0: Uploading JavaScript module: $f"
+                curl_put $f "js_modules/$(basename $f .js)"
+            done
+
             echo "$0: Looking for configuration snippets in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.json"); do
                 echo "$0: Applying configuration $f";
@@ -60,9 +68,13 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
             done
 
             # warn on filetypes we don't know what to do with
-            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem"); do
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
                 echo "$0: Ignoring $f";
             done
+        else
+            echo "$0: /docker-entrypoint.d/ is empty, creating 'welcome' configuration..."
+            curl_put /usr/share/unit/welcome/welcome.json "config"
+        fi
 
         echo "$0: Stopping Unit daemon after initial configuration..."
         kill -TERM $(/bin/cat /var/run/unit.pid)
@@ -83,9 +95,6 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         echo
         echo "$0: Unit initial configuration complete; ready for start up..."
         echo
-        else
-            echo "$0: /docker-entrypoint.d/ is empty, skipping initial configuration..."
-        fi
     fi
 fi
 
diff --git a/unit_python/welcome.html b/unit_python/welcome.html
new file mode 100644
index 0000000..9c4f828
--- /dev/null
+++ b/unit_python/welcome.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Welcome to NGINX Unit</title>
+        <style type="text/css">
+            body { background: white; color: black; font-family: sans-serif; margin: 2em; line-height: 1.5; }
+            h1,h2 { color: #00974d; }
+            li { margin-bottom: 0.5em; }
+            pre { background-color: beige; padding: 0.4em; }
+            hr { margin-top: 2em; border: 1px solid #00974d; }
+            .indent { margin-left: 1.5em; }
+        </style>
+    </head>
+    <body>
+        <h1>Welcome to NGINX Unit</h1>
+        <p>Congratulations! NGINX Unit is installed and running.</p>
+        <h3>Useful Links</h3>
+        <ul>
+            <li><b><a href="https://unit.nginx.org/configuration/?referer=welcome&platform=docker">https://unit.nginx.org/configuration/</a></b><br>
+                To get started with Unit, see the <em>Configuration</em> docs, starting with
+                the <em>Quick Start</em> guide.</li>
+            <li><b><a href="https://unit.nginx.org/howto/docker/?referer=welcome&platform=docker">https://unit.nginx.org/howto/docker/</a></b><br>
+                For guidance about running <em>Unit in Docker</em> and tips for containerized
+                applications.
+            <li><b><a href="https://github.com/nginx/unit">https://github.com/nginx/unit</a></b><br>
+                See our GitHub repo to browse the code, contribute, or seek help from the
+                <a href="https://github.com/nginx/unit#community">community</a>.</li>
+        </ul>
+
+        <h2>Next steps</h2>
+
+        <h3>Check Current Configuration</h3>
+        <div class="indent">
+        <p>Unit's control API is currently listening for configuration changes
+           on the <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix socket</a> at
+           <b>/var/run/control.unit.sock</b> inside the container.<br>
+           To see the current configuration run:</p>
+        <pre>docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config</pre>
+        </div>
+
+        <hr>
+        <p><a href="https://unit.nginx.org/?referer=welcome&platform=docker">NGINX Unit &mdash; the universal web app server</a><br>
+        NGINX, Inc. &copy; 2023</p>
+    </body>
+</html>
diff --git a/unit_python/welcome.json b/unit_python/welcome.json
new file mode 100644
index 0000000..2a148da
--- /dev/null
+++ b/unit_python/welcome.json
@@ -0,0 +1,25 @@
+{
+    "listeners": {
+        "*:80": {
+            "pass": "routes"
+        }
+    },
+
+    "routes": [
+        {
+            "match": {
+                "headers": {
+                    "accept": "*text/html*"
+                }
+            },
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.html"
+            }
+        },
+        {
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.md"
+            }
+        }
+    ]
+}
diff --git a/unit_python/welcome.md b/unit_python/welcome.md
new file mode 100644
index 0000000..fef3d15
--- /dev/null
+++ b/unit_python/welcome.md
@@ -0,0 +1,29 @@
+Welcome to NGINX Unit
+=====================
+
+Congratulations! NGINX Unit is installed and running.
+
+Useful Links
+------------
+
+ * https://unit.nginx.org/
+   - Get started with the 'Configuration' docs, starting with the 'Quick Start' guide.
+
+ * https://unit.nginx.org/howto/docker/
+   - Guidance for running Unit in a container and tips for containerized applications.
+
+ * https://github.com/nginx/unit
+   - See our GitHub repo to browse the code, contribute, or seek help from the community.
+
+Current Configuration
+---------------------
+Unit's control API is currently listening for configuration changes on the Unix socket at
+`/var/run/control.unit.sock` inside the container.
+
+Read the current configuration with
+```
+docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config
+```
+
+---
+NGINX Unit - the universal web app server
diff --git a/unit_ruby/Dockerfile.ruby3.2 b/unit_ruby/Dockerfile.ruby3.2
index 19a763f..4a6b60e 100644
--- a/unit_ruby/Dockerfile.ruby3.2
+++ b/unit_ruby/Dockerfile.ruby3.2
@@ -6,42 +6,46 @@ LABEL org.opencontainers.image.url="https://unit.nginx.org"
 LABEL org.opencontainers.image.source="https://github.com/nginx/unit"
 LABEL org.opencontainers.image.documentation="https://unit.nginx.org/installation/#docker-images"
 LABEL org.opencontainers.image.vendor="NGINX Docker Maintainers <[email protected]>"
-LABEL org.opencontainers.image.version="1.29.1"
+LABEL org.opencontainers.image.version="1.30.0"
 
 RUN set -ex \
     && savedAptMark="$(apt-mark showmanual)" \
     && apt-get update \
-    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev \
+    && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates mercurial build-essential libssl-dev libpcre2-dev curl pkg-config \
     && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \
-    && hg clone -u 1.29.1-1 https://hg.nginx.org/unit \
+    && hg clone -u 1.30.0-1 https://hg.nginx.org/unit \
     && cd unit \
     && NCPU="$(getconf _NPROCESSORS_ONLN)" \
     && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \
     && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \
     && LD_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_LDFLAGS_MAINT_APPEND="-Wl,--as-needed -pie" dpkg-buildflags --get LDFLAGS)" \
-    && CONFIGURE_ARGS="--prefix=/usr \
-                --state=/var/lib/unit \
+    && CONFIGURE_ARGS_MODULES="--prefix=/usr \
+                --statedir=/var/lib/unit \
                 --control=unix:/var/run/control.unit.sock \
                 --pid=/var/run/unit.pid \
                 --log=/var/log/unit.log \
-                --tmp=/var/tmp \
+                --tmpdir=/var/tmp \
                 --user=unit \
                 --group=unit \
                 --openssl \
                 --libdir=/usr/lib/$DEB_HOST_MULTIARCH" \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && CONFIGURE_ARGS="$CONFIGURE_ARGS_MODULES \
+                --njs" \
+    && make -j $NCPU -C pkg/contrib .njs \
+    && export PKG_CONFIG_PATH=$(pwd)/pkg/contrib/njs/build \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd-debug \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd-debug \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --ld-opt="$LD_OPT" --modulesdir=/usr/lib/unit/modules \
     && make -j $NCPU unitd \
-    && install -pm755 build/unitd /usr/sbin/unitd \
+    && install -pm755 build/sbin/unitd /usr/sbin/unitd \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/debug-modules --debug \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/debug-modules --debug \
     && ./configure ruby \
     && make -j $NCPU ruby-install \
     && make clean \
-    && ./configure $CONFIGURE_ARGS --cc-opt="$CC_OPT" --modules=/usr/lib/unit/modules \
+    && ./configure $CONFIGURE_ARGS_MODULES --cc-opt="$CC_OPT" --modulesdir=/usr/lib/unit/modules \
     && ./configure ruby \
     && make -j $NCPU ruby-install \
     && cd \
@@ -71,9 +75,10 @@ RUN set -ex \
     && ln -sf /dev/stdout /var/log/unit.log
 
 COPY docker-entrypoint.sh /usr/local/bin/
+COPY welcome.* /usr/share/unit/welcome/
 
 STOPSIGNAL SIGTERM
 
 ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
-
+EXPOSE 80
 CMD ["unitd", "--no-daemon", "--control", "unix:/var/run/control.unit.sock"]
diff --git a/unit_ruby/docker-entrypoint.sh b/unit_ruby/docker-entrypoint.sh
index e0afd7e..4646409 100755
--- a/unit_ruby/docker-entrypoint.sh
+++ b/unit_ruby/docker-entrypoint.sh
@@ -25,8 +25,7 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
     if /usr/bin/find "/var/lib/unit/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
         echo "$0: /var/lib/unit/ is not empty, skipping initial configuration..."
     else
-        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
-            echo "$0: /docker-entrypoint.d/ is not empty, launching Unit daemon to perform initial configuration..."
+        echo "$0: Launching Unit daemon to perform initial configuration..."
         /usr/sbin/$1 --control unix:/var/run/control.unit.sock
 
         for i in $(/usr/bin/seq $WAITLOOPS); do
@@ -41,12 +40,21 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         # this curl call will get a reply once unit is fully launched
         /usr/bin/curl -s -X GET --unix-socket /var/run/control.unit.sock http://localhost/
 
+        if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -print -quit 2>/dev/null | /bin/grep -q .; then
+            echo "$0: /docker-entrypoint.d/ is not empty, applying initial configuration..."
+
             echo "$0: Looking for certificate bundles in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.pem"); do
                 echo "$0: Uploading certificates bundle: $f"
                 curl_put $f "certificates/$(basename $f .pem)"
             done
 
+            echo "$0: Looking for JavaScript modules in /docker-entrypoint.d/..."
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.js"); do
+                echo "$0: Uploading JavaScript module: $f"
+                curl_put $f "js_modules/$(basename $f .js)"
+            done
+
             echo "$0: Looking for configuration snippets in /docker-entrypoint.d/..."
             for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -name "*.json"); do
                 echo "$0: Applying configuration $f";
@@ -60,9 +68,13 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
             done
 
             # warn on filetypes we don't know what to do with
-            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem"); do
+            for f in $(/usr/bin/find /docker-entrypoint.d/ -type f -not -name "*.sh" -not -name "*.json" -not -name "*.pem" -not -name "*.js"); do
                 echo "$0: Ignoring $f";
             done
+        else
+            echo "$0: /docker-entrypoint.d/ is empty, creating 'welcome' configuration..."
+            curl_put /usr/share/unit/welcome/welcome.json "config"
+        fi
 
         echo "$0: Stopping Unit daemon after initial configuration..."
         kill -TERM $(/bin/cat /var/run/unit.pid)
@@ -83,9 +95,6 @@ if [ "$1" = "unitd" ] || [ "$1" = "unitd-debug" ]; then
         echo
         echo "$0: Unit initial configuration complete; ready for start up..."
         echo
-        else
-            echo "$0: /docker-entrypoint.d/ is empty, skipping initial configuration..."
-        fi
     fi
 fi
 
diff --git a/unit_ruby/welcome.html b/unit_ruby/welcome.html
new file mode 100644
index 0000000..9c4f828
--- /dev/null
+++ b/unit_ruby/welcome.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Welcome to NGINX Unit</title>
+        <style type="text/css">
+            body { background: white; color: black; font-family: sans-serif; margin: 2em; line-height: 1.5; }
+            h1,h2 { color: #00974d; }
+            li { margin-bottom: 0.5em; }
+            pre { background-color: beige; padding: 0.4em; }
+            hr { margin-top: 2em; border: 1px solid #00974d; }
+            .indent { margin-left: 1.5em; }
+        </style>
+    </head>
+    <body>
+        <h1>Welcome to NGINX Unit</h1>
+        <p>Congratulations! NGINX Unit is installed and running.</p>
+        <h3>Useful Links</h3>
+        <ul>
+            <li><b><a href="https://unit.nginx.org/configuration/?referer=welcome&platform=docker">https://unit.nginx.org/configuration/</a></b><br>
+                To get started with Unit, see the <em>Configuration</em> docs, starting with
+                the <em>Quick Start</em> guide.</li>
+            <li><b><a href="https://unit.nginx.org/howto/docker/?referer=welcome&platform=docker">https://unit.nginx.org/howto/docker/</a></b><br>
+                For guidance about running <em>Unit in Docker</em> and tips for containerized
+                applications.
+            <li><b><a href="https://github.com/nginx/unit">https://github.com/nginx/unit</a></b><br>
+                See our GitHub repo to browse the code, contribute, or seek help from the
+                <a href="https://github.com/nginx/unit#community">community</a>.</li>
+        </ul>
+
+        <h2>Next steps</h2>
+
+        <h3>Check Current Configuration</h3>
+        <div class="indent">
+        <p>Unit's control API is currently listening for configuration changes
+           on the <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Unix socket</a> at
+           <b>/var/run/control.unit.sock</b> inside the container.<br>
+           To see the current configuration run:</p>
+        <pre>docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config</pre>
+        </div>
+
+        <hr>
+        <p><a href="https://unit.nginx.org/?referer=welcome&platform=docker">NGINX Unit &mdash; the universal web app server</a><br>
+        NGINX, Inc. &copy; 2023</p>
+    </body>
+</html>
diff --git a/unit_ruby/welcome.json b/unit_ruby/welcome.json
new file mode 100644
index 0000000..2a148da
--- /dev/null
+++ b/unit_ruby/welcome.json
@@ -0,0 +1,25 @@
+{
+    "listeners": {
+        "*:80": {
+            "pass": "routes"
+        }
+    },
+
+    "routes": [
+        {
+            "match": {
+                "headers": {
+                    "accept": "*text/html*"
+                }
+            },
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.html"
+            }
+        },
+        {
+            "action": {
+                "share": "/usr/share/unit/welcome/welcome.md"
+            }
+        }
+    ]
+}
diff --git a/unit_ruby/welcome.md b/unit_ruby/welcome.md
new file mode 100644
index 0000000..fef3d15
--- /dev/null
+++ b/unit_ruby/welcome.md
@@ -0,0 +1,29 @@
+Welcome to NGINX Unit
+=====================
+
+Congratulations! NGINX Unit is installed and running.
+
+Useful Links
+------------
+
+ * https://unit.nginx.org/
+   - Get started with the 'Configuration' docs, starting with the 'Quick Start' guide.
+
+ * https://unit.nginx.org/howto/docker/
+   - Guidance for running Unit in a container and tips for containerized applications.
+
+ * https://github.com/nginx/unit
+   - See our GitHub repo to browse the code, contribute, or seek help from the community.
+
+Current Configuration
+---------------------
+Unit's control API is currently listening for configuration changes on the Unix socket at
+`/var/run/control.unit.sock` inside the container.
+
+Read the current configuration with
+```
+docker exec -ti <containerID> curl --unix-socket /var/run/control.unit.sock http://localhost/config
+```
+
+---
+NGINX Unit - the universal web app server

Relevant Maintainers:

@yosifkit yosifkit merged commit 0df5f38 into docker-library:master May 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants