Skip to content

Commit

Permalink
Merge pull request #57 from weaponsforge/wip/weaponsforge-53
Browse files Browse the repository at this point in the history
Wip/weaponsforge 53
  • Loading branch information
weaponsforge authored Aug 30, 2022
2 parents be2aed9 + 8afbf77 commit f8782c9
Show file tree
Hide file tree
Showing 15 changed files with 169 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
name: Deploy to Production Environment

# This workflow deploys the backend, a full-server express app to Vercel
# as opposed to their recommended approach of deploying serverless functions
# using NextJS "pages/api". Vercel CLI v28.2.0 is used for deployment

# This workflow will trigger on any tag/release created on *any* branch
# Make sure to create tags/releases only from the "master" branch for consistency
on:
Expand Down Expand Up @@ -60,7 +64,7 @@ jobs:
npm install
npm run lint
deploy-docs:
deploy-client:
name: Deploy client to Github Pages
needs: lint-client
runs-on: ubuntu-latest
Expand All @@ -77,3 +81,37 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./
publish_branch: gh-pages

deploy-server:
name: Deploy Server to Vercel
needs: lint-server
runs-on: ubuntu-latest
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
steps:
- name: Checkout the repository
uses: actions/checkout@v3
- name: Use NodeJS v16.14.2
uses: actions/setup-node@v3
with:
node-version: 16.14.2
- name: Install Vercel CLI
run: npm install --global [email protected]
- name: Pull Vercel Environment Information
run: |
cd server
vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: |
cd server
vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: |
cd server
vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: Post Deployment Clean-up
run: |
cd server
rm -r -f .vercel
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ node_modules/
.vscode
.env
*.zip

.vercel

.vercel
3 changes: 3 additions & 0 deletions server/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
ALLOWED_ORIGINS=http://localhost:3000
ALLOW_CORS=0
API_RATE_LIMIT=100
API_WINDOW_MS_MINUTES=15
MONGO_URI=mongodb://localhost/todo-next
DEPLOYMENT_PLATFORM=regular
2 changes: 2 additions & 0 deletions server/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
node_modules/
.env
*.zip

.vercel
15 changes: 15 additions & 0 deletions server/.vercelignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
node_modules/
*.env
*.zip
*.md
*.toml

.vercel
.vscode
.git
.github
.eslintrc.js
.eslintignore
.vercelignore
package.json
package-lock.json
13 changes: 8 additions & 5 deletions server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,14 @@ The following dependencies are used for this project's localhost development env

3. Set up the environment variables. Create a `.env `file inside the **/server** directory with reference to the `.env.example` file.<br>

| Variable Name | Description |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| MONGO_URI | MongoDB connection string.<br>Default value uses the localhost MongoDB connection string. |
| ALLOWED_ORIGINS | IP/domain origins in comma-separated values that are allowed to access the API if `ALLOW_CORS=1`.<br> Include `http://localhost:3000` by default to allow CORS access to the **/client** app. |
| ALLOW_CORS | Allow Cross-Origin Resource Sharing (CORS) on the API endpoints.<br><br>Default value is `1`, allowing access to domains listed in `ALLOWED_ORIGINS`.<br> Setting to `0` will make all endpoints accept requests from all domains, including Postman. |
| Variable Name | Description |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API_WINDOW_MS_MINUTES | Time in `minutes` where `API_RATE_LIMIT` times of successive calls from an IP are allowed on the server. |
| API_RATE_LIMIT | It's the maximum number of allowed API requests on the server per `API_WINDOW_MS_MINUTES`. <br>Users will receive a `429 - Too many requests` server error after hitting the limit.<br>The limit will reset after API_WINDOW_MS_MINUTES minutes, after which users can resume making API requests. |
| ALLOW_CORS | Allow Cross-Origin Resource Sharing (CORS) on the API endpoints.<br><br>Default value is `1`, allowing access to domains listed in `ALLOWED_ORIGINS`.<br> Setting to `0` will make all endpoints accept requests from all domains, including Postman. |
| ALLOWED_ORIGINS | IP/domain origins in comma-separated values that are allowed to access the API if `ALLOW_CORS=1`.<br> Include `http://localhost:3000` by default to allow CORS access to the **/client** app. |
| DEPLOYMENT_PLATFORM | This variable refers to the backend `server`'s hosting platform, defaulting to `DEPLOYMENT_PLATFORM=regular`<br>for full-server NodeJS express apps.<br><br>Valid values are:<br>`regular` - for traditional full-server NodeJS express apps<br>`vercel` - for Vercel (serverless) |
| MONGO_URI | MongoDB connection string.<br>Default value uses the localhost MongoDB connection string. |

