# Strapi Headless CMS on DomainIndia VPS
TL;DR
Strapi is the most popular open-source headless CMS — a Node.js admin panel that generates a REST or GraphQL API from content types you define. Perfect for decoupled architectures: Strapi serves content, your frontend (React, Vue, Next.js) consumes it. This guide deploys a production Strapi on DomainIndia VPS.
## Headless vs traditional CMS
| Traditional (WordPress) | Headless (Strapi) |
| Single repo, HTML+CSS+JS | Separate backend (API) + frontend (any) |
| Template layer coupled to content | API-first, zero presentation |
| Hard to reuse across web+mobile+IoT | One API serves all clients |
| PHP ecosystem | Node.js ecosystem |
| Plugins often fragile | TypeScript SDK + custom controllers |
Pick Strapi when:
- You need the same content in web + mobile + email
- You want developers to build custom frontends with React/Vue/Next/Flutter
- Editorial team wants a friendly UI to manage content
- You'll outgrow WordPress for content schema complexity
## Requirements
- DomainIndia VPS (2+ GB RAM; 4 GB for production with Postgres)
- Node.js 20+
- PostgreSQL (recommended) or MySQL/MariaDB
- nginx for reverse proxy + SSL
## Step 1 — Create Strapi project
On your laptop first (faster dev loop):
```bash
npx create-strapi-app@latest my-cms --quickstart
# Quickstart uses SQLite (fine for dev)
```
Visit `http://localhost:1337/admin` — create admin account.
Create content types (e.g. "Article" with title, body, author, thumbnail). Strapi auto-generates the API endpoints.
Test API:
```bash
curl http://localhost:1337/api/articles
```
## Step 2 — Prepare production config
Edit `config/database.ts` for production:
```typescript
export default ({ env }) => ({
connection: {
client: 'postgres',
connection: {
host: env('DATABASE_HOST', 'localhost'),
port: env.int('DATABASE_PORT', 5432),
database: env('DATABASE_NAME', 'strapi'),
user: env('DATABASE_USERNAME', 'strapi'),
password: env('DATABASE_PASSWORD'),
ssl: env.bool('DATABASE_SSL', false),
},
pool: { min: 2, max: 10 },
},
});
```
`config/server.ts`:
```typescript
export default ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
url: env('PUBLIC_URL', 'https://cms.yourcompany.com'),
proxy: true, // behind nginx
app: {
keys: env.array('APP_KEYS'),
},
});
```
## Step 3 — Setup VPS
```bash
# On VPS as root
sudo dnf install -y nodejs postgresql-server postgresql-contrib nginx certbot python3-certbot-nginx git
# or Ubuntu:
# curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
# sudo apt install -y nodejs postgresql nginx certbot python3-certbot-nginx git
# PostgreSQL setup
sudo postgresql-setup --initdb
sudo systemctl enable --now postgresql
sudo -u postgres psql < ({
upload: {
config: {
provider: 'aws-s3',
providerOptions: {
credentials: {
accessKeyId: env('AWS_ACCESS_KEY_ID'),
secretAccessKey: env('AWS_SECRET_ACCESS_KEY'),
},
region: 'auto',
endpoint: env('AWS_ENDPOINT'), // e.g. Cloudflare R2 endpoint
params: { Bucket: env('AWS_BUCKET') },
},
},
},
});
```
See our [Cloudflare R2 article](https://domainindia.com/support/kb/cloudflare-workers-r2-storage-domainindia) for zero-egress storage setup.
## Step 9 — Backups
Daily Postgres + uploads backup:
```bash
# /etc/cron.d/strapi-backup
0 3 * * * strapi /bin/bash -c '
pg_dump -h localhost -U strapi strapi | gzip > /home/strapi/backups/db-$(date +%Y%m%d).sql.gz &&
tar czf /home/strapi/backups/uploads-$(date +%Y%m%d).tar.gz -C /home/strapi/my-cms/public/uploads . &&
find /home/strapi/backups -name "*.gz" -mtime +30 -delete
'
```
See [Automated Backups](https://domainindia.com/support/kb/automated-backups-cron-rclone-s3) for off-site copies.
## Plugins worth installing
- **Internationalization (i18n)** — multi-language content
- **Users & Permissions** — JWT auth for API
- **Content Versioning** — track edits
- **SEO plugin** — meta tags per entry
- **GraphQL plugin** — GraphQL alongside REST
- **Meilisearch / Algolia plugin** — search
## Common pitfalls
## FAQ
Q
Strapi vs Directus vs Payload CMS?
Strapi — largest ecosystem, most plugins. Directus — SQL-first, excellent DB integration. Payload — TypeScript-native, newer but very clean. All valid; Strapi is the safest pick in 2026.
Q
Strapi Cloud vs self-hosted?
Strapi Cloud ($15-$300+/mo) — zero ops but US-based. Self-host on DomainIndia VPS — lower cost, data sovereignty in India, more setup work.
Q
Scalability?
Strapi handles 1000+ req/sec on a 4 GB VPS with caching. For bigger loads, horizontal scale with load balancer + Redis session/cache.
Q
Can I use Strapi for e-commerce?
Possible but not ideal — no built-in cart/checkout. Pair with Medusa.js or use a dedicated e-commerce platform.
Q
Is Strapi free?
Community Edition (free, self-host) is feature-complete. Enterprise Edition adds SSO, audit logs, premium support.
Run your own Strapi CMS on a DomainIndia VPS — full control, data in India.
Get started