Strapi
Published in

Strapi

How to Deploy Strapi Docker Container On AWS Elastic Beanstalk

A step-by-step guide to hosting your Strapi application on AWS elastic beanstalk

Prerequisites

To follow up through this article, you should have the following:

  1. Understanding of Docker
  2. Basic understanding of AWS cloud concepts
  3. AWS account
  4. AWS CLI installed (If you don’t have it installed, click here to start.).
  5. Basic understanding of Strapi
  6. Node.js downloaded and installed.
  7. Yarn as Node package manager
  8. Vscode or any code editor

What is Strapi?

Strapi is the leading open-source, customizable, headless CMS based on Node.js; it is used to develop and manage content using RESTful APIs and GraphQL.

Scaffolding a Strapi Project

In this article, I’ll show how to use the template blog to quickly scaffold a Strapi project. You can apply what we will do here for any Strapi project or template.

yarn create strapi-app bloggy --template blog

Connect to PostgreSQL Database

Create a new PostgreSQL container with the following command:

docker run --name strapi-bloggy-db -v my_dbdata:/var/lib/postgresql/data -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=strapi -d postgres:13.6
All Databases in the container
const path = require('path');

module.exports = ({ env }) => ({
connection: {
client: 'postgres',
connection: {
host: env('DATABASE_HOST', '12l7.0.0.1'),
port: env.int('DATABASE_PORT', 5432),
database: env('DATABASE_NAME', 'strapi'),
user: env('DATABASE_USERNAME', 'postgres'),
password: env('DATABASE_PASSWORD', 'postgres'),
schema: env('DATABASE_SCHEMA', 'public'),
ssl: env('DATABASE_SSL', false),
},
debug: false,
},
});
yarn add pg
yarn develop
http://localhost:1337/admin
AWS RDS Naming Conventions
module.exports =  ({ env }) => ({
connection: {
client: 'postgres',
connection: {
host: env('RDS_HOSTNAME', ''),
port: env.int('RDS_PORT', undefined),
database: env('RDS_DB_NAME', ''),
user: env('RDS_USERNAME', ''),
password: env('RDS_PASSWORD', ''),
ssl: env.bool('DATABASE_SSL', false)
}
}
});
Config Folder Structure

Build the Strapi Docker Image

You should currently be running the Strapi server from your local machine; now, you need to run Strapi as a Docker container. Make two docker files: Dockerfile will be used in production and Dockerfile.dev for development.

FROM node:16
ENV NODE_ENV=production
WORKDIR /opt/
COPY ./package.json ./yarn.lock ./
ENV PATH /opt/node_modules/.bin:$PATH
RUN yarn install
WORKDIR /opt/app
COPY . .
RUN yarn build
EXPOSE 1337
CMD ["yarn", "start"]
FROM node:16
ENV NODE_ENV=development
WORKDIR /opt/
COPY ./package.json ./yarn.lock ./
ENV PATH /opt/node_modules/.bin:$PATH
RUN yarn install
WORKDIR /opt/app
COPY . .
RUN yarn build
EXPOSE 1337
CMD ["yarn", "develop"]
.tmp/
.cache/
.git/
build/
node_modules/
docker build -t bloggy:v1.0 .

Putting All Together with Docker-Compose

Docker-Compose simplifies creating multiple Docker containers with a single yml file. It helps to create Docker containers with configuration for volumes and networks.

npx @strapi-community/dockerize
  1. What environments do you want to configure? » Development
  2. What database do you want to use? » PostgreSQL
  3. Database host: Localhost
  4. Database Port: 5432
