Deployment guide

Installing Apache Airflow on a VPS: self-hosted automation

Deploy on a VPS Cloud →

Automation9 min read

Installing Apache Airflow on a VPS: self-hosted automation

Apache Airflow is the open source reference for orchestrating data pipelines as DAGs written in Python. Schedulers, operators, sensors and a rich UI make it the de facto standard for ETL and batch data. Self-hosted on a VPS, it becomes your central scheduler, without depending on a costly managed service.

Why self-host Apache Airflow on a VPS

Airflow is the tool data teams choose when they want to describe their pipelines in pure Python: each DAG is a .py file that defines tasks, their dependencies and their scheduling. The provider ecosystem is immense (SQL databases, S3, BigQuery, dbt, Spark…), and the community gigantic. Managed services (Cloud Composer, MWAA) charge a high hourly rate for the environment; by self-hosting Airflow on a VPS, you get the same engine for the cost of a server, and your DAGs run as close as possible to your internal data sources. It is also a matter of control: provider versions, custom Python dependencies, variables and connections, everything stays in your hands. The official Docker Compose deployment (CeleryExecutor) faithfully reproduces a production architecture: webserver, scheduler, workers, Redis and PostgreSQL.

Concrete benefits of self-hosting

  • DAGs in pure Python, versioned in Git, with controlled dependencies and providers.
  • Huge ecosystem of operators: SQL, cloud, dbt, Spark, HTTP, and more.
  • Robust scheduler: cron, dependencies between tasks, backfill and catchup.
  • Scalable Celery workers to absorb hundreds of tasks in parallel.
  • Execution close to your internal databases, with no transit through a third-party cloud.
  • The cost of a VPS instead of a managed environment billed by the hour.

Technical requirements

Airflow is the most resource-hungry tool in this series in a CeleryExecutor configuration, because it simultaneously runs webserver, scheduler, worker(s), triggerer, Redis and PostgreSQL. The official documentation recommends at least 4 GB of RAM, but for comfortable production aim for 4 vCPU and 8 GB of RAM; 16 GB if your DAGs load pandas or large volumes. Plan for 40 GB of disk, Docker and Docker Compose, and a domain (airflow.yourdomain.com). The LocalExecutor mode lightens the stack (without Celery or Redis) and can run on 4 GB if your needs remain modest.

Deploy Apache Airflow with Docker Compose

01

Fetch the official compose

Create /opt/airflow, then download the reference file: curl -LfO https://airflow.apache.org/docs/apache-airflow/stable/docker-compose.yaml. Create the expected subfolders: mkdir -p ./dags ./logs ./plugins ./config.

02

Set the permissions and the UID

Airflow requires a consistent UID for the mounted volumes. Generate the environment file: echo -e "AIRFLOW_UID=$(id -u)" > .env. Without this, the scheduler will not be able to write its logs and will crash on startup.

03

Initialize the database

Launch the migration and the creation of the admin account: docker compose up airflow-init. This command prepares PostgreSQL, applies the migrations and creates the default user airflow / airflow, to be changed afterwards.

04

Start the complete stack

Launch all the services: docker compose up -d. Check that webserver, scheduler, worker and triggerer are healthy with docker compose ps. The webserver listens on port 8080.

05

Reverse proxy and HTTPS

Put Caddy in front of the webserver: airflow.yourdomain.com { reverse_proxy localhost:8080 }. HTTPS protects access to the Airflow UI, which exposes connections, variables and potentially sensitive logs.

06

Drop in a DAG and run it

Place a minimal hello.py file in ./dags (a DAG with a BashOperator or PythonOperator). The scheduler detects it within a few seconds. Enable it in the UI, trigger a manual execution and inspect the task logs.

Never put heavy logic directly in the DAG file: the scheduler parses all the .py files at regular intervals (min_file_process_interval), and a costly import at module level slows down the entire scheduler. Keep the parsing code light and offload the work into the tasks. To manage custom Python dependencies, build your own image derived from apache/airflow with a requirements.txt rather than installing packages at runtime: your workers start faster and remain reproducible. Finally, monitor the growth of the ./logs folder and purge it regularly.

The ideal Cloud VPS for Airflow

Airflow in Celery mode demands RAM and several containers: the ServOrbit Cloud VPS provides the resources, preconfigured Docker and automatic SSL to host your data scheduler self-hosted, at a controlled cost.

Need help?

Browse our help center and FAQ, or write to our team — support in French, English and Arabic.