Deploying Strapi on CentOS Stream 8 with Nginx and Phusion Passenger
Hey there! If you’re like me, you’ve probably found yourself scratching your head trying to get your Strapi CMS up and running on CentOS Stream 8. Fear not, because I’ve been through the trenches and am here to guide you step-by-step on how to do it. Grab a cup of coffee, sit back, and let’s dive into it!
Why Strapi?
First off, if you haven’t heard about Strapi, it’s a fantastic open-source headless CMS. It’s super flexible and perfect for anyone wanting to build powerful APIs without breaking a sweat.
Assumptions and Prerequisites
Before we start, let's go over some assumptions and prerequisites. We’re assuming the following:
The code repository for Strapi is already cloned into the directory
/var/www/
strapi.example.com
.A
.env
file is set up with all necessary environment variables.MySQL Server is installed and set up.
The database for Strapi is created and configured.
SSL certificates are set up and loaded in
nginx.conf
or in another location.Nginx is installed and configured.
Deployment Options
Phusion Passenger (Single Domain): Uses Phusion Passenger to host both the API and admin backend on the same domain with a different admin path.
Phusion Passenger (Separate Domains): Uses Phusion Passenger to host the API and admin backend on separate domains.
Nginx Reverse Proxy and System Service (Single Domain): Uses Nginx reverse proxy and a systemd service to host both the API and admin backend on the same domain.
Common Steps
Step 1: Switch to the Hosting User
Before installing NVM and other dependencies, switch to the user that will host the application. In this case, we'll use the system user.
sudo su - system
Step 2: Install NVM
We start by installing NVM. This handy tool allows us to manage different versions of Node.js without the hassle.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
Once that’s done, add NVM to ~/.bashrc
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
Verify that NVM is installed:
nvm --version
Step 3: Install Node.js
Next, we need to install the required Node.js version. For our setup, we’ll go with Node.js version 18.
nvm install 18
nvm use 18
node --version
Deployment Option 1: Phusion Passenger (Single Domain)
Step 4: Create app.js
app.js
is the default entry file for Phusion Passenger when hosting Node applications. For custom files, add passenger_startup_fil custom.js;
within your Nginx virtual host.const strapi = require("@strapi/strapi");
strapi({ dir: "./build" }).start();
Step 5: Update Configuration Files
Add the following to config/server.js
:
url: env('BACKEND_PUBLIC_URL', 'http://localhost:1337'),
Add the following to .env
:
BACKEND_PUBLIC_URL=https://strapi.example.com
PUBLIC_ADMIN_PATH=/ui
Add the following to config/admin.js
:
url: env('PUBLIC_ADMIN_PATH', '/admin'),
Step 6: Install Dependencies & Build Project
Install project dependencies and build the admin backend application:
NODE_ENV=production yarn install
NODE_ENV=production yarn build
Step 7: Configure Nginx
/admin
by default). Hence, /
is redirected to /admin/
within the Nginx virtual host.Create a new Nginx configuration file:
sudo vim /etc/nginx/conf.d/strapi.example.com.conf
Add the following configuration:
server {
server_name strapi.example.com;
listen 443 ssl http2;
listen [::]:443 ssl http2;
passenger_enabled on;
passenger_app_type node;
passenger_nodejs /home/system/.nvm/versions/node/v18.20.3/bin/node;
root /var/www/strapi.example.com/public;
# Invalidate cache according to Strapi Cloud guidelines:
# https://docs.strapi.io/cloud/getting-started/caching
add_header Cache-Control "max-age=10, must-revalidate" always;
location /ui {
if ($request_uri ~ ^/ui[^/]*$) {
return 301 $request_uri/;
}
alias /var/www/strapi.example.com/build/;
try_files $uri $uri/ /ui/index.html;
}
access_log /var/log/nginx/strapi.example.com_access.log;
error_log /var/log/nginx/strapi.example.com_error.log;
}
Test your Nginx configuration:
sudo nginx -t
Reload Nginx:
sudo systemctl reload nginx
Step 8: Verify Everything is Working
Your Strapi CMS should be up and running. Just open your browser and head to https://strapi.example.com/ui/ to see your site live in action.
Deployment Option 2: Phusion Passenger (Separate Domains)
Step 4: Create app.js
app.js
is the default entry file for Phusion Passenger when hosting Node applications. For custom files, add passenger_startup_fil custom.js;
within your Nginx virtual host.const strapi = require("@strapi/strapi");
strapi({ dir: "./build" }).start();
Step 5: Update Configuration Files
Add the following to config/server.js
:
url: env('BACKEND_PUBLIC_URL', 'http://localhost:1337'),
Add the following to .env
:
BACKEND_PUBLIC_URL=https://strapi.example.com
Step 6: Install Dependencies & Build Project
Install project dependencies and build the admin backend application:
NODE_ENV=production yarn install
NODE_ENV=production yarn build
Step 7: Configure Nginx
Create a new Nginx configuration file:
sudo vim /etc/nginx/conf.d/strapi.example.com.conf
Add the following configuration:
server {
server_name strapi-backend.example.com;
listen 443 ssl http2;
listen [::]:443 ssl http2;
passenger_enabled on;
passenger_app_type node;
passenger_nodejs /home/system/.nvm/versions/node/v18.20.3/bin/node;
root /var/www/strapi.example.com/public;
# Invalidate cache according to Strapi Cloud guidelines:
# https://docs.strapi.io/cloud/getting-started/caching
add_header Cache-Control "max-age=10, must-revalidate" always;
access_log /var/log/nginx/strapi-backend.example.com_access.log;
error_log /var/log/nginx/strapi-backend.example.com_error.log;
}
server {
server_name strapi-frontend.example.com;
listen 443 ssl http2;
listen [::]:443 ssl http2;
root /var/www/strapi.example.com/public;
# Invalidate cache according to Strapi Cloud guidelines:
# https://docs.strapi.io/cloud/getting-started/caching
add_header Cache-Control "max-age=10, must-revalidate" always;
location / {
return 301 /admin/;
}
location /admin {
if ($request_uri ~ ^/admin[^/]*$) {
return 301 $request_uri/;
}
alias /var/www/strapi.example.com/build/;
try_files $uri $uri/ /admin/index.html;
}
access_log /var/log/nginx/strapi.example.com_access.log;
error_log /var/log/nginx/strapi.example.com_error.log;
}
Test your Nginx configuration:
sudo nginx -t
Reload Nginx:
sudo systemctl reload nginx
Step 8: Verify Everything is Working
Your Strapi CMS should be up and running. Visit https://strapi-backend.example.com for the API and https://strapi-frontend.example.com for the admin backend.
Deployment Option 3: Nginx Reverse Proxy and System Service (Single Domain)
Step 4: Install Dependencies & Build Project
Install project dependencies and build the admin backend application:
NODE_ENV=production yarn install
NODE_ENV=production yarn build
Step 5: Configure Nginx
Create a new Nginx configuration file:
sudo vim /etc/nginx/conf.d/strapi.example.com.conf
Add the following configuration:
server {
server_name strapi.example.com;
listen 443 ssl http2;
listen [::]:443 ssl http2;
passenger_enabled on;
root /var/www/strapi.example.com/public;
# Invalidate cache according to Strapi Cloud guidelines:
# https://docs.strapi.io/cloud/getting-started/caching
add_header Cache-Control "max-age=10, must-revalidate" always;
location / {
try_files $uri/index.html $uri @strapi;
}
location @strapi {
proxy_pass http://localhost:1337;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass_request_headers on;
}
}
Test your Nginx configuration to make sure everything is in order:
sudo nginx -t
Reload Nginx:
sudo systemctl reload nginx
Step 6: Set Up Strapi as a Systemd Service
To ensure Strapi starts on boot and runs reliably, we’ll set it up as a systemd service.
Create the service file:
sudo vim /etc/systemd/system/strapi.example.com.service
Add the following configuration:
[Unit]
Description=Strapi CMS Example
After=network.target
[Service]
Type=simple
User=nginx
Group=nginx
WorkingDirectory=/var/www/strapi.example.com
Environment="NVM_DIR=/home/system/.nvm"
ExecStart=/bin/bash -c 'source /home/system/.nvm/nvm.sh && nvm use 18 && NODE_ENV=production yarn start'
Restart=on-failure
[Install]
WantedBy=multi-user.target
Step 7: Reload and Restart the Service
Reload systemd to recognize our new service:
sudo systemctl daemon-reload
Enable and start the service:
sudo systemctl enable strapi.example.com
sudo systemctl start strapi.example.com
Step 8: Verify Everything is Working
Check the status of the service to ensure it’s running:
sudo systemctl status strapi.example.com
And there you have it! Your Strapi CMS should be up and running. Just open your browser and head to https://strapi.example.com to see your site in action.
Troubleshooting
If you encounter any issues during this setup, here are a few troubleshooting tips:
Service Fails to Start:
Check the service logs for detailed error messages using
journalctl -u
strapi.example.com
.Ensure that the nginx user has the necessary permissions to access the project directory and execute the commands.
Verify that the paths in the service file are correct.
Nginx Configuration Errors:
Test your Nginx configuration with
sudo nginx -t
to identify any syntax errors.Ensure all required modules are enabled in Nginx.
Environment Issues:
Ensure that NVM and Node.js are correctly set up by running the commands directly in the terminal as the nginx user.
Verify that the
~/.bashrc
settings are loaded correctly by opening a new terminal session or reloading the profile withsource ~/.bashrc
.
Access Issues:
Ensure your firewall settings allow traffic on the necessary ports (80 for HTTP and 443 for HTTPS).
Check that your DNS settings point to the correct server IP address for
strapi.example.com
.
Deployment Tips
When re-deploying, delete the
/build
directory before runningNODE_ENV=production yarn build
.Clear the cache if necessary.
Conclusion
Deploying Strapi on CentOS Stream 8 with Nginx and Fusion Passenger might seem daunting at first, but with these steps, you’re well on your way to having a powerful CMS up and running. Remember, the key is ensuring all configurations are correct and that the right environment variables are set.
Happy coding, and enjoy your new Strapi setup!
Subscribe to my newsletter
Read articles from Vadim Kononov directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Vadim Kononov
Vadim Kononov
I am an accomplished Solution Architect, Full Stack Developer and DevOps Specialist with a passion for creative leadership and mentorship, business optimization and technical direction, and ingenious solutions to complex problems. I am especially interested in App & Web Development, Cyber Security, Cloud Computing, Data Science, Open Source Software, Statistical Analysis and Discrete Mathematics.