Running Airflow behind a reverse proxy
Airflow can be set up behind a reverse proxy, with the ability to set its endpoint with great flexibility.
For example, you can configure your reverse proxy to get:
https://lab.mycompany.com/myorg/airflow/
To do so, you need to set the following setting in your airflow.cfg:
base_url = http://my_host/myorg/airflow
Configure your reverse proxy (e.g. nginx) to pass the url and http header as it for the Airflow webserver, without any rewrite, for example:
server { listen 80; server_name lab.mycompany.com; location /myorg/airflow/ { proxy_pass http://localhost:8080; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_redirect off; proxy_http_version 1.1; } }Some parts of the UI are rendered inside iframes (Auth managers security links for instance), you need to make sure that you are not setting a restricted CSP for iframe rendering such as
frame-ancestors 'none'. You can set the CSP header in your reverse proxy configuration, for example:add_header Content-Security-Policy "frame-ancestors 'self';";
Use
--proxy-headersCLI flag to tell Uvicorn to respect these headers:airflow api-server --proxy-headersIf your proxy server is not on the same host (or in the same docker container) as Airflow, then you will need to set the
FORWARDED_ALLOW_IPSenvironment variable so Uvicorn knows who to trust this header from. See Uvicorn’s docs. For the full options you can pass here. (Please note the--forwarded-allow-ipsCLI option does not exist in Airflow.)Please make sure your proxy does not enforce http-only status on the Set-Cookie headers. Airflow frontend needs to access the cookies through javascript, and a http-only flag would disturb this functionality.
Helm Chart Configuration
When deploying Airflow using the Helm chart behind a reverse proxy (e.g., nginx ingress), you need to configure the API server to respect proxy headers.
Configure the API server arguments to include the --proxy-headers flag:
apiServer:
args: ["bash", "-c", "exec airflow api-server --proxy-headers"]
If your proxy server is not on the same host as Airflow, set the FORWARDED_ALLOW_IPS environment variable:
apiServer:
args: ["bash", "-c", "exec airflow api-server --proxy-headers"]
env:
- name: FORWARDED_ALLOW_IPS
value: "*" # Use "*" for trusted environments, or specify proxy IP ranges for production
Additionally, configure your ingress annotations to pass the necessary headers. For nginx ingress, add these annotations:
ingress:
apiServer:
enabled: true
annotations:
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
nginx.ingress.kubernetes.io/proxy-redirect-off: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
hosts:
- name: airflow.example.com
tls:
enabled: true
secretName: airflow-tls
Make sure to also set the base_url in your Airflow configuration:
config:
api:
base_url: https://airflow.example.com