diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 365afcd93013074816b0acd3fd3f911ea8935478..bbb1fb26792cb68260355ee908515fade6c213c0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,7 +18,7 @@ variables:
     - export DISCOURSE_MAJOR=`echo $DISCOURSE_VERSION | cut -d"." -f1-3`
     - echo $DISCOURSE_MAJOR
     - echo $DISCOURSE_VERSION
-    - /kaniko/executor --context .  ${DESTINATION} --build-arg DISCOURSE_VERSION=$DISCOURSE_VERSION  
+    - /kaniko/executor --single-snapshot --context .  ${DESTINATION} --build-arg DISCOURSE_VERSION=$DISCOURSE_VERSION
   except:
   - master
 
diff --git a/Dockerfile b/Dockerfile
index 7ec8073407900260134678a90ceadd4e4e744af4..ad46755db6bd849695a4585dc4ad93cb209aa85d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,48 +1,125 @@
-ARG from=discourse/base
-ARG tag=slim
-ARG DISCOURSE_VERSION=test-passed
+FROM debian:bullseye-slim
 
-FROM $from:$tag
-
-ENV RAILS_ENV=production \
-    DISCOURSE_SERVE_STATIC_ASSETS=true \
-    EMBER_CLI_COMPILE_DONE=1 \
-    EMBER_CLI_PROD_ASSETS=1 \
-    RUBY_GLOBAL_METHOD_CACHE_SIZE=131072 \
+# slim https://github.com/discourse/discourse_docker/blob/main/image/base/slim.Dockerfile#L5
+ENV RUBY_ALLOCATOR=/usr/lib/libjemalloc.so.1 \
+    RUSTUP_HOME=/usr/local/rustup \
+    CARGO_HOME=/usr/local/cargo \
+    PATH=/usr/local/cargo/bin:$PATH \
+    LEFTHOOK=0
+# release https://github.com/discourse/discourse_docker/blob/main/image/base/release.Dockerfile#L6
+ENV RAILS_ENV=production
+# web template https://github.com/discourse/discourse_docker/blob/main/templates/web.template.yml#L1
+ENV DISCOURSE_SERVE_STATIC_ASSETS=true \
+    SKIP_EMBER_CLI_COMPILE=1 \
     RUBY_GC_HEAP_GROWTH_MAX_SLOTS=40000 \
     RUBY_GC_HEAP_INIT_SLOTS=400000 \
-    RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.5 \
-    RUBY_GC_MALLOC_LIMIT=90000000
+    RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.5
 
+#LABEL maintainer="Sam Saffron \"https://twitter.com/samsaffron\""
 
-# jq needed to create kubernetes CM
-RUN apt-get update && apt-get install -y jq
+RUN echo 'deb http://deb.debian.org/debian bullseye-backports main' > /etc/apt/sources.list.d/bullseye-backports.list
+RUN echo "debconf debconf/frontend select Teletype" | debconf-set-selections
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install gnupg sudo curl
 
-WORKDIR /var/www/discourse
+RUN DEBIAN_FRONTEND=noninteractive apt-get install -y locales locales-all
+ENV LC_ALL en_US.UTF-8
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US.UTF-8
 
-RUN git config --global --add safe.directory /var/www/discourse &&\
-    git remote set-branches --add origin ${DISCOURSE_VERSION} &&\
-    git fetch --depth 1 origin ${DISCOURSE_VERSION} &&\
-    sudo -u discourse bundle config --local deployment true &&\
-    sudo -u discourse bundle config --local path ./vendor/bundle &&\
-    sudo -u discourse bundle config --local without test development &&\
-    sudo -u discourse bundle config --local jobs 4 && \
-    sudo -u discourse bundle install &&\
-    sudo -u discourse yarn install --frozen-lockfile  &&\
-    sudo -u discourse yarn cache clean &&\
-    find /var/www/discourse/vendor/bundle -name tmp -type d -exec rm -rf {} + &&\
-    chown -R discourse:discourse /var/www/discourse
+RUN curl --silent --location https://deb.nodesource.com/setup_18.x | sudo bash -
+RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
+RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
+RUN apt-get -y update
+# install these without recommends to avoid pulling in e.g.
+# X11 libraries, mailutils
+RUN DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends git jq
+RUN DEBIAN_FRONTEND=noninteractive apt-get -y install autoconf build-essential ca-certificates \
+                       libxslt-dev libcurl4-openssl-dev \
+                       libssl-dev libyaml-dev libtool \
+                       libpcre3 libpcre3-dev zlib1g zlib1g-dev \
+                       libxml2-dev gawk \
+                       libreadline-dev libpq-dev \
+                       psmisc whois brotli libunwind-dev \
+                       libtcmalloc-minimal4 cmake \
+                       pngcrush pngquant ripgrep
 
