fixed a docker issue updated the README
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
node_modules
|
node_modules
|
||||||
App.css
|
|
||||||
start_in_tmux.sh
|
start_in_tmux.sh
|
||||||
default.json
|
default.json
|
||||||
production.json
|
production.json
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Dev connector
|
||||||
|
---
|
||||||
|
> Web app created with React, Redux, MUI in the front end. Express and mongoose
|
||||||
|
> on the back end. It also has docker images.
|
||||||
|
|
||||||
|
## Docker Usage:
|
||||||
|
`docker compose -f docker-compose.yml up`
|
||||||
|
> The app is available at http://localhost:8080
|
||||||
|
|
||||||
|
## Run the app locally
|
||||||
|
Requires running mongodb service.
|
||||||
|
|
||||||
|
In the client directory:
|
||||||
|
`npm run dev`
|
||||||
|
In the server directory:
|
||||||
|
```MONGO_URL=mongodb://the_username:the_password@localhost:3456/the_database JWT_SECRET=mysecrettoken npm run server```
|
||||||
|
The app will be available at http://localhost:5173
|
||||||
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
# The first FROM is now a stage called build-stage
|
|
||||||
|
|
||||||
FROM node:20 AS build-stage
|
FROM node:20 AS build-stage
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
services:
|
|
||||||
app:
|
|
||||||
image: devcon-frontend-dev
|
|
||||||
build:
|
|
||||||
context: . # The context will pick this directory as the "build context"
|
|
||||||
dockerfile: dev.Dockerfile # This will simply tell which dockerfile to read
|
|
||||||
volumes:
|
|
||||||
- ./:/usr/src/app # The path can be relative, so ./ is enough to say "the same location as the docker-compose.yml"
|
|
||||||
ports:
|
|
||||||
- 5173:3000
|
|
||||||
container_name: devcon-front-dev
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
services:
|
|
||||||
app:
|
|
||||||
image: todo-front-dev
|
|
||||||
build:
|
|
||||||
context: . # The context will pick this directory as the "build context"
|
|
||||||
dockerfile: dev.Dockerfile # This will simply tell which dockerfile to read
|
|
||||||
volumes:
|
|
||||||
- ./:/usr/src/app # The path can be relative, so ./ is enough to say "the same location as the docker-compose.yml"
|
|
||||||
ports:
|
|
||||||
- 5173:5173
|
|
||||||
container_name: todo-front
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: devcon-frontend-dev
|
image: devcon-frontend
|
||||||
build:
|
build:
|
||||||
context: ./client
|
context: ./client
|
||||||
dockerfile: ./dev.Dockerfile
|
dockerfile: ./Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- 5173:5173
|
- 5173:5173
|
||||||
environment:
|
environment:
|
||||||
@@ -12,10 +12,10 @@ services:
|
|||||||
- ./client:/usr/src/app
|
- ./client:/usr/src/app
|
||||||
|
|
||||||
server:
|
server:
|
||||||
image: devcon-backend-dev
|
image: devcon-backend
|
||||||
build:
|
build:
|
||||||
context: ./server
|
context: ./server
|
||||||
dockerfile: ./dev.Dockerfile
|
dockerfile: ./Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- 5000:5000
|
- 5000:5000
|
||||||
volumes:
|
volumes:
|
||||||
+7
-5
@@ -1,19 +1,21 @@
|
|||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: devcon-frontend-dev
|
image: devcon-frontend
|
||||||
build:
|
build:
|
||||||
context: ./client
|
context: ./client
|
||||||
dockerfile: ./dev.Dockerfile
|
dockerfile: ./Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 8080:80
|
||||||
|
environment:
|
||||||
|
VITE_BACKEND_URL: http://server:5000
|
||||||
volumes:
|
volumes:
|
||||||
- ./client:/usr/src/app
|
- ./client:/usr/src/app
|
||||||
|
|
||||||
server:
|
server:
|
||||||
image: devcon-backend-dev
|
image: devcon-backend
|
||||||
build:
|
build:
|
||||||
context: ./server
|
context: ./server
|
||||||
dockerfile: ./dev.Dockerfile
|
dockerfile: ./Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- 5000:5000
|
- 5000:5000
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -2,14 +2,12 @@ FROM node:20
|
|||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
|
||||||
COPY --chown=node:node . .
|
COPY --chown=node:node . .
|
||||||
|
|
||||||
RUN npm ci
|
RUN npm ci
|
||||||
|
|
||||||
ENV DEBUG=express:*
|
ENV DEBUG=express:*
|
||||||
|
|
||||||
|
|
||||||
USER node
|
USER node
|
||||||
|
|
||||||
CMD npm start
|
CMD npm start
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ ENV DEBUG=express:*
|
|||||||
|
|
||||||
USER node
|
USER node
|
||||||
|
|
||||||
CMD npm start server
|
CMD npm run server
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
services:
|
|
||||||
mongo:
|
|
||||||
image: mongo
|
|
||||||
ports:
|
|
||||||
- 3456:27017
|
|
||||||
environment:
|
|
||||||
MONGO_INITDB_ROOT_USERNAME: root
|
|
||||||
MONGO_INITDB_ROOT_PASSWORD: example
|
|
||||||
MONGO_INITDB_DATABASE: the_database
|
|
||||||
volumes:
|
|
||||||
- ../mongo/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js
|
|
||||||
- mongo_data:/data/db
|
|
||||||
server: # The name of the service, can be anything
|
|
||||||
image: devcon-backend-dev # Declares which image to use
|
|
||||||
build: . # Declares where to build if image is not found
|
|
||||||
ports: # Declares the ports to publish
|
|
||||||
- 5000:5000
|
|
||||||
volumes:
|
|
||||||
- ./.:/usr/src/app
|
|
||||||
environment:
|
|
||||||
MONGO_URL: "mongodb://the_username:the_password@mongo:27017/the_database"
|
|
||||||
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
mongo_data:
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
services:
|
|
||||||
app: # The name of the service, can be anything
|
|
||||||
image: devcon-backend # Declares which image to use
|
|
||||||
build: . # Declares where to build if image is not found
|
|
||||||
ports: # Declares the ports to publish
|
|
||||||
- 3000:3000
|
|
||||||
mongo:
|
|
||||||
image: mongo
|
|
||||||
ports:
|
|
||||||
- 3456:27017
|
|
||||||
environment:
|
|
||||||
MONGO_INITDB_ROOT_USERNAME: root
|
|
||||||
MONGO_INITDB_ROOT_PASSWORD: example
|
|
||||||
MONGO_INITDB_DATABASE: the_database
|
|
||||||
volumes:
|
|
||||||
- ./mongo/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js
|
|
||||||
- mongo_data:/data/db
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
mongo_data:
|
|
||||||
+1
-3
@@ -5,9 +5,7 @@
|
|||||||
"main": "server.ts",
|
"main": "server.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "ts-node server.ts",
|
"start": "ts-node server.ts",
|
||||||
"server": "ts-node-dev server.ts",
|
"server": "ts-node-dev server.ts"
|
||||||
"client": "npm start --prefix client --trace-depracation",
|
|
||||||
"dev": "concurrently \"npm run server\" \"npm run client\""
|
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
|||||||
+26
-31
@@ -1,14 +1,14 @@
|
|||||||
import express from 'express'
|
import express from "express";
|
||||||
import bcrypt from 'bcryptjs'
|
import bcrypt from "bcryptjs";
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from "jsonwebtoken";
|
||||||
|
|
||||||
import auth from '../../middleware/auth'
|
import auth from "../../middleware/auth";
|
||||||
import config from 'config'
|
import config from "config";
|
||||||
import { check, validationResult } from "express-validator";
|
import { check, validationResult } from "express-validator";
|
||||||
|
|
||||||
import User from '../../models/User'
|
import User from "../../models/User";
|
||||||
import type { Request, Response } from 'express';
|
import type { Request, Response } from "express";
|
||||||
import { isUserId } from '../../utils';
|
import { isUserId } from "../../utils";
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
// @route GET api/auth
|
// @route GET api/auth
|
||||||
@@ -16,19 +16,16 @@ const router = express.Router();
|
|||||||
// @access Private
|
// @access Private
|
||||||
router.get("/", auth, async (req: any, res) => {
|
router.get("/", auth, async (req: any, res) => {
|
||||||
try {
|
try {
|
||||||
let user: unknown = null
|
let user: unknown = null;
|
||||||
if (isUserId(req)) {
|
if (isUserId(req)) {
|
||||||
user = await User.findById(req.user.id).select("-password");
|
user = await User.findById(req.user.id).select("-password");
|
||||||
res.json(user);
|
res.json(user);
|
||||||
}
|
} else {
|
||||||
else {
|
throw new Error("missing id in request");
|
||||||
throw new Error('missing id in request')
|
|
||||||
}
|
}
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (typeof err === 'string')
|
if (typeof err === "string") console.error(err);
|
||||||
console.error(err)
|
else if (err instanceof Error) console.error(err.message);
|
||||||
else if (err instanceof Error)
|
|
||||||
console.error(err.message);
|
|
||||||
res.status(500).send("Server Error");
|
res.status(500).send("Server Error");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -72,25 +69,23 @@ router.post(
|
|||||||
id: user.id,
|
id: user.id,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const jwtSecret = config.get('jwtSecret')
|
|
||||||
if (typeof jwtSecret === 'string') jwt.sign(
|
const jwtSecret = process.env.JWT_SECRET
|
||||||
payload,
|
? process.env.JWT_SECRET
|
||||||
jwtSecret,
|
: config.get("jwtSecret");
|
||||||
{ expiresIn: 360000 },
|
|
||||||
(err, token) => {
|
if (typeof jwtSecret === "string")
|
||||||
|
jwt.sign(payload, jwtSecret, { expiresIn: 360000 }, (err, token) => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
res.json({ token });
|
res.json({ token });
|
||||||
}
|
});
|
||||||
);
|
else throw new Error("Error signing the jwt token");
|
||||||
else throw new Error('Error signing the jwt token')
|
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (typeof err === 'string')
|
if (typeof err === "string") console.error(err);
|
||||||
console.error(err)
|
else if (err instanceof Error) console.error(err.message);
|
||||||
else if (err instanceof Error)
|
|
||||||
console.error(err.message);
|
|
||||||
res.status(500).send("Server error");
|
res.status(500).send("Server error");
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router;
|
||||||
|
|||||||
+13
-17
@@ -8,7 +8,6 @@ import User from "../../models/User";
|
|||||||
|
|
||||||
import normalizeUrl from "normalize-url";
|
import normalizeUrl from "normalize-url";
|
||||||
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// @route POST api/users
|
// @route POST api/users
|
||||||
@@ -20,7 +19,7 @@ router.post(
|
|||||||
check("email", "Please include a valid email").isEmail(),
|
check("email", "Please include a valid email").isEmail(),
|
||||||
check(
|
check(
|
||||||
"password",
|
"password",
|
||||||
"Please enter a password with 6 or more characters"
|
"Please enter a password with 6 or more characters",
|
||||||
).isLength({ min: 6 }),
|
).isLength({ min: 6 }),
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
const errors = validationResult(req);
|
const errors = validationResult(req);
|
||||||
@@ -45,7 +44,7 @@ router.post(
|
|||||||
r: "pg",
|
r: "pg",
|
||||||
d: "mm",
|
d: "mm",
|
||||||
}),
|
}),
|
||||||
{ forceHttps: true }
|
{ forceHttps: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
user = new User({
|
user = new User({
|
||||||
@@ -67,24 +66,21 @@ router.post(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const jwtSecret = config.get('jwtSecret')
|
const jwtSecret = process.env.JWT_SECRET
|
||||||
if (typeof jwtSecret === 'string') jwt.sign(
|
? process.env.JWT_SECRET
|
||||||
payload,
|
: config.get("jwtSecret");
|
||||||
jwtSecret,
|
|
||||||
{ expiresIn: "5 days" },
|
if (typeof jwtSecret === "string")
|
||||||
(err, token) => {
|
jwt.sign(payload, jwtSecret, { expiresIn: "5 days" }, (err, token) => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
res.json({ token });
|
res.json({ token });
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (typeof err === 'string')
|
if (typeof err === "string") console.error(err);
|
||||||
console.error(err)
|
else if (err instanceof Error) console.error(err.message);
|
||||||
else if (err instanceof Error)
|
|
||||||
console.error(err.message);
|
|
||||||
res.status(500).send("Server error");
|
res.status(500).send("Server error");
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router;
|
||||||
|
|||||||
+3
-3
@@ -3,11 +3,11 @@
|
|||||||
# systemctl start mongodb.service
|
# systemctl start mongodb.service
|
||||||
|
|
||||||
sn=devCon
|
sn=devCon
|
||||||
cd ~/devConnectTS/
|
cd ~/dev-connect/
|
||||||
tmux new-session -s "$sn" -n etc -d "nvim .; exec zsh"
|
tmux new-session -s "$sn" -n etc -d "nvim .; exec zsh"
|
||||||
cd ~/devConnectTS/client
|
cd ~/dev-connect/client
|
||||||
tmux new-window -t "$sn:2" -n "client" "npm run dev"
|
tmux new-window -t "$sn:2" -n "client" "npm run dev"
|
||||||
cd ~/devConnectTS/server
|
cd ~/dev-connect/server
|
||||||
tmux new-window -t "$sn:3" -n "server" "npm run server"
|
tmux new-window -t "$sn:3" -n "server" "npm run server"
|
||||||
|
|
||||||
tmux select-window -t "$sn:1"
|
tmux select-window -t "$sn:1"
|
||||||
|
|||||||
Reference in New Issue
Block a user