I recently embarked on the journey of running a dockerized version of Strapi on the DigitalOcean App Platform. Here's a detailed walkthrough of my setup process, following the official documentation.
First, I followed the Strapi Quick Start Guide to set up Strapi. This guide is a great starting point for getting a basic Strapi application up and running.
Next, I dockerized the Strapi setup. The official Docker installation guide was invaluable for this step. Notably, I opted not to add the database service to the docker-compose.yml
file. Instead, I configured the database separately on DigitalOcean.
After setting up my Strapi application and dockerizing it, I pushed the repository to GitHub. Then, I deployed it on the DigitalOcean App Platform, again following the official documentation. Here, I paired the app with a Managed PostgreSQL Database from DigitalOcean.
Note that I skipped the part where you have to create separate ./config/env/production
folder for production environment.
Setting up the environment variables correctly on the DigitalOcean App Platform is crucial. Here are the variables I used:
NODE_ENV=production
APP_URL=${APP_URL}
DATABASE_CLIENT=postgres
DATABASE_HOST=${db.HOSTNAME}
DATABASE_PORT=${db.PORT}
DATABASE_NAME=${db.DATABASE}
DATABASE_USERNAME=${db.USERNAME}
DATABASE_PASSWORD=${db.PASSWORD}
DATABASE_SSL_REJECT_UNAUTHORIZED=false
DATABASE_SSL=true
Make sure to set DATABASE_SSL
to true
as DigitalOcean Database policy required incoming connections to be secured.
These variables ensure that Strapi connects to the PostgreSQL database correctly. I also set the component environment variables.
APP_KEYS="toBeModified1,toBeModified2"
API_TOKEN_SALT=tobemodified
ADMIN_JWT_SECRET=tobemodified
TRANSFER_TOKEN_SALT=tobemodified
JWT_SECRET=tobemodified
DATABASE_SSL_REJECT_UNAUTHORIZED=false
Make sure to replace the placeholders with your actual values.
After the build is successfully running, you can visit the App Platform link.
Running Strapi and Docker may require at least 2GB of RAM to build successfully. To avoid any resource-related issues, I chose the $25/month plan, which provides 2 GB RAM, 1 vCPU, and 200 GB bandwidth.
If you prefer not to use DigitalOcean's managed PostgreSQL database, you can also include the database as a Docker service too. Follow the adjustments below.
Add strapiDB
service to your docker-compose.yml
file.
version: '3'
services:
strapi:
container_name: strapi
build: .
image: strapi:latest
restart: unless-stopped
env_file: .env
environment:
DATABASE_CLIENT: postgres
DATABASE_HOST: ${DATABASE_HOST}
DATABASE_PORT: ${DATABASE_PORT}
DATABASE_NAME: ${DATABASE_NAME}
DATABASE_USERNAME: ${DATABASE_USERNAME}
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
JWT_SECRET: ${JWT_SECRET}
ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET}
APP_KEYS: ${APP_KEYS}
NODE_ENV: ${NODE_ENV}
volumes:
- ./config:/opt/app/config
- ./src:/opt/app/src
- ./package.json:/opt/package.json
- ./yarn.lock:/opt/yarn.lock
- ./.env:/opt/app/.env
- ./public/uploads:/opt/app/public/uploads
ports:
- '1337:1337'
networks:
- strapi
depends_on:
- strapiDB
strapiDB:
container_name: strapiDB
platform: linux/amd64 #for platform error on Apple M1 chips
restart: unless-stopped
env_file: .env
image: postgres:12.0-alpine
environment:
POSTGRES_USER: ${DATABASE_USERNAME}
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
POSTGRES_DB: ${DATABASE_NAME}
volumes:
- strapi-data:/var/lib/postgresql/data/ #using a volume
- ./data:/var/lib/postgresql/data/ # if you want to use a bind folder
ports:
- '5432:5432'
networks:
- strapi
volumes:
strapi-data:
networks:
strapi:
name: Strapi
driver: bridge
In this configuration, Docker will bind the folder ./data
to the local machine as well. So you'd want to ignore that folder inside your .gitignore
file.
data/
.env
Next, you'd want to update your .env
file.
HOST=0.0.0.0
PORT=1337
APP_KEYS="toBeModified1,toBeModified2"
API_TOKEN_SALT=tobemodified
ADMIN_JWT_SECRET=tobemodified
TRANSFER_TOKEN_SALT=tobemodified
JWT_SECRET=tobemodified
# Database
DATABASE_CLIENT=postgres
DATABASE_HOST=strapiDB
DATABASE_PORT=5432
DATABASE_NAME=strapi
DATABASE_USERNAME=strapi
DATABASE_PASSWORD=strapi
DATABASE_POOL_MIN=0
Notice that I set DATABASE_POOL_MIN=0
. This is important as Docker will kill any idle connections, making it impossible to keep any open connections to the database.
Running both the app and the db containers can be more resource heavy, you may need to increase the size of your application. While building this app, I encountered multiple Out of Memory
errors. If you encounter this, you may have to increase the resource plan.
For reference, you can check out the repository I put together for this deployment here. For the included database, you can check it out under the branch database-included
.
Deploying Dockerized Strapi on DigitalOcean App Platform was a smooth experience thanks to the comprehensive documentation provided by Strapi. With the right configuration and sufficient resources, you can get your Strapi application up and running in no time.