diff --git a/airbase-docker/README.md b/airbase-docker/README.md
new file mode 100644
index 000000000..3c1915e5c
--- /dev/null
+++ b/airbase-docker/README.md
@@ -0,0 +1,27 @@
+# Airlift Docker Builder
+
+For modules that contain a file named `.build-airlift-docker`,
+the Maven properties below are used to generate a docker image during the
+package phase and to deploy/push that image during the delpoy phase. This
+[docker file](../airbase-docker/src/main/resources/AirliftDockerfile) is
+used to build the image.
+
+Note: modules must also contain `.build-airlift` so that the Airlift
+launcher tarball is generated. The Maven build will fail if this file
+is missing.
+
+## Maven Properties
+
+| Name | Default Value | Details |
+| ----- | ------------- | ------- |
+| air.docker.skip | false | skip all docker executions |
+| air.docker.skip-build | false | skip docker build |
+| air.docker.skip-deploy | false | skip docker deploy |
+| air.docker.skip-tag | false | skip docker tagging |
+| air.docker.verbose | false | enable verbose mode for dockerfile-maven-plugin |
+| air.docker.repository | harbor.starburstdata.net/starburstdata/${project.artifactId} | Harbor/image name |
+| air.docker.application-name | ${project.artifactId} | `APPLICATION_NAME` in [AirliftDockerfile](../airbase-docker/src/main/resources/AirliftDockerfile) |
+| air.docker.maintainer | ${project.groupId} | `MAINTAINER` in [AirliftDockerfile](../airbase-docker/src/main/resources/AirliftDockerfile) |
+| air.docker.user | airlift | `USER` in [AirliftDockerfile](../airbase-docker/src/main/resources/AirliftDockerfile) |
+| air.docker.jdk | openjdk:${project.build.targetJdk}-jdk | `JAVA_VERSION` in [AirliftDockerfile](../airbase-docker/src/main/resources/AirliftDockerfile) |
+| air.docker.port | 8080 | `APPLICATION_PORT` in [AirliftDockerfile](../airbase-docker/src/main/resources/AirliftDockerfile) |
diff --git a/airbase-docker/pom.xml b/airbase-docker/pom.xml
new file mode 100644
index 000000000..f7d2b8ac6
--- /dev/null
+++ b/airbase-docker/pom.xml
@@ -0,0 +1,16 @@
+
+
+ 4.0.0
+
+
+ io.airlift
+ airbase-root
+ 113-SNAPSHOT
+
+
+ airbase-docker
+
+ Docker file for Airbase
+
diff --git a/airbase-docker/src/main/resources/AirliftDockerfile b/airbase-docker/src/main/resources/AirliftDockerfile
new file mode 100644
index 000000000..7cdc97df0
--- /dev/null
+++ b/airbase-docker/src/main/resources/AirliftDockerfile
@@ -0,0 +1,54 @@
+ARG ARTIFACT_ID
+ARG ARTIFACT_VERSION
+ARG APPLICATION_NAME
+ARG JAVA_VERSION
+ARG MAINTAINER
+ARG USER
+ARG APPLICATION_PORT
+
+FROM alpine:3 as extractor
+
+ARG ARTIFACT_ID
+ARG ARTIFACT_VERSION
+ARG APPLICATION_NAME
+ARG JAVA_VERSION
+ARG MAINTAINER
+ARG USER
+ARG APPLICATION_PORT
+
+ADD ${ARTIFACT_ID}-${ARTIFACT_VERSION}.tar.gz /opt/${APPLICATION_NAME}
+RUN ln -s "${ARTIFACT_ID}-${ARTIFACT_VERSION}" /opt/${APPLICATION_NAME}/${ARTIFACT_ID}
+
+FROM ${JAVA_VERSION}
+
+ARG ARTIFACT_ID
+ARG ARTIFACT_VERSION
+ARG APPLICATION_NAME
+ARG JAVA_VERSION=11-jdk
+ARG MAINTAINER
+ARG USER
+ARG APPLICATION_PORT
+
+LABEL maintainer=${MAINTAINER}
+LABEL service=${ARTIFACT_ID} version=${ARTIFACT_VERSION}
+
+RUN apt-get update && \
+ apt-get install -y \
+ jq \
+ python \
+ tmux && \
+ rm -rf /var/lib/apt/lists/* && \
+ adduser --home /opt/${APPLICATION_NAME}/${ARTIFACT_ID} --no-create-home --disabled-login --gecos "" ${USER} && \
+ mkdir /var/log/${APPLICATION_NAME} && \
+ chown -R ${USER}:${USER} /var/log/${APPLICATION_NAME}
+
+COPY --chown=${USER}:${USER} --from=extractor /opt/${APPLICATION_NAME} /opt/${APPLICATION_NAME}
+
+EXPOSE ${APPLICATION_PORT}
+
+ENV APPLICATION_NAME=${APPLICATION_NAME}
+ENV ARTIFACT_ID=${ARTIFACT_ID}
+
+CMD /opt/${APPLICATION_NAME}/${ARTIFACT_ID}/bin/launcher run \
+ --etc-dir=/etc/${APPLICATION_NAME} \
+ --verbose
diff --git a/airbase/pom.xml b/airbase/pom.xml
index ad590b0f3..57b0da31e 100644
--- a/airbase/pom.xml
+++ b/airbase/pom.xml
@@ -1483,5 +1483,133 @@
+
+
+
+
+
+
+
+
+
+ build-airlift-docker
+
+
+
+ .build-airlift-docker
+
+
+
+
+ false
+ ${air.docker.skip}
+ ${air.docker.skip}
+ ${air.docker.skip}
+ ${project.artifactId}
+ ${project.groupId}
+ airlift
+ openjdk:${project.build.targetJdk}-jdk
+ 8080
+ harbor.starburstdata.net/starburstdata/${project.artifactId}
+ false
+
+
+
+
+ io.airlift
+ airbase-docker
+ 113-SNAPSHOT
+ provided
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+ package
+
+ enforce
+
+
+
+
+
+ .build-airlift
+
+ A .build-airlift file is required to build the launcher tarball.
+
+
+
+ ${project.build.directory}/${project.artifactId}-${project.version}.tar.gz
+
+ Airlift launcher tarball wasn't built
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ airlift-docker
+ validate
+
+ unpack-dependencies
+
+
+ ${project.build.directory}
+ io.airlift
+ airbase-docker
+ META-INF/**
+
+
+
+
+
+
+ com.spotify
+ dockerfile-maven-plugin
+ 1.4.13
+
+
+ docker
+
+ build
+ push
+
+
+
+
+ ${air.docker.skip-build}
+ ${air.docker.skip-deploy}
+ ${air.docker.skip-tag}
+ ${air.docker.repository}
+ ${project.version}
+ ${project.build.directory}
+ ${project.build.directory}/AirliftDockerfile
+ true
+ ${air.docker.verbose}
+
+ ${project.artifactId}
+ ${project.version}
+ ${air.docker.application-name}
+ ${air.docker.maintainer}
+ ${air.docker.user}
+ ${air.docker.jdk}
+ ${air.docker.port}
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 669edda71..1d3dab91d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,6 +50,7 @@
airbase
airbase-policy
+ airbase-docker