diff --git a/.hadolint.yaml b/.hadolint.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b76a5107288288a6d6300380d8558b50bcaea578
--- /dev/null
+++ b/.hadolint.yaml
@@ -0,0 +1,8 @@
+failure-threshold: warning
+ignored:
+  - DL3008
+  - DL3013
+format: tty
+trustedRegistries:
+  - docker.io
+  - gcr.io
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 02e25ceed4fc5aa558b7da2d3a70d859405f9d70..72b612b862d91612789e701e6feb5f9991844d4e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -18,5 +18,6 @@
     "Weaviate",
     "Zilliz"
   ],
-  "eslint.experimental.useFlatConfig": true
-}
\ No newline at end of file
+  "eslint.experimental.useFlatConfig": true,
+  "docker.languageserver.formatter.ignoreMultilineInstructions": true
+}
diff --git a/docker/Dockerfile b/docker/Dockerfile
index b1ea62a63f14d149d8c6c715e939cb34e99941b4..2edbadb2cfd64aff05f30fcb7548384bc791766c 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -1,12 +1,17 @@
 # Setup base image
-FROM ubuntu:jammy-20230522 AS base
+FROM ubuntu:jammy-20230916 AS base
 
+# Build arguments
 ARG ARG_UID=1000
 ARG ARG_GID=1000
 
 FROM base AS build-arm64
 RUN echo "Preparing build of AnythingLLM image for arm64 architecture"
 
+SHELL ["/bin/bash", "-o", "pipefail", "-c"]
+
+# Install system dependencies
+# hadolint ignore=DL3008,DL3013
 RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
     DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
         unzip curl gnupg libgfortran5 libgbm1 tzdata netcat \
@@ -25,8 +30,8 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
         && rm yarn_1.22.19_all.deb
 
 # Create a group and user with specific UID and GID
-RUN groupadd -g $ARG_GID anythingllm && \
-    useradd -u $ARG_UID -m -d /app -s /bin/bash -g anythingllm anythingllm && \
+RUN groupadd -g "$ARG_GID" anythingllm && \
+    useradd -l -u "$ARG_UID" -m -d /app -s /bin/bash -g anythingllm anythingllm && \
     mkdir -p /app/frontend/ /app/server/ /app/collector/ && chown -R anythingllm:anythingllm /app
 
 # Copy docker helper scripts
@@ -61,6 +66,10 @@ RUN echo "Done running arm64 specific installtion steps"
 FROM base AS build-amd64
 RUN echo "Preparing build of AnythingLLM image for non-ARM architecture"
 
+SHELL ["/bin/bash", "-o", "pipefail", "-c"]
+
+# Install system dependencies
+# hadolint ignore=DL3008,DL3013
 RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
     DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
         curl gnupg libgfortran5 libgbm1 tzdata netcat \
@@ -79,8 +88,8 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
         && rm yarn_1.22.19_all.deb
 
 # Create a group and user with specific UID and GID
-RUN groupadd -g $ARG_GID anythingllm && \
-    useradd -u $ARG_UID -m -d /app -s /bin/bash -g anythingllm anythingllm && \
+RUN groupadd -g "$ARG_GID" anythingllm && \
+    useradd -l -u "$ARG_UID" -m -d /app -s /bin/bash -g anythingllm anythingllm && \
     mkdir -p /app/frontend/ /app/server/ /app/collector/ && chown -R anythingllm:anythingllm /app
 
 # Copy docker helper scripts
@@ -95,6 +104,8 @@ RUN chmod +x /usr/local/bin/docker-entrypoint.sh && \
 #############################################
 # COMMON BUILD FLOW FOR ALL ARCHS
 #############################################
+
+# hadolint ignore=DL3006
 FROM build-${TARGETARCH} AS build
 RUN echo "Running common build flow of AnythingLLM image for all architectures"
 
@@ -102,43 +113,54 @@ USER anythingllm
 WORKDIR /app
 
 # Install frontend dependencies
-FROM build as frontend-deps
+FROM build AS frontend-deps
 
 COPY ./frontend/package.json ./frontend/yarn.lock ./frontend/
-RUN cd ./frontend/ && yarn install --network-timeout 100000 && yarn cache clean
+WORKDIR /app/frontend
+RUN yarn install --network-timeout 100000 && yarn cache clean
+WORKDIR /app
 
 # Install server dependencies
-FROM build as server-deps
+FROM build AS server-deps
 COPY ./server/package.json ./server/yarn.lock ./server/
