diff --git a/.circleci/config.yml b/.circleci/config.yml index ac9ca05..1c85a93 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,9 +26,32 @@ jobs: name: Test Frontend command: | npm test + build_docker_image: + docker: + - image: circleci/node:14 + + working_directory: ~/app + + steps: + - checkout + - run: + name: Build Docker Image + command: | + docker build -t $DOCKER_HUB_USERNAME/mern-ludo:latest . + - run: + name: Push Docker Image + command: | + echo "$DOCKER_HUB_PASSWORD" | docker login -u "$DOCKER_HUB_USERNAME" --password-stdin + docker push $DOCKER_HUB_USERNAME/mern-ludo:latest + + workflows: version: 2 build: jobs: - build_and_test + - build_docker_image: + filters: + branches: + only: main \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..71a7578 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,35 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/engine/reference/builder/#dockerignore-file + +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.next +**/.cache +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +**/build +**/dist +LICENSE +README.md +node_modules diff --git a/.gitignore b/.gitignore index d2d2990..2e01d74 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ backend/node_modules /coverage # production -/build +build # misc .DS_Store @@ -21,3 +21,4 @@ backend/node_modules npm-debug.log* yarn-debug.log* yarn-error.log* +.env \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8c665bc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM node:14 as frontend +WORKDIR /app +COPY . /app +RUN npm install --production +RUN npm run build + +FROM node:14 as backend +WORKDIR /app +COPY /backend /app +RUN npm install + +FROM node:14 +WORKDIR /app +COPY --from=backend /app /app/ +COPY --from=frontend /app/build /app/build + +EXPOSE 8080 + +CMD ["npm", "run", "start"] diff --git a/README.md b/README.md index af4d172..e4ce3f8 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ mongodb+srv://madmin:@clustername.mongodb.net/?retryWrites=tru ``` -3. Add this URL to the /backend/credentials.js file +3. Add this URL to the /backend/.env file (refer to .env.example) 4. Perform these commands in the main directory: diff --git a/backend/.env.example b/backend/.env.example new file mode 100644 index 0000000..52a81f1 --- /dev/null +++ b/backend/.env.example @@ -0,0 +1,3 @@ +PORT=8080 +CONNECTION_URI=your_mongodb_connection_uri +NODE_ENV="development" \ No newline at end of file diff --git a/backend/config/database.js b/backend/config/database.js index 5873253..f347966 100644 --- a/backend/config/database.js +++ b/backend/config/database.js @@ -1,9 +1,7 @@ -const CONNECTION_URI = require('../credentials.js'); - module.exports = function (mongoose) { mongoose.set('useFindAndModify', false); mongoose - .connect(CONNECTION_URI, { + .connect(process.env.CONNECTION_URI, { useNewUrlParser: true, useUnifiedTopology: true, dbName: 'test', diff --git a/backend/config/session.js b/backend/config/session.js index 56ead1c..c66fb40 100644 --- a/backend/config/session.js +++ b/backend/config/session.js @@ -1,8 +1,8 @@ const session = require('express-session'); -const CONNECTION_URI = require('../credentials.js'); const MongoDBStore = require('connect-mongodb-session')(session); + const store = new MongoDBStore({ - uri: CONNECTION_URI, + uri: process.env.CONNECTION_URI, collection: 'sessions', }); const sessionMiddleware = session({ diff --git a/backend/credentials.js b/backend/credentials.js deleted file mode 100644 index 4be1469..0000000 --- a/backend/credentials.js +++ /dev/null @@ -1,2 +0,0 @@ -// Write your own mongoDBatlas credentials here -module.exports = ''; diff --git a/backend/package-lock.json b/backend/package-lock.json index df591ca..4e797bb 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -10,6 +10,7 @@ "connect-mongodb-session": "^3.1.1", "cookie-parser": "^1.4.5", "cors": "^2.8.5", + "dotenv": "^16.3.1", "express": "^4.17.1", "express-session": "^1.17.1", "mongoose": "^5.12.0", @@ -708,6 +709,17 @@ "node": ">=0.3.1" } }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -3157,6 +3169,11 @@ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, + "dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", diff --git a/backend/package.json b/backend/package.json index c45bf84..3f5149b 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,6 +5,7 @@ "connect-mongodb-session": "^3.1.1", "cookie-parser": "^1.4.5", "cors": "^2.8.5", + "dotenv": "^16.3.1", "express": "^4.17.1", "express-session": "^1.17.1", "mongoose": "^5.12.0", diff --git a/backend/server.js b/backend/server.js index f018038..b4a1cd0 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1,10 +1,12 @@ const express = require('express'); const cors = require('cors'); +const path = require('path'); const cookieParser = require('cookie-parser'); const mongoose = require('mongoose'); +require('dotenv').config(); const { sessionMiddleware } = require('./config/session'); -const PORT = 8080; +const PORT = process.env.PORT; const app = express(); @@ -30,9 +32,10 @@ require('./config/database')(mongoose); require('./config/socket')(server); if (process.env.NODE_ENV === 'production') { - app.use(express.static('/app/build')); - app.get('/', (req, res) => { - res.sendFile('/app/build/index.html'); + app.use(express.static('./build')); + app.get('*', (req, res) => { + const indexPath = path.join(__dirname, './build/index.html'); + res.sendFile(indexPath); }); } diff --git a/package.json b/package.json index 5f62271..e7ffcc6 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,7 @@ "scripts": { "start": "react-scripts start", "build": "react-scripts build", - "heroku-postbuild": "cd backend && npm install && cd .. && npm install && npm run build", - "test": "react-scripts test", - "eject": "react-scripts eject" + "test": "react-scripts test" }, "eslintConfig": { "extends": [ @@ -48,11 +46,10 @@ "last 1 safari version" ] }, - "proxy": "http://localhost:5000", "devDependencies": { "@testing-library/jest-dom": "^6.1.5", "@testing-library/react": "^14.1.2", "cypress": "^13.6.1", - "@babel/plugin-proposal-private-property-in-object": "^7.16.7" + "@babel/plugin-transform-private-property-in-object": "^7.16.7" } }