Skip to content

Commit 89bed72

Browse files
committed
Add ability to run locally with Docker. Update packages. Add ping endpoint.
1 parent d6840b0 commit 89bed72

13 files changed

+4344
-2306
lines changed

.dockerignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
.dynamodb/
3+
.history/
4+
.webpack/

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ yarn-error.log
66
.history/
77
.terraform/
88
*.tfplan*
9-
*.tfstate*
9+
*.tfstate*
10+
.dynamodb/

Dockerfile

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM node:10-alpine
2+
WORKDIR /app
3+
4+
COPY package.json yarn.lock serverless.yml ./
5+
RUN yarn install --ignore-scripts
6+
7+
COPY tsconfig.json tsconfig.json tslint.json webpack.config.ts ./
8+
COPY src src
9+
10+
EXPOSE 3000/tcp
11+
12+
ENTRYPOINT ["yarn", "run", "docker-dev"]

README.md

+21-3
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,37 @@ See [Apiary](http://docs.serverlessapi.apiary.io) for API structure - defined in
2222

2323
To run locally you must run two servers - DB and API.
2424

25-
Serverless-webpack, serverless-dynamodb-local and serverless-offline offer great tooling for local Serverless development. To start a local server that will mimic AWS API Gateway, run the commands below. Both servers will fire up and code will be reloaded upon change so that every request to your local server will serve the latest code.
25+
Serverless-webpack, serverless-dynamodb-local and serverless-offline offer great tooling for local Serverless development. To start local servers that mimic AWS API Gateway and DyanamoDB, run the commands below. Both servers will fire up and code will be reloaded upon change so that every request to your API will serve the latest code.
2626

2727
Serverless-dynamodb-local requires Java Runtime Engine (JRE) version 6.x or newer.
2828

29-
**DYNAMODB_PORT and AUTH0_CLIENT_SECRET environment variables must be set before `yarn run dev` command below.**
29+
**AUTH0_CLIENT_SECRET environment variable must be set before `yarn run dev` command below. Optional DYNAMODB_PORT and DYNAMODB_HOST environment variables may be set to override the defaults (localhost:8000).**
3030

31-
E.g. `DYNAMODB_PORT=8001 AUTH0_CLIENT_SECRET=YOUR_SECRET yarn run dev`
31+
E.g. `AUTH0_CLIENT_SECRET=YOUR_SECRET yarn run dev`
3232

3333
```
3434
yarn install (serverless dynamodb install included as postinstall script)
3535
yarn run dev
3636
```
3737

38+
Submit requests to http://localhost:3000. The DynamoDB shell console is available at http://localhost:8000/shell.
39+
40+
## Running locally with Docker
41+
42+
Maintaining a Java installation for the sake of running DynamoDB locally is a pain, running in a Docker container is far easier. As above, to run locally you must run two servers - DB and API.
43+
44+
To start the local servers that mimic AWS API Gateway and DyanamoDB using docker, run the commands below.
45+
46+
**AUTH0_CLIENT_SECRET environment variable must be set before `docker-compose up --build` command below.**
47+
48+
E.g. `AUTH0_CLIENT_SECRET=YOUR_SECRET docker-compose up --build`
49+
50+
```
51+
docker-compose up --build
52+
```
53+
54+
Submit requests to http://localhost:3000. The DynamoDB shell console is available at http://localhost:8000/shell.
55+
3856
## Testing
3957

4058
TBC

docker-compose.yml

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
version: '3.7'
2+
services:
3+
dynamodb:
4+
image: amazon/dynamodb-local
5+
restart: always
6+
healthcheck:
7+
test: ["CMD-SHELL", "curl -f http://localhost:8000/shell/ || exit 1"]
8+
interval: 1s
9+
timeout: 10s
10+
retries: 3
11+
ports:
12+
- "8000:8000"
13+
expose:
14+
- "8000"
15+
16+
api:
17+
build:
18+
context: .
19+
depends_on:
20+
- dynamodb
21+
links:
22+
- dynamodb
23+
ports:
24+
- "3000:3000"
25+
restart: always
26+
healthcheck:
27+
test: "curl -f http://api/ping"
28+
interval: 5s
29+
timeout: 3s
30+
retries: 5
31+
environment:
32+
AUTH0_CLIENT_SECRET: ${AUTH0_CLIENT_SECRET}
33+
DYNAMODB_HOST: dynamodb
34+
DYNAMODB_PORT: 8000
35+
DYNAMODB_NO_START: 'true'

package.json

+29-27
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,41 @@
55
"main": "src/index.ts",
66
"scripts": {
77
"postinstall": "serverless dynamodb install",
8-
"dev": "serverless offline start",
8+
"dev": "cross-env NODE_ENV=development serverless offline start",
9+
"docker-dev": "cross-env NODE_ENV=development serverless offline start --host 0.0.0.0",
910
"lint": "tslint --type-check --project tsconfig.json || exit 0",
1011
"deploy": "cross-env NODE_ENV=production serverless deploy"
1112
},
1213
"author": "Jordan Hornblow <[email protected]>",
1314
"license": "MIT",
1415
"dependencies": {
15-
"aws-sdk": "^2.117.0",
16-
"jsonwebtoken": "^8.0.1",
17-
"moment": "^2.18.1",
18-
"uuid": "^3.1.0"
16+
"aws-sdk": "^2.531.0",
17+
"jsonwebtoken": "^8.5.1",
18+
"moment": "^2.24.0",
19+
"uuid": "^3.3.3"
1920
},
2021
"devDependencies": {
21-
"@types/aws-lambda": "^0.0.16",
22-
"@types/jsonwebtoken": "^7.2.3",
23-
"@types/node": "^8.0.28",
24-
"@types/uuid": "^3.4.2",
25-
"@types/webpack": "^3.0.10",
26-
"awesome-typescript-loader": "^3.2.3",
27-
"cross-env": "^5.0.5",
28-
"serverless": "^1.22.0",
29-
"serverless-dynamodb-autoscaling": "^0.6.1",
30-
"serverless-dynamodb-local": "^0.2.25",
31-
"serverless-offline": "^3.16.0",
32-
"serverless-plugin-custom-domain": "^2.0.0",
33-
"serverless-webpack": "^3.0.0",
34-
"source-map-loader": "^0.2.1",
35-
"tslint": "^5.7.0",
36-
"tslint-config-airbnb": "^5.3.0",
37-
"tslint-loader": "^3.5.3",
38-
"tsutils": "^2.8.2",
39-
"typescript": "^2.5.2",
40-
"webpack": "^3.6.0",
41-
"webpack-node-externals": "^1.6.0"
22+
"@types/aws-lambda": "^8.10.31",
23+
"@types/jsonwebtoken": "^8.3.4",
24+
"@types/node": "^12.7.5",
25+
"@types/uuid": "^3.4.5",
26+
"@types/webpack": "^4.39.1",
27+
"cross-env": "^6.0.0",
28+
"fork-ts-checker-webpack-plugin": "^1.5.0",
29+
"serverless": "^1.52.0",
30+
"serverless-dynamodb-autoscaling": "^0.6.2",
31+
"serverless-dynamodb-local": "^0.2.38",
32+
"serverless-offline": "^5.11.0",
33+
"serverless-plugin-custom-domain": "^2.0.2",
34+
"serverless-webpack": "^5.3.1",
35+
"source-map-loader": "^0.2.4",
36+
"ts-loader": "^6.1.0",
37+
"tslint": "^5.20.0",
38+
"tslint-config-airbnb": "^5.11.1",
39+
"tslint-loader": "^3.5.4",
40+
"tsutils": "^3.17.1",
41+
"typescript": "^3.6.3",
42+
"webpack": "^4.40.2",
43+
"webpack-node-externals": "^1.7.2"
4244
}
43-
}
45+
}