-COPY install /tmp/install
+RUN cd / &&\
+    apt-get clean &&\
+    locale-gen en_US &&\
+    DEBIAN_FRONTEND=noninteractive apt-get install -y wget nodejs yarn &&\
+    npm install -g terser uglify-js pnpm
+
+ADD install-imagemagick /tmp/install-imagemagick
+RUN /tmp/install-imagemagick
+
+ADD install-jemalloc /tmp/install-jemalloc
+RUN /tmp/install-jemalloc
+
+ADD install-rust /tmp/install-rust
+ADD install-ruby /tmp/install-ruby
+ADD install-oxipng /tmp/install-oxipng
+RUN /tmp/install-rust && /tmp/install-ruby && /tmp/install-oxipng && rustup self uninstall -y
+
+RUN echo 'gem: --no-document' >> /usr/local/etc/gemrc &&\
+    gem update --system
+
+# This tool allows us to disable huge page support for our current process
+# since the flag is preserved through forks and execs it can be used on any
+# process
+ADD thpoff.c /src/thpoff.c
+RUN gcc -o /usr/local/sbin/thpoff /src/thpoff.c && rm /src/thpoff.c
+
+# clean up for docker squash
+RUN rm -fr /usr/share/man &&\
+    rm -fr /usr/share/doc &&\
+    rm -fr /usr/share/vim/vim74/doc &&\
+    rm -fr /usr/share/vim/vim74/lang &&\
+    rm -fr /usr/share/vim/vim74/spell/en* &&\
+    rm -fr /usr/share/vim/vim74/tutor &&\
+    rm -fr /usr/local/share/doc &&\
+    rm -fr /usr/local/share/ri &&\
+    rm -fr /usr/local/share/ruby-build &&\
+    rm -fr /var/lib/apt/lists/* &&\
+    rm -fr /root/.gem &&\
+    rm -fr /root/.npm &&\
+    rm -fr /tmp/*
+
+# this can probably be done, but I worry that people changing PG locales will have issues
+# cd /usr/share/locale && rm -fr `ls -d */ | grep -v en`
+
+# this is required for aarch64 which uses buildx
+# see https://github.com/docker/buildx/issues/150
+RUN rm -f /etc/service
+
+ARG DISCOURSE_VERSION
+
+# Discourse specific bits
+RUN useradd discourse -s /bin/bash -m -U &&\
+    install -dm 0755 -o discourse -g discourse /var/www/discourse &&\ 
+    sudo -u discourse curl -s -L https://github.com/discourse/discourse/archive/refs/tags/${DISCOURSE_VERSION}.tar.gz | tar xvz -C  /var/www/discourse --strip-components 1 &&\
+    gem install bundler --conservative -v $(awk '/BUNDLED WITH/ { getline; gsub(/ /,""); print $0 }' /var/www/discourse/Gemfile.lock) &&\
+    chown -R discourse:discourse /var/www/discourse
 
 USER discourse
+WORKDIR /var/www/discourse
+
+RUN bundle config --local deployment true &&\
+    bundle config --local path ./vendor/bundle &&\
+    bundle config --local without test development &&\
+    bundle config --local jobs 4 && \
+    bundle install &&\
+    yarn install --frozen-lockfile &&\
+    yarn cache clean &&\
+    find /var/www/discourse/vendor/bundle -name tmp -type d -exec rm -rf {} +
+
+COPY install /tmp/install
 
 RUN cd /var/www/discourse/plugins \
  && for plugin in $(cat /tmp/install/plugin-list); do \
-      git clone $plugin; \
+      git clone --depth 1 $plugin; \
     done
 
-RUN  cd app/assets/javascripts/discourse && \
+RUN cd app/assets/javascripts/discourse && \
      /var/www/discourse/app/assets/javascripts/node_modules/.bin/ember build -prod
 
-CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
+CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
\ No newline at end of file
diff --git a/install-imagemagick b/install-imagemagick
new file mode 100755
index 0000000000000000000000000000000000000000..911e719e618052fcebadae26281f94bb567ef138
--- /dev/null
+++ b/install-imagemagick
@@ -0,0 +1,72 @@
+#!/bin/bash
+set -e
+
+# version check: https://github.com/ImageMagick/ImageMagick/releases
+IMAGE_MAGICK_VERSION="7.1.0-62"
+IMAGE_MAGICK_HASH="d282117bc6d0e91ad1ad685d096623b96ed8e229f911c891d83277b350ef884a"
+
+# We use debian, but GitHub CI is stuck on Ubuntu Bionic, so this must be compatible with both
+LIBJPEGTURBO=$(cat /etc/issue | grep -qi Debian && echo 'libjpeg62-turbo libjpeg62-turbo-dev' || echo 'libjpeg-turbo8 libjpeg-turbo8-dev')
+
+# Ubuntu 22.04/22.10  doesn't have libwebp6
+LIBWEBP=$(cat /etc/issue | grep -qi 'Ubuntu 22' && echo 'libwebp7' || echo 'libwebp6')
+
+PREFIX=/usr/local
+WDIR=/tmp/imagemagick
+
+# Install build deps
+apt -y -q remove imagemagick
+apt -y -q install git make gcc pkg-config autoconf curl g++ yasm cmake \
+    libde265-0 libde265-dev ${LIBJPEGTURBO} x265 libx265-dev libtool \
+    libpng16-16 libpng-dev ${LIBJPEGTURBO} ${LIBWEBP} libwebp-dev libgomp1 \
+    libwebpmux3 libwebpdemux2 ghostscript libxml2-dev libxml2-utils librsvg2-dev \
+    libltdl7-dev libbz2-dev gsfonts libtiff-dev libfreetype6-dev libjpeg-dev
+
+# Ubuntu doesn't like `bullseye-backports`
+if cat /etc/issue | grep -qi 'Ubuntu 22'; then
+  apt -y install libheif1 libaom-dev libheif-dev
+else
+  # Use backports instead of compiling it
+  apt -y -q install -t bullseye-backports libheif1 libaom-dev libheif-dev
+fi
+
+mkdir -p $WDIR
+cd $WDIR
+
+# Build and install ImageMagick
+wget -q -O $WDIR/ImageMagick.tar.gz "https://github.com/ImageMagick/ImageMagick/archive/$IMAGE_MAGICK_VERSION.tar.gz"
+sha256sum $WDIR/ImageMagick.tar.gz
+echo "$IMAGE_MAGICK_HASH $WDIR/ImageMagick.tar.gz" | sha256sum -c
+IMDIR=$WDIR/$(tar tzf $WDIR/ImageMagick.tar.gz --wildcards "ImageMagick-*/configure" |cut -d/ -f1)
+tar zxf $WDIR/ImageMagick.tar.gz -C $WDIR
+cd $IMDIR
+PKG_CONF_LIBDIR=$PREFIX/lib LDFLAGS=-L$PREFIX/lib CFLAGS=-I$PREFIX/include ./configure \
+          --prefix=$PREFIX \
+          --enable-static \
+          --enable-bounds-checking \
+          --enable-hdri \
+          --enable-hugepages \
+          --with-threads \
+          --with-modules \
+          --with-quantum-depth=16 \
+          --without-magick-plus-plus \
+          --with-bzlib \
+          --with-zlib \
+          --without-autotrace \
+          --with-freetype \
+          --with-jpeg \
+          --without-lcms \
+          --with-lzma \
+          --with-png \
+          --with-tiff \
+          --with-heic \
+          --with-rsvg \
+          --with-webp
+make all && make install
+
+cd $HOME
+rm -rf $WDIR
+ldconfig /usr/local/lib
+
+# Validate ImageMagick install
+test $(convert -version | grep -o -e png -e tiff -e jpeg -e freetype -e heic -e webp | wc -l) -eq 6
diff --git a/install-jemalloc b/install-jemalloc
new file mode 100755
index 0000000000000000000000000000000000000000..b07597874abbd8c986e711bf41f3562d803c993e
--- /dev/null
+++ b/install-jemalloc
@@ -0,0 +1,26 @@
+#!/bin/bash
+set -e
+
+# version check: https://github.com/jemalloc/jemalloc/releases
+
+# jemalloc stable
+mkdir /jemalloc-stable
+cd /jemalloc-stable
+
+wget -q https://github.com/jemalloc/jemalloc/releases/download/3.6.0/jemalloc-3.6.0.tar.bz2
+sha256sum jemalloc-3.6.0.tar.bz2
+echo "e16c2159dd3c81ca2dc3b5c9ef0d43e1f2f45b04548f42db12e7c12d7bdf84fe jemalloc-3.6.0.tar.bz2" | sha256sum -c
+tar --strip-components=1 -xjf jemalloc-3.6.0.tar.bz2
+./configure --prefix=/usr && make && make install
+cd / && rm -rf /jemalloc-stable
+
+# jemalloc new
+mkdir /jemalloc-new
+cd /jemalloc-new
+
+wget -q https://github.com/jemalloc/jemalloc/releases/download/5.3.0/jemalloc-5.3.0.tar.bz2
+sha256sum jemalloc-5.3.0.tar.bz2
+echo "2db82d1e7119df3e71b7640219b6dfe84789bc0537983c3b7ac4f7189aecfeaa jemalloc-5.3.0.tar.bz2" | sha256sum -c
+tar --strip-components=1 -xjf jemalloc-5.3.0.tar.bz2 
+./configure --prefix=/usr --with-install-suffix=5.3.0 && make build_lib && make install_lib
+cd / && rm -rf /jemalloc-new
diff --git a/install-oxipng b/install-oxipng
new file mode 100755
index 0000000000000000000000000000000000000000..a6933ab6dde2a3b2d404c1ed44ec419420a0a644
--- /dev/null
+++ b/install-oxipng
@@ -0,0 +1,24 @@
+#!/bin/bash
+set -e
+
+# version check: https://github.com/shssoichiro/oxipng/releases
+OXIPNG_VERSION="8.0.0"
+OXIPNG_HASH="ef96d6340e70900de0a38ace8f5f20878f6c256b18b0c59cd87f2b515437b87b"
+OXIPNG_ARCHIVE="v${OXIPNG_VERSION}.tar.gz"
+OXIPNG_DIR="oxipng-${OXIPNG_VERSION}"
+
+# Install other deps
+apt-get -y install advancecomp jhead jpegoptim libjpeg-turbo-progs optipng
+
+cd /tmp
+wget -q https://github.com/shssoichiro/oxipng/archive/refs/tags/${OXIPNG_ARCHIVE}
+sha256sum ${OXIPNG_ARCHIVE}
+echo "${OXIPNG_HASH} ${OXIPNG_ARCHIVE}" | sha256sum -c
+
+tar -zxf ${OXIPNG_ARCHIVE}
+cd ${OXIPNG_DIR}
+
+CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse /usr/local/cargo/bin/cargo build --release
+cp target/release/oxipng /usr/local/bin
+
+cd / && rm -fr /tmp/${OXIPNG_DIR}
diff --git a/install-ruby b/install-ruby
new file mode 100755
index 0000000000000000000000000000000000000000..4be5a5f1f4978b616046138f9eeb66a4278fab7b
--- /dev/null
+++ b/install-ruby
@@ -0,0 +1,16 @@
+#!/bin/bash
+set -e
+
+RUBY_VERSION="3.2.2"
+export CONFIGURE_OPTS="--enable-yjit"
+
+apt-get -y install --no-install-recommends ruby bison libffi-dev
+
+mkdir /src
+git -C /src clone https://github.com/rbenv/ruby-build.git
+cd /src/ruby-build && ./install.sh
+cd / && rm -fr /src
+
+ruby-build ${RUBY_VERSION} /usr/local
+
+apt-get -y purge ruby
diff --git a/install-rust b/install-rust
new file mode 100755
index 0000000000000000000000000000000000000000..b452637813285cd7cfb3f3d9747c666860b5037d
--- /dev/null
+++ b/install-rust
@@ -0,0 +1,30 @@
+#!/bin/bash
+set -e
+
+# see https://github.com/rust-lang/docker-rust/blob/master/Dockerfile-debian.template
+export RUSTUP_HOME=/usr/local/rustup
+export CARGO_HOME=/usr/local/cargo
+export PATH=/usr/local/cargo/bin:$PATH
+export RUST_VERSION=1.68.0
+export RUSTUP_VERSION=1.25.2
+
+dpkgArch="$(dpkg --print-architecture)"
+
+case "${dpkgArch##*-}" in
+    amd64) rustArch='x86_64-unknown-linux-gnu'; rustupSha256='bb31eaf643926b2ee9f4d8d6fc0e2835e03c0a60f34d324048aa194f0b29a71c' ;;
+    armhf) rustArch='armv7-unknown-linux-gnueabihf'; rustupSha256='6626b90205d7fe7058754c8e993b7efd91dedc6833a11a225b296b7c2941194f' ;;
+    arm64) rustArch='aarch64-unknown-linux-gnu'; rustupSha256='4ccaa7de6b8be1569f6b764acc28e84f5eca342f5162cd5c810891bff7ed7f74' ;;
+    i386) rustArch='i686-unknown-linux-gnu'; rustupSha256='34392b53a25c56435b411d3e575b63aab962034dd1409ba405e708610c829607' ;;
+    *) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;;
+esac
+
+url="https://static.rust-lang.org/rustup/archive/${RUSTUP_VERSION}/${rustArch}/rustup-init"
+wget "$url"
+echo "${rustupSha256} *rustup-init" | sha256sum -c -
+chmod +x rustup-init
+./rustup-init -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION --default-host ${rustArch}
+rm rustup-init
+chmod -R a+w $RUSTUP_HOME $CARGO_HOME
+rustup --version
+cargo --version
+rustc --version
diff --git a/thpoff.c b/thpoff.c
new file mode 100644
index 0000000000000000000000000000000000000000..31953192d21e8af3b21222f20c1935f5c7d6e02e
--- /dev/null
+++ b/thpoff.c
@@ -0,0 +1,39 @@
+// PUBLIC DOMAIN CODE
+//
+// A tiny program that disable transparent huge pages on arbitrary processes
+// thpoff echo 1 : will run echo 1 with SET_THP_DISABLE true on the process
+#include <stdio.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+#include <errno.h>
+
+int main( int argc, char **argv) {
+    if (argc < 2) {
+	fprintf(stderr, "ERROR: expecting at least 1 argument!\n");
+	return -1;
+    }
+    prctl(PR_SET_THP_DISABLE, 1, 0, 0, 0);
+
+    char* newargv[argc];
+    int i;
+
+    newargv[argc-1] = NULL;
+    for (i=1; i<argc; i++) {
+	newargv[i-1] = argv[i];
+    }
+
+    execvp(argv[1], newargv);
+
+    if (errno == ENOENT) {
+	fprintf(stderr, "ERROR: file not found\n");
+	return -1;
+    } else if (errno == EACCES) {
+	fprintf(stderr, "ERROR: can not run file\n");
+	return -1;
+    } else if (errno > 0) {
+	fprintf(stderr, "ERROR: %i errno while attempting to run file\n", errno);
+	return -1;
+    }
+
+    return 0;
+}