├── .env.example ├── .gitignore ├── README.md ├── app.json ├── config ├── admin.js ├── api.js ├── database.js ├── middlewares.js ├── plugins.js └── server.js ├── favicon.ico ├── package.json ├── public ├── robots.txt └── uploads │ └── .gitkeep ├── script └── postInstall.js ├── src ├── admin │ ├── app.example.js │ └── webpack.config.example.js ├── api │ └── .gitkeep ├── extensions │ └── .gitkeep └── index.js └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | HOST=0.0.0.0 2 | PORT=1337 3 | 4 | DATABASE_URL=... 5 | 6 | CLOUDINARY_NAME=... 7 | CLOUDINARY_KEY=... 8 | CLOUDINARY_SECRET=... 9 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ############################ 2 | # OS X 3 | ############################ 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | Icon 9 | .Spotlight-V100 10 | .Trashes 11 | ._* 12 | 13 | 14 | ############################ 15 | # Linux 16 | ############################ 17 | 18 | *~ 19 | 20 | 21 | ############################ 22 | # Windows 23 | ############################ 24 | 25 | Thumbs.db 26 | ehthumbs.db 27 | Desktop.ini 28 | $RECYCLE.BIN/ 29 | *.cab 30 | *.msi 31 | *.msm 32 | *.msp 33 | 34 | 35 | ############################ 36 | # Packages 37 | ############################ 38 | 39 | *.7z 40 | *.csv 41 | *.dat 42 | *.dmg 43 | *.gz 44 | *.iso 45 | *.jar 46 | *.rar 47 | *.tar 48 | *.zip 49 | *.com 50 | *.class 51 | *.dll 52 | *.exe 53 | *.o 54 | *.seed 55 | *.so 56 | *.swo 57 | *.swp 58 | *.swn 59 | *.swm 60 | *.out 61 | *.pid 62 | 63 | 64 | ############################ 65 | # Logs and databases 66 | ############################ 67 | 68 | .tmp 69 | *.log 70 | *.sql 71 | *.sqlite 72 | *.sqlite3 73 | 74 | 75 | ############################ 76 | # Misc. 77 | ############################ 78 | 79 | *# 80 | ssl 81 | .idea 82 | nbproject 83 | public/uploads/* 84 | !public/uploads/.gitkeep 85 | 86 | ############################ 87 | # Node.js 88 | ############################ 89 | 90 | lib-cov 91 | lcov.info 92 | pids 93 | logs 94 | results 95 | node_modules 96 | .node_history 97 | 98 | ############################ 99 | # Tests 100 | ############################ 101 | 102 | testApp 103 | coverage 104 | 105 | ############################ 106 | # Strapi 107 | ############################ 108 | 109 | .env 110 | license.txt 111 | exports 112 | *.cache 113 | build 114 | .strapi-updater.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 Getting started with Strapi 2 | 3 | This repository contains a basic Strapi application which is quickly and easily deployable on Heroku through a one-click deploy button 4 | 5 | 6 | 7 | 8 | 9 | ## Requirements 10 | 11 | To deploy this project on Heroku, you'll need: 12 | 13 | - An Heroku account (Free) 14 | - A Cloudinary account for hosting your assets (Free) 15 | 16 | ## Database 17 | 18 | This project will use the [postgresql Heroku addons](https://elements.heroku.com/addons/heroku-postgresql). The database configuration can be found in the `config/database.js` file. Using the existing configuration means that you project will also use the production postgresql database when running locally on your machine. 19 | You will need to have the same `DATABASE_URL` that the addon will create on your Heroku project if you want to use the postresql database locally. 20 | 21 | - Create an `.env` file at the root of your project containing the following code: 22 | 23 | ``` 24 | DATABASE_URL=... 25 | ``` 26 | 27 | If you want to use an SQLite database just for editing your collection-types, configurations locally on your machine, please comment the postgresql configuration in the `config/database.js` file and uncomment the SQLite one. 28 | You can also create a `config/env/production/database.js` file containing the postgresql connection and only keep the SQLite connection in your `config/database.js`. This way you'll have two different database connection depending on the environment. 29 | 30 | ## Upload 31 | 32 | This project will upload your assets on your Cloudinary account. The configuration can be found in the `config/plugins.js` file. Using the existing configuration means that you project will also use the cloudinary upload provider when running locally on your machine. 33 | You will need to have the same `CLOUDINARY_NAME`, `CLOUDINARY_KEY` and `CLOUDINARY_SECRET` variables in an `.env` file locally on your machine. 34 | 35 | - Create an `.env` file at the root of your project containing the following code: 36 | 37 | ``` 38 | CLOUDINARY_NAME=... 39 | CLOUDINARY_KEY=... 40 | CLOUDINARY_SECRET=... 41 | ``` 42 | 43 | If you want to upload your assets on your computer when running locally on your machine, please comment the content of your `config/plugins.js` file. 44 | You can also create a `config/env/production/plugins.js` file containing the cloudinary provider and delete your `config/plugins.js`. This way you'll have two different upload providers depending on the environment. 45 | 46 | Strapi comes with a full featured [Command Line Interface](https://docs.strapi.io/developer-docs/latest/developer-resources/cli/CLI.html) (CLI) which lets you scaffold and manage your project in seconds. 47 | 48 | ### `develop` 49 | 50 | Start your Strapi application with autoReload enabled. [Learn more](https://docs.strapi.io/developer-docs/latest/developer-resources/cli/CLI.html#strapi-develop) 51 | 52 | ``` 53 | npm run develop 54 | # or 55 | yarn develop 56 | ``` 57 | 58 | ### `start` 59 | 60 | Start your Strapi application with autoReload disabled. [Learn more](https://docs.strapi.io/developer-docs/latest/developer-resources/cli/CLI.html#strapi-start) 61 | 62 | ``` 63 | npm run start 64 | # or 65 | yarn start 66 | ``` 67 | 68 | ### `build` 69 | 70 | Build your admin panel. [Learn more](https://docs.strapi.io/developer-docs/latest/developer-resources/cli/CLI.html#strapi-build) 71 | 72 | ``` 73 | npm run build 74 | # or 75 | yarn build 76 | ``` 77 | 78 | ## ⚙️ Deployment 79 | 80 | Strapi gives you many possible deployment options for your project. Find the one that suits you on the [deployment section of the documentation](https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/deployment.html). 81 | 82 | ## 📚 Learn more 83 | 84 | - [Resource center](https://strapi.io/resource-center) - Strapi resource center. 85 | - [Strapi documentation](https://docs.strapi.io) - Official Strapi documentation. 86 | - [Strapi tutorials](https://strapi.io/tutorials) - List of tutorials made by the core team and the community. 87 | - [Strapi blog](https://docs.strapi.io) - Official Strapi blog containing articles made by the Strapi team and the community. 88 | - [Changelog](https://strapi.io/changelog) - Find out about the Strapi product updates, new features and general improvements. 89 | 90 | Feel free to check out the [Strapi GitHub repository](https://github.com/strapi/strapi). Your feedback and contributions are welcome! 91 | 92 | ## ✨ Community 93 | 94 | - [Discord](https://discord.strapi.io) - Come chat with the Strapi community including the core team. 95 | - [Forum](https://forum.strapi.io/) - Place to discuss, ask questions and find answers, show your Strapi project and get feedback or just talk with other Community members. 96 | - [Awesome Strapi](https://github.com/strapi/awesome-strapi) - A curated list of awesome things related to Strapi. 97 | 98 | --- 99 | 100 | 🤫 Psst! [Strapi is hiring](https://strapi.io/careers). 101 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Strapi", 3 | "description": "Strapi Heroku 1 click deploy button", 4 | "keywords": [ 5 | "strapi", 6 | "heroku" 7 | ], 8 | "repository": "https://github.com/strapi/strapi-heroku-template", 9 | "addons": [ 10 | "heroku-postgresql:hobby-dev" 11 | ], 12 | "image": "heroku/nodejs", 13 | "buildpacks": [ 14 | { 15 | "url": "heroku/nodejs" 16 | } 17 | ], 18 | "env": { 19 | "CLOUDINARY_NAME": { 20 | "description": "Cloud name of your Cloudinary account", 21 | "required": "true" 22 | }, 23 | "CLOUDINARY_KEY": { 24 | "description": "Cloudinary API Key", 25 | "required": "true" 26 | }, 27 | "CLOUDINARY_SECRET": { 28 | "description": "Cloudinary API Secret", 29 | "required": "true" 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /config/admin.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | auth: { 3 | secret: env('ADMIN_JWT_SECRET', '7396046a9eed089e536d31beff252071'), 4 | }, 5 | }); 6 | -------------------------------------------------------------------------------- /config/api.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rest: { 3 | defaultLimit: 25, 4 | maxLimit: 100, 5 | withCount: true, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /config/database.js: -------------------------------------------------------------------------------- 1 | // const path = require("path"); 2 | 3 | const { parse } = require("pg-connection-string"); 4 | 5 | module.exports = ({ env }) => { 6 | const { host, port, database, user, password } = parse(env("DATABASE_URL")); 7 | 8 | return { 9 | connection: { 10 | client: "postgres", 11 | connection: { 12 | host, 13 | port, 14 | database, 15 | user, 16 | password, 17 | schema: env("DATABASE_SCHEMA", "public"), // Not required 18 | ssl: { 19 | rejectUnauthorized: env.bool("DATABASE_SSL_SELF", false), // For self-signed certificates 20 | }, 21 | }, 22 | debug: false, 23 | }, 24 | }; 25 | }; 26 | 27 | // Use this configuration for an SQLite database on your machine. 28 | // module.exports = ({ env }) => ({ 29 | // connection: { 30 | // client: "sqlite", 31 | // connection: { 32 | // filename: path.join( 33 | // __dirname, 34 | // "..", 35 | // env("DATABASE_FILENAME", ".tmp/data.db") 36 | // ), 37 | // }, 38 | // useNullAsDefault: true, 39 | // }, 40 | // }); 41 | -------------------------------------------------------------------------------- /config/middlewares.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | "strapi::errors", 3 | "strapi::cors", 4 | "strapi::poweredBy", 5 | "strapi::logger", 6 | "strapi::query", 7 | "strapi::body", 8 | "strapi::session", 9 | "strapi::favicon", 10 | "strapi::public", 11 | { 12 | name: "strapi::security", 13 | config: { 14 | contentSecurityPolicy: { 15 | useDefaults: true, 16 | directives: { 17 | "connect-src": ["'self'", "https:"], 18 | "img-src": ["'self'", "data:", "blob:", "res.cloudinary.com"], 19 | "media-src": ["'self'", "data:", "blob:", "res.cloudinary.com"], 20 | upgradeInsecureRequests: null, 21 | }, 22 | }, 23 | }, 24 | }, 25 | ]; 26 | -------------------------------------------------------------------------------- /config/plugins.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | upload: { 3 | config: { 4 | provider: "cloudinary", 5 | providerOptions: { 6 | cloud_name: env("CLOUDINARY_NAME"), 7 | api_key: env("CLOUDINARY_KEY"), 8 | api_secret: env("CLOUDINARY_SECRET"), 9 | }, 10 | actionOptions: { 11 | upload: {}, 12 | delete: {}, 13 | }, 14 | }, 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /config/server.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ env }) => ({ 2 | host: env("HOST", "0.0.0.0"), 3 | port: env.int("PORT", 1337), 4 | app: { 5 | keys: env.array("APP_KEYS", ["testKey1", "testKey2"]), 6 | }, 7 | }); 8 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strapi/strapi-heroku-template/a9292f133753f8064e8a9f2c402969006422e112/favicon.ico -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-project", 3 | "private": true, 4 | "version": "0.1.0", 5 | "description": "A Strapi application", 6 | "scripts": { 7 | "develop": "strapi develop", 8 | "start": "strapi start", 9 | "build": "strapi build", 10 | "strapi": "strapi" 11 | }, 12 | "devDependencies": {}, 13 | "dependencies": { 14 | "@strapi/plugin-i18n": "4.1.2", 15 | "@strapi/plugin-users-permissions": "4.1.2", 16 | "@strapi/provider-upload-cloudinary": "^4.1.2", 17 | "@strapi/strapi": "4.1.2", 18 | "fs": "^0.0.1-security", 19 | "pg": "^8.7.3", 20 | "pg-connection-string": "^2.5.0", 21 | "sqlite3": "5.0.2", 22 | "uuidv4": "^6.2.12" 23 | }, 24 | "author": { 25 | "name": "A Strapi developer" 26 | }, 27 | "strapi": { 28 | "uuid": "61e8a3da-dbc1-4656-ba9a-d9c78e99ef5c" 29 | }, 30 | "engines": { 31 | "node": ">=12.x.x <=16.x.x", 32 | "npm": ">=6.0.0" 33 | }, 34 | "license": "MIT" 35 | } 36 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # To prevent search engines from seeing the site altogether, uncomment the next two lines: 2 | # User-Agent: * 3 | # Disallow: / 4 | -------------------------------------------------------------------------------- /public/uploads/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strapi/strapi-heroku-template/a9292f133753f8064e8a9f2c402969006422e112/public/uploads/.gitkeep -------------------------------------------------------------------------------- /script/postInstall.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const uuid = require("uuid/v4"); 3 | 4 | const filePath = `./package.json`; 5 | 6 | try { 7 | if (fs.existsSync(filePath)) { 8 | let rawFile = fs.readFileSync(filePath); 9 | let packageJSON = JSON.parse(rawFile); 10 | 11 | packageJSON.strapi.uuid = "HEROKU-" + uuid(); 12 | 13 | let data = JSON.stringify(packageJSON); 14 | fs.writeFileSync(filePath, data); 15 | } 16 | } catch (e) { 17 | console.error(e); 18 | } 19 | -------------------------------------------------------------------------------- /src/admin/app.example.js: -------------------------------------------------------------------------------- 1 | export default { 2 | config: { 3 | locales: [ 4 | // 'ar', 5 | // 'fr', 6 | // 'cs', 7 | // 'de', 8 | // 'dk', 9 | // 'es', 10 | // 'he', 11 | // 'id', 12 | // 'it', 13 | // 'ja', 14 | // 'ko', 15 | // 'ms', 16 | // 'nl', 17 | // 'no', 18 | // 'pl', 19 | // 'pt-BR', 20 | // 'pt', 21 | // 'ru', 22 | // 'sk', 23 | // 'sv', 24 | // 'th', 25 | // 'tr', 26 | // 'uk', 27 | // 'vi', 28 | // 'zh-Hans', 29 | // 'zh', 30 | ], 31 | }, 32 | bootstrap(app) { 33 | console.log(app); 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /src/admin/webpack.config.example.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* eslint-disable no-unused-vars */ 4 | module.exports = (config, webpack) => { 5 | // Note: we provide webpack above so you should not `require` it 6 | // Perform customizations to webpack config 7 | // Important: return the modified config 8 | return config; 9 | }; 10 | -------------------------------------------------------------------------------- /src/api/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strapi/strapi-heroku-template/a9292f133753f8064e8a9f2c402969006422e112/src/api/.gitkeep -------------------------------------------------------------------------------- /src/extensions/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strapi/strapi-heroku-template/a9292f133753f8064e8a9f2c402969006422e112/src/extensions/.gitkeep -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | /** 5 | * An asynchronous register function that runs before 6 | * your application is initialized. 7 | * 8 | * This gives you an opportunity to extend code. 9 | */ 10 | register(/*{ strapi }*/) {}, 11 | 12 | /** 13 | * An asynchronous bootstrap function that runs before 14 | * your application gets started. 15 | * 16 | * This gives you an opportunity to set up your data model, 17 | * run jobs, or perform some special logic. 18 | */ 19 | bootstrap(/*{ strapi }*/) {}, 20 | }; 21 | --------------------------------------------------------------------------------