diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..05c0b4d
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,28 @@
+*
+!LICENSE
+
+# opentts-abc
+!opentts-abc/setup.py
+!opentts-abc/LICENSE
+!opentts-abc/MANIFEST.in
+!opentts-abc/opentts_abc/*.py
+!opentts-abc/opentts_abc/VERSION
+
+# Mimic 3 TTS
+!mimic3-tts/setup.py
+!mimic3-tts/LICENSE
+!mimic3-tts/MANIFEST.in
+!mimic3-tts/requirements.txt
+!mimic3-tts/mimic3_tts/*.py
+!mimic3-tts/mimic3_tts/VERSION
+
+# HTTP server
+!mimic3-http/setup.py
+!mimic3-http/LICENSE
+!mimic3-http/MANIFEST.in
+!mimic3-http/requirements.txt
+!mimic3-http/mimic3_http/css/
+!mimic3-http/mimic3_http/img/
+!mimic3-http/mimic3_http/templates/
+!mimic3-http/mimic3_http/*.py
+!mimic3-http/mimic3_http/VERSION
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..155540b
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,82 @@
+# Copyright 2022 Mycroft AI Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+# -----------------------------------------------------------------------------
+# Dockerfile for Mimic 3 (https://github.com/MycroftAI/mimic3)
+#
+# Requires Docker buildx: https://docs.docker.com/buildx/working-with-buildx/
+# -----------------------------------------------------------------------------
+
+FROM debian:bullseye as build
+ARG TARGETARCH
+ARG TARGETVARIANT
+
+ENV LANG C.UTF-8
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN echo "Dir::Cache var/cache/apt/${TARGETARCH}${TARGETVARIANT};" > /etc/apt/apt.conf.d/01cache
+
+RUN --mount=type=cache,id=apt-build,target=/var/cache/apt \
+ mkdir -p /var/cache/apt/${TARGETARCH}${TARGETVARIANT}/archives/partial && \
+ apt-get update && \
+ apt-get install --yes --no-install-recommends \
+ python3 python3-pip python3-venv \
+ build-essential python3-dev
+
+RUN mkdir -p /home/mimic3/app
+WORKDIR /home/mimic3/app
+
+# Create virtual environment
+RUN --mount=type=cache,id=pip-venv,target=/root/.cache/pip \
+ python3 -m venv .venv && \
+ .venv/bin/pip3 install --upgrade pip && \
+ .venv/bin/pip3 install --upgrade wheel setuptools
+
+COPY ./ /home/mimic3/app/
+
+# Install packages in order
+RUN --mount=type=cache,id=pip-requirements,target=/root/.cache/pip \
+ .venv/bin/pip3 install -e opentts-abc && \
+ .venv/bin/pip3 install -e mimic3-tts && \
+ .venv/bin/pip3 install -e mimic3-http
+
+# -----------------------------------------------------------------------------
+
+FROM debian:bullseye as run
+ARG TARGETARCH
+ARG TARGETVARIANT
+
+ENV LANG C.UTF-8
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN echo "Dir::Cache var/cache/apt/${TARGETARCH}${TARGETVARIANT};" > /etc/apt/apt.conf.d/01cache
+
+RUN --mount=type=cache,id=apt-run,target=/var/cache/apt \
+ mkdir -p /var/cache/apt/${TARGETARCH}${TARGETVARIANT}/archives/partial && \
+ apt-get update && \
+ apt-get install --yes --no-install-recommends \
+ python3 ca-certificates
+
+RUN useradd -ms /bin/bash mimic3
+
+# Copy virtual environment and source code
+COPY --from=build /home/mimic3/app/ /home/mimic3/app/
+
+USER mimic3
+WORKDIR /home/mimic3/app
+
+EXPOSE 59125
+
+ENTRYPOINT ["/home/mimic3/app/.venv/bin/python3", "-m", "mimic3_http"]
diff --git a/Makefile b/Makefile
index 2e100d0..d4a2871 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
#
-.PHONY: dist
+.PHONY: dist docker
dist:
cd opentts-abc && python3 setup.py sdist
@@ -23,3 +23,6 @@ dist:
cp opentts-abc/dist/opentts_abc-*.tar.gz dist/
cp mimic3-tts/dist/mimic3_tts-*.tar.gz dist/
cp mimic3-http/dist/mimic3_http-*.tar.gz dist/
+
+docker:
+ docker buildx build . -f Dockerfile --tag mycroftai/mimic3 --load
diff --git a/docker/mimic3 b/docker/mimic3
new file mode 100755
index 0000000..4c3609f
--- /dev/null
+++ b/docker/mimic3
@@ -0,0 +1,78 @@
+#!/usr/bin/env bash
+# Copyright 2022 Mycroft AI Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+# Run mimic3 --update to update Docker image
+
+args=()
+repo='mycroftai/mimic3'
+tag='latest'
+docker='docker'
+
+while [[ -n "$1" ]]; do
+ if [[ "$1" == '--update' ]]; then
+ # Update Docker image
+ update='1'
+ args+=("$1")
+ else
+ args+=("$1")
+ fi
+
+ shift 1
+done
+
+if [[ -n "${update}" ]]; then
+ docker pull "${repo}:${tag}"
+fi
+
+docker_run_args=()
+
+if [[ -d /etc/ssl/certs ]]; then
+ # This directory seems to usually have symlinks to other directories
+ docker_run_args+=('-v' '/etc/ssl/certs:/etc/ssl/certs:ro')
+
+ # Create temp file with all certificate directories found
+ cert_dirs_file="$(mktemp)"
+ function finish {
+ rm -rf "${cert_dirs_file}"
+ }
+ trap finish EXIT
+
+ while read -r cert_path; do
+ # Follow symlinks and record directory paths
+ cert_path="$(readlink -f "${cert_path}")"
+ cert_dir="$(dirname "${cert_path}")"
+ echo $cert_dir >> "${cert_dirs_file}"
+ done < <(find /etc/ssl/certs -name '*.pem' -type l)
+
+ # Map unique certificate directories
+ while read -r cert_dir; do
+ docker_run_args+=('-v' "${cert_dir}:${cert_dir}:ro")
+ done < <(sort < "${cert_dirs_file}" | uniq)
+fi
+
+"${docker}" run \
+ -i \
+ -e "HOME=${HOME}" \
+ -v "$HOME:${HOME}" \
+ -w "${PWD}" \
+ --device /dev/snd:/dev/snd \
+ --user "$(id -u):$(id -g)" "${docker_run_args[@]}" \
+ --entrypoint '/home/mimic3/app/.venv/bin/python3' \
+ "${repo}:${tag}" \
+ -m mimic3_tts \
+ --stdout \
+ "${args[@]}"
diff --git a/docker/mimic3-server b/docker/mimic3-server
new file mode 100755
index 0000000..f6b137c
--- /dev/null
+++ b/docker/mimic3-server
@@ -0,0 +1,79 @@
+#!/usr/bin/env bash
+# Copyright 2022 Mycroft AI Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+# Run mimic3-server --update to update Docker image
+
+args=()
+repo='mycroftai/mimic3'
+tag='latest'
+docker='docker'
+port='59125'
+
+while [[ -n "$1" ]]; do
+ if [[ "$1" == '--update' ]]; then
+ # Update Docker image
+ update='1'
+ elif [[ "$1" == '--port' ]]; then
+ port="$2"
+ args+=('--port' "${port}")
+ shift 1
+ else
+ args+=("$1")
+ fi
+
+ shift 1
+done
+
+if [[ -n "${update}" ]]; then
+ docker pull "${repo}:${tag}"
+fi
+
+docker_run_args=()
+
+if [[ -d /etc/ssl/certs ]]; then
+ # This directory seems to usually have symlinks to other directories
+ docker_run_args+=('-v' '/etc/ssl/certs:/etc/ssl/certs:ro')
+
+ # Create temp file with all certificate directories found
+ cert_dirs_file="$(mktemp)"
+ function finish {
+ rm -rf "${cert_dirs_file}"
+ }
+ trap finish EXIT
+
+ while read -r cert_path; do
+ # Follow symlinks and record directory paths
+ cert_path="$(readlink -f "${cert_path}")"
+ cert_dir="$(dirname "${cert_path}")"
+ echo $cert_dir >> "${cert_dirs_file}"
+ done < <(find /etc/ssl/certs -name '*.pem' -type l)
+
+ # Map unique certificate directories
+ while read -r cert_dir; do
+ docker_run_args+=('-v' "${cert_dir}:${cert_dir}:ro")
+ done < <(sort < "${cert_dirs_file}" | uniq)
+fi
+
+"${docker}" run \
+ -it \
+ -p "${port}:${port}" \
+ -e "HOME=${HOME}" \
+ -v "$HOME:${HOME}" \
+ -w "${PWD}" \
+ --user "$(id -u):$(id -g)" "${docker_run_args[@]}" \
+ "${repo}:${tag}" \
+ "${args[@]}"