Public
Snippet $27467 authored by Ariel Barreiro

Quick notes on setting up letsencrypt automatic renewal on a platform.sh app container

Edited
Platofrmsh-and-letsencrypt.md

Define useful mounts for the rest to work nicely

# The mounts that will be performed when the package is deployed.
mounts:
    "/public/.well-known": "shared:files/.well-known"
    "/keys": "shared:files/keys"
    "/.platformsh": "shared:files/.platformsh"

Allow well-known to be accessible

# The configuration of app when it is exposed to the web.
web:
    # Specific parameters for different URL prefixes.
    locations:
        '/.well-known':
            # Allow access to all files in the public files directory.
            allow: true
            expires: 5m
            passthru: false
            root: 'public/.well-known'

            # Do not execute PHP scripts.
            scripts: false

Install lego and platform-cli phar on build the build hooks

# The hooks executed at various points in the lifecycle of the application.
hooks:
    # We run deploy hook after your application has been deployed and started.
    build: |
      mv public/sites/default/scripts ./
      mkdir -p .global/bin
      curl -sL https://github.com/xenolf/lego/releases/download/v0.3.1/lego_linux_amd64.tar.xz | tar -C .global/bin -xJ --strip-components=1 lego/lego
      curl -sfSL -o .global/bin/platform.phar https://github.com/platformsh/platformsh-cli/releases/download/v3.5.0/platform.phar

Add the following to /app/.platformsh/config.yaml

api:
    token_file: token

Configure an API token for the platform-cli on https://accounts.platform.sh/user/xxxx/api-tokens (your platform user account) and add the token to a /app/.platformsh/token file.

You could add these files on build/deploy hook, but I rather don't have the token in the repo.

Request an initial certificate from the instance ssh and install it:

# Create account and renew the certificate
lego --email="support@example.com" --domains="www.example.com" --webroot=/app/public/ --path=/app/keys/ -a run
# Split the certificate from any intermediate chain
csplit -f /app/keys/certificates/www.example.com.crt- /app/keys/certificates/www.example.com.crt '/-----BEGIN CERTIFICATE-----/' '{1}' -z -s
# Update the certificates on the domain
php /app/.global/bin/platform.phar domain:update -p $PLATFORM_PROJECT --no-wait --yes --cert /app/keys/certificates/www.example.com.crt-00 --chain /app/keys/certificates/www.example.com.crt-01 --key /app/keys/certificates/www.example.com.key example.com

Configure a monthly crontab

# The configuration of scheduled execution.
crons:
    letsencrypt:
        spec: '0 0 1 * *'
        cmd: '/bin/sh /app/scripts/letsencrypt.sh'

Make sure letsencrypt.sh is accessible and do something like the following:

#!/usr/bin/env bash
set -e

if [ "$PLATFORM_ENVIRONMENT" = "master" ]
  then
    # Renew the certificate
    lego --email="support@example.com" --domains="www.example.com" --webroot=/app/public/ --path=/app/keys/ -a renew
    # Split the certificate from any intermediate chain
    csplit -f /app/keys/certificates/www.example.com.crt- /app/keys/certificates/www.example.com.crt '/-----BEGIN CERTIFICATE-----/' '{1}' -z -s
    # Update the certificates on the domain
    php /app/.global/bin/platform.phar domain:update -p $PLATFORM_PROJECT --no-wait --yes --cert /app/keys/certificates/www.example.com.crt-00 --chain /app/keys/certificates/www.example.com.crt-01 --key /app/keys/certificates/www.example.com.key example.com
fi