Caddy & Python Flask
Download Caddy
curl -L "https://caddyserver.com/api/download?os=linux&arch=amd64" -o /tmp/caddy
sudo chown root:root /tmp/caddy
sudo chmod +x /tmp/caddy
sudo mv /tmp/caddy /usr/local/bin/caddy
Or if you want to use systemd service in production on Debian https://caddyserver.com/docs/install#debian-ubuntu-raspbian
Run Caddy
sudo caddy reverse-proxy --from example.com --to 127.0.0.1:5000
The ACME Success Checklist
Caddy's auto-HTTPS is fully automatic, but the ACME Let's Encrypt challenge will strictly fail if the following environmental conditions are not met before you hit Enter:
- DNS A Record:
example.commust be publicly registered and its DNSArecord must point to the public IP address of the server running Caddy. - Open Ports: Ports
80and443must be open on your server's firewall and accessible from the public internet. - Root Privileges: You generally must run Caddy with
sudo(or as root) because non-root users are restricted from binding to privileged system ports (anything under port 1024, which includes 80 and 443).
When you run the command, Caddy will automatically generate a private key, solve the HTTP-01 challenge on port 80, download the certificate, and start serving your Flask app securely on port 443.
More on Let's Encrypt https://letsencrypt.org/getting-started/
sudo apt update
sudo apt install python3-venv python3-pip -y
mkdir app
cd app
python3 -m venv .venv
source .venv/bin/activate
pip install Flask Authlib requests certifi cryptography
nano app.py
import os
from flask import Flask, url_for, session, redirect
from authlib.integrations.flask_client import OAuth
app = Flask(__name__)
app.secret_key = os.urandom(24)
app.config.update(
GOOGLE_CLIENT_ID='YOUR_GOOGLE_CLIENT_ID',
GOOGLE_CLIENT_SECRET='YOUR_GOOGLE_CLIENT_SECRET'
)
oauth = OAuth(app)
google = oauth.register(
name='google',
server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
client_kwargs={'scope': 'openid email profile'}
)
@app.route('/')
def index():
user = session.get('user')
if user:
return f"Hello, {user.get('email')}. <br><a href='/logout'>Logout</a>"
return '<a href="/login">Login with Google</a>'
@app.route('/login')
def login():
redirect_uri = url_for('auth', _external=True)
return google.authorize_redirect(redirect_uri)
@app.route('/auth')
def auth():
token = google.authorize_access_token()
user = token.get('userinfo')
session['user'] = user
return redirect('/')
@app.route('/logout')
def logout():
session.pop('user', None)
return redirect('/')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
python3 app.py
Now if your DNS is setup to point the the correct ip address, and if TCP 443 is exposed this should work.
For containerized deployments you can use:
https://docs.docker.com/compose/
https://docs.docker.com/reference/samples/flask/
https://github.com/caddyserver/ingress
and deploy your app via a deploy in Kubernetes using a helm chart. See https://helm.sh/docs/chart_template_guide/getting_started/.
This is a simple example of how applications work. Sadly, many software developers or Cloud Engineers can't do this as they have very little understanding of how the Internet & interconnected systems work beyond cloud UI button clicking. As you can see it's not that difficult. Our example of minimalistic code makes it easy to see how simple.
Curious about the OSI Model check out:
https://www.cloudflare.com/learning/ddos/glossary/open-systems-interconnection-model-osi/
https://en.wikipedia.org/wiki/OSI_model
More Notes
Why use package manager?
The absolute safest way to install software like Caddy is through your operating system's official package manager (like apt, dnf, or pacman) using Caddy's official repository.
Using a package manager is superior because:
- Cryptographic Verification: It automatically checks GPG signatures to guarantee the binary hasn't been tampered with.
- Automated Updates: You receive security patches through your normal system update routine rather than having to manually
curlthe binary again. - System Integration: It automatically configures the necessary systemd services, dedicated users, and proper folder permissions (like
/etc/caddyand/var/lib/caddy).
