Add scripts to renew certs with certbot
This commit is contained in:
parent
707695d631
commit
cd24eacee4
11
README.md
11
README.md
@ -85,11 +85,11 @@ PORTAINER_PASSWORD=
|
|||||||
AI_OPENAI_API_KEY=
|
AI_OPENAI_API_KEY=
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Edit GoTrue Dockerfile
|
3. Edit GoTrue Dockerfile (Not needed on latest version)
|
||||||
|
|
||||||
Modify the base Dockerfile from the Appflowy-Cloud repo to the one in this repo that installs bash, so the healthcheck can run.
|
Modify the base Dockerfile from the Appflowy-Cloud repo to the one in this repo that installs bash, so the healthcheck can run.
|
||||||
|
|
||||||
4. Edit nginx.conf
|
4. Edit nginx.conf (Not needed on latest version)
|
||||||
|
|
||||||
Modify the base nginx.conf to the version in this repo to resolve a potential websocket DNS resolution issue.
|
Modify the base nginx.conf to the version in this repo to resolve a potential websocket DNS resolution issue.
|
||||||
|
|
||||||
@ -140,13 +140,14 @@ docker-compose up -d
|
|||||||
10. Set up auto renewal for the certificates with cron job:
|
10. Set up auto renewal for the certificates with cron job:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo crontab -e
|
crontab -e
|
||||||
```
|
```
|
||||||
Add this line to run the renewal daily (it will only renew if necessary):
|
Add this line to run the renewal every month on the 1st day at 2:00 AM:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
0 3 * * * certbot renew --quiet --deploy-hook "docker-compose restart nginx"
|
0 2 1 * * /home/moeny/AppFlowy-Cloud/check-and-renew-certs.sh >> /var/log/cert-renewal.log 2>&1
|
||||||
```
|
```
|
||||||
|
You will need to add [check-and-renew-certs.sh](check-and-renew-certs.sh) and [renew-certs.sh](renew-certs.sh) in the `AppFlowy-Cloud` directory.
|
||||||
|
|
||||||
## Additional considerations
|
## Additional considerations
|
||||||
|
|
||||||
|
49
check-and-renew-certs.sh
Normal file
49
check-and-renew-certs.sh
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Run this script with a cron job every month on the 1st day at 2:00 AM
|
||||||
|
# crontab -e
|
||||||
|
# 0 2 1 * * /home/moeny/AppFlowy-Cloud/check-and-renew-certs.sh >> /var/log/cert-renewal.log 2>&1
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
COMPOSE_FILE="/home/moeny/AppFlowy-Cloud/docker-compose.yml"
|
||||||
|
DEPLOY_TRIGGER="/etc/letsencrypt/deploy-hook-triggered"
|
||||||
|
|
||||||
|
# Ensure we're in the right directory
|
||||||
|
cd "$(dirname "$COMPOSE_FILE")"
|
||||||
|
|
||||||
|
# Set environment variables to ensure non-interactive operation
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
export PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Run certbot container with explicit non-interactive settings and timeout
|
||||||
|
echo "[$(date)] Starting certificate renewal check..."
|
||||||
|
if timeout --signal=KILL 5m docker compose -f "$COMPOSE_FILE" run --rm \
|
||||||
|
-e TERM=dumb \
|
||||||
|
-e PYTHONUNBUFFERED=1 \
|
||||||
|
--no-TTY \
|
||||||
|
< /dev/null \
|
||||||
|
certbot; then
|
||||||
|
echo "[$(date)] Certbot completed successfully"
|
||||||
|
else
|
||||||
|
exit_code=$?
|
||||||
|
if [ $exit_code -eq 137 ]; then # SIGKILL exit code
|
||||||
|
echo "[$(date)] ERROR: Certbot timed out after 5 minutes, killing container..."
|
||||||
|
# Find and kill any hanging certbot containers
|
||||||
|
docker ps --filter "name=certbot" -q | xargs -r docker kill
|
||||||
|
else
|
||||||
|
echo "[$(date)] ERROR: Certbot failed with exit code $exit_code"
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if certificates were renewed
|
||||||
|
if [ -f "$DEPLOY_TRIGGER" ]; then
|
||||||
|
echo "[$(date)] Certificates were renewed, restarting nginx..."
|
||||||
|
docker compose -f "$COMPOSE_FILE" restart nginx
|
||||||
|
sudo rm "$DEPLOY_TRIGGER"
|
||||||
|
echo "[$(date)] Nginx restarted successfully"
|
||||||
|
else
|
||||||
|
echo "[$(date)] No certificate renewal needed"
|
||||||
|
fi
|
@ -219,6 +219,21 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- AF_BASE_URL=${APPFLOWY_BASE_URL:?err}
|
- AF_BASE_URL=${APPFLOWY_BASE_URL:?err}
|
||||||
- AF_GOTRUE_URL=${API_EXTERNAL_URL}
|
- AF_GOTRUE_URL=${API_EXTERNAL_URL}
|
||||||
|
|
||||||
|
certbot:
|
||||||
|
image: certbot/certbot
|
||||||
|
volumes:
|
||||||
|
- /etc/letsencrypt:/etc/letsencrypt
|
||||||
|
- /var/lib/letsencrypt:/var/lib/letsencrypt
|
||||||
|
- /home/moeny/AppFlowy-Cloud/renew-certs.sh:/renew-certs.sh
|
||||||
|
- /home/moeny/keys/tsig.key:/tsig.key:ro
|
||||||
|
environment:
|
||||||
|
- BIND_SERVER=ns1.moeny.ai
|
||||||
|
- DOMAIN=appflowy.moeny.ai
|
||||||
|
- EMAIL=appflowy-certbot@moeny.ai
|
||||||
|
- TSIG_KEY=/tsig.key
|
||||||
|
entrypoint: sh /renew-certs.sh
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres_data:
|
postgres_data:
|
||||||
minio_data:
|
minio_data:
|
86
renew-certs.sh
Normal file
86
renew-certs.sh
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Install required packages
|
||||||
|
apk add --no-cache bind-tools
|
||||||
|
|
||||||
|
# Use environment variables with fallbacks
|
||||||
|
DOMAIN=${DOMAIN:-"appflowy.moeny.ai"}
|
||||||
|
EMAIL=${EMAIL:-"appflowy-certbot@moeny.ai"}
|
||||||
|
BIND_SERVER=${BIND_SERVER:-"ns1.moeny.ai"}
|
||||||
|
TSIG_KEY=${TSIG_KEY:-"/tsig.key"} # This will be the path inside the container
|
||||||
|
CERTBOT_DIR="/etc/letsencrypt"
|
||||||
|
|
||||||
|
# Create the auth script with embedded functions
|
||||||
|
cat > /tmp/auth.sh << 'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Function to add DNS challenge record
|
||||||
|
domain="$CERTBOT_DOMAIN"
|
||||||
|
token="$CERTBOT_VALIDATION"
|
||||||
|
|
||||||
|
echo "Adding DNS challenge for $domain with token $token"
|
||||||
|
nsupdate -k "/tsig.key" << NSUPDATE
|
||||||
|
server $BIND_SERVER
|
||||||
|
update add _acme-challenge.$domain. 300 IN TXT "$token"
|
||||||
|
send
|
||||||
|
NSUPDATE
|
||||||
|
|
||||||
|
# Wait for DNS propagation
|
||||||
|
echo "Waiting 30 seconds for DNS propagation..."
|
||||||
|
sleep 30
|
||||||
|
|
||||||
|
# Verify the record
|
||||||
|
echo "Verifying DNS record..."
|
||||||
|
if dig +short @$BIND_SERVER TXT _acme-challenge.$domain | grep -q "$token"; then
|
||||||
|
echo "DNS challenge record verified successfully"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "ERROR: DNS challenge record not found or incorrect"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
chmod +x /tmp/auth.sh
|
||||||
|
|
||||||
|
# Create cleanup script with embedded function
|
||||||
|
cat > /tmp/cleanup.sh << 'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
domain="$CERTBOT_DOMAIN"
|
||||||
|
echo "Removing DNS challenge for $domain"
|
||||||
|
nsupdate -k "/tsig.key" << NSUPDATE
|
||||||
|
server $BIND_SERVER
|
||||||
|
update delete _acme-challenge.$domain. TXT
|
||||||
|
send
|
||||||
|
NSUPDATE
|
||||||
|
EOF
|
||||||
|
chmod +x /tmp/cleanup.sh
|
||||||
|
|
||||||
|
# Check if certificate already exists
|
||||||
|
if [ -d "/etc/letsencrypt/live/$DOMAIN" ]; then
|
||||||
|
echo "Certificate exists, attempting renewal..."
|
||||||
|
certbot renew \
|
||||||
|
--manual \
|
||||||
|
--preferred-challenges dns \
|
||||||
|
--manual-auth-hook /tmp/auth.sh \
|
||||||
|
--manual-cleanup-hook /tmp/cleanup.sh \
|
||||||
|
--deploy-hook "touch /etc/letsencrypt/deploy-hook-triggered" \
|
||||||
|
--force-renewal
|
||||||
|
else
|
||||||
|
echo "No certificate found, performing initial certificate request..."
|
||||||
|
certbot certonly \
|
||||||
|
--manual \
|
||||||
|
--preferred-challenges dns \
|
||||||
|
--manual-auth-hook /tmp/auth.sh \
|
||||||
|
--manual-cleanup-hook /tmp/cleanup.sh \
|
||||||
|
--deploy-hook "touch /etc/letsencrypt/deploy-hook-triggered" \
|
||||||
|
-d "$DOMAIN" \
|
||||||
|
--email "$EMAIL" \
|
||||||
|
--agree-tos \
|
||||||
|
--non-interactive
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean up temporary scripts
|
||||||
|
rm -f /tmp/auth.sh /tmp/cleanup.sh
|
||||||
|
|
||||||
|
echo "Certificate operation completed. Check /etc/letsencrypt/deploy-hook-triggered for successful deployment."
|
Loading…
Reference in New Issue
Block a user