diff --git a/Makefile b/Makefile
index ffbd81dce..264f67671 100644
--- a/Makefile
+++ b/Makefile
@@ -242,7 +242,8 @@ versioned-images := 		php-8.1-fpm \
 							ruby-3.3 \
 							opensearch-2 \
 							mysql-8.0 \
-							mysql-8.4
+							mysql-8.4 \
+							valkey-8
 
 # default-versioned-images are images that formerly had no versioning, and are made backwards-compatible.
 # the below versions are the ones that map to the unversioned namespace
@@ -326,6 +327,7 @@ build/ruby-3.1 build/ruby-3.2 build/ruby-3.3: build/commons
 build/opensearch-2: build/commons
 build/mongo-4: build/commons 
 build/mysql-8.0 build/mysql-8.4: build/commons
+build/valkey-8: build/commons
 
 #######
 ####### Building Images
diff --git a/helpers/TESTING_service_images_dockercompose.md b/helpers/TESTING_service_images_dockercompose.md
index ceb203e03..aa44907b0 100644
--- a/helpers/TESTING_service_images_dockercompose.md
+++ b/helpers/TESTING_service_images_dockercompose.md
@@ -41,6 +41,7 @@ docker run --rm --net all-images_default jwilder/dockerize dockerize -wait tcp:/
 docker run --rm --net all-images_default jwilder/dockerize dockerize -wait tcp://redis-7:6379 -timeout 1m
 docker run --rm --net all-images_default jwilder/dockerize dockerize -wait tcp://solr-8:8983 -timeout 1m
 docker run --rm --net all-images_default jwilder/dockerize dockerize -wait tcp://solr-9:8983 -timeout 1m
