Routing for separate subdomains for API and admin page

System Information
  • Strapi Version: 4.11.0
  • Operating System: Ubuntu 22.04 LTS
  • Database: PostgreSQL 14
  • Node Version: 18.16.0
  • NPM Version: 9.5.1
  • Yarn Version: -

Hi. I have a server with two configured subdomains:

  • admin.website.com
  • api.website.com.

On this server, my Strapi app is running on 1338 port: http://localhost:1338.

I want to configure the API to be available on the subdomain api.website.com, and the admin page is available on admin.website.com.
In other words: what is now locally available on http://localhost:1338/api should be available on http://api.website.com, http://localhost:1338/admin on http://admin.website.com.

Examples:

  • http://localhost:1338/api/blog-articlehttp://api.website.com/blog-article
  • http://localhost:1338/adminhttp://admin.website.com
  • http://localhost:1338/admin/content-manager/collectionType/api::blog-article.blog-articlehttp://admin.website.com/content-manager/collectionType/api::blog-article.blog-article
  • http://localhost:1338/admin/auth/loginhttp://admin.website.com/auth/login

The server uses NGINX, so I started implementing it.

For the API, it was straightforward:

# /etc/nginx/sites-available/api.website.com.conf

server {
   listen  80;
   server_name api.website.com;

   location / {
       proxy_pass http://localhost:1338;
       rewrite    /(.+) /api/$1 break;
       proxy_set_header Host $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;
       add_header Access-Control-Allow-Origin *;
   }
}

After restarting NGINX, the API was available at the address I wanted. Example: http://api.website.com/blog-article.

However, I was unable to achieve the intended result with the NGINX configuration for the admin page. After re-reading the documentation, I decided to experiment with the url parameter in the project’s configuration files config/admin.js and config/server.js. But unfortunately, without success.

One of the options I tried:

// config/admin.js

module.exports = ({ env }) => ({
  auth: {
    secret: env('ADMIN_JWT_SECRET'),
  },
  apiToken: {
    salt: env('API_TOKEN_SALT'),
  },
  url: '/'
});

+

# /etc/nginx/sites-available/admin.website.com.conf

server {
      listen  80;
      server_name admin.website.com;

     location / {
         proxy_pass http://localhost:1338;

         proxy_set_header Host $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;
     }
}

By using '/' as the value for the url parameter in config/admin.js, I hoped to bypass the welcome page and directly display the admin page. But, I got an error: pathname required.

More error details
0|strapi  | AssertionError [ERR_ASSERTION]: pathname required
0|strapi  |     at send (/home/strapi/source/node_modules/koa-send/index.js:52:3)
0|strapi  |     at serve (/home/strapi/source/node_modules/koa-static/index.js:44:24)
0|strapi  |     at /home/strapi/source/node_modules/@strapi/admin/server/routes/serve-admin-panel.js:62:11
0|strapi  |     at dispatch (/home/strapi/source/node_modules/koa-compose/index.js:42:32)
0|strapi  |     at serveAdminMiddleware (/home/strapi/source/node_modules/@strapi/admin/server/routes/serve-admin-panel.js:15:11)
0|strapi  |     at dispatch (/home/strapi/source/node_modules/koa-compose/index.js:42:32)
0|strapi  |     at returnBodyMiddleware (/home/strapi/source/node_modules/@strapi/strapi/lib/services/server/compose-endpoint.js:52:24)
0|strapi  |     at dispatch (/home/strapi/source/node_modules/koa-compose/index.js:42:32)
0|strapi  |     at policiesMiddleware (/home/strapi/source/node_modules/@strapi/strapi/lib/services/server/policy.js:24:11)
0|strapi  |     at dispatch (/home/strapi/source/node_modules/koa-compose/index.js:42:32)
0|strapi  |     at /home/strapi/source/node_modules/@strapi/strapi/lib/services/server/compose-endpoint.js:33:12
0|strapi  |     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

As a temporary solution, I updated the configurations as follows:

// config/admin.js

module.exports = ({ env }) => ({
  auth: {
    secret: env('ADMIN_JWT_SECRET'),
  },
  apiToken: {
    salt: env('API_TOKEN_SALT'),
  }
});

+

# /etc/nginx/sites-available/admin.website.com.conf

server {
      listen  80;
      server_name admin.website.com;

     location / {
         proxy_pass http://localhost:1338;
         rewrite    /(.+)   /$1 break;
         rewrite    /   /admin break;

         proxy_set_header Host $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;
     }
}

Now, when opening http://admin.website.com, I do reach the admin page. Although, while navigating within the admin pages, the links still contain the /admin path, which follows after http://admin.website.com. This is not surprising since /admin is the default value for the url parameter in config/admin.js.

As a result, I have:

  • Instead of the needed http://admin.website.com/content-manager/collectionType/api::blog-article.blog-article, I got http://admin.website.com/admin/content-manager/collectionType/api::blog-article.blog-article
  • instead of http://admin.website.com/auth/login, I got http://admin.website.com/admin/auth/login

…and so on.

Please advise on how to configure the routing to fix admin page paths.