✔ Do you want to create a docker-compose file? 🐳 … No / Yes
✔ What environments do you want to configure? › Development
✔ Whats the name of the project? … strapi
✔ What database do you want to use? › PostgreSQL
✔ Database Host … localhost
✔ Database Name … strapi
✔ Database Username … postgres
✔ Database Password … ********
✔ Database Port … 5432
.tmp/
.cache/
.git/
build/
node_modules/
.env
version: '3'
services:
strapi:
container_name: strapi
build: .
image: strapi:latest
restart: unless-stopped
env_file: .env
environment:
DATABASE_CLIENT: ${DATABASE_CLIENT}
DATABASE_HOST: strapiDB
DATABASE_NAME: ${DATABASE_NAME}
DATABASE_USERNAME: ${DATABASE_USERNAME}
DATABASE_PORT: ${DATABASE_PORT}
JWT_SECRET: ${JWT_SECRET}
ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET}
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
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/arm64/v8 #for platform error on Apple M1 chips
restart: unless-stopped
env_file: .env
image: postgres:13.6
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
HOST=0.0.0.0
PORT=1337
APP_KEYS=zz1kt2QS2I7BBuP8EuIjlA==,L8XX/OEbybRFh40q8DzIng==,yt4yAvYgK83xycthu5yxtA==,X7Gcx1VVAUm8d+A7rTZ7Yw==
API_TOKEN_SALT=MWPCH4U70a2E8ubTlAC6Yg==
ADMIN_JWT_SECRET=hJXXOaTmQl8A4zXbiqTicQ==
JWT_SECRET=aUnqqM5AwuUQAyxXE6LQnQ==
# @strapi-community/dockerize variables
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=strapi
DATABASE_USERNAME=postgres
DATABASE_PASSWORD=postgres
NODE_ENV=development
DATABASE_CLIENT=postgres
docker-compose build
docker-compose up
proof

How to Deploy a Docker Container in AWS

AWS provides many services to deploy Docker containers; the most popular services are:

  • Elastic Container Service
  • Elastic Beanstal

Deploying the Docker Image on Elastic Beanstalk

A flow diagram of Elastic Beanstallk process
  1. Create a file, Dockerrun.aws.json, and uploaded it to the S3 bucket. You can refence it later when creating an Elastic Beanstalk environment to pull the image from ECR.
  2. Create the environment.
  3. Config the environment.

Push the Strapi Docker Image to AWS ECR

The Amazon ECR Repository Page
Choosing the image name
Create repository
View of all repositories
Steps

Setup a New IAM User

To get started using AWS CLI, you need to obtain the Access key ID and Access Secret key. That access key gives permission to CLI to make programmatic calls like updating or creating any resources. In our case, we need to add an image in the ECR repository. To do so, we need to start with the following steps.

  1. Click on “Add users”
  2. Choose an appropriate User name. Put a checkmark on “Select AWS credential type → Access key — Programmatic access.” Then click on “Next: Permissions”
  3. Choose “Attach existing policies directly” and put a checkmark on “AdministratorAccess” then click on “Next: Tags”.
  1. That is a preview page that gives an overview of what we have done. After reviewing, click on “Create User”.
  2. Download and save these keys on your PC by clicking on “Download .csv”.

Configure AWS CLI to Interact with AWS Resources and Services

Now we have the Access Key ID and Secret Access Key, we can configure AWS CLI by running the following command:

aws configure
result
docker build -t bloggy:v1.0 .
docker tag bloggy:v1.0 391161446417.dkr.ecr.us-east-1.amazonaws.com/bloggy:v1.0
docker push 391161446417.dkr.ecr.us-east-1.amazonaws.com/bloggy:v1.0
bloggy

Create an S3 Deployment Bucket

In the AWS console, search and navigate to S3 and follow the steps outlined below.

Create a bucket button
Create a bucket page
Further configurations
{
"AWSEBDockerrunVersion": "1",
"Image": {
"Name": "391161446417.dkr.ecr.us-east-1.amazonaws.com/bloggy:v1.0",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "1337"
}
]
}
upload page
result
json file details page

Create Elastic Beanstalk Application

In the AWS console, search and navigate to Elastic Beanstalk page.

elastic beanstalk page
Further configurations
application code page
source code origin details
configuration page
instance types details
Details
Environment properties details
  • Engine version: 13.6 (same as local development)
  • Instance class: db.t4.micro
  • storage: 5
  • Choose a username and password.
screenshot
Create app page
server instance details page

How to Automate Deployment with CI/CD

To automate deployment in a real-world CI/CD environment, you need to do three steps:

  1. Change image tag in “Dockerrun.aws.json”, then upload the file to S3. Check out this link: S3 File Upload · Actions · GitHub Marketplace
  2. Deploy a new version in Elastic Beanstalk. The following link could be helpful: Beanstalk Deploy · Actions · GitHub Marketplace

Conclusion

In this tutorial, you learned how to deploy Strapi as a Docker container in AWS Elastic Beanstalk, connected to PostgreSQL in Relational Database Service. You also saw an overview of how you can automate these deployment steps in CI/CD pipelines like GitHub actions.

Resources

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store