Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"extends": ["xo-space"],
"env": {
"jest": true
},
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,5 @@ override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc

env_variables.yml
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16.4.2
16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Dockerfile
FROM node:16-alpine as build

WORKDIR /usr/app
COPY . .
ENV NODE_ENV=production
ENV PORT=8080
ENV SOCKET_PORT=65080
RUN yarn install --frozen-lockfile --production=false
RUN yarn build

FROM node:16-alpine
WORKDIR /usr/app
COPY --from=build /usr/app .
EXPOSE 8080 65080
CMD yarn start
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,16 @@ This was created mainly for offline gaming, to avoid writing player lists manual

### Production setup (maintainers only):

- To be updated for docker-container and k8s support
Reference - https://github.com/Deeptiman/go-cache-kubernetes (https://deeptiman.medium.com/a-data-caching-service-in-kubernetes-1e9dbcdb8f91)

- Create k8s cluster (By default, 3 standard nodes are created for our cluster)
`gcloud container clusters create fifa-api-server --zone asia-south1-a`
- Get the credentials so we can manage it locally through kubectl
`gcloud container clusters get-credentials fifa-api-server --zone asia-south1-a`
- Apply redis deployment
`kubectl apply k8s/redis/redis-deployment.yaml`
- Apply mongodb deployment
`kubectl apply k8s/mongodb/mongodb-deployment.yaml`

#### Setup terraforn