serverless.yml

+19-4
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@ package:
3030

3131
custom:
3232
domain: sls-api.603.nz
33-
webpack: ./webpack.config.ts
34-
webpackIncludeModules: true
33+
webpack:
34+
webpackConfig: ./webpack.config.ts
35+
includeModules: true
3536
dynamodb:
3637
start:
37-
port: ${env:DYNAMODB_PORT}
38-
inMemory: true
38+
port: ${env:DYNAMODB_PORT, 8000}
39+
host: ${env:DYNAMODB_HOST, localhost}
3940
migrate: true
41+
noStart: ${env:DYNAMODB_NO_START, false}
42+
stages:
43+
- ${self:provider.stage}
4044
capacities:
4145
- table: ItemsTable
4246
index:
@@ -51,6 +55,17 @@ custom:
5155
usage: 0.1
5256

5357
functions:
58+
ping:
59+
handler: src/index.pingHandler
60+
memory: 512
61+
timeout: 60
62+
events:
63+
- http:
64+
method: get
65+
path: ping
66+
cors: true
67+
integration: lambda-proxy
68+
5469
authorizer:
5570
handler: src/index.authorizer
5671
environment:

src/Event.ts

-32
This file was deleted.

src/Response.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default class Response {
1111
statusCode: number;
1212
body?: string;
1313
headers: {
14-
[name: string] : string,
14+
[name: string]: string,
1515
};
1616

1717
constructor(args: ResponseArgs = defaultResponseArgs) {
@@ -25,4 +25,3 @@ export default class Response {
2525
}
2626
}
2727
}
28-

src/database.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import ResponseError from './ResponseError';
88
const db = process.env.IS_OFFLINE ?
99
new DynamoDB.DocumentClient({
1010
region: 'localhost',
11-
endpoint: `http://localhost:${process.env.DYNAMODB_PORT}`,
11+
accessKeyId: 'MOCK_ACCESS_KEY_ID',
12+
secretAccessKey: 'MOCK_SECRET_ACCESS_KEY',
13+
endpoint: `http://${process.env.DYNAMODB_HOST || 'localhost'}:${process.env.DYNAMODB_PORT || 8000}`,
1214
}) :
1315
new DynamoDB.DocumentClient();
1416

@@ -40,7 +42,7 @@ export async function getItemById(userId: string, itemId: string): Promise<Item>
4042

4143
if (data.Item === undefined) {
4244
const notFoundError = new Error(`An item could not be found with id: ${itemId}`) as ResponseError;
43-
45+
4446
notFoundError.responseStatusCode = 404;
4547

4648
throw notFoundError;

0 commit comments

Comments
 (0)