#!/bin/sh set -eu # Deploy renewed TLS material into a compose project's certs volume and # restart the services that consume it. # # Usage: script.sh # # Requires $compose_cmd: the compose wrapper base command, quoted as needed, # e.g. compose_cmd="compose --chdir /opt/compose/mailu --project mailu". if [ "$#" -ne 2 ]; then echo "Usage: $0 " >&2 exit 1 fi ssl_cert_source_dir="$1" docker_compose_instance_directory="$2" : "${compose_cmd:=}" if [ -z "$compose_cmd" ]; then echo "ERROR: compose_cmd is not set. It must point to the compose wrapper base command." >&2 echo "Example: compose_cmd='compose --chdir --project '" >&2 exit 1 fi docker_compose_cert_directory="${docker_compose_instance_directory%/}/volumes/certs" if [ ! -d "$ssl_cert_source_dir" ]; then echo "ERROR: ssl_cert_source_dir does not exist or is not a directory: $ssl_cert_source_dir" >&2 exit 1 fi if [ ! -d "$docker_compose_cert_directory" ]; then echo "Creating certs directory: $docker_compose_cert_directory" mkdir -p "$docker_compose_cert_directory" fi echo "Copying certificates from: $ssl_cert_source_dir -> $docker_compose_cert_directory" cp -RvL "${ssl_cert_source_dir}/"* "$docker_compose_cert_directory" if [ -f "${ssl_cert_source_dir}/privkey.pem" ] && [ -f "${ssl_cert_source_dir}/fullchain.pem" ]; then cp -v "${ssl_cert_source_dir}/privkey.pem" "${docker_compose_cert_directory}/key.pem" cp -v "${ssl_cert_source_dir}/fullchain.pem" "${docker_compose_cert_directory}/cert.pem" elif [ -f "${ssl_cert_source_dir}/key.pem" ] && [ -f "${ssl_cert_source_dir}/cert.pem" ]; then cp -v "${ssl_cert_source_dir}/key.pem" "${docker_compose_cert_directory}/key.pem" cp -v "${ssl_cert_source_dir}/cert.pem" "${docker_compose_cert_directory}/cert.pem" else echo "ERROR: Could not determine key/cert mapping for Mailu." >&2 echo "Looked for: privkey.pem+fullchain.pem OR key.pem+cert.pem in: $ssl_cert_source_dir" >&2 exit 1 fi chmod a+r -v "${docker_compose_cert_directory}/"* || exit 1 cd "$docker_compose_instance_directory" || exit 1 services="$(sh -c "$compose_cmd -- ps --services")" restart_services="" for service in $services; do echo "Checking service: $service" container_id="$(sh -c "$compose_cmd -- ps -q \"$service\"" | head -n1)" if [ -z "$container_id" ]; then echo "No running container for service: $service, skipping." continue fi if docker inspect --type container "$container_id" \ --format '{{range .Mounts}}{{println .Source}}{{end}}' \ | grep -qx "$docker_compose_cert_directory"; then echo "Certificate mount found in service: $service" restart_services="$restart_services $service" else echo "No certificate mount in service: $service, skipping." fi done if [ -n "$(echo "$restart_services" | tr -d ' ')" ]; then echo "Restarting certificate-consuming services to apply new certificates:${restart_services}" # shellcheck disable=SC2086 sh -c "$compose_cmd -- restart $restart_services" || exit 1 else echo "No certificate-consuming services found. Nothing to restart." fi