diff --git a/hosting/couchdb/Dockerfile b/hosting/couchdb/Dockerfile
index f83df7038b..36abc2dd19 100644
--- a/hosting/couchdb/Dockerfile
+++ b/hosting/couchdb/Dockerfile
@@ -1,4 +1,101 @@
-FROM couchdb:3.2.1
+# Modified from https://github.com/apache/couchdb-docker/blob/main/3.3.3/Dockerfile
+#
+# Everything in this `base` image is adapted from the official `couchdb` image's
+# Dockerfile. Only modifications related to upgrading from Debian bullseye to
+# bookworm have been included. The `runner` image contains Budibase's
+# customisations to the image, e.g. adding Clouseau.
+FROM node:20-slim AS base
+
+# Add CouchDB user account to make sure the IDs are assigned consistently
+RUN groupadd -g 5984 -r couchdb && useradd -u 5984 -d /opt/couchdb -g couchdb couchdb
+
+# be sure GPG and apt-transport-https are available and functional
+RUN set -ex; \
+ apt-get update; \
+ apt-get install -y --no-install-recommends \
+ apt-transport-https \
+ ca-certificates \
+ dirmngr \
+ gnupg \
+ ; \
+ rm -rf /var/lib/apt/lists/*
+
+# grab tini for signal handling and zombie reaping
+# see https://github.com/apache/couchdb-docker/pull/28#discussion_r141112407
+RUN set -eux; \
+ apt-get update; \
+ apt-get install -y --no-install-recommends tini; \
+ rm -rf /var/lib/apt/lists/*; \
+ tini --version
+
+# http://docs.couchdb.org/en/latest/install/unix.html#installing-the-apache-couchdb-packages
+ENV GPG_COUCH_KEY \
+# gpg: rsa8192 205-01-19 The Apache Software Foundation (Package repository signing key)
+ 390EF70BB1EA12B2773962950EE62FB37A00258D
+RUN set -eux; \
+ apt-get update; \
+ apt-get install -y curl; \
+ export GNUPGHOME="$(mktemp -d)"; \
+ curl -fL -o keys.asc https://couchdb.apache.org/repo/keys.asc; \
+ gpg --batch --import keys.asc; \
+ gpg --batch --export "${GPG_COUCH_KEY}" > /usr/share/keyrings/couchdb-archive-keyring.gpg; \
+ command -v gpgconf && gpgconf --kill all || :; \
+ rm -rf "$GNUPGHOME"; \
+ apt-key list; \
+ apt purge -y --autoremove curl; \
+ rm -rf /var/lib/apt/lists/*
+
+ENV COUCHDB_VERSION 3.3.3
+
+RUN . /etc/os-release; \
+ echo "deb [signed-by=/usr/share/keyrings/couchdb-archive-keyring.gpg] https://apache.jfrog.io/artifactory/couchdb-deb/ ${VERSION_CODENAME} main" | \
+ tee /etc/apt/sources.list.d/couchdb.list >/dev/null
+
+# https://github.com/apache/couchdb-pkg/blob/master/debian/README.Debian
+RUN set -eux; \
+ apt-get update; \
+ \
+ echo "couchdb couchdb/mode select none" | debconf-set-selections; \
+# we DO want recommends this time
+ DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-downgrades --allow-remove-essential --allow-change-held-packages \
+ couchdb="$COUCHDB_VERSION"~bookworm \
+ ; \
+# Undo symlinks to /var/log and /var/lib
+ rmdir /var/lib/couchdb /var/log/couchdb; \
+ rm /opt/couchdb/data /opt/couchdb/var/log; \
+ mkdir -p /opt/couchdb/data /opt/couchdb/var/log; \
+ chown couchdb:couchdb /opt/couchdb/data /opt/couchdb/var/log; \
+ chmod 777 /opt/couchdb/data /opt/couchdb/var/log; \
+# Remove file that sets logging to a file
+ rm /opt/couchdb/etc/default.d/10-filelog.ini; \
+# Check we own everything in /opt/couchdb. Matches the command in dockerfile_entrypoint.sh
+ find /opt/couchdb \! \( -user couchdb -group couchdb \) -exec chown -f couchdb:couchdb '{}' +; \
+# Setup directories and permissions for config. Technically these could be 555 and 444 respectively
+# but we keep them as 755 and 644 for consistency with CouchDB defaults and the dockerfile_entrypoint.sh.
+ find /opt/couchdb/etc -type d ! -perm 0755 -exec chmod -f 0755 '{}' +; \
+ find /opt/couchdb/etc -type f ! -perm 0644 -exec chmod -f 0644 '{}' +; \
+# only local.d needs to be writable for the docker_entrypoint.sh
+ chmod -f 0777 /opt/couchdb/etc/local.d; \
+# apt clean-up
+ rm -rf /var/lib/apt/lists/*;
+
+# Add configuration
+COPY --chown=couchdb:couchdb couch/10-docker-default.ini /opt/couchdb/etc/default.d/
+# COPY --chown=couchdb:couchdb vm.args /opt/couchdb/etc/
+
+COPY docker-entrypoint.sh /usr/local/bin
+RUN ln -s usr/local/bin/docker-entrypoint.sh /docker-entrypoint.sh # backwards compat
+ENTRYPOINT ["tini", "--", "/docker-entrypoint.sh"]
+
+VOLUME /opt/couchdb/data
+
+# 5984: Main CouchDB endpoint
+# 4369: Erlang portmap daemon (epmd)
+# 9100: CouchDB cluster communication port
+EXPOSE 5984 4369 9100
+CMD ["/opt/couchdb/bin/couchdb"]
+
+FROM base as runner
ENV COUCHDB_USER admin
ENV COUCHDB_PASSWORD admin
@@ -6,9 +103,9 @@ EXPOSE 5984
RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common wget unzip curl && \
wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | apt-key add - && \
- apt-add-repository 'deb http://security.debian.org/debian-security bullseye-security/updates main' && \
+ apt-add-repository 'deb http://security.debian.org/debian-security bookworm-security/updates main' && \
apt-add-repository 'deb http://archive.debian.org/debian stretch-backports main' && \
- apt-add-repository 'deb https://packages.adoptium.net/artifactory/deb bullseye main' && \
+ apt-add-repository 'deb https://packages.adoptium.net/artifactory/deb bookworm main' && \
apt-get update && apt-get install -y --no-install-recommends temurin-8-jdk && \
rm -rf /var/lib/apt/lists/
diff --git a/hosting/couchdb/clouseau/clouseau.ini b/hosting/couchdb/clouseau/clouseau.ini
index 578a5acafa..014fb854f3 100644
--- a/hosting/couchdb/clouseau/clouseau.ini
+++ b/hosting/couchdb/clouseau/clouseau.ini
@@ -4,7 +4,7 @@
name=clouseau@127.0.0.1
; set this to the same distributed Erlang cookie used by the CouchDB nodes
-cookie=monster
+cookie=COUCHDB_ERLANG_COOKIE
; the path where you would like to store the search index files
dir=DATA_DIR/search
diff --git a/hosting/couchdb/couch/10-docker-default.ini b/hosting/couchdb/couch/10-docker-default.ini
new file mode 100644
index 0000000000..1aa633cbfc
--- /dev/null
+++ b/hosting/couchdb/couch/10-docker-default.ini
@@ -0,0 +1,8 @@
+; CouchDB Configuration Settings
+
+; Custom settings should be made in this file. They will override settings
+; in default.ini, but unlike changes made to default.ini, this file won't be
+; overwritten on server upgrade.
+
+[chttpd]
+bind_address = any
diff --git a/hosting/couchdb/couch/vm.args b/hosting/couchdb/couch/vm.args
index e9e4416863..11845dd6d4 100644
--- a/hosting/couchdb/couch/vm.args
+++ b/hosting/couchdb/couch/vm.args
@@ -12,7 +12,7 @@
# erlang cookie for clouseau security
-name couchdb@127.0.0.1
--setcookie monster
+-setcookie COUCHDB_ERLANG_COOKIE
# Ensure that the Erlang VM listens on a known port
-kernel inet_dist_listen_min 9100
diff --git a/hosting/couchdb/docker-entrypoint.sh b/hosting/couchdb/docker-entrypoint.sh
new file mode 100755
index 0000000000..bd709b7b73
--- /dev/null
+++ b/hosting/couchdb/docker-entrypoint.sh
@@ -0,0 +1,122 @@
+#!/bin/bash
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+set -e
+
+# first arg is `-something` or `+something`
+if [ "${1#-}" != "$1" ] || [ "${1#+}" != "$1" ]; then
+ set -- /opt/couchdb/bin/couchdb "$@"
+fi
+
+# first arg is the bare word `couchdb`
+if [ "$1" = 'couchdb' ]; then
+ shift
+ set -- /opt/couchdb/bin/couchdb "$@"
+fi
+
+if [ "$1" = '/opt/couchdb/bin/couchdb' ]; then
+ # this is where runtime configuration changes will be written.
+ # we need to explicitly touch it here in case /opt/couchdb/etc has
+ # been mounted as an external volume, in which case it won't exist.
+ # If running as the couchdb user (i.e. container starts as root),
+ # write permissions will be granted below.
+ touch /opt/couchdb/etc/local.d/docker.ini
+
+ # if user is root, assume running under the couchdb user (default)
+ # and ensure it is able to access files and directories that may be mounted externally
+ if [ "$(id -u)" = '0' ]; then
+ # Check that we own everything in /opt/couchdb and fix if necessary. We also
+ # add the `-f` flag in all the following invocations because there may be
+ # cases where some of these ownership and permissions issues are non-fatal
+ # (e.g. a config file owned by root with o+r is actually fine), and we don't
+ # to be too aggressive about crashing here ...
+ find /opt/couchdb \! \( -user couchdb -group couchdb \) -exec chown -f couchdb:couchdb '{}' +
+
+ # Ensure that data files have the correct permissions. We were previously
+ # preventing any access to these files outside of couchdb:couchdb, but it
+ # turns out that CouchDB itself does not set such restrictive permissions
+ # when it creates the files. The approach taken here ensures that the
+ # contents of the datadir have the same permissions as they had when they
+ # were initially created. This should minimize any startup delay.
+ find /opt/couchdb/data -type d ! -perm 0755 -exec chmod -f 0755 '{}' +
+ find /opt/couchdb/data -type f ! -perm 0644 -exec chmod -f 0644 '{}' +
+
+ # Do the same thing for configuration files and directories. Technically
+ # CouchDB only needs read access to the configuration files as all online
+ # changes will be applied to the "docker.ini" file below, but we set 644
+ # for the sake of consistency.
+ find /opt/couchdb/etc -type d ! -perm 0755 -exec chmod -f 0755 '{}' +
+ find /opt/couchdb/etc -type f ! -perm 0644 -exec chmod -f 0644 '{}' +
+ fi
+
+ if [ ! -z "$NODENAME" ] && ! grep "couchdb@" /opt/couchdb/etc/vm.args; then
+ echo "-name couchdb@$NODENAME" >> /opt/couchdb/etc/vm.args
+ fi
+
+ if [ "$COUCHDB_USER" ] && [ "$COUCHDB_PASSWORD" ]; then
+ # Create admin only if not already present
+ if ! grep -Pzoqr "\[admins\]\n$COUCHDB_USER =" /opt/couchdb/etc/local.d/*.ini /opt/couchdb/etc/local.ini; then
+ printf "\n[admins]\n%s = %s\n" "$COUCHDB_USER" "$COUCHDB_PASSWORD" >> /opt/couchdb/etc/local.d/docker.ini
+ fi
+ fi
+
+ if [ "$COUCHDB_SECRET" ]; then
+ # Set secret only if not already present
+ if ! grep -Pzoqr "\[chttpd_auth\]\nsecret =" /opt/couchdb/etc/local.d/*.ini /opt/couchdb/etc/local.ini; then
+ printf "\n[chttpd_auth]\nsecret = %s\n" "$COUCHDB_SECRET" >> /opt/couchdb/etc/local.d/docker.ini
+ fi
+ fi
+
+ if [ "$COUCHDB_ERLANG_COOKIE" ]; then
+ cookieFile='/opt/couchdb/.erlang.cookie'
+ if [ -e "$cookieFile" ]; then
+ if [ "$(cat "$cookieFile" 2>/dev/null)" != "$COUCHDB_ERLANG_COOKIE" ]; then
+ echo >&2
+ echo >&2 "warning: $cookieFile contents do not match COUCHDB_ERLANG_COOKIE"
+ echo >&2
+ fi
+ else
+ echo "$COUCHDB_ERLANG_COOKIE" > "$cookieFile"
+ fi
+ chown couchdb:couchdb "$cookieFile"
+ chmod 600 "$cookieFile"
+ fi
+
+ if [ "$(id -u)" = '0' ]; then
+ chown -f couchdb:couchdb /opt/couchdb/etc/local.d/docker.ini || true
+ fi
+
+ # if we don't find an [admins] section followed by a non-comment, display a warning
+ if ! grep -Pzoqr '\[admins\]\n[^;]\w+' /opt/couchdb/etc/default.d/*.ini /opt/couchdb/etc/local.d/*.ini /opt/couchdb/etc/local.ini; then
+ # The - option suppresses leading tabs but *not* spaces. :)
+ cat >&2 <<-'EOWARN'
+*************************************************************
+ERROR: CouchDB 3.0+ will no longer run in "Admin Party"
+ mode. You *MUST* specify an admin user and
+ password, either via your own .ini file mapped
+ into the container at /opt/couchdb/etc/local.ini
+ or inside /opt/couchdb/etc/local.d, or with
+ "-e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password"
+ to set it via "docker run".
+*************************************************************
+EOWARN
+ exit 1
+ fi
+
+ if [ "$(id -u)" = '0' ]; then
+ export HOME=$(echo ~couchdb)
+ exec setpriv --reuid=couchdb --regid=couchdb --clear-groups "$@"
+ fi
+fi
+
+exec "$@"
\ No newline at end of file
diff --git a/hosting/couchdb/runner.sh b/hosting/couchdb/runner.sh
index 9f6a853ca7..aaadee6b43 100644
--- a/hosting/couchdb/runner.sh
+++ b/hosting/couchdb/runner.sh
@@ -1,6 +1,7 @@
#!/bin/bash
DATA_DIR=${DATA_DIR:-/data}
+COUCHDB_ERLANG_COOKIE=${COUCHDB_ERLANG_COOKIE:-B9CFC32C-3458-4A86-8448-B3C753991CA7}
mkdir -p ${DATA_DIR}
mkdir -p ${DATA_DIR}/couch/{dbs,views}
@@ -60,6 +61,9 @@ else
sed -i "s#DATA_DIR#/data#g" /opt/couchdb/etc/local.ini
fi
+sed -i "s#COUCHDB_ERLANG_COOKIE#${COUCHDB_ERLANG_COOKIE}#g" /opt/couchdb/etc/vm.args
+sed -i "s#COUCHDB_ERLANG_COOKIE#${COUCHDB_ERLANG_COOKIE}#g" /opt/clouseau/clouseau.ini
+
# Start Clouseau. Budibase won't function correctly without Clouseau running, it
# powers the search API endpoints which are used to do all sorts, including
# populating app grids.
diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile
index f9044cd124..ee98b0729d 100644
--- a/hosting/single/Dockerfile
+++ b/hosting/single/Dockerfile
@@ -3,7 +3,6 @@ FROM node:20-slim as build
# install node-gyp dependencies
RUN apt-get update && apt-get install -y --no-install-recommends g++ make python3 jq
-
# copy and install dependencies
WORKDIR /app
COPY package.json .
@@ -39,10 +38,9 @@ COPY packages/worker/pm2.config.js packages/worker/pm2.config.js
COPY packages/string-templates packages/string-templates
-FROM budibase/couchdb as runner
+FROM budibase/couchdb:v3.3.3 as runner
ARG TARGETARCH
ENV TARGETARCH $TARGETARCH
-ENV NODE_MAJOR 20
#TARGETBUILD can be set to single (for single docker image) or aas (for azure app service)
# e.g. docker build --build-arg TARGETBUILD=aas ....
ARG TARGETBUILD=single
@@ -60,10 +58,8 @@ RUN apt install -y software-properties-common apt-transport-https ca-certificate
&& apt install postgresql-client-15 -y \
&& apt remove software-properties-common apt-transport-https gpg -y
-# install other dependencies, nodejs, oracle requirements, jdk8, redis, nginx
-WORKDIR /nodejs
-COPY scripts/install-node.sh ./install.sh
-RUN chmod +x install.sh && ./install.sh
+# We use pm2 in order to run multiple node processes in a single container
+RUN npm install --global pm2
# setup nginx
COPY hosting/single/nginx/nginx.conf /etc/nginx
diff --git a/hosting/single/runner.sh b/hosting/single/runner.sh
index 886da4c916..3126eedfb1 100644
--- a/hosting/single/runner.sh
+++ b/hosting/single/runner.sh
@@ -97,10 +97,12 @@ fi
sleep 10
pushd app
-pm2 start -l /dev/stdout --name app "yarn run:docker"
+pm2 start --name app "yarn run:docker"
popd
pushd worker
-pm2 start -l /dev/stdout --name worker "yarn run:docker"
+pm2 start --name worker "yarn run:docker"
popd
echo "end of runner.sh, sleeping ..."
+
+tail -f $HOME/.pm2/logs/*.log
sleep infinity
diff --git a/lerna.json b/lerna.json
index 62068e25a8..a62c15997d 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
- "version": "2.19.6",
+ "version": "2.20.5",
"npmClient": "yarn",
"packages": [
"packages/*",
diff --git a/packages/account-portal b/packages/account-portal
index 8c446c4ba3..4384bc742c 160000
--- a/packages/account-portal
+++ b/packages/account-portal
@@ -1 +1 @@
-Subproject commit 8c446c4ba385592127fa31755d3b64467b291882
+Subproject commit 4384bc742ca22fb1e9bf91843e65ae929daf17e2
diff --git a/packages/bbui/src/Layout/Page.svelte b/packages/bbui/src/Layout/Page.svelte
index 57c264231b..2169a12459 100644
--- a/packages/bbui/src/Layout/Page.svelte
+++ b/packages/bbui/src/Layout/Page.svelte
@@ -43,6 +43,7 @@
flex-direction: row;
justify-content: flex-start;
align-items: stretch;
+ overflow-y: scroll !important;
flex: 1 1 auto;
overflow-x: hidden;
}
diff --git a/packages/bbui/src/Typography/Body.svelte b/packages/bbui/src/Typography/Body.svelte
index 71b4dca248..2123eeee95 100644
--- a/packages/bbui/src/Typography/Body.svelte
+++ b/packages/bbui/src/Typography/Body.svelte
@@ -20,3 +20,9 @@
>