diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 647b71c8bd0213a62d26da02820ebaea5bc24d61..e702fa93dbc5993bc5381871c3e4852eac835f43 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -35,7 +35,7 @@ authors:
 # Test containers scripts are up to date
 containers:
   stage: initial
-  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
+  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
   script:
     - cd containers
     - python write_dockerfiles.py #HACK
@@ -43,7 +43,7 @@ containers:
     # write_dockerfiles.py and commit the changes.
     - git diff --exit-code
     - cp env-template.yml env.yml
-    - echo "  - python=3.10" >> env.yml
+    - echo "  - python=3.11" >> env.yml
     - mamba env create -f env.yml -n test --dry-run
 
 .test-python: &test-python
@@ -78,6 +78,10 @@ basic-3.11:
   <<: *test-python
   image: python:3.11
 
+basic-3.12:
+  <<: *test-python
+  image: python:3.12
+
 .test-samplers-import: &test-samplers-import
   stage: initial
   script:
@@ -93,6 +97,10 @@ import-samplers-3.11:
   <<: *test-samplers-import
   image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
 
+import-samplers-3.12:
+  <<: *test-samplers-import
+  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python312
+
 .precommits: &precommits
   stage: initial
   script:
@@ -104,19 +112,19 @@ import-samplers-3.11:
     # Run precommits (flake8, spellcheck, isort, no merge conflicts, etc)
     - pre-commit run --all-files --verbose --show-diff-on-failure
 
-precommits-py3.10:
+precommits-py3.11:
   <<: *precommits
-  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
+  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
   variables:
-    CACHE_DIR: ".pip310"
-    PYVERSION: "python310"
+    CACHE_DIR: ".pip311"
+    PYVERSION: "python311"
 
 install:
   stage: initial
   parallel:
     matrix:
       - EXTRA: [gw, mcmc, all]
-  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
+  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
   script:
     - pip install .[$EXTRA]
 
@@ -132,8 +140,13 @@ install:
 
 python-3.10:
   <<: *unit-test
-  needs: ["basic-3.10", "precommits-py3.10"]
+  needs: ["basic-3.10"]
   image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
+
+python-3.11:
+  <<: *unit-test
+  needs: ["basic-3.11", "precommits-py3.11"]
+  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
   after_script:
     - coverage html
     - coverage xml
@@ -147,10 +160,10 @@ python-3.10:
       - htmlcov/
     expire_in: 30 days
 
-python-3.11:
+python-3.12:
   <<: *unit-test
-  needs: ["basic-3.11"]
-  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
+  needs: ["basic-3.12"]
+  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python312
 
 .test-sampler: &test-sampler
   stage: test
@@ -161,18 +174,23 @@ python-3.11:
 
 python-3.10-samplers:
   <<: *test-sampler
-  needs: ["basic-3.10", "precommits-py3.10"]
+  needs: ["basic-3.10"]
   image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
 
 python-3.11-samplers:
   <<: *test-sampler
-  needs: ["basic-3.11"]
+  needs: ["basic-3.11", "precommits-py3.11"]
   image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
 
-integration-tests-python-3.10:
+python-3.12-samplers:
+  <<: *test-sampler
+  needs: ["basic-3.12"]
+  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python312
+
+integration-tests-python-3.11:
   stage: test
-  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
-  needs: ["basic-3.10", "precommits-py3.10"]
+  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
+  needs: ["basic-3.11", "precommits-py3.11"]
   only:
     - schedules
   script:
@@ -193,18 +211,23 @@ integration-tests-python-3.10:
 plotting-python-3.10:
   <<: *plotting
   image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
-  needs: ["basic-3.10", "precommits-py3.10"]
+  needs: ["basic-3.10"]
 
 plotting-python-3.11:
   <<: *plotting
   image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
-  needs: ["basic-3.11"]
+  needs: ["basic-3.11", "precommits-py3.11"]
+
+plotting-python-3.12:
+  <<: *plotting
+  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python312
+  needs: ["basic-3.12"]
 
 # ------------------- Docs stage -------------------------------------------
 
 docs:
   stage: docs
-  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
+  image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
   before_script:
     - python -m ipykernel install
   script:
@@ -225,7 +248,7 @@ docs:
 
 pages:
   stage: deploy
-  needs: ["docs", "python-3.10"]
+  needs: ["docs", "python-3.11"]
   script:
     - mkdir public/
     - mv htmlcov/ public/
