Railway

Deploy Doris

Sub-second analytics on billions of rows, self-hosted and MySQL-compatible

Deploy Doris

Just deployed

/data

Just deployed

/data

doris-storage

Bucket

Just deployed

Apache Doris logo

Deploy and Host Apache Doris on Railway

Apache Doris is an open-source MPP analytical database that answers aggregations, joins and window functions over hundreds of millions of rows in well under a second, through the ordinary MySQL wire protocol. It came out of Baidu, graduated from the Apache Incubator in 2022, and runs dashboards and real-time warehouses at Xiaomi and Tencent. Teams reach for it when Postgres stops keeping up with GROUP BY over billions of rows but they will not give up SQL joins, upserts or the tooling they have.

Self-host Apache Doris on Railway with this template and you get a complete two-tier cluster, not a single container. A Frontend (FE) service holds the catalog, plans SQL and serves the web console; a Backend (BE) service stores every tablet and runs the vectorized execution engine. A managed object storage bucket is wired in as a cold tier, so partitions past a cooldown window move off local disk. The two nodes find each other over the private network by hostname, so they survive redeploys, and the cluster takes queries as soon as the deploy is green — no manual registration, no default password left in place.

Diagram of the Doris frontend and backend services on Railway

Getting Started with Apache Doris on Railway

Set DORIS_ROOT_PASSWORD when you deploy — the only input the template needs. When the deploy is green, open the Frontend's public URL and sign in as root with that password. The Playground tab holds a SQL editor and a database tree; click a database there first, because the editor sends statements without a default schema until you do.

Your first useful action is to create a database and a table and check the numbers come back. Run CREATE DATABASE demo;, refresh the tree, select demo, and create a table:

CREATE TABLE demo.pageviews (
  event_date DATE NOT NULL,
  country VARCHAR(2) NOT NULL,
  path VARCHAR(128) NOT NULL,
  views BIGINT NOT NULL
) ENGINE=OLAP
DUPLICATE KEY(event_date, country)
DISTRIBUTED BY HASH(country) BUCKETS 4
PROPERTIES ("replication_num" = "1");

replication_num must be 1 while the cluster has a single Backend. Insert a few rows, run a GROUP BY, and confirm the Results panel reports Run successfully with a millisecond execution time; SHOW FRONTENDS and SHOW BACKENDS should show both nodes Alive. Beyond ad-hoc queries, connect over the TCP proxy the template exposes for port 9030 with any MySQL client, and point Superset, Metabase or dbt there.

Doris Playground rolling up 600,000 pageview rows by country Monthly pageviews cross-tabulated by device in the Doris query editor Querying a refreshed Doris materialized view of daily country totals

About Hosting Apache Doris

Doris is a columnar, vectorized, massively parallel database for interactive analytics on data that keeps changing. Unlike most OLAP engines it has first-class primary-key upserts through its Unique Key model, so late corrections and CDC streams do not force a rewrite, and its cost-based optimizer makes multi-table joins practical rather than something to design around.

  • MySQL protocol compatibility — existing drivers, BI tools and shells connect unchanged
  • Three table models — Duplicate for raw events, Aggregate for rollups, Unique for upsertable rows
  • Materialized views, synchronous rollups and asynchronous multi-table views
  • Inverted indexes for full-text search and high-cardinality filtering
  • Stream Load and Routine Load for HTTP micro-batches and Kafka ingestion
  • External catalogs for querying Hive, Iceberg, Postgres and MySQL in place

Self-host it when latency, data residency or per-seat pricing rules out a hosted warehouse.

Why Deploy Apache Doris on Railway

Running an MPP cluster normally means sizing thread pools and wiring service discovery by hand.

  • Frontend and Backend deploy together, tuned for their containers
  • The Backend registers by private hostname and survives every redeploy
  • Persistent volumes for metadata and tablets, plus a cold tier in object storage
  • The MySQL port is published through a TCP proxy for external clients
  • No ZooKeeper or Kubernetes to operate

Common Use Cases

  • Customer-facing analytics — dashboards that stay interactive at high concurrency, each query filtered to one tenant
  • Real-time data warehousing — streaming events from Kafka, upserting dimensions, joining at query time
  • Log and observability search — inverted indexes over structured logs, so filters and time aggregations run in one engine

