---
title: "Deploy Casdoor | (Just Updated) SSO and OIDC Identity Provider, Postgres, Admin Password Generated on Deploy"
description: "Casdoor SSO and OIDC identity server, Postgres, generated admin password"
category: "Authentication"
url: https://railway.com/deploy/casdoor-or-just-updated-sso-and-oidc-ide
---

# Deploy Casdoor | (Just Updated) SSO and OIDC Identity Provider, Postgres, Admin Password Generated on Deploy

Casdoor SSO and OIDC identity server, Postgres, generated admin password

**[Deploy Casdoor | (Just Updated) SSO and OIDC Identity Provider, Postgres, Admin Password Generated on Deploy on Railway](https://railway.com/template/casdoor-or-just-updated-sso-and-oidc-ide)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/casdoor-or-just-updated-sso-and-oidc-ide/manifest.json

- **Creator:** SuperSlowSloth
- **Category:** Authentication

## Template content

### casdoor

- **Image:** casbin/casdoor:v4.25.0@sha256:a63e7a78257c43c90b22a49bf93becca7007dc47b4f97bec763aa50bcc9c9ee9
- **Start command:** `/bin/sh -c 'export runmode=prod driverName=postgres dbName=postgres origin="https://$RAILWAY_PUBLIC_DOMAIN" initAdminPassword="$CASDOOR_ADMIN_PASSWORD" dataSourceName="user=postgres password=$DB_PASSWORD host=$DB_HOST port=5432 sslmode=disable dbname=postgres"; sed -i "s/^httpport = .*/httpport = $PORT/" /conf/app.conf; until nc -z "$DB_HOST" 5432; do sleep 2; done; exec /server'`
- **Health check:** /api/health
- **Public domain:** Yes

### postgres

- **Image:** postgres:17@sha256:31ba9c94a03ada9988f2bb493a22a75eef3a185884533e5cdbcd498ea835b08f

## Documentation

# Deploy and Host Casdoor on Railway

**Built for an LLM agent to deploy and use.** There is no welcome-page password step and nothing to fill in: the `admin` password is generated at deploy time and valid from the first boot. The contract below lists every URL, variable name and the one script that proves it works.

Casdoor is an open-source identity and access management (IAM) platform: single sign-on (SSO), OAuth 2.0 and OpenID Connect (OIDC) provider, SAML, LDAP, social login, multi-factor authentication and an admin UI, with SDKs for most languages. This template runs Casdoor together with a PostgreSQL database.

## About Hosting Casdoor

This template runs two services. `casdoor` is the official **Casdoor 4.25.0** image (`casbin/casdoor`, pinned by digest). It is stateless: organizations, applications, users and signing certificates all live in PostgreSQL. `postgres` is the official **postgres:17** image (pinned by digest) with a volume at `/var/lib/postgresql`, reachable only on the private network. The `casdoor` start command waits for the database, points Casdoor at it, sets the public origin from the Railway domain (so the OIDC issuer URL is right) and hands the generated admin password to the stock server, so the same values apply after every redeploy. Allow about a minute for the first deploy to turn healthy.

### Agent contract

- Public URL: `https://` plus the `RAILWAY_PUBLIC_DOMAIN` of the `casdoor` service, used below as `CASDOOR_URL`. It serves the admin UI at `/`, the REST API under `/api`, OIDC discovery at `/.well-known/openid-configuration` and the OAuth endpoints under `/login/oauth`.
- Private URL: `http://casdoor.railway.internal:8080`
- Credentials: the built-in administrator `admin` (organization `built-in`) with the password in `CASDOOR_ADMIN_PASSWORD`. The database password is `DB_PASSWORD`, shared with the `postgres` service as `POSTGRES_PASSWORD`.
- Auth: POST the login to `/api/login` (body below) and keep the session cookie, or read `clientId` and `clientSecret` of the `app-built-in` application after login and send them as HTTP basic auth. There is no default `123` password.
- Health: `GET /api/health` returns 200 with no credentials

```bash
# run with CASDOOR_URL and CASDOOR_ADMIN_PASSWORD set; needs curl
J=$(mktemp); N="agent-check-$(date +%s)"
curl -s -o /dev/null -w 'health %{http_code}\n' "$CASDOOR_URL/api/health"
curl -s "$CASDOOR_URL/.well-known/openid-configuration" | grep -o "\"issuer\": \"$CASDOOR_URL\""
curl -s "$CASDOOR_URL/api/get-organizations?owner=admin" | grep -o 'Please sign in first'
curl -s -c "$J" -H 'Content-Type: application/json' -d "{\"application\":\"app-built-in\",\"organization\":\"built-in\",\"username\":\"admin\",\"password\":\"$CASDOOR_ADMIN_PASSWORD\",\"type\":\"login\"}" "$CASDOOR_URL/api/login" | grep -o '"data": "built-in/admin"'
curl -s -b "$J" -H 'Content-Type: application/json' -d "{\"owner\":\"admin\",\"name\":\"$N\",\"displayName\":\"$N\",\"passwordType\":\"plain\"}" "$CASDOOR_URL/api/add-organization" | grep -o '"data": "Affected"'
curl -s -b "$J" "$CASDOOR_URL/api/get-organization?id=admin/$N" | grep -o "\"name\": \"$N\""
curl -s -b "$J" -H 'Content-Type: application/json' -d "{\"owner\":\"admin\",\"name\":\"$N\"}" "$CASDOOR_URL/api/delete-organization" | grep -o '"data": "Affected"'
```

A fresh deploy prints `health 200`, the issuer line, `Please sign in first`, `"data": "built-in/admin"` and then `"data": "Affected"`, the organization's own name, and `"data": "Affected"` again. Point an application at `CASDOOR_URL` as its OIDC issuer, or open `CASDOOR_URL` and sign in as `admin`.

## Why Deploy Casdoor on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Casdoor on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

- **Agent-ready** - a generated admin password that works on first boot, a contract block and one working script; no `admin` / `123` login and no welcome-page step.
- **Correct issuer** - the public origin comes from the Railway domain, so OIDC discovery advertises the URL your applications can actually reach.
- **State survives redeploys** - organizations, applications, users and signing certificates live in PostgreSQL on a volume.
- **Private database** - PostgreSQL has no public domain and is reached over the private network.
- **Pinned images** - both images are pinned by digest, so a redeploy never changes the server version underneath you.

## Common Use Cases

- **Single sign-on for your own apps** - one OIDC or OAuth 2.0 provider in front of internal tools and customer-facing products.
- **Self-hosted Auth0 or Keycloak alternative** - users, social login, MFA and SAML on infrastructure you control.
- **Agent-driven identity management** - let an AI agent create organizations, applications and users through the REST API.

## Dependencies for Casdoor Hosting

- A PostgreSQL database (included in this template, volume at `/var/lib/postgresql`).

### Deployment Dependencies

- [casdoor/casdoor](https://github.com/casdoor/casdoor) - upstream project
- [Casdoor documentation](https://casdoor.org/docs/overview) - API reference, OIDC setup and SDKs


## Similar templates

- [Keycloak](https://railway.com/deploy/mSwigX) — [2026-11-04] Keycloak with keywind theme + Apple & Discord providers
- [lua-protector](https://railway.com/deploy/lua-protector) — Test deployed my project first
- [bknd](https://railway.com/deploy/p4nTYL) — Feature-rich yet lightweight backend

Open this page in a browser: https://railway.com/deploy/casdoor-or-just-updated-sso-and-oidc-ide
