{"id":13578855,"url":"https://github.com/61FINTECH/deploy-strapi-on-aws","last_synced_at":"2025-04-05T19:34:01.283Z","repository":{"id":37735902,"uuid":"164843279","full_name":"61FINTECH/deploy-strapi-on-aws","owner":"61FINTECH","description":"Deploying a Strapi API on AWS (EC2 \u0026 RDS \u0026 S3)","archived":false,"fork":false,"pushed_at":"2022-06-23T07:20:14.000Z","size":21,"stargazers_count":195,"open_issues_count":2,"forks_count":60,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-11-05T16:49:32.033Z","etag":null,"topics":["aws","cms","ec2","graphql","https","pm2","postgresql","rds","s3","strapi","tutorial"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/61FINTECH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-09T10:41:05.000Z","updated_at":"2024-10-16T04:32:54.000Z","dependencies_parsed_at":"2022-07-12T16:44:02.720Z","dependency_job_id":null,"html_url":"https://github.com/61FINTECH/deploy-strapi-on-aws","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/61FINTECH%2Fdeploy-strapi-on-aws","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/61FINTECH%2Fdeploy-strapi-on-aws/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/61FINTECH%2Fdeploy-strapi-on-aws/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/61FINTECH%2Fdeploy-strapi-on-aws/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/61FINTECH","download_url":"https://codeload.github.com/61FINTECH/deploy-strapi-on-aws/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247393095,"owners_count":20931804,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","cms","ec2","graphql","https","pm2","postgresql","rds","s3","strapi","tutorial"],"created_at":"2024-08-01T15:01:34.362Z","updated_at":"2025-04-05T19:34:00.972Z","avatar_url":"https://github.com/61FINTECH.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"⚠️ THIS REPOSITORY IS NO LONGER MAINTAINED. \n\n👉 WE RECOMMEND FOLLOWING [THIS GUIDE](https://github.com/Qovery/terraform-examples/tree/main/examples/deploy-strapi-with-postgresql-on-aws) TO DEPLOY STRAPI ON AWS.\n\n\n----\n# Deploying a Strapi API on AWS (EC2 \u0026 RDS \u0026 S3)\n\u003e Goal: build a HTTPS-secured Strapi API with dev \u0026 staging \u0026 prod modes\n\nEverything done in the following is [AWS Free Tier](https://aws.amazon.com/free/) eligible.  \nMake sure you have already skimmed the [Strapi docs](https://strapi.io/documentation/3.x.x) before you start.\n\n## § Create EC2 instance / RDS instance / S3 bucket\n\n\u003e You can skim this section if you are familiar with AWS\n\n### ⊙ EC2\n1. Click `Launch Instance` button\n2. Choose AMI: `Ubuntu Server 18.04 LTS (HVM), SSD Volume Type`\n3. Choose Instance Type: `General purpose, t2.micro`\n4. Configure Instance: *as you like*\n5. Add Storage: `General Purpose SSD (gp2), 8 GB`\n6. Add Tags: *as you like*\n7. Configure Security Group:\n    * SSH (22) - `My IP` or `Anywhere` or *as you like*\n    * HTTP (80) - `Anywhere`\n    * HTTPS (443) - `Anywhere`\n8. Review: click `Launch` button, then a modal pops up. If you are a:\n    * Newbie: Choose `Create a new key pair` named `strapi-cms`, download it as `strapi-cms.pem`\n    * Veteran: *as you like*\n9. Finally, click `Launch Instances` button\n\n### ⊙ RDS\n1. Click `Create database` button\n2. Select engine: `PostgreSQL`\n3. Choose use case: *as you like*\n4. Specify DB details:\n    * DB engine version: `PostgreSQL 10.x-R1`\n    * DB instance class: `db.t2.micro`\n    * Multi-AZ deployment: `No`\n    * Storage: `General Purpose (SSD), 20 GB`\n    * DB instance identifier: *as you like*\n    * Master username: *as you like*\n    * Password: *as you like, recommend https://passwordsgenerator.net*\n5. Configure advanced settings\n    * Public accessibility: `Yes` *(that's why you need a super strong password)*\n    * Database name: `strapi`\n    * Monitoring \u0026 Maintenance window: *choose an idle peroid in your timezone*\n    * Click `Create database` button\n6. Instance Details panel - Security groups\n    * Edit inbound rules: PostgreSQL (5432) - `Anywhere`\n7. Create databases for dev \u0026 staging modes (GUI recommend: https://dbeaver.io)\n    * Development mode: `strapi_dev`\n    * Staging mode: `strapi_staging`\n    * Production mode: `strapi` *(already exists)*\n\n### ⊙ S3\n0. Click `Create bucket` button\n1. Name and region\n    * Bucket name: *as you like*\n2. Configure options: *as you like*\n3. Set permissions\n    * - [ ] `Block new public ACLs and uploading public objects (Recommended)`\n    * - [ ] `Remove public access granted through public ACLs (Recommended)`\n    * - [x] `Block new public bucket policies (Recommended)`\n    * - [x] `Block public and cross-account access if bucket has public policies (Recommended)`\n    * `Do not grant Amazon S3 Log Delivery group write access to this bucket`\n4. Review: click `Create bucket` button\n\n## § Point your domain to EC2\nPoint the A / CNAME records to the EC2's IPv4 Public IP / Public DNS (IPv4), such as:\n* Development mode: `dev-cms.yourdomain.com`\n* Staging mode: `staging-cms.yourdomain.com`\n* Production mode: `cms.yourdomain.com`\n\n## § Warm up EC2\n\n### ⊙ Login to EC2 \u0026 update\nSwitch to the directory where the key pair `strapi-cms.pem` locates:\n\n```shell\n$ ssh -i strapi-cms.pem ubuntu@\u003cec2-public-ip\u003e\n$ sudo apt update\n```\n\n### ⊙ Install Nginx\n\n```shell\n$ sudo apt install nginx\n```\n\n### ⊙ Install nvm \u0026 Node.js \u0026 PM2\n* Install [nvm](https://github.com/creationix/nvm#install-script):\n    ```shell\n    $ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash\n    ```\n* Install Node.js:\n    ```shell\n    $ nvm install 10\n    ```\n* Install [PM2](https://pm2.io):\n    ```shell\n    $ npm i pm2 -g\n    ```\n\n### ⊙ Install Certbot\nAccording to https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx :\n\n```shell\n$ sudo apt-get install software-properties-common\n$ sudo add-apt-repository universe\n$ sudo add-apt-repository ppa:certbot/certbot\n$ sudo apt-get update\n$ sudo apt-get install python-certbot-nginx\n```\n\n## § Create a local Strapi project\n\n### ⊙ Installation and initialization\nFirstly, install Strapi (refer to https://strapi.io/documentation/3.x.x/getting-started/installation.html):\n\n```shell\n$ npm i -g strapi@alpha\n```\n\nSecondary, create a new project (refer to https://strapi.io/documentation/3.x.x/cli/CLI.html#strapi-new):\n\n```shell\n$ strapi new strapi-cms \\\n    --dbclient=postgres \\\n    --dbport=5432 \\\n    --dbhost=\u003cRDS endpoint\u003e \\\n    --dbname=strapi_dev \\\n    --dbusername=\u003cRDS master username\u003e \\\n    --dbpassword=\u003cRDS password\u003e\n```\n\nFinally, **DO NOT** rush to `strapi start` for now.  \nThere are some preparatory procedures to accomplish.  \n(By the way, you may be interested in https://strapi.io/documentation/3.x.x/advanced/usage-tracking.html)\n\n### ⊙ Complete database configuration\n\u003e If you prefer best practices like https://12factor.net/config and https://github.com/i0natan/nodebestpractices/blob/master/sections/projectstructre/configguide.md , you'd better use tools like [dotenv](https://www.npmjs.com/package/dotenv) instead.\n\n`strapi-cms/config/environments/development/database.json` has been completed during the initialization.  \nComplete `strapi-cms/config/environments/{staging|production}/database.json` based on it. For example:\n\n```js\n{\n  \"defaultConnection\": \"default\",\n  \"connections\": {\n    \"default\": {\n      \"connector\": \"strapi-hook-bookshelf\",\n      \"settings\": {\n        \"client\": \"postgres\",\n        \"host\": \"\u003cRDS endpoint\u003e\",\n        \"port\": 5432,\n        \"database\": \"\u003cstrapi_staging|strapi\u003e\",\n        \"username\": \"\u003cRDS master username\u003e\",\n        \"password\": \"\u003cRDS password\u003e\"\n      },\n      \"options\": {\n        \"ssl\": false\n      }\n    }\n  }\n}\n```\n\n### ⊙ Fix listening ports\nModify `port` in `strapi-cms/config/environments/{staging|production}/server.json`:\n* development: 1337 (default)\n* staging: 1338\n* production: 1339\n\n### ⊙ Install S3 upload plugin\n\u003e Refer to https://strapi.io/documentation/3.x.x/guides/upload.html#install-providers\n\n```shell\n$ npm i -S strapi-provider-upload-aws-s3@alpha\n```\n\n### ⊙ Add npm scripts for staging \u0026 production mode\n\u003e You can use [PM2 - Ecosystem File](https://pm2.io/doc/en/runtime/guide/ecosystem-file/) instead if you'd like to\n\n`npm start` is for development mode by default.  \nYou can set `NODE_ENV` before it according to https://strapi.io/documentation/3.x.x/guides/deployment.html .  \nHowever, for the sake of compatibility, [cross-env](https://www.npmjs.com/package/cross-env) is introduced.\n\n```shell\n$ npm i -D cross-env\n```\n\nSo `strapi-cms/package.json` may look like:\n\n```js\n{\n  ...\n  \"scripts\": {\n    \"setup\": \"cd admin \u0026\u0026 npm run setup\",\n    \"start\": \"node server.js\",                         // for development mode\n    \"staging\": \"cross-env NODE_ENV=staging npm start\", // for staging mode \n    \"prod\": \"cross-env NODE_ENV=production npm start\", // for production mode\n    \"strapi\": \"node_modules/strapi/bin/strapi.js\",\n    \"lint\": \"node_modules/.bin/eslint api/**/*.js config/**/*.js plugins/**/*.js\",\n    \"postinstall\": \"node node_modules/strapi/lib/utils/post-install.js\"\n  },\n  ...\n}\n```\n\n### ⊙ Add [`nginx.conf`](https://github.com/61FINTECH/deploy-strapi-on-aws/blob/master/nginx.conf) to the project root\n\u003e If you prefer best practices using `/etc/nginx/{sites-available|sites-enabled}`, you may need help from https://nginxconfig.io or https://github.com/h5bp/server-configs-nginx . I prefer single file `nginx.conf` because of simplicity.\n\nDon't forget to replace all `yourdomain.com` with yours.\n\n### ⊙ Run\n```shell\n$ cd strapi-cms \u0026\u0026 strapi start\n```\n\nYour browser will open http://localhost:1337 automatically later.  \nCreate an admin with a strong password.\n\n### ⊙ Complete S3 settings\nVisit [PLUGINS \u003e Files Upload](http://localhost:1337/admin/plugins/upload/configurations/development) to complete the S3 settings for all modes.\n\n### ⊙ GraphQL\nIf you'd like to equip GraphQL, visit [GENERAL \u003e Marketplace](http://localhost:1337/admin/install-plugin) to download.  \nRefer to https://strapi.io/documentation/3.x.x/guides/graphql.html for further info.\n\n### ⊙ Configure response \u0026 security\nSince Strapi will be running behind a well-tuned Nginx, you should:\n* Visit [GENERAL \u003e Configurations \u003e ENVIRONMENTS \u003e Response](http://localhost:1337/admin/plugins/settings-manager/response/production), set *Production* \u0026 *Staging*'s *Gzip* to `OFF`\n* Visit [GENERAL \u003e Configurations \u003e ENVIRONMENTS \u003e Security](http://localhost:1337/admin/plugins/settings-manager/security/development), copy all the settings from *Development* to *Production* \u0026 *Staging*\n\n\u003e For more details, please turn to https://strapi.io/documentation/3.x.x/configurations/configurations.html\n\n### ⊙ Push to a [Github free private repo](https://blog.github.com/2019-01-07-new-year-new-github/) (or Gitlab, etc)\n```json\n$ git init\n$ git add -A\n$ git commit -m 'init'\n$ git remote add origin \u003cprivate-git-repo-url\u003e\n$ git push -u origin master\n```\n\n## § Deploy Strapi on EC2\n\n### ⊙ Pull the repo and install npm dependencies\n```shell\n$ cd ~\n$ git clone \u003cprivate-git-repo-url\u003e\n$ cd strapi-cms\n$ npm i\n```\n\n### ⊙ Run all modes with PM2\nThanks to [this Stack Overflow comment](https://stackoverflow.com/questions/31579509/can-pm2-run-an-npm-start-script/37775318#comment64893202_37775318), you can run npm scripts with PM2:\n\n```shell\n$ pm2 start npm --name \"strapi-dev\" -- start\n$ pm2 start npm --name \"strapi-staging\" -- run staging\n$ pm2 start npm --name \"strapi-prod\" -- run prod\n```\n\nAlso, you need to set up the [PM2 Startup Hook](https://pm2.io/doc/en/runtime/guide/startup-hook/) in case of reboot:\n\n```shell\n$ pm2 startup\n$ pm2 save\n```\n\n### ⊙ Replace `/etc/nginx/nginx.conf` with yours\n\n```shell\n$ cd ~/strapi-cms\n$ sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup\n$ sudo cp nginx.conf /etc/nginx/nginx.conf\n```\n\n### ⊙ Obtain SSL certificates\nAccording to https://nginxconfig.io :\n\n```shell\n# HTTPS - certbot (before first run): create ACME-challenge common directory\n$ sudo mkdir -p /var/www/_letsencrypt \u0026\u0026 chown www-data /var/www/_letsencrypt\n\n# HTTPS - certbot (before first run): disable SSL directives\n$ sudo sed -i -r 's/(listen .*443)/\\1;#/g; s/(ssl_(certificate|certificate_key|trusted_certificate) )/#;#\\1/g' /etc/nginx/nginx.conf\n\n# Reload Nginx config\n$ sudo systemctl reload nginx\n\n# HTTPS - certbot: obtain certificates\n$ sudo certbot certonly\n    --webroot -n --agree-tos --force-renewal \\\n    -w /var/www/_letsencrypt \\\n    --email \u003cyour-email\u003e \\\n    -d cms.\u003cyourdomain.com\u003e \\\n    -d staging-cms.\u003cyourdomain.com\u003e \\\n    -d dev-cms.\u003cyourdomain.com\u003e\n\n# HTTPS - certbot (after first run): enable SSL directives\n$ sudo sed -i -r 's/#?;#//g' /etc/nginx/nginx.conf\n\n# Reload Nginx config again\n$ sudo systemctl reload nginx\n```\n\nAll done! Visit https://{cms|staging-cms|dev-cms}.yourdomain.com to see if it works.\n\n### ⊙ Further optimizations\n* See https://strapi.io/documentation/3.x.x/guides/deployment.html\n* Remove `strapi-cms/public/index.html`\n\n## § Summary\nNow you have:\n* A Strapi API running on dev \u0026 staging \u0026 prod modes simultaneously\n* PM2-guarded processes with reboot startup hooks\n* Forced HTTPS-secured traffic for all\n* Auto-renew SSL certificates for free\n\n\u003e PRs \u0026 issues are welcome! Sharing your experience will save others' time! [![tip](https://img.shields.io/badge/BuyMe-aCoffee-brightgreen.svg)](https://github.com/kenberkeley/tip)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F61FINTECH%2Fdeploy-strapi-on-aws","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F61FINTECH%2Fdeploy-strapi-on-aws","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F61FINTECH%2Fdeploy-strapi-on-aws/lists"}