By Thomas Smyth
Published 14th June 2022
To start, we must initiate a new Payload project from Payload’s starter kit and push it to a Git repository on a Git provider linked to your Northflank account to allow Northflank to access it.
Initiate a new Payload project by running
npm init payload-app
and inputting the information requested by the command line interface.The command line interface will ask you for connection details to a MongoDB database, these details will be used when running your application locally for development purposes. For this you could deploy a MongoDB instance locally, or deploy a MongoDB addon on Northflank and forward to it with the Northflank CLI.
Create a new file called
.gitignore
that contains the following:# Profile files .env # Dependencies node_modules/
Before you can deploy Payload to a production environment, we must configure it via the /src/payload.config.ts
file:
Configure Payload to work with the correct hostname by setting
serverURL
toprocess.env.PAYLOAD_PUBLIC_BASE_DNS
, as seen in the example below.To ensure Payload continues to run locally for development purposes, add
PAYLOAD_PUBLIC_BASE_DNS=http://localhost:3000
to your.env
file. When you deploy Payload on Northflank you will need to set the Northflank domain or your own custom domain as an environment variable with this key, see deploy to Northflank.
Configure Payload's rate limiter to work behind Northflank's load balancers by setting
rateLimit.trustProxy
totrue
, as seen in the example below.By enabling this option Payload will rate limit requests based on the originating IP addresses of the requests to the Northflank load balancers. Without this option being enabled, all requests will appear as if they are originating from the Northflank load balancers and your users will get rate limited very quickly without cause.
import { buildConfig } from 'payload/config'; import path from 'path'; // import Examples from './collections/Examples'; import Users from './collections/Users'; export default buildConfig({ serverURL: process.env.PAYLOAD_PUBLIC_BASE_DNS, rateLimit: { trustProxy: true, }, admin: { user: Users.slug, }, collections: [ Users, // Add Collections here // Examples, ], typescript: { outputFile: path.resolve(__dirname, 'payload-types.ts') }, });
To deploy your new project on Northflank, we must configure a Dockerfile
that defines the environment the Payload app will run in.
Create a new file called Dockerfile that contains the following:
ARG NODE_VERSION=14 # Setup the build container. FROM node:${NODE_VERSION}-alpine AS build WORKDIR /home/node # Install dependencies. COPY package*.json . RUN yarn install # Copy the source files. COPY src src COPY tsconfig.json . # Build the application. RUN yarn build && yarn cache clean # Setup the runtime container. FROM node:${NODE_VERSION}-alpine WORKDIR /home/node # Copy the built application. COPY --from=build /home/node /home/node # Expose the service's port. EXPOSE 3000 # Run the service. CMD ["yarn", "run", "serve"]
Commit and push your project to a Git repository on a Git provider linked to your Northflank account.
For more information on how to link a Git account to your Northflank account, check out our documentation.
Not familiar with Git? Check out GitHub’s Git Guide.
Now we have initiated our Payload project, we can now deploy it to Northflank.
Create a new combined service with the following configuration:
Under repository, select the Git repository you pushed your project to.
Under build options, select the Dockerfile build type.
Port 3000 will automatically be detected from the image manifest and will be exposed with the HTTP protocol.
Under resources, it’s recommended to use plan
nf-compute-50
or larger to ensure appropriate app performance.
Create a new MongoDB addon.
Choose the storage size according to your needs, it can be increased later if your storage needs change.
Create a new secret group.
Add the following keys and assign them the respective values.
Key Value PAYLOAD_PUBLIC_BASE_DNS
The unique code.run
domain, found at the top right corner of your service, or the custom domain linked to your service prefixed withhttps://
.PAYLOAD_SECRET
A random secret. To bring up a tool to generating random secrets, click the key symbol at the top right of the secrets section of the form.
Link the
MONGO_SRV
variable from the MongoDB addon created in the previous step and assign it the aliasMONGODB_URI
.
Wait for your project to be built and deployed, if your project has already been deployed restart the service and wait for it to restart, then open the web interface by clicking on the link in the top right corner of your service.
On the initial Payload page, you will be asked to create a user. Once you have created a user, you will be able to start creating content and data!
If you wish to enable Payload's uploads feature on your deployment, you can configure your deployment to upload files to a persistent volume attached to your service, or an S3 bucket provided by a MinIO addon. I recommend the latter of these options as it will allow you to run multiple instances of your Payload service making your service scale better and be more resilient. Each of these options are documented in more detail below.
This section will show you how to enable uploads to a persistent volume. The full source code used in this section can be found in this Git repository.
Set
update
in the appropriate collection to{ staticURL: '/uploads', staticDir: '/uploads' }
, as seen in the example below:import { CollectionConfig } from 'payload/types'; // Example Collection - For reference only, this must be added to payload.config.ts to be used. const Examples: CollectionConfig = { slug: 'examples', upload: { staticURL: '/uploads', staticDir: '/uploads' }, admin: { useAsTitle: 'someField', }, fields: [ { name: 'someField', type: 'text', }, ], } export default Examples;
Commit and push the change to your Git repository.
In your combined service, navigate to "Volumes" and add a new volume with the container mount path
/uploads
.Choose the storage size according to your needs, it can be increased later if your storage needs change.
This section will show you how to enable uploads to a S3 bucket provided by a MinIO addon. The full source code used in this section can be found in this Git repository.
Configure the Payload cloud storage plugin in the
/src/payload.config.ts
file, as seen in the example below:import { buildConfig } from 'payload/config'; import { cloudStorage } from '@payloadcms/plugin-cloud-storage'; import { s3Adapter } from '@payloadcms/plugin-cloud-storage/s3'; import path from 'path'; import Examples from './collections/Examples'; import Users from './collections/Users'; export default buildConfig({ serverURL: process.env.PAYLOAD_PUBLIC_BASE_DNS, admin: { user: Users.slug, }, collections: [ Users, Examples, ], typescript: { outputFile: path.resolve(__dirname, 'payload-types.ts') }, plugins: [ // Pass the plugin to Payload cloudStorage({ collections: { // Enable cloud storage for Examples collection examples: { // Create the S3 adapter adapter: s3Adapter({ config: { endpoint: process.env.MINIO_ENDPOINT, credentials: { accessKeyId: process.env.MINIO_ACCESS_KEY, secretAccessKey: process.env.MINIO_SECRET_KEY, }, region: 'us-east-1', forcePathStyle: true, }, bucket: 'uploads', }), }, }, }), ], });
In the example, we have enabled the
examples
collection and enabled uploads for it.For more information on how to configure the Payload cloud storage plugin, check out their GitHub repository.
Commit and push the change to your Git repository.
Create a new MinIO addon.
Enable the "Publicly accessible" option.
Link the following variables to your secret group created in the earlier step and assign them the respective aliases.
Variable name Alias EXTERNAL_MINIO_ENDPOINT
MINIO_ENDPOINT
ACCESS_KEY
MINIO_ACCESS_KEY
SECRET_KEY
MINIO_SECRET_KEY
Choose the storage size according to your needs, it can be increased later if your storage needs change.
Create a bucket in your MinIO addon named
uploads
, you can do this with the MinIO Client by runningEXTERNAL_MINIO_CONNECT_COMMAND
command found in your addon's connection details and thenmc mb <addon name>/uploads
.
Restart your combined service.
If you encounter any issues while following this guide we're happy to assist you with your Payload deployment at support@northflank.com. At Northflank we also have dedicated support plans for business customers.
ERROR (payload): Forbidden: You are not allowed to perform this action.
This error usually occurs because serverUrl
has not been configured correctly. To resolve:
- Check
serverUrl
is set in your application'sbuildConfig
toprocess.env.PAYLOAD_PUBLIC_BASE_DNS
- Ensure your application is receiving the environment variable
PAYLOAD_PUBLIC_BASE_DNS
, the value should be the full domain name you are using to access the application, including thehttps://
prefix. You can run the commandprintenv | grep PAYLOAD_PUBLIC_BASE_DNS
in the shell of a running container to check it exists in your runtime environment.
See the configure payload and deploy to Northflank for detailed instructions.
Northflank allows you to deploy your code and databases within minutes. Sign up for a Northflank account and create a free project to get started.
- Multiple read and write replicas
- Observe & monitor with real-time metrics & logs
- Low latency and high performance
- Backup, restore and fork databases
- Private and optional public load balancing as well as Northflank local proxy