Back to Notes

Deploy Strapi

  1. Install node.js
apt update
apt install -y ca-certificates curl gnupg
mkdir -p /etc/apt/keyrings
 
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
 | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
 
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" \
 > /etc/apt/sources.list.d/nodesource.list
 
apt update
apt install -y nodejs
node -v
npm -v
 
  1. Install PostgreSQL
apt install -y postgresql postgresql-contrib
systemctl enable --now postgresql

create db and user

sudo -u postgres psql <<'SQL'
CREATE USER strapi WITH PASSWORD 'your_password';
CREATE DATABASE strapi OWNER strapi;
GRANT ALL PRIVILEGES ON DATABASE strapi TO strapi;
SQL
  1. Build Strapi in /opt/strapi
cd /opt/strapi
npx create-strapi-app@latest . --no-run
  1. Configuration Create Keys
openssl rand -base64 32

Configuration

cat > /opt/strapi/.env <<'EOF'
NODE_ENV=production
 
DATABASE_CLIENT=postgres
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5432
DATABASE_NAME=strapi
DATABASE_USERNAME=strapi
DATABASE_PASSWORD=your_password
 
URL=https://strapi.domain.com
 
APP_KEYS=key1,key2,key3,key4
API_TOKEN_SALT=key5
ADMIN_JWT_SECRET=key6
JWT_SECRET=key7
EOF
 
  1. First run
cd /opt/strapi
npm install
npm run build
npm run start
  1. Permanent Strapi by using systemd create service file
cat > /etc/systemd/system/strapi.service <<'EOF'
[Unit]
Description=Strapi CMS
After=network.target postgresql.service
 
[Service]
Type=simple
WorkingDirectory=/opt/strapi/strapi_name
EnvironmentFile=/opt/strapi/strapi_name/.env
ExecStart=/usr/bin/npm run start
Restart=always
RestartSec=5
User=root
 
[Install]
WantedBy=multi-user.target
EOF

run

systemctl daemon-reload
systemctl enable --now strapi
systemctl status strapi --no-pager
journalctl -u strapi -f
  1. Login in http://ip:1377/admin

  2. dev mode systemctl stop strapi(running on production mode) cd /opt/strapi/strapi_name npm run dev

02/21/26 update

  1. Webui need build after update
npm run build

Add

ExecStartPre=/bin/bash -lc 'test -f node_modules/@strapi/admin/dist/server/server/build/index.html || /usr/bin/npm run build'

Under [Service] in strapi.service

  1. Switch prod and dev button Add a service first
nano /etc/systemd/system/strapi-dev.service
[Unit]
Description=Strapi CMS (Development)
After=network.target postgresql.service
Wants=postgresql.service
 
[Service]
Type=simple
WorkingDirectory=/opt/strapi/jqiu006.net
EnvironmentFile=/opt/strapi/jqiu006.net/.env
Environment=NODE_ENV=development
 
ExecStart=/usr/bin/npm run develop
Restart=on-failure
RestartSec=2
 
User=root
StandardOutput=journal
StandardError=journal
 
[Install]
WantedBy=multi-user.target

Unable start at boot

sudo systemctl daemon-reload
sudo systemctl disable --now strapi-dev 2>/dev/null || true

Add a command "strapi"

sudo nano /usr/local/bin/strapi
#!/usr/bin/env bash
set -euo pipefail
 
mode="${1:-}"
if [[ "$mode" != "prod" && "$mode" != "dev" ]]; then
  echo "Usage: strapi-mode prod|dev"
  exit 1
fi
 
if [[ "$mode" == "prod" ]]; then
  systemctl stop strapi-dev.service 2>/dev/null || true
  systemctl start strapi.service
  systemctl status strapi.service --no-pager -l
else
  systemctl stop strapi.service 2>/dev/null || true
  systemctl start strapi-dev.service
  systemctl status strapi-dev.service --no-pager -l
fi

Permission

sudo chmod +x /usr/local/bin/strapi-mode

Now use"strapi dev" and "strapi prod" to switch mode