mirror of
https://github.com/zulip/docker-zulip.git
synced 2025-10-24 08:33:47 +00:00
setup: Add certbot support.
The task is to generate a self-signed cert so Zulip can be started, then to wait until Zulip is up before using certbot to generate new certs. Zulip needs to be up so it can meet certbot's challenge. Using a deploy hook, certs are persisted in the data directory. The same applies to renewal. Tweaked by tabbott mostly to edit comments remove an unnecessary setting before merging. Fixes #120.
This commit is contained in:
@@ -84,6 +84,7 @@ RUN apt-get -q dist-upgrade -y && \
|
|||||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
COPY entrypoint.sh /sbin/entrypoint.sh
|
COPY entrypoint.sh /sbin/entrypoint.sh
|
||||||
|
COPY certbot-deploy-hook /sbin/certbot-deploy-hook
|
||||||
|
|
||||||
VOLUME ["$DATA_DIR"]
|
VOLUME ["$DATA_DIR"]
|
||||||
EXPOSE 80 443
|
EXPOSE 80 443
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -168,11 +168,11 @@ which you need to encode in the YAML file. For example,
|
|||||||
comma-separated list of the backend names
|
comma-separated list of the backend names
|
||||||
(E.g. `"EmailAuthBackend,GitHubAuthBackend"`).
|
(E.g. `"EmailAuthBackend,GitHubAuthBackend"`).
|
||||||
|
|
||||||
**SSL Certificates**. By default, the image will generate a
|
**SSL Certificates**. By default, the image will generate a self-signed cert.
|
||||||
self-signed cert. We
|
You can set `SSL_CERTIFICATE_GENERATION: "certbot"` within `docker-compose.yml`
|
||||||
[will soon also support certbot](https://github.com/zulip/docker-zulip/issues/120)
|
to enable automatically-renewed Let's Encrypt certificates. By using certbot
|
||||||
for this, just like we do in normal Zulip installations
|
here, you are agreeing to the [Let's Encrypt
|
||||||
(contributions welcome!).
|
ToS](https://community.letsencrypt.org/tos).
|
||||||
|
|
||||||
You can also provide an SSL certificate for your Zulip server by
|
You can also provide an SSL certificate for your Zulip server by
|
||||||
putting it in `/opt/docker/zulip/zulip/certs/` (by default, the
|
putting it in `/opt/docker/zulip/zulip/certs/` (by default, the
|
||||||
|
|||||||
29
certbot-deploy-hook
Executable file
29
certbot-deploy-hook
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
backup() {
|
||||||
|
if [ -e "$1" ]; then
|
||||||
|
# If the user is setting up our automatic certbot-management on a
|
||||||
|
# system that already has certs for Zulip, use some extra caution
|
||||||
|
# to keep the old certs available. This naming is consistent with Zulip's
|
||||||
|
# own setup-certbot backups.
|
||||||
|
mv -f --backup=numbered "$1" "$1".setup-certbot || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
source_cert_dir=/etc/letsencrypt/live/"$SETTING_EXTERNAL_HOST"
|
||||||
|
dest_cert_dir="$DATA_DIR"/certs
|
||||||
|
|
||||||
|
# Persist the certs to the data directory.
|
||||||
|
backup "$dest_cert_dir"/zulip.key
|
||||||
|
backup "$dest_cert_dir"/zulip.combined-chain.crt
|
||||||
|
cp -f "$source_cert_dir"/privkey.pem "$dest_cert_dir"/zulip.key
|
||||||
|
cp -f "$source_cert_dir"/fullchain.pem "$dest_cert_dir"/zulip.combined-chain.crt
|
||||||
|
|
||||||
|
# Ensure nginx can find them.
|
||||||
|
ln -nsf "$dest_cert_dir"/zulip.key /etc/ssl/private/zulip.key
|
||||||
|
ln -nsf "$dest_cert_dir"/zulip.combined-chain.crt /etc/ssl/certs/zulip.combined-chain.crt
|
||||||
|
|
||||||
|
# Restart various services so the new certs can be used.
|
||||||
|
supervisorctl restart nginx
|
||||||
@@ -168,12 +168,18 @@ configureCerts() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if [ ! -e "$DATA_DIR/certs/zulip.key" ] && [ ! -e "$DATA_DIR/certs/zulip.combined-chain.crt" ]; then
|
if [ ! -e "$DATA_DIR/certs/zulip.key" ] && [ ! -e "$DATA_DIR/certs/zulip.combined-chain.crt" ]; then
|
||||||
|
|
||||||
if [ "$GENERATE_CERTBOT_CERT" = "True" ]; then
|
if [ "$GENERATE_CERTBOT_CERT" = "True" ]; then
|
||||||
echo "Certbot not yet supported"
|
# Zulip isn't yet running, so the certbot's challenge can't be met.
|
||||||
exit 1
|
# We'll schedule this for later.
|
||||||
# TODO: Run setup-certbot and move /etc/letsencrypt to the data dir?
|
echo "Scheduling LetsEncrypt cert generation ..."
|
||||||
# /home/zulip/deployments/current/setup/setup-certbot "$SETTING_EXTERNAL_HOST"
|
GENERATE_CERTBOT_CERT_SCHEDULED=True
|
||||||
elif [ "$GENERATE_SELF_SIGNED_CERT" = "True" ]; then
|
|
||||||
|
# Generate self-signed certs just to get Zulip going.
|
||||||
|
GENERATE_SELF_SIGNED_CERT=True
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$GENERATE_SELF_SIGNED_CERT" = "True" ]; then
|
||||||
echo "Generating self-signed certificates ..."
|
echo "Generating self-signed certificates ..."
|
||||||
mkdir -p "$DATA_DIR/certs"
|
mkdir -p "$DATA_DIR/certs"
|
||||||
/home/zulip/deployments/current/scripts/setup/generate-self-signed-cert "$SETTING_EXTERNAL_HOST"
|
/home/zulip/deployments/current/scripts/setup/generate-self-signed-cert "$SETTING_EXTERNAL_HOST"
|
||||||
@@ -407,12 +413,43 @@ runPostSetupScripts() {
|
|||||||
set -e
|
set -e
|
||||||
echo "Post setup scripts execution succeeded."
|
echo "Post setup scripts execution succeeded."
|
||||||
}
|
}
|
||||||
|
function runCertbotAsNeeded() {
|
||||||
|
if [ ! "$GENERATE_CERTBOT_CERT_SCHEDULED" = "True" ]; then
|
||||||
|
echo "Certbot is not scheduled to run."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Waiting for nginx to come online before generating certbot certificate ..."
|
||||||
|
while ! curl -sk "$SETTING_EXTERNAL_HOST" >/dev/null 2>&1; do
|
||||||
|
sleep 1;
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Generating LetsEncrypt/certbot certificate ..."
|
||||||
|
|
||||||
|
# Remove the self-signed certs which were only needed to get Zulip going.
|
||||||
|
rm -f "$DATA_DIR"/certs/zulip.key "$DATA_DIR"/certs/zulip.combined-chain.crt
|
||||||
|
|
||||||
|
ZULIP_CERTBOT_DEPLOY_HOOK="/sbin/certbot-deploy-hook"
|
||||||
|
|
||||||
|
# Accept the terms of service automatically.
|
||||||
|
/home/zulip/deployments/current/scripts/setup/setup-certbot \
|
||||||
|
--agree-tos \
|
||||||
|
--hostname="$SETTING_EXTERNAL_HOST" \
|
||||||
|
--email="$SETTING_ZULIP_ADMINISTRATOR" \
|
||||||
|
--deploy-hook "$ZULIP_CERTBOT_DEPLOY_HOOK"
|
||||||
|
|
||||||
|
echo "LetsEncrypt cert generated."
|
||||||
|
}
|
||||||
bootstrappingEnvironment() {
|
bootstrappingEnvironment() {
|
||||||
echo "=== Begin Bootstrap Phase ==="
|
echo "=== Begin Bootstrap Phase ==="
|
||||||
waitingForDatabase
|
waitingForDatabase
|
||||||
zulipFirstStartInit
|
zulipFirstStartInit
|
||||||
zulipMigration
|
zulipMigration
|
||||||
runPostSetupScripts
|
runPostSetupScripts
|
||||||
|
# Hack: We run this in the background, since we need nginx to be
|
||||||
|
# started before we can create the certificate. See #142 for
|
||||||
|
# details on how we can clean this up.
|
||||||
|
runCertbotAsNeeded &
|
||||||
echo "=== End Bootstrap Phase ==="
|
echo "=== End Bootstrap Phase ==="
|
||||||
}
|
}
|
||||||
# END appRun functions
|
# END appRun functions
|
||||||
|
|||||||
Reference in New Issue
Block a user