Dependencies for Apache Doris

  • Frontendapache/doris:fe-4.0.8: catalog, SQL planner, MySQL endpoint and console, with cluster metadata on its own volume.
  • Backendapache/doris:be-4.0.8: storage and execution engine, holding tablets and the write-ahead log on its own volume.
  • Object storage bucket — a managed S3-compatible bucket registered as a Doris storage resource with a cold-tier policy.

Both build from the gridalpha/doris-railway repository, which layers Railway-specific startup over the official Apache Doris images.

Environment Variables Reference

VariableServicePurpose
DORIS_ROOT_PASSWORDFrontendPassword for root; the only value you supply
DORIS_BE_HOSTFrontendPrivate hostname the Backend registers under
DORIS_S3_BUCKET / DORIS_S3_ENDPOINTFrontendBucket and endpoint for the cold tier
DORIS_S3_COOLDOWN_TTLFrontendSeconds before a partition moves to object storage
DORIS_FE_HEAP_PERCENTFrontendShare of container memory given to the JVM heap
DORIS_ENABLE_HTTP_AUTHFrontendRequires credentials on REST and metrics routes

Deployment Dependencies

Self-Hosting Apache Doris

Outside Railway, the quickest way to try Doris is the all-in-one image, which runs both roles in one container:

docker run -d -p 8030:8030 -p 9030:9030 apache/doris:all-in-one-4.1.3

A real cluster splits the roles. A Docker Compose fragment for the shape this template deploys:

services:
  fe:
    image: apache/doris:fe-4.0.8
    environment: { FE_SERVERS: "fe1:10.0.0.2:9010", FE_ID: "1" }
  be:
    image: apache/doris:be-4.0.8
    environment: { FE_SERVERS: "fe1:10.0.0.2:9010", BE_ADDR: "10.0.0.3:9050" }

Both roles need vm.max_map_count raised and swap disabled on the host, and every Backend must be registered with ALTER SYSTEM ADD BACKEND before the cluster accepts a table.

Hardware Requirements for Self-Hosting Apache Doris

ResourceMinimumRecommended
CPU4 vCPU across both services8+ vCPU per service
RAM4 GB Frontend, 4 GB Backend8 GB Frontend, 16 GB+ Backend
Storage5 GB per service volume20 GB metadata, 100 GB+ tablets
RuntimeJava 17, x86-64 with AVX2Same, with more Backends for scale

Scale by adding Backend services rather than raising replicas: each Backend registers under its own private hostname, and replicas of one service share one.

Is Apache Doris Free to Self-Host?

Apache Doris is free and open source under the Apache 2.0 licence, with no paid edition, seat count or feature gate. Commercial support and a managed cloud are sold separately by VeloDB, but nothing here depends on them. Deploying costs only the Railway resources the services consume.

FAQ

What is Apache Doris? An open-source MPP analytical database for real-time reporting and interactive analytics. It stores data in columns, executes queries with a vectorized engine across many cores, and speaks the MySQL protocol.

Why does the template include an object storage bucket? Local volumes are finite and analytical tables grow. The template registers the bucket as a Doris storage resource with a railway_cold policy, so attaching it to a table moves old partitions into object storage, still queryable.

How do I connect Superset, Metabase or dbt to self-hosted Apache Doris? Use the TCP proxy endpoint for port 9030 with any MySQL connector — host, port, user root, password. Tools configured as "MySQL" need no special driver.

Why does CREATE TABLE fail with "Failed to find enough backend"? The table asks for more replicas than the cluster has Backends. With one Backend, set PROPERTIES ("replication_num" = "1") on every table, and raise it after adding a second Backend service.

How do I load data into Apache Doris on Railway? For files and micro-batches use Stream Load, an HTTP PUT against the Frontend's public URL with your credentials. For continuous ingestion use Routine Load against Kafka. For data already in SQL reach, INSERT INTO ... SELECT from an external catalog.


Template Content

doris-storage

Bucket

More templates in this category

View Template
NEW
Typesense vs Meilisearch
self-hosted Typesense vs Meilisearch

onepush
0
View Template
Betterlytics
Betterlytics is a cookieless analytics platform GDPR-compliant.

OpenSource Templates
27
View Template
NEW
Finance Tracker
Private multi-user household finance ledger with budgets and CSV import.

wotonews
0