Expand All @@ -45,7 +54,7 @@ This was created mainly for offline gaming, to avoid writing player lists manual
ssh-keygen -f ~/.ssh/gcloud_id_rsa
```

#### Old version
#### Old deployment instructions

Build and use pm2 to start your process

Expand Down
26 changes: 26 additions & 0 deletions app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# [START appengine_yaml]
service: fifa-multiplayer-server
# Default runtime with node v12.19 not compatible
runtime: custom
env: flex

# Use only a single instance, so that this local-memory-only app will work
# consistently with multiple users. To work across multiple instances, an
# extra-instance messaging system or data store would be needed.
manual_scaling:
instances: 1
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10
includes:
- env_variables.yml

# [START network]
network:
instance_tag: websocket
forwarded_ports:
- 65080
session_affinity: true
# [END network]
# [END appengine_yaml]
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ services:
volumes:
- redis-vol:/var/lib/redis
ports:
- '${REDIS_PORT}:${REDIS_PORT}'
- 6379:6379
networks:
- fifa-network

Expand Down
26 changes: 26 additions & 0 deletions k8s/app/app-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: fifa-api
spec:
selector:
matchLabels:
app: fifa-api
template:
metadata:
labels:
app: fifa-api
spec:
containers:
- name: fifa-api
image: sauravmh/fifa-api:latest
imagePullPolicy: Never
resources:
requests:
memory: '64Mi'
cpu: '250m'
limits:
memory: '500Mi'
cpu: '4G'
ports:
- containerPort: 8080
Empty file added k8s/app/app-service.yaml
Empty file.
13 changes: 13 additions & 0 deletions k8s/mongodb/mongodb-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: mongodb-service
labels:
name: mongo
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None
selector:
role: mongo
53 changes: 53 additions & 0 deletions k8s/mongodb/mongodb-statefulset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongod
spec:
serviceName: mongodb-service
replicas: 3
selector:
matchLabels:
role: mongo
template:
metadata:
labels:
role: mongo
environment: test
replicaset: MainRepSet
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mongod-container
image: mongo
env:
- name: PUID
value: '1000'
- name: PGID
value: '1000'
- name: MONGO_INITDB_DATABASE
value: 'fifa-db'
command:
- 'mongod'
- '--bind_ip'
- '0.0.0.0'
- '--replSet'
- 'MainRepSet'
resources:
requests:
cpu: '0.2'
memory: 200Mi
ports:
- containerPort: 27017
volumeMounts:
- name: mongodb-persistent-storage-claim
mountPath: /data/db
volumeClaimTemplates:
- metadata:
name: mongodb-persistent-storage-claim
annotations:
volume.beta.kubernetes.io/storage-class: 'standard'
spec:
accessModes: ['ReadWriteOnce']
resources:
requests:
storage: 1Gi
30 changes: 30 additions & 0 deletions k8s/redis/redis-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: redismod
spec:
replicas: 1
selector:
matchLabels:
app: redismod
template:
metadata:
labels:
app: redismod
spec:
containers:
- name: redismod
image: redislabs/redismod
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
memory: '1G'
cpu: '4G'
ports:
- containerPort: 6379
securityContext:
capabilities:
add:
- SYS_RESOURCE
12 changes: 12 additions & 0 deletions k8s/redis/redis-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: redis-service
labels:
app: redis-service
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redismod
15 changes: 9 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
"name": "fifa-api",
"version": "1.1.0",
"description": "Fifa custom Team builder API based on express js with es6 and integrated with mongodb",
"type": "module",
"exports": "./build/app.js",
"main": "./build/app.js",
"engines": {
"node": ">=12.19.0"
"node": "16.x"
},
"scripts": {
"test": "jest",
"build": "babel ./src --out-dir ./build -s",
"start": "node build/app.js",
"start": "node ./build/app.js",
"dev": "nodemon --exec babel-node src/app.js",
"lint": "xo"
"lint": "xo",
"gcp-build": "yarn build"
},
"xo": {
"prettier": true,
Expand Down Expand Up @@ -47,7 +48,7 @@
"@babel/node": "7.12.17",
"@babel/plugin-transform-runtime": "^7.13.8",
"@babel/preset-env": "7.12.17",
"@babel/runtime": "7.12.18",
"@babel/runtime": "7.15.4",
"algoliasearch": "4.8.5",
"babel-eslint": "10.1.0",
"bcrypt": "5.0.0",
Expand All @@ -56,8 +57,10 @@
"dotenv": "8.2.0",
"eslint-config-xo-space": "^0.27.0",
"eslint-plugin-prettier": "^3.4.0",
"jest": "^27.0.6",
"nodemon": "2.0.7",
"prettier": "2.2.1",
"socket.io-client": "^4.1.2",
"xo": "^0.40.1"
}
}
1 change: 0 additions & 1 deletion sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ ALGOLIA_INDEX_NAME=dev_PLAYERS
ALGOLIA_ID=QZWP9XEPO2

REDIS_PORT=6379
API_PORT=8080
SOCKET_PORT=65080
4 changes: 2 additions & 2 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ app.use((error, _request, response, _) => {
handleError(error, response);
});

app.listen(config.API_PORT, () => {
consola.success(`Api listening on port ${config.API_PORT}!`);
app.listen(config.PORT, () => {
consola.success(`Api listening on port ${config.PORT}!`);
});

server.listen(config.SOCKET_PORT, () => {
Expand Down
2 changes: 1 addition & 1 deletion src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const config = {

DB_URL: getDefault(process.env.DB_URL, 'mongodb://localhost:27017/fifa-db'),
JWT_SECRET: getDefault(process.env.JWT_SECRET, 'REDACTED'),
API_PORT: process.env.API_PORT ? Number.parseInt(process.env.API_PORT, 10) : 8080,
PORT: process.env.PORT ? Number.parseInt(process.env.PORT, 10) : 8080,
SOCKET_PORT: process.env.SOCKET_PORT ? Number.parseInt(process.env.SOCKET_PORT, 10) : 65080,
REDIS_PORT: process.env.REDIS_PORT ? Number.parseInt(process.env.REDIS_PORT, 10) : 6379,
REDIS_HOST: getDefault(process.env.REDIS_HOST, 'localhost'),
Expand Down
45 changes: 45 additions & 0 deletions src/socker/tests/createSocketConnection.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { createServer } from 'http';
import { Server } from 'socket.io';
import Client from 'socket.io-client';

describe('Initiate a socket-io connection', () => {
let io;
let serverSocket;
let clientSocket;

beforeAll(done => {
const httpServer = createServer();
io = new Server(httpServer);
httpServer.listen(() => {
const port = httpServer.address().port;
clientSocket = new Client(`http://localhost:${port}`);
io.on('connection', socket => {
serverSocket = socket;
});
clientSocket.on('connect', done);
});
});

afterAll(() => {
io.close();
clientSocket.close();
});

test('[emit] form server and [recieve] to client message', done => {
clientSocket.on('hello', arg => {
expect(arg).toBe('world');
done();
});
serverSocket.emit('hello', 'world');
});

test('[emit] form client and [recieve] to server message', done => {
serverSocket.on('hi', cb => {
cb('hola');
});
clientSocket.emit('hi', arg => {
expect(arg).toBe('hola');
done();
});
});
});
Loading