-RUN cd ./server/ && yarn install --production --network-timeout 100000 && yarn cache clean
+WORKDIR /app/server
+RUN yarn install --production --network-timeout 100000 && yarn cache clean
+WORKDIR /app
 
 # Compile Llama.cpp bindings for node-llama-cpp for this operating system.
 USER root
-RUN cd ./server && npx --no node-llama-cpp download
+WORKDIR /app/server
+RUN npx --no node-llama-cpp download
+WORKDIR /app
 USER anythingllm
 
 # Build the frontend
-FROM frontend-deps as build-stage
+FROM frontend-deps AS build-stage
 COPY ./frontend/ ./frontend/
-RUN cd ./frontend/ && yarn build && yarn cache clean
+WORKDIR /app/frontend
+RUN yarn build && yarn cache clean
+WORKDIR /app
 
 # Setup the server
-FROM server-deps as production-stage
+FROM server-deps AS production-stage
 COPY --chown=anythingllm:anythingllm ./server/ ./server/
 
 # Copy built static frontend files to the server public directory
-COPY --from=build-stage /app/frontend/dist ./server/public
+COPY --chown=anythingllm:anythingllm --from=build-stage /app/frontend/dist ./server/public
 
 # Copy the collector
 COPY --chown=anythingllm:anythingllm ./collector/ ./collector/
 
 # Install collector dependencies
+WORKDIR /app/collector
 ENV PUPPETEER_DOWNLOAD_BASE_URL=https://storage.googleapis.com/chrome-for-testing-public 
-RUN cd /app/collector && yarn install --production --network-timeout 100000 && yarn cache clean
+RUN yarn install --production --network-timeout 100000 && yarn cache clean
 
 # Migrate and Run Prisma against known schema
-RUN cd ./server && npx prisma generate --schema=./prisma/schema.prisma
-RUN cd ./server && npx prisma migrate deploy --schema=./prisma/schema.prisma
+WORKDIR /app/server
+RUN npx prisma generate --schema=./prisma/schema.prisma && \
+    npx prisma migrate deploy --schema=./prisma/schema.prisma
+WORKDIR /app
 
 # Setup the environment
 ENV NODE_ENV=production
@@ -152,4 +174,4 @@ HEALTHCHECK --interval=1m --timeout=10s --start-period=1m \
   CMD /bin/bash /usr/local/bin/docker-healthcheck.sh || exit 1
 
 # Run the server
-ENTRYPOINT ["/bin/bash", "/usr/local/bin/docker-entrypoint.sh"]
\ No newline at end of file
+ENTRYPOINT ["/bin/bash", "/usr/local/bin/docker-entrypoint.sh"]
diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh
index 3d890db1deef40ccd1bdd5d7b4000c9f04eed581..1ac69e5baf46ff19c0d817460b63d5f7e73fc52f 100755
--- a/docker/docker-entrypoint.sh
+++ b/docker/docker-entrypoint.sh
@@ -1,9 +1,10 @@
 #!/bin/bash
-{ cd /app/server/ &&\
-  npx prisma generate --schema=./prisma/schema.prisma &&\
-  npx prisma migrate deploy --schema=./prisma/schema.prisma &&\
-  node /app/server/index.js
+{
+  cd /app/server/ &&
+    npx prisma generate --schema=./prisma/schema.prisma &&
+    npx prisma migrate deploy --schema=./prisma/schema.prisma &&
+    node /app/server/index.js
 } &
 { node /app/collector/index.js; } &
 wait -n
-exit $?
\ No newline at end of file
+exit $?
diff --git a/docker/docker-healthcheck.sh b/docker/docker-healthcheck.sh
index 45a88477d9195d322973d2aa1fbd45461310af08..49bee3e1bf0e090754226ffd7baf2f5c10e5eb4f 100644
--- a/docker/docker-healthcheck.sh
+++ b/docker/docker-healthcheck.sh
@@ -4,10 +4,10 @@
 response=$(curl --write-out '%{http_code}' --silent --output /dev/null http://localhost:3001/api/ping)
 
 # If the HTTP response code is 200 (OK), the server is up
-if [ $response -eq 200 ]; then
-    echo "Server is up"
-    exit 0
+if [ "$response" -eq 200 ]; then
+  echo "Server is up"
+  exit 0
 else
-    echo "Server is down"
-    exit 1
+  echo "Server is down"
+  exit 1
 fi