Deployment guide

Deploying a Strapi application on a VPS

Deploy on a VPS Cloud →

Development8 min read

Deploying a Strapi application on a VPS

Strapi is the reference open-source headless CMS in Node.js. Self-hosting it on a VPS gives you full ownership of your content, your database and your uploads, without depending on Strapi Cloud. Here is how to put it into production with PostgreSQL, Docker and a reverse proxy.

Why self-host Strapi on a VPS

Strapi is designed to be self-hosted: it's a Node.js application that exposes a REST or GraphQL API and a React administration panel. Deploying it on your own VPS, rather than on Strapi Cloud, means your data, your uploaded media and your database stay under your exclusive control, which is often a requirement for client projects or data-localization constraints. You choose your database (PostgreSQL recommended in production over SQLite), your media storage (local disk or S3), and you are not limited by the entry or admin-user quotas of managed offerings. A VPS also lets you run Strapi and its consumer front end on the same infrastructure.

Concrete benefits

  • Full ownership of the content, the PostgreSQL database and the uploaded media
  • Free choice of database and storage (local disk or S3-compatible bucket)
  • No quota on entries, content types or administrator users
  • REST and GraphQL APIs exposed on your domain, with no intermediary or imposed rate limit
  • Community plugins freely installable, without a platform's validation
  • Controlled data localization, useful for compliance and client requirements

Hardware and software prerequisites

Strapi is more resource-hungry than front-end frameworks because the React admin build is heavy. Aim for a VPS with 2 vCPU and 4 GB of RAM minimum: the admin interface build can consume more than 2 GB of RAM on its own, and it's common for a build to fail with an OOM on an undersized server. In stable production, the application then runs comfortably. Install Docker and Docker Compose, and provision a PostgreSQL 16 database (ideally in its own container). Point cms.mydomain.com at the VPS IP. Plan for 15 GB of disk for the node_modules, the uploads and the backups.

Step-by-step deployment

01

Configure the production database

Give up SQLite in production. In config/database.js, configure the postgres client and read the credentials from the environment (DATABASE_HOST, DATABASE_NAME, DATABASE_USERNAME, DATABASE_PASSWORD). PostgreSQL is far more robust under concurrent load.

02

Define the production secrets

Strapi requires several keys: APP_KEYS, API_TOKEN_SALT, ADMIN_JWT_SECRET, JWT_SECRET and TRANSFER_TOKEN_SALT. Generate them randomly and place them in a .env file that is never committed. Without these keys, the admin will refuse to start in production mode.

03

Build the administration interface

Run NODE_ENV=production npm run build to compile the React admin panel. If the build runs out of memory, temporarily increase the VPS swap or build the Docker image on a more powerful machine before pushing it.

04

Orchestrate with Docker Compose

Declare a strapi service (based on node:20) and a db service (postgres:16) in docker-compose.yml, linked by an internal network. Mount a volume for public/uploads so that the media survive redeployments. Start with docker compose up -d.

05

Place Nginx as a reverse proxy

Configure a vhost to http://127.0.0.1:1337 (Strapi's default port). Increase client_max_body_size to 50M or more to allow large media uploads, otherwise uploads will fail with a 413 error.

06

Enable HTTPS and set the public URL

Run certbot --nginx -d cms.mydomain.com, then set URL=https://cms.mydomain.com in Strapi's server config. This URL is indispensable for the media links and the admin panel to work correctly behind the proxy.

Offload media storage to an S3-compatible bucket thanks to the @strapi/provider-upload-aws-s3 upload provider: your uploads no longer bloat the VPS disk and survive any container recreation, with no volume to back up. For the database, automate a daily pg_dump via a cron on the VPS and copy the dump off the server. Finally, run Strapi with NODE_ENV=production without fail: development mode recompiles the admin on the fly and exposes the Content-Type Builder, to be avoided in production.

Host your Strapi CMS in full autonomy

The ServOrbit Cloud VPS provides the RAM needed for the Strapi admin build and a ready-to-use Docker + PostgreSQL environment, to keep full ownership of your content and your data.

Need help?

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