@@ -267,6 +290,11 @@ build-python311-container:
   variables:
     PYVERSION: "python311"
 
+build-python312-container:
+  <<: *build-container
+  variables:
+    PYVERSION: "python312"
+
 pypi-release:
   stage: deploy
   image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
diff --git a/containers/v3-dockerfile-test-suite-python312 b/containers/v3-dockerfile-test-suite-python312
new file mode 100644
index 0000000000000000000000000000000000000000..60c0228d108947632f9617d64a23446896ab04e8
--- /dev/null
+++ b/containers/v3-dockerfile-test-suite-python312
@@ -0,0 +1,27 @@
+# This dockerfile is written automatically and should not be modified by hand.
+
+FROM containers.ligo.org/docker/base:conda
+LABEL name="bilby CI testing" \
+maintainer="Gregory Ashton <gregory.ashton@ligo.org>, Colm Talbot <colm.talbot@ligo.org>"
+
+COPY env-template.yml env.yml
+RUN echo "  - python=3.12" >> env.yml
+ENV conda_env python312
+
+RUN mamba env create -f env.yml -n ${conda_env}
+RUN echo "source activate ${conda_env}" > ~/.bashrc
+ENV PATH /opt/conda/envs/${conda_env}/bin:$PATH
+RUN /bin/bash -c "source activate ${conda_env}"
+RUN mamba info
+RUN python --version
+
+# Add the ROQ data to the image
+RUN mkdir roq_basis \
+    && cd roq_basis \
+    && wget https://git.ligo.org/lscsoft/ROQ_data/raw/master/IMRPhenomPv2/4s/B_linear.npy \
+    && wget https://git.ligo.org/lscsoft/ROQ_data/raw/master/IMRPhenomPv2/4s/B_quadratic.npy \
+    && wget https://git.ligo.org/lscsoft/ROQ_data/raw/master/IMRPhenomPv2/4s/fnodes_linear.npy \
+    && wget https://git.ligo.org/lscsoft/ROQ_data/raw/master/IMRPhenomPv2/4s/fnodes_quadratic.npy \
+    && wget https://git.ligo.org/lscsoft/ROQ_data/raw/master/IMRPhenomPv2/4s/params.dat \
+    && wget https://git.ligo.org/soichiro.morisaki/roq_basis/raw/main/IMRPhenomD/16s_nospins/basis_addcal.hdf5 \
+    && wget https://git.ligo.org/soichiro.morisaki/roq_basis/raw/main/IMRPhenomD/16s_nospins/basis_multiband_addcal.hdf5
diff --git a/containers/write_dockerfiles.py b/containers/write_dockerfiles.py
index 1ca29f98fb09e495b2c91cda033e41d16e9fdb65..064c5d0f1d27bf639ae8fea12b705a25da2859a9 100644
--- a/containers/write_dockerfiles.py
+++ b/containers/write_dockerfiles.py
@@ -3,7 +3,7 @@ from datetime import date
 with open("dockerfile-template", "r") as ff:
     template = ff.read()
 
-python_versions = [(3, 10), (3, 11)]
+python_versions = [(3, 10), (3, 11), (3, 12)]
 today = date.today().strftime("%Y%m%d")
 
 for python_major_version, python_minor_version in python_versions:
diff --git a/docs/installation.txt b/docs/installation.txt
index 378ee65f8f97c12b3c55989403183e05d53108d3..0583ce8712399a382d1b022477765cb4193cbfaa 100644
--- a/docs/installation.txt
+++ b/docs/installation.txt
@@ -10,7 +10,7 @@ Installation
 
           $ conda install -c conda-forge bilby
 
-      Supported python versions: 3.10-3.11.
+      Supported python versions: 3.10-3.12.
 
    .. tab:: Pip
 
@@ -18,7 +18,7 @@ Installation
 
           $ pip install bilby
 
-      Supported python versions: 3.10-3.11.
+      Supported python versions: 3.10-3.12.
 
 
 This will install all requirements for running :code:`bilby` for general
@@ -47,7 +47,7 @@ wave inference, please additionally run the following commands.
 Install bilby from source
 -------------------------
 
-:code:`bilby` is developed and tested with Python 3.10-3.11. In the
+:code:`bilby` is developed and tested with Python 3.10-3.12. In the
 following, we assume you have a working python installation, `python pip
 <https://packaging.python.org/tutorials/installing-packages/#use-pip-for-installing)>`_,
 and `git <https://git-scm.com/>`_. See :ref:`installing-python` for our