diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..d4ed5894e9b759f546e411d4ca8748f4c46715a5
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,6 @@
+.bloop/
+.idea/
+.settings/
+project/project/
+project/target/
+target/
diff --git a/.scalafmt.conf b/.scalafmt.conf
new file mode 100644
index 0000000000000000000000000000000000000000..1004936b4172590e670c160b8a4881754974417c
--- /dev/null
+++ b/.scalafmt.conf
@@ -0,0 +1,9 @@
+style = defaultWithAlign
+
+danglingParentheses        = true
+indentOperator             = spray
+maxColumn                  = 100
+project.excludeFilters     = [".*\\.sbt"]
+rewrite.rules              = [AsciiSortImports, RedundantBraces, RedundantParens]
+spaces.inImportCurlyBraces = true
+unindentTopLevelOperators  = false
diff --git a/Dockerfile b/Dockerfile
index a163ccbfc926a4c8f56c866cdb78727b3e528b1e..27b59336b1552b0100b0aced6a27c79248fbedeb 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -13,7 +13,14 @@ RUN cp /usr/share/maven/ref/settings-docker.xml /root/.m2/settings.xml \
     && mvn clean package
 
 FROM hbpmip/java-base:11.0.1-1
-MAINTAINER Mirco Nasuti <mirco.nasuti@chuv.ch>
+
+RUN apt-get update && apt-get install -y --no-install-recommends curl \
+    && rm -rf /var/lib/apt/lists/* /tmp/*
+
+COPY docker/config/application.tmpl /config/application.tmpl
+COPY docker/README.md docker/run.sh /
+
+COPY --from=java-build-env /project/target/portal-backend.jar /usr/share/jars/
 
 ARG BUILD_DATE
 ARG VCS_REF
@@ -26,14 +33,6 @@ ENV APP_NAME="Portal backend" \
     CONTEXT_PATH="/services" \
     BUGSNAG_KEY="dff301aa15eb795a6d8b22b600586f77"
 
-RUN apt-get update && apt-get install -y --no-install-recommends curl \
-    && rm -rf /var/lib/apt/lists/* /tmp/*
-
-COPY docker/config/application.tmpl /config/application.tmpl
-COPY docker/README.md docker/run.sh /
-
-COPY --from=java-build-env /project/target/portal-backend.jar /usr/share/jars/
-
 ENTRYPOINT ["/run.sh"]
 
 # 8080: Web service API, health checks on http://host:8080$CONTEXT_PATH/health
diff --git a/LICENSE b/LICENSE
index 3f6f8acee18a45d9ae755cf36ca43429b793c3bd..e7feb41710f16bb1a4635d25da2c339488e9c9d7 100644
--- a/LICENSE
+++ b/LICENSE
@@ -15,21 +15,21 @@ circumstances otherwise permitted by law or as expressly set out in this License
                     GNU AFFERO GENERAL PUBLIC LICENSE
                        Version 3, 19 November 2007
 
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
                             Preamble
 
-  The GNU Affero General Public License is a free, copyleft license
-for software and other kinds of works, specifically designed to ensure
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
 cooperation with the community in the case of network server software.
 
-  The licenses for most software and other practical works are
-designed to take away your freedom to share and change the works.  By
-contrast, our General Public Licenses are intended to guarantee your
-freedom to share and change all versions of a program--to make sure it
-remains free software for all its users.
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
 
   When we speak of free software, we are referring to freedom, not
 price.  Our General Public Licenses are designed to make sure that you
@@ -74,11 +74,10 @@ modification follow.
 
   0. Definitions.
 
-  "This License" refers to version 3 of the GNU Affero General Public
-License.
+  "This License" refers to version 3 of the GNU Affero General Public License.
 
-  "Copyright" also means copyright-like laws that apply to other kinds
-of works, such as semiconductor masks.
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
 
   "The Program" refers to any copyrightable work licensed under this
 License.  Each licensee is addressed as "you".  "Licensees" and
@@ -391,12 +390,12 @@ that material) supplement the terms of this License with terms:
   All other non-permissive additional terms are considered "further
 restrictions" within the meaning of section 10.  If the Program as you
 received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further restriction,
-you may remove that term.  If a license document contains a further
-restriction but permits relicensing or conveying under this License, you
-may add to a covered work material governed by the terms of that license
-document, provided that the further restriction does not survive such
-relicensing or conveying.
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
 
   If you add terms to a covered work in accord with this section, you
 must place, in the relevant source files, a statement of the
@@ -565,34 +564,34 @@ shall include the Corresponding Source for any work covered by version 3
 of the GNU General Public License that is incorporated pursuant to the
 following paragraph.
 
-  Notwithstanding any other provision of this License, you have permission
-to link or combine any covered work with a work licensed under version 3
-of the GNU General Public License into a single combined work, and to
-convey the resulting work.  The terms of this License will continue to
-apply to the part which is the covered work, but the work with which it is
-combined will remain governed by version 3 of the GNU General Public
-License.
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
 
   14. Revised Versions of this License.
 
   The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time.  Such new
-versions will be similar in spirit to the present version, but may differ
-in detail to address new problems or concerns.
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
 
   Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU Affero
-General Public License "or any later version" applies to it, you have
-the option of following the terms and conditions either of that
-numbered version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number
-of the GNU Affero General Public License, you may choose any version
-ever published by the Free Software Foundation.
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
 
   If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that
-proxy's public statement of acceptance of a version permanently
-authorizes you to choose that version for the Program.
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
 
   Later license versions may give you additional or different
 permissions.  However, no additional obligations are imposed on any
@@ -631,9 +630,9 @@ an absolute waiver of all civil liability in connection with the
 Program, unless a warranty or assumption of liability accompanies a
 copy of the Program in return for a fee.
 
-                       END OF TERMS AND CONDITIONS
+                     END OF TERMS AND CONDITIONS
 
-              How to Apply These Terms to Your New Programs
+            How to Apply These Terms to Your New Programs
 
   If you develop a new program, and you want it to be of the greatest
 possible use to the public, the best way to achieve this is to make it
@@ -648,9 +647,9 @@ the "copyright" line and a pointer to where the full notice is found.
     Copyright (C) <year>  <name of author>
 
     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.
+    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
@@ -658,7 +657,7 @@ the "copyright" line and a pointer to where the full notice is found.
     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 <http://www.gnu.org/licenses/>.
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 Also add information on how to contact you by electronic and paper mail.
 
@@ -673,4 +672,4 @@ specific requirements.
   You should also get your employer (if you work as a programmer) or school,
 if any, to sign a "copyright disclaimer" for the program, if necessary.
 For more information on this, and how to apply and follow the GNU AGPL, see
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
diff --git a/after-git-clone.sh b/after-git-clone.sh
index 2f72056fbb086ecc2eed4821809a8e66795f6917..9495dadda1b43d0517160df51bfd985d306c6828 100755
--- a/after-git-clone.sh
+++ b/after-git-clone.sh
@@ -1,3 +1,3 @@
 #!/bin/sh
 
-pre-commit install
+[ -x /usr/local/bin/pre-commit ] && pre-commit install
diff --git a/after-update.sh b/after-update.sh
index 2f72056fbb086ecc2eed4821809a8e66795f6917..9495dadda1b43d0517160df51bfd985d306c6828 100755
--- a/after-update.sh
+++ b/after-update.sh
@@ -1,3 +1,3 @@
 #!/bin/sh
 
-pre-commit install
+[ -x /usr/local/bin/pre-commit ] && pre-commit install
diff --git a/build.sh b/build.sh
index 3a35bac2bf4f9066a99427cfad86ddd2d8db1e29..beb4b5d032cd389c1e2aa43e740ab4906390577a 100755
--- a/build.sh
+++ b/build.sh
@@ -18,20 +18,21 @@ get_script_dir () {
 
 cd "$(get_script_dir)"
 
-if pgrep -lf sshuttle > /dev/null ; then
-  echo "sshuttle detected. Please close this program as it messes with networking and prevents builds inside Docker to work"
-  exit 1
-fi
-
 if [[ $NO_SUDO || -n "$CIRCLECI" ]]; then
-  CAPTAIN="captain"
+  DOCKER="docker"
 elif groups $USER | grep &>/dev/null '\bdocker\b'; then
-  CAPTAIN="captain"
+  DOCKER="docker"
 else
-  CAPTAIN="sudo captain"
+  DOCKER="sudo docker"
 fi
 
-BUILD_DATE=$(date -Iseconds) \
-  VCS_REF=$(git describe --tags --dirty) \
-  VERSION=$(git describe --tags --dirty) \
-  $CAPTAIN build
+IMAGE="hbpmip/portal-backend"
+VCS_REF=$(git describe --tags --dirty)
+VERSION=$(git describe --tags --dirty)
+
+docker build --build-arg BUILD_DATE=$(date -Iseconds) \
+    --build-arg VCS_REF=$VCS_REF \
+    --build-arg VERSION=$VERSION \
+    --tag "$IMAGE:latest" \
+    --tag "$IMAGE:$VERSION" \
+    .
diff --git a/captain.yml b/captain.yml
deleted file mode 100644
index df758b1cd462746759226f05a855f42c3efdcda6..0000000000000000000000000000000000000000
--- a/captain.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-target_image:
-  build: Dockerfile
-  image: hbpmip/portal-backend
-  pre:
-    - echo "Building portal-backend image"
-  post:
-    - echo "Finished building portal-backend image"
-  test:
-    - ./tests/test.sh
diff --git a/publish.sh b/publish.sh
index b84e4aa7c229d9b027b79f1d858ebcdb2266ba9c..7e9394bef8f6f9f74c52bfc7a43c572af5ad29f1 100755
--- a/publish.sh
+++ b/publish.sh
@@ -1,5 +1,12 @@
 #!/usr/bin/env bash
 
+#
+# Build the release image for the project and publish it on Dockerhub, then
+# announce the new version on Slack
+#
+# Option:
+#   --no-tests: skip the test suite
+
 set -o pipefail  # trace ERR through pipes
 set -o errtrace  # trace ERR through 'time command' and other functions
 set -o errexit   ## set -e : exit the script if any statement returns a non-true return value
@@ -24,17 +31,29 @@ if pgrep -lf sshuttle > /dev/null ; then
 fi
 
 if [ $NO_SUDO ]; then
-  CAPTAIN="captain"
-elif groups $USER | grep &>/dev/null '\bdocker\b'; then
-  CAPTAIN="captain"
+  DOCKER="docker"
+elif groups "$USER" | grep &>/dev/null '\bdocker\b'; then
+  DOCKER="docker"
 else
-  CAPTAIN="sudo captain"
+  DOCKER="sudo docker"
 fi
 
+# No integration tests defined for this project yet
+tests=0
+for param in "$@"
+do
+  if [ "--no-tests" == "$param" ]; then
+    tests=0
+    echo "INFO: --no-tests option detected !"
+  fi
+done
+
 # Build
 echo "Build the project..."
 ./build.sh
-#./tests/test.sh
+if [ $tests == 1 ]; then
+  ./tests/test.sh
+fi
 echo "[ok] Done"
 
 count=$(git status --porcelain | wc -l)
@@ -65,7 +84,7 @@ select_part() {
 
 git pull --tags
 # Look for a version tag in Git. If not found, ask the user to provide one
-[ $(git tag --points-at HEAD | grep portal-backend | wc -l) == 1 ] || (
+[ $(git tag --points-at HEAD | wc -l) == 1 ] || (
   latest_version=$(bumpversion --dry-run --list patch | grep current_version | sed -r s,"^.*=",, || echo '0.0.1')
   echo
   echo "Current commit has not been tagged with a version. Latest known version is $latest_version."
@@ -91,19 +110,21 @@ updated_version=$(bumpversion --dry-run --list patch | grep current_version | se
 # Build again to update the version
 echo "Build the project for distribution..."
 ./build.sh
-#./tests/test.sh
+if [ $tests == 1 ]; then
+  ./tests/test.sh
+fi
+echo "[ok] Done"
+
+# Push on Docker Hub
+echo
+echo "Publishing..."
+IMAGE=hbpmip/portal-backend
+$DOCKER push "$IMAGE:latest"
+$DOCKER push "$IMAGE:$updated_version"
 
 git push
 git push --tags
 
-# Push on Docker Hub
-#  WARNING: Requires captain 1.1.0 to push user tags
-BUILD_DATE=$(date -Iseconds) \
-  VCS_REF=$updated_version \
-  VERSION=$updated_version \
-  WORKSPACE=$WORKSPACE \
-  $CAPTAIN push target_image --branch-tags=false --commit-tags=false --tag $updated_version
-
 # Notify on slack
 sed "s/USER/${USER^}/" $WORKSPACE/slack.json > $WORKSPACE/.slack.json
 sed -i.bak "s/VERSION/$updated_version/" $WORKSPACE/.slack.json