+docker run --rm --net all-images_default jwilder/dockerize dockerize -wait tcp://valkey-8:6379 -timeout 1m
 ```
 
 Verification commands
@@ -70,6 +71,7 @@ docker ps --filter label=com.docker.compose.project=all-images | grep Up | grep
 docker ps --filter label=com.docker.compose.project=all-images | grep Up | grep solr-8
 docker ps --filter label=com.docker.compose.project=all-images | grep Up | grep solr-9
 docker ps --filter label=com.docker.compose.project=all-images | grep Up | grep nginx
+docker ps --filter label=com.docker.compose.project=all-images | grep Up | grep valkey-8
 docker ps --filter label=com.docker.compose.project=all-images | grep Up | grep varnish-6
 docker ps --filter label=com.docker.compose.project=all-images | grep Up | grep varnish-7
 
@@ -349,6 +351,28 @@ docker compose exec -T commons sh -c "curl -kL http://nginx:8080" | grep "hr" |
 docker compose exec -T commons sh -c "curl -I nginx:8080" | grep -i "Server" | grep -i "openresty"
 docker compose exec -T commons sh -c "curl -I nginx:8080" | grep -i "X-Lagoon"
 
+# valkey-8 should be running Valkey v8 server and Redis compatible
+docker compose exec -T valkey-8 sh -c "valkey-server --version" | grep v=8.
+docker compose exec -T valkey-8 sh -c "redis-server --version" | grep v=8.
+
+# valkey-8 should be running Valkey v8 cli and Redis compatible
+docker compose exec -T valkey-8 sh -c "valkey-cli --version" | grep 8.
+docker compose exec -T valkey-8 sh -c "redis-cli --version" | grep 8.
+
+# valkey-8 should be Redis 7.2.4 compatible
+docker compose exec -T valkey-8 sh -c "redis-cli INFO" | grep valkey_version | grep :8.
+docker compose exec -T valkey-8 sh -c "redis-cli INFO" | grep redis_version | grep :7.2.4
+
+# valkey-8 should be able to see Valkey databases
+docker compose exec -T valkey-8 sh -c "valkey-cli CONFIG GET databases"
+
+# valkey-8 should have initialized database
+docker compose exec -T valkey-8 sh -c "valkey-cli dbsize"
+
+# valkey-8 should be able to read/write data
+docker compose exec -T commons sh -c "curl -kL http://internal-services-test:3000/redis?service=valkey-8" | grep "SERVICE_HOST=valkey-8"
+docker compose exec -T commons sh -c "curl -kL http://internal-services-test:3000/redis?service=valkey-8" |grep "LAGOON_TEST_VAR=all-images"
+
 # varnish-6 should have correct vmods in varnish folder
 docker compose exec -T varnish-6 sh -c "ls -la /usr/lib/varnish/vmods" | grep libvmod_bodyaccess.so
 docker compose exec -T varnish-6 sh -c "ls -la /usr/lib/varnish/vmods" | grep libvmod_dynamic.so
diff --git a/helpers/services-docker-compose.yml b/helpers/services-docker-compose.yml
index 728e4f3c7..3220e1f90 100644
--- a/helpers/services-docker-compose.yml
+++ b/helpers/services-docker-compose.yml
@@ -123,6 +123,12 @@ services:
       - "8983"
     user: solr
 
+  valkey-8:
+    image: uselagoon/valkey-8:latest
+    ports:
+      - "6379"
+    << : *default-user # uses the defined user from top
+
   varnish-6:
     image: uselagoon/varnish-6:latest
     labels:
diff --git a/images/valkey/8.Dockerfile b/images/valkey/8.Dockerfile
new file mode 100644
index 000000000..686aa8bc4
--- /dev/null
+++ b/images/valkey/8.Dockerfile
@@ -0,0 +1,45 @@
+ARG IMAGE_REPO
+FROM ${IMAGE_REPO:-lagoon}/commons AS commons
+FROM valkey/valkey:8.0.0-alpine3.20
+
+
+ARG LAGOON_VERSION
+ENV LAGOON_VERSION=$LAGOON_VERSION
+LABEL org.opencontainers.image.authors="The Lagoon Authors"
+LABEL org.opencontainers.image.source="https://github.com/uselagoon/lagoon-images/blob/main/images/valkey/8.Dockerfile"
+LABEL org.opencontainers.image.url="https://github.com/uselagoon/lagoon-images"
+LABEL org.opencontainers.image.version="${LAGOON_VERSION}"
+LABEL org.opencontainers.image.description="Valkey 8 image optimised for running in Lagoon in production and locally"
+LABEL org.opencontainers.image.title="uselagoon/valkey-8"
+LABEL org.opencontainers.image.base.name="docker.io/valkey/valkey:8-alpine"
+
+ENV LAGOON=valkey
+
+ENV FLAVOR=ephemeral
+
+# Copy commons files
+COPY --from=commons /lagoon /lagoon
+COPY --from=commons /bin/fix-permissions /bin/ep /bin/docker-sleep /bin/wait-for /bin/
+COPY --from=commons /sbin/tini /sbin/
+COPY --from=commons /home /home
+
+RUN fix-permissions /etc/passwd \
+    && mkdir -p /home \
+    && mkdir -p /etc/valkey
+
+ENV TMPDIR=/tmp \
+    TMP=/tmp \
+    HOME=/home \
+    # When Bash is invoked via `sh` it behaves like the old Bourne Shell and sources a file that is given in `ENV`
+    ENV=/home/.bashrc \
+    # When Bash is invoked as non-interactive (like `bash -c command`) it sources a file that is given in `BASH_ENV`
+    BASH_ENV=/home/.bashrc
+
+COPY conf /etc/valkey/
+COPY docker-entrypoint /lagoon/entrypoints/70-valkey-entrypoint
+
+RUN fix-permissions /etc/valkey \
+    fix-permissions /data
+
+ENTRYPOINT ["/sbin/tini", "--", "/lagoon/entrypoints.sh"]
+CMD ["valkey-server", "/etc/valkey/valkey.conf"]
diff --git a/images/valkey/conf/ephemeral.conf b/images/valkey/conf/ephemeral.conf
new file mode 100644
index 000000000..4840b8259
--- /dev/null
+++ b/images/valkey/conf/ephemeral.conf
@@ -0,0 +1,4 @@
+
+# this disabled the persistent cache
+save ""
+appendonly no
diff --git a/images/valkey/conf/persistent.conf b/images/valkey/conf/persistent.conf
new file mode 100644
index 000000000..e1060eced
--- /dev/null
+++ b/images/valkey/conf/persistent.conf
@@ -0,0 +1,17 @@
+save 300 1
+save 60 100
+
+appendonly yes
+appendfsync everysec
+
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+
+# RDB files created with checksum disabled have a checksum of zero that will
+# tell the loading code to skip the check.
+rdbchecksum yes
+
+# The filename where to dump the DB
+dbfilename valkey.rdb
+
+dir /data
diff --git a/images/valkey/conf/valkey.conf b/images/valkey/conf/valkey.conf
new file mode 100644
index 000000000..4be42e16c
--- /dev/null
+++ b/images/valkey/conf/valkey.conf
@@ -0,0 +1,16 @@
+# Valkey configuration file for non-persistent cache
+# see https://github.com/valkey-io/valkey/blob/unstable/valkey.conf for all possible configs.
+
+loglevel ${LOGLEVEL:-notice}
+databases ${DATABASES:-1}
+
+maxmemory ${MAXMEMORY:-400mb}
+maxmemory-policy ${MAXMEMORYPOLICY:-allkeys-lru}
+
+# allow other hosts to connect to us
+protected-mode no
+bind 0.0.0.0
+
+${REQUIREPASS_CONF:-}
+
+include /etc/valkey/${FLAVOR:-ephemeral}.conf
diff --git a/images/valkey/docker-entrypoint b/images/valkey/docker-entrypoint
new file mode 100755
index 000000000..a4b9b7596
--- /dev/null
+++ b/images/valkey/docker-entrypoint
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+if [[ -n "${REDIS_PASSWORD}" ]]; then
+  echo "You should not use the REDIS_PASSWORD environment variable, use VALKEY_PASSWORD instead"
+  export VALKEY_PASSWORD=${REDIS_PASSWORD}
+fi
+
+if [[ -n "${VALKEY_PASSWORD}" ]]; then
+  export REQUIREPASS_CONF="# Enable basic/simple authentication
+# Warning: since Valkey is pretty fast an outside user can try up to
+# 150k passwords per second against a good box. This means that you should
+# use a very strong password otherwise it will be very easy to break.
+requirepass ${VALKEY_PASSWORD}"
+fi
+
+# Check if VALKEY_FLAVOR or FLAVOR is set and has the value "persistent"
+if [ "${VALKEY_FLAVOR}" = "persistent" ] || [ "${FLAVOR}" = "persistent" ]; then
+    FLAVOR="persistent"
+else
+    FLAVOR="ephemeral"
+fi
+echo "FLAVOR is set to: $FLAVOR"
+
+ep /etc/valkey/*
+
+exec "$@"