## Usage

Expand Down
13 changes: 13 additions & 0 deletions server/api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## api

The `/api` directory is required by vercel when using the @latest `vercel.json` configuration file settings (for Vercel CLI v28.2.0 as of this writing).

Ideally, this directory should contain **serverless functions** [written per file](https://vercel.com/guides/using-express-with-vercel#next.js) following the NextJS api pages writing guide, but we'd like to deploy a standalone full-server express app on vercel.

### References

[[1]](https://vercel.com/guides/using-express-with-vercel) - using express with vercel<br>
[[2]](https://vercel.com/docs/project-configuration#project-configuration/functions) - project config with vercel.json

@weaponsforge<br>
20220828
4 changes: 4 additions & 0 deletions server/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require('dotenv').config()
const app = require('../src/index')

module.exports = app
18 changes: 18 additions & 0 deletions server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
"name": "server",
"version": "1.0.0",
"description": "This directory will contain the backend express server that will serve the Todo CRUD API endpoints.",
"main": "src/index.js",
"main": "api/index.js",
"scripts": {
"start": "node src/index.js",
"start": "node api/index.js",
"start:vercel": "node api/index.js",
"dev": "nodemon watch src/index.js",
"lint": "eslint src",
"lint:fix": "eslint src --fix"
Expand All @@ -16,6 +17,7 @@
"cors": "^2.8.5",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"express-rate-limit": "^6.5.2",
"mongoose": "^6.5.2"
},
"devDependencies": {
Expand Down
10 changes: 10 additions & 0 deletions server/public/401.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>401</title>
</head>
<body>
<p>Unauthorized</p>
</body>
</html>
10 changes: 10 additions & 0 deletions server/public/404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
<p>404 Not Found</p>
</body>
</html>
10 changes: 10 additions & 0 deletions server/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Todo Notes API</title>
</head>
<body>
<p>Welcome to the Todo Notes API v1</p>
</body>
</html>
19 changes: 15 additions & 4 deletions server/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ require('./utils/db')
const express = require('express')
const cors = require('cors')
const cookieParser = require('cookie-parser')
const rateLimit = require('express-rate-limit')
const app = express()
const PORT = process.env.PORT || 3001

const { corsOptions } = require('./utils/cors_options')
const controllers = require('./controllers')

const limiter = rateLimit({
windowMs: process.env.API_WINDOW_MS_MINUTES * 60 * 1000, // in minutes
max: process.env.API_RATE_LIMIT, // limit each IP to API_RATE_LIMIT requests per windowMs
message: 'Too many requests from this IP. Please try again after 15 minutes.'
})

// Initialize the express app
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
Expand All @@ -19,7 +26,7 @@ if (process.env.ALLOW_CORS === '1') {
app.use(cors(corsOptions))
}

app.use('/api', controllers)
app.use('/api', limiter, controllers)

app.get('*', (req, res) => {
return res.status(200).send('Welcome to the Todo API')
Expand All @@ -29,6 +36,10 @@ app.use((err, req, res, next) => {
return res.status(500).send(err.message)
})

app.listen(PORT, () => {
console.log(`listening on http://localhost:${PORT}`)
})
if (process.env.DEPLOYMENT_PLATFORM !== 'vercel') {
app.listen(PORT, () => {
console.log(`listening on http://localhost:${PORT}`)
})
}

module.exports = app
14 changes: 14 additions & 0 deletions server/vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"rewrites": [
{
"source": "/api/(.*)",
"destination": "/api"
}
],
"redirects": [
{
"source": "/src(.*)",
"destination": "/public/401.html"
}
]
}

0 comments on commit f8782c9

Please sign in to comment.