如何在CloudFoundry上通过HTTPS运行Gunicorn部署Django并解决SSL错误
Hey there, let's break down how to fix this SSL warning and get your Django app running smoothly on Cloud Foundry with Gunicorn over HTTPS on port 443.
That warning pops up because your application (or a library it uses, like requests) is making an HTTPS request without verifying the server's SSL certificate. This triggers a security red flag, and in some cases, it can lead to internal server errors (500s) because your app isn't handling the insecure connection properly.
On Cloud Foundry, the routing layer usually handles SSL termination (meaning external HTTPS requests are decrypted before reaching your app), but if your app makes internal HTTPS calls (e.g., to its own API endpoints or external services), you need to ensure those requests validate certificates correctly.
Let's demystify these two files:
server.key: This is your private key file, part of an encrypted key pair. It's used to decrypt data sent by clients over HTTPS and must be kept secure (never commit it to public version control!).server.cert: This is your public SSL certificate, signed by a Certificate Authority (CA) like Let's Encrypt. It contains your public key and domain identity information, so clients can verify that they're connecting to the legitimate server.
In most Cloud Foundry setups, you won't need to pass these directly to Gunicorn (since CF handles SSL termination), but if you have a specific use case where Gunicorn needs to handle SSL directly, you'll need them.
We'll cover two approaches—start with the recommended one first.
Option 1: Use Cloud Foundry's Built-in SSL Termination (Best Practice)
CF's routing layer is designed to handle SSL, so your app can listen on a regular HTTP port (like 8000) and let CF handle the HTTPS encryption/decryption. Here's how to fix the warning and secure your app:
- Tell Django it's behind an HTTPS proxy: Add this to your
settings.py:
This lets Django know that incoming requests are actually HTTPS, even though they reach your app as HTTP.SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') - Fix internal HTTPS request validation: If your app uses
requeststo make HTTPS calls, set theREQUESTS_CA_BUNDLEenvironment variable in yourmanifest.ymlto point to the system CA certificate bundle (which exists in CF containers by default):
This ensures allapplications: - name: your-app-name env: REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt # ... other environment variablesrequestscalls automatically validate SSL certificates using trusted CA roots.
Option 2: Configure Gunicorn to Handle SSL Directly (For Special Cases)
If you need Gunicorn to terminate SSL itself (e.g., bypassing CF's routing layer), follow these steps:
Step 1: Obtain Your SSL Cert & Key
- Get a valid SSL certificate for your domain from a CA (Let's Encrypt is free and widely used). You'll receive
server.cert(with the full certificate chain) andserver.key(your private key). - Make sure
server.keyisn't password-protected—Gunicorn can't handle encrypted private keys.
Step 2: Add the Files to Cloud Foundry Securely
Never commit sensitive cert/key files to Git. Instead, use a User-Provided Service to store them:
- Run this command in your terminal (replace paths to your files):
cf create-user-provided-service ssl-credentials -p '{"server_cert":"$(cat path/to/server.cert)","server_key":"$(cat path/to/server.key)"}' - Bind this service to your app in
manifest.yml:applications: - name: your-app-name services: - ssl-credentials # ... other app configs
Step 3: Update Gunicorn's Start Command
Modify your Procfile to pull the cert/key from the service and start Gunicorn with SSL:
web: gunicorn --bind 0.0.0.0:443 \ --certfile <(echo "$VCAP_SERVICES" | jq -r '.["user-provided"][0].credentials.server_cert') \ --keyfile <(echo "$VCAP_SERVICES" | jq -r '.["user-provided"][0].credentials.server_key') \ your_project.wsgi:application
Note: Ensure your Cloud Foundry environment allows apps to listen on port 443—some setups restrict this, which is why Option 1 is preferred.
- Verify that all internal HTTPS requests in your app are using certificate validation (avoid setting
verify=Falseinrequestscalls—it's unsafe!). - If you're using Django's
securesettings, make sureSECURE_SSL_REDIRECTis set toTrue(but only if you're using Option 1, since CF handles the redirect).
内容的提问来源于stack exchange,提问作者richa verma

