Caddy Proxying
As Strapi does not handle SSL directly and hosting a Node.js service on the "edge" network is not a secure solution it is recommended that you use some sort of proxy application such as Nginx, Apache, HAProxy, Traefik, or others. This guide contains some sample configurations for Caddy, naturally these configs may not suit all environments and you will likely need to adjust them to fit your needs.
Caddy has some very easy to use options relating to Let's encrypt and automated SSL certificate issuing/renewing, while it is certainly the "newer" web server market, it is quickly becoming a great "non-technical" user application for proxying.
Caddy is still very much in development and as such is evolving often, this guide is based on Caddy v2.0.0.
Configuration
The following configuration is based on "Caddy File" type, this is a single file configuration that Caddy will use to run the web server. There are multiple other options such as the Caddy REST API that this guide will not cover, you should review the Caddy documentation for further information on alternatives. You can also visit the Caddy Community to speak with others relating to configuration questions.
Strapi server
In order to take full advantage of a proxied Strapi application, Strapi should be configured so it's aware of the upstream proxy. Like with the below configurations there are 3 matching examples. Additional information can be found in the server configuration and admin configuration documentations.
These examples use the default API Prefix of /api
. This can be changed without the need to directly modify the Nginx configuration (see the API prefix documentation).
If the url
key is changed in the ./config/admin.js
or ./config/server.js
files, the admin panel needs to be rebuilt with yarn build
or npm run build
.
- Subdomain
- Subfolder unified
Subdomain Strapi configuration
- Example domain:
api.example.com
- Example admin:
api.example.com/admin
- Example API:
api.example.com/api
- Example uploaded files (local provider):
api.example.com/uploads
- JavaScript
- TypeScript
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
url: 'https://api.example.com',
});
export default ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
url: 'https://api.example.com',
});
Subfolder unified Strapi configuration
- Example domain:
example.com/test
- Example admin:
example.com/test/admin
- Example API:
example.com/test/api
- Example uploaded Files (local provider):
example.com/test/uploads
- JavaScript
- TypeScript
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
url: 'https://example.com/test',
});
export default ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
url: 'https://example.com/test',
});
Caddy file
The Caddyfile is a convenient Caddy configuration format for humans. It is most people's favorite way to use Caddy because it is easy to write, easy to understand, and expressive enough for most use cases.
In the following examples you will need to replace your domain, and should you wish to use SSL you will need to tweak these Caddy file configs to suit your needs, SSL is not covered in this guide and you should review the Caddy documentation.
The following are 2 example Caddy configurations:
- Subdomain-based such as
api.example.com
- Subfolder-based with both the API and Admin on the same subfolder (e.g.
example.com/test/api
andexample.com/test/admin
)
Using subfolder split (eg: https://example.com/dashboard
and https://example.com/api
) are not supported nor recommended with Strapi. It's advised that you either use subdomains (eg: https://api.example.com
) or subfolder unified (eg: https://example.com/strapi/dashboard
and https://example.com/strapi/api
).
- Subdomain
- Subfolder unified
Subdomain
This configuration is using a subdomain dedicated to Strapi only. It will bind to port 80 HTTP and proxies all requests (both API and admin) to the Strapi server running locally on the address specified. If you have configured Caddy properly to handle automated SSL, you can remove the http://
and Caddy will automatically convert all HTTP to HTTPS traffic.
- Example domain:
api.example.com
- Example admin panel:
api.example.com/admin
- Example API:
api.example.com/api
- Example uploaded Files (local provider):
api.example.com/uploads
# path: /etc/caddy/Caddyfile
http://api.example.com {
reverse_proxy 127.0.0.1:1337
}
Subfolder unified
This configuration is using a subfolder dedicated to Strapi only. It will bind to port 80 HTTP and hosts the front-end files on /var/www
like a normal web server, but proxies all Strapi requests on the example.com/test
sub-path.
This example configuration is not focused on the front end hosting and should be adjusted to your front-end software requirements.
- Example domain:
example.com/test
- Example admin panel:
example.com/test/admin
- Example API:
example.com/test/api
- Example uploaded Files (local provider):
example.com/test/uploads
# path: /etc/caddy/Caddyfile
http://example.com {
root * /var/www
file_server
route /test* {
uri strip_prefix /test
reverse_proxy 127.0.0.1:1337
}
}
Redirecting landing page to admin panel
If you do not wish to have the default landing page mounted on /
you can create a custom middleware using the sample code below to automatically redirect to your admin panel.
This sample configuration expects that the admin panel is accessible on /admin
. If you used one of the above configurations to change this to /dashboard
you will also need to adjust this sample configuration.
module.exports = ({ env }) => [
// ...
{ resolve: '../src/middlewares/admin-redirect' },
];
module.exports = (_config, { strapi }) => {
const redirects = ['/', '/index.html'].map((path) => ({
method: 'GET',
path,
handler: (ctx) => ctx.redirect('/admin'),
config: { auth: false },
}));
strapi.server.routes(redirects);
};