Deploy Dify.ai
Dify Is an Open-Source Platform for Building LLM-Powered Applications
SANDBOX
Just deployed
/dependencies
Storage Provision
Just deployed
Postgres
Just deployed
/var/lib/postgresql/data
Worker
Just deployed
Just deployed
Just deployed
Weaviate
Just deployed
/var/lib/weaviate
Storage
Just deployed
/data
Plugin Daemon
Just deployed
Redis
Just deployed
/data
Database Provision
Just deployed
🤖 Dify on Railway — Lean Stack
Self-host Dify, the open-source LLM app platform, on Railway — same RAG/agent/workflow features as the standard deploy, running one fewer service.
🎯 What is Dify?
Dify is an open-source platform for building and running LLM applications: a visual workflow builder, RAG pipelines for your own documents and knowledge bases, agent tooling with 50+ built-in integrations, and a model-agnostic backend that talks to OpenAI, Anthropic, local models, and dozens of other providers — all through one console and one API.
Common Use Cases
- Internal Knowledge Bases: Connect your company's documents to build a secure, private RAG pipeline for employee Q&A.
- Autonomous AI Agents: Equip LLMs with custom tools (API calls, web scraping) to automate complex, multi-step tasks.
- Customer Support Bots: Deploy intelligent, context-aware chatbots trained on your product documentation and help center articles.
- Visual Prompt Orchestration: Design and test multi-model workflows visually before exposing them via API to your frontend applications.
⚡ Why This Template
The reference Dify stack ships 11 containers, including a dedicated Weaviate service for vector search. This template drops Weaviate and points Dify at pgvector instead — a Postgres extension running on the same Postgres instance Dify already needs for its application data. Same knowledge-base/RAG functionality, one fewer container to provision and pay for, and one less service that Dify's own hosting guides flag as a common source of out-of-memory crashes on smaller hosts.
MinIO stays, on purpose. It's tempting to drop it too and write uploads straight to a Railway volume, but Railway doesn't support sharing one volume across services — and Dify's Api and Worker containers both need read/write access to the same uploaded files (Api saves what you upload, Worker processes it into the knowledge base afterward). MinIO gives them shared access over the network, which a local volume can't.
Deploy and Host
About Hosting
Hosting Dify on Railway provides a managed, scalable environment for your LLM applications without the overhead of traditional infrastructure. Railway handles the container orchestration, internal DNS, and volume management out of the box, allowing you to focus on building AI workflows rather than debugging server configurations.
Why Deploy
- Cost Efficiency: By replacing Weaviate with
pgvector, you consolidate your database and vector store, significantly reducing your monthly resource footprint. - Zero-Config Networking: Railway's internal private networking securely connects your Api, Worker, Postgres, Redis, and MinIO services without exposing backend databases to the public internet.
- Instant Scaling: You can easily scale up RAM and CPU for the Worker and Sandbox containers independently as your background processing and code execution needs grow.
Dependencies for
Deployment Dependencies
- Railway Account: A Developer or Pro plan. (The Hobby tier minimums will not provide enough RAM for the Dify Api and Worker containers to run stably).
- PostgreSQL 16 (with pgvector): Serves as both the application database and the vector store.
- Redis 7: Required for caching and acting as the Celery task broker.
- MinIO: Required for shared, network-accessible file storage between the Api and Worker containers.
- LLM API Keys: Active API keys for OpenAI, Anthropic, or other providers to power your agents once the platform is live.
🏗️ Architecture
| Service | Image | Role | Volume |
|---|---|---|---|
| Postgres | pgvector/pgvector:pg16 | App database + vector store | /var/lib/postgresql/data |
| Redis | redis:7-alpine | Cache + Celery broker | /data |
| Api | langgenius/dify-api:latest | REST API, workflow + RAG engine | — |
| Worker | langgenius/dify-api:latest, Celery start command | Async jobs: indexing, embeddings | — |
| Web | langgenius/dify-web:latest | Console + chat UI | — |
| Sandbox | langgenius/dify-sandbox:latest | Isolated code execution for tools | — |
| Plugin Daemon | langgenius/dify-plugin-daemon:latest-local | Runs installed plugins | — |
| Storage | minio/minio | Shared file storage for Api + Worker | /data |
| Storage Provision (temp) | minio/mc | Creates the storage bucket, once | — |
| DB Provision (temp) | postgres:16-alpine | Creates the plugin DB + vector extension, once | — |
Note: 8 services run long-term. The two "temp" jobs get deleted after first deploy — same pattern as the standard Dify template.
🚀 Deployment Steps
- New empty project on Railway.
- Add Postgres from
pgvector/pgvector:pg16(not Railway's native Postgres plugin — it needs the pgvector extension pre-built in). SetPOSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DB=dify. Mount a volume at/var/lib/postgresql/data. - Add Redis from
redis:7-alpine. Mount a volume at/data. Set the start command toredis-server --requirepass $REDIS_PASSWORDand defineREDIS_PASSWORD. - Add Storage from
minio/minio. Mount a volume at/data. SetMINIO_ROOT_USER,MINIO_ROOT_PASSWORD, start commandminio server /data --console-address ":9001". - Add Storage Provision from
minio/mc— a one-off job that creates the bucket against the Storage service, then exits. Reference Storage's internal domain via Railway's${{Storage.RAILWAY_PRIVATE_DOMAIN}}variable syntax. - Add DB Provision from
postgres:16-alpine— a one-off job that connects to Postgres and runsCREATE DATABASE dify_plugin;plusCREATE EXTENSION IF NOT EXISTS vector;on the dify database. - Add Plugin Daemon, Sandbox, Api, Worker, Web from the images above, wiring each to Postgres/Redis via Railway's variable references rather than hardcoding hosts.
- Generate public domains for Web and Api separately.
- Set
CONSOLE_API_URL,SERVICE_API_URL, andAPP_WEB_URLto your actual generated domains, and setWEB_API_CORS_ALLOW_ORIGINS/CONSOLE_CORS_ALLOW_ORIGINSso Web can call Api across domains. - Deploy everything, then delete Storage Provision and DB Provision once they've run successfully.
Important: Worker's exact Celery start command and the current storage variable names (
OPENDAL_*vsS3_*) shift between Dify releases — confirm both against the currentdocker-compose.yamland.env.examplebefore you publish.
🔑 Core Environment Variables
| Variable | Where | Notes |
|---|---|---|
SECRET_KEY | Api, Worker | 32+ random characters. Changing it later logs out every user. |
INIT_PASSWORD | Api | Gates the /install admin-setup page. Leave it set until your admin account exists. |
DB_USERNAME / DB_PASSWORD / DB_HOST / DB_PORT / DB_DATABASE | Api, Worker | Point at the Postgres service, DB_DATABASE=dify |
DB_PLUGIN_DATABASE | Plugin Daemon | dify_plugin — created by DB Provision |
REDIS_HOST / REDIS_PORT / REDIS_PASSWORD | Api, Worker | Point at the Redis service |
VECTOR_STORE | Api, Worker | pgvector |
PGVECTOR_HOST / PGVECTOR_PORT / PGVECTOR_USER / PGVECTOR_PASSWORD / PGVECTOR_DATABASE | Api, Worker | Same Postgres service as DB_* — PGVECTOR_DATABASE=dify |
CONSOLE_API_URL / SERVICE_API_URL / APP_WEB_URL | Api, Web | Your real Railway domains, once generated |
Note: Storage (MinIO/S3) and Plugin Daemon variables aren't in this table because their exact names move between Dify versions — pull the current list from Dify's .env.example linked above rather than trusting a snapshot here.
👤 First-Time Admin Setup
Dify doesn't ship default credentials. On first boot:
- Visit
[https://your-web-domain.up.railway.app/install](https://your-web-domain.up.railway.app/install) - Enter the value you set for
INIT_PASSWORD - Create your admin email + password
- Log in at the regular console URL from then on
If you didn't set INIT_PASSWORD, check the Api service's deploy logs — Dify may print a one-time setup link there instead, the same way PocketBase does.
🛡️ Security Considerations
- Set a real
SECRET_KEYandINIT_PASSWORDbefore your first deploy — don't leave either blank on a public domain. - Rotate
MINIO_ROOT_PASSWORD,REDIS_PASSWORD, andPOSTGRES_PASSWORDaway from any example values before going live. - Keep
INIT_PASSWORDset until setup is complete; it has no effect afterward, so there's no need to remove it, but don't publish it anywhere.
📊 Limitations
- Heavier than a typical Railway template — budget real RAM for Api, Worker, and Sandbox, not hobby-tier minimums.
- Two separate public domains (Web, Api) means CORS config to get right, unlike single-domain Nginx-fronted Dify setups.
- First deploy takes a few minutes longer than a single-service template while Postgres, Redis, and MinIO all come up before Api can start cleanly.
🔗 Links
- Dify Documentation
- Dify GitHub
- Dify Environment Variables Reference
- Railway Documentation
📄 License
This template deploys official Dify images under the Dify Open Source License (Apache 2.0 plus two restrictions: no unauthorized multi-tenant SaaS use, no removing Dify's branding from the console). This is a community deployment template, not an official Dify or LangGenius product.
Made with ❤️ for the Railway community
Template Content
SANDBOX
langgenius/dify-sandboxStorage Provision
minio/mcPostgres
postgres:15-alpineWorker
langgenius/dify-apiWeaviate
semitechnologies/weaviateStorage
minio/minioPlugin Daemon
langgenius/dify-plugin-daemonRedis
redis:6-alpineDatabase Provision
postgres:15-alpine

