Reduce container image size

The container images contained more layers than needed and did contain
cache files from package installations. This increased the image size
unnecessarily.

This change optimizes the image contents and adds a description of some
best practices to the developers guide.

Change-Id: I7d0fd1711c4cad5aeb930e3096be5dc6327be385
diff --git a/Documentation/developer-guide.md b/Documentation/developer-guide.md
index c6be262..656ec1b 100644
--- a/Documentation/developer-guide.md
+++ b/Documentation/developer-guide.md
@@ -10,9 +10,6 @@
 https://gerrit.googlesource.com/k8s-gerrit. You will need a
 [generated cookie][2].
 
-[1]: https://gerrit-review.googlesource.com/Documentation/user-upload.html#_git_push
-[2]: https://gerrit.googlesource.com/new-password
-
 Gerrit depends on "Change-Id" annotations in your commit message.
 If you try to push a commit without one, it will explain how to
 install the proper git-hook:
@@ -35,3 +32,39 @@
 ```
 git push origin HEAD:refs/for/master
 ```
+
+## Developing container images
+
+When changing or creating container images, keep the image size as small as
+possible. This reduces storage space needed for images, the upload time and most
+importantly the download time, which improves startup time of pods.
+
+Some good practices are listed here:
+
+- **Chain commands:** Each `RUN`-command creates a new layer in the docker image.
+Each layer increases the total image size. Thus, reducing the number of layers,
+can also reduce the image size.
+
+- **Clean up after package installation:** The package installation creates a
+number of cache files, which should be removed after installation. In Ubuntu/Debian-
+based images use the following snippet (This requires `apt-get update` before
+each package installation!):
+
+```docker
+RUN apt-get update && \
+    apt get install -y <packages> && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/*
+```
+
+- **Clean up temporary files immediately:** If temporary files are created by a
+command remove them in the same command chain.
+
+- **Use multi stage builds:** If some complicated build processes are needed for
+building parts of the container image, of which only the final product is needed,
+use [multi stage builds][3]
+
+
+[1]: https://gerrit-review.googlesource.com/Documentation/user-upload.html#_git_push
+[2]: https://gerrit.googlesource.com/new-password
+[3]: https://docs.docker.com/develop/develop-images/multistage-build/
diff --git a/container-images/apache-git-http-backend/Dockerfile b/container-images/apache-git-http-backend/Dockerfile
index d341e6d..c5d39b7 100644
--- a/container-images/apache-git-http-backend/Dockerfile
+++ b/container-images/apache-git-http-backend/Dockerfile
@@ -1,24 +1,33 @@
 FROM base:latest
 
 # Install apache2
-RUN apt-get update && apt-get -y install apache2 apache2-utils
-RUN a2enmod cgi alias env ssl
+RUN apt-get update && \
+    apt-get -y install \
+      apache2  \
+      apache2-utils && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/* && \
+    a2enmod \
+      cgi \
+      alias \
+      env \
+      ssl && \
+    rm -f /etc/apache2/sites-enabled/000-default.conf
 
 # Configure git-http-backend
 COPY git-https-backend.conf /etc/apache2/sites-available/
-RUN ln -s \
-  /etc/apache2/sites-available/git-https-backend.conf \
-  /etc/apache2/sites-enabled/git-https-backend.conf
 COPY git-http-backend.conf /etc/apache2/sites-available/
 RUN ln -s \
-  /etc/apache2/sites-available/git-http-backend.conf \
-  /etc/apache2/sites-enabled/git-http-backend.conf
-RUN sed -i -e 's/APACHE_RUN_USER=www-data/APACHE_RUN_USER=gerrit/' /etc/apache2/envvars
-RUN sed -i -e 's/APACHE_RUN_GROUP=www-data/APACHE_RUN_GROUP=users/' /etc/apache2/envvars
+      /etc/apache2/sites-available/git-https-backend.conf \
+      /etc/apache2/sites-enabled/git-https-backend.conf && \
+    ln -s \
+      /etc/apache2/sites-available/git-http-backend.conf \
+      /etc/apache2/sites-enabled/git-http-backend.conf
+RUN sed -i -e 's/APACHE_RUN_USER=www-data/APACHE_RUN_USER=gerrit/' /etc/apache2/envvars && \
+    sed -i -e 's/APACHE_RUN_GROUP=www-data/APACHE_RUN_GROUP=users/' /etc/apache2/envvars
 
 COPY tools/* /var/tools/
 COPY tools/create_repo.sh /var/cgi/create_repo.sh
-RUN rm -f /etc/apache2/sites-enabled/000-default.conf
 
 # Allow incoming traffic
 EXPOSE 80
diff --git a/container-images/base/Dockerfile b/container-images/base/Dockerfile
index d08e8b3..3e43e6f 100644
--- a/container-images/base/Dockerfile
+++ b/container-images/base/Dockerfile
@@ -1,9 +1,11 @@
 FROM ubuntu:18.04
 
-RUN apt-get update
-RUN apt-get -y install git
+RUN apt-get update && \
+    apt-get -y install \
+      git \
+      openssh-client \
+      sudo && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/*
 
-# Allow remote connectivity and sudo
-RUN apt-get -y install openssh-client sudo
-
-COPY tools/* /var/tools/
\ No newline at end of file
+COPY tools/* /var/tools/
diff --git a/container-images/gerrit-base/Dockerfile b/container-images/gerrit-base/Dockerfile
index 9eb60fc..a8c682c 100644
--- a/container-images/gerrit-base/Dockerfile
+++ b/container-images/gerrit-base/Dockerfile
@@ -1,10 +1,16 @@
 FROM base:latest
 
-RUN apt-get update && apt-get -y install curl unzip openjdk-8-jdk
+RUN apt-get update && \
+    apt-get -y install \
+      curl \
+      unzip \
+      openjdk-8-jdk && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/*
 
-RUN mkdir -p /var/gerrit/bin
-RUN mkdir -p /var/gerrit/etc
-RUN mkdir -p /var/war
+RUN mkdir -p /var/gerrit/bin && \
+    mkdir -p /var/gerrit/etc && \
+    mkdir -p /var/war
 
 # Download Gerrit release
 ARG GERRIT_WAR_URL=https://gerrit-ci.gerritforge.com/view/Gerrit/job/Gerrit-bazel-stable-2.16/lastSuccessfulBuild/artifact/gerrit/bazel-bin/release.war
@@ -16,8 +22,8 @@
 # Allow incoming traffic
 EXPOSE 29418 8080
 
-RUN chown -R gerrit:users /var/gerrit
-RUN chown -R gerrit:users /var/war
+RUN chown -R gerrit:users /var/gerrit && \
+    chown -R gerrit:users /var/war
 USER gerrit
 
 ENTRYPOINT ["/bin/bash", "/var/tools/start"]
diff --git a/container-images/gerrit-slave/Dockerfile b/container-images/gerrit-slave/Dockerfile
index b63038a..b89f302 100644
--- a/container-images/gerrit-slave/Dockerfile
+++ b/container-images/gerrit-slave/Dockerfile
@@ -1,11 +1,13 @@
 FROM gerrit-base:latest
 
-RUN java -jar /var/gerrit/bin/gerrit.war init --batch --no-auto-start --install-plugin singleusergroup -d /var/gerrit
-
 COPY tools/* /var/tools/
 
-# Install MySQL driver for Gerrit
-
-RUN /var/tools/download_db_driver
-
-RUN git config -f /var/gerrit/etc/gerrit.config container.slave true
+# Initialize Gerrit site, install MySQL driver for Gerrit and configure Gerrit
+# as slave
+RUN java -jar /var/gerrit/bin/gerrit.war init \
+      --batch \
+      --no-auto-start \
+      --install-plugin singleusergroup \
+      -d /var/gerrit && \
+    /var/tools/download_db_driver && \
+    git config -f /var/gerrit/etc/gerrit.config container.slave true
diff --git a/container-images/git-gc/Dockerfile b/container-images/git-gc/Dockerfile
index 18790b1..e92bec8 100644
--- a/container-images/git-gc/Dockerfile
+++ b/container-images/git-gc/Dockerfile
@@ -1,16 +1,19 @@
 FROM base:latest
 
 # Install cron
-RUN apt-get update
-RUN apt-get -y install cron
+RUN apt-get update && \
+    apt-get -y install \
+      cron && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/*
 
 COPY tools/* /var/tools/
 COPY cron/* /var/cron/
-RUN mkdir -p /var/log/git
 
 ARG GERRIT_UID=1000
-RUN useradd gerrit -u $GERRIT_UID -g users
-RUN chown gerrit:users /var/log/git
+RUN useradd gerrit -u $GERRIT_UID -g users && \
+    mkdir -p /var/log/git && \
+    chown gerrit:users /var/log/git
 
 VOLUME ["/var/gerrit/git"]
 
diff --git a/container-images/mysql-replication-init/Dockerfile b/container-images/mysql-replication-init/Dockerfile
index 5d0f8f3..b68d2be 100644
--- a/container-images/mysql-replication-init/Dockerfile
+++ b/container-images/mysql-replication-init/Dockerfile
@@ -1,7 +1,11 @@
 FROM ubuntu:18.04
 
-RUN apt-get update && apt-get install -y mysql-client
+RUN apt-get update && \
+    apt-get install -y \
+      mysql-client && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/*
 
 COPY tools/* /var/tools/
 
-ENTRYPOINT ["/bin/bash", "/var/tools/start"]
\ No newline at end of file
+ENTRYPOINT ["/bin/bash", "/var/tools/start"]