Docker build. Catch client routes on server. Initial config utility
This commit is contained in:
parent
d2e6ebae4f
commit
1636b705de
10 changed files with 125 additions and 13 deletions
1
.dockerignore
Normal file
1
.dockerignore
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules
|
17
Dockerfile
Normal file
17
Dockerfile
Normal file
|
@ -0,0 +1,17 @@
|
|||
FROM node:14-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json .
|
||||
|
||||
RUN npm install --only=production
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN mkdir -p ./public ./data
|
||||
RUN mv ./client/build/* ./public
|
||||
RUN rm -rf ./client
|
||||
|
||||
EXPOSE 5005
|
||||
|
||||
CMD ["node", "server.js"]
|
42
README.md
Normal file
42
README.md
Normal file
|
@ -0,0 +1,42 @@
|
|||
# Flame
|
||||
|
||||
## Description
|
||||
Flame is self-hosted startpage for your server. It's inspired (heavily) by [SUI](https://github.com/jeroenpardon/sui)
|
||||
|
||||
## Technology
|
||||
- Backend
|
||||
- Node.js + Express
|
||||
- Sequelize ORM + SQLite
|
||||
- Frontend
|
||||
- React
|
||||
- Redux
|
||||
- TypeScript
|
||||
- Deployment
|
||||
- Docker
|
||||
|
||||
## Development
|
||||
```sh
|
||||
git clone https://github.com/pawelmalak/flame
|
||||
cd flame
|
||||
|
||||
# run only once
|
||||
<TODO>
|
||||
|
||||
# start backend and frontend development servers
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Deployment with Docker
|
||||
```sh
|
||||
# build image
|
||||
docker build -t flame .
|
||||
|
||||
# run container
|
||||
docker run \
|
||||
-p 5005:5005 \
|
||||
-v <host_dir>:/app/data \
|
||||
flame
|
||||
```
|
||||
|
||||
## Functionality
|
||||
todo
|
7
api.js
7
api.js
|
@ -1,10 +1,13 @@
|
|||
const path = require('path');
|
||||
const express = require('express');
|
||||
const errorHandler = require('./middleware/errorHandler');
|
||||
|
||||
const api = express();
|
||||
|
||||
api.get('/', (req, res) => {
|
||||
res.send('Server is working');
|
||||
// Static files
|
||||
api.use(express.static(path.join(__dirname, 'public')));
|
||||
api.get(/^\/(?!api)/, (req, res) => {
|
||||
res.sendFile(path.join(__dirname, 'public/index.html'));
|
||||
})
|
||||
|
||||
// Body parser
|
||||
|
|
4
db.js
4
db.js
|
@ -9,13 +9,13 @@ const sequelize = new Sequelize({
|
|||
const connectDB = async () => {
|
||||
try {
|
||||
await sequelize.authenticate({ logging: false });
|
||||
console.log('Connected to database'.cyan.underline);
|
||||
console.log('Connected to database');
|
||||
|
||||
await sequelize.sync({
|
||||
// alter: true,
|
||||
logging: false
|
||||
});
|
||||
console.log('All models were synced'.cyan.underline);
|
||||
console.log('All models were synced');
|
||||
} catch (error) {
|
||||
console.error('Unable to connect to the database:', error);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ const errorHandler = (err, req, res, next) => {
|
|||
// }
|
||||
|
||||
console.log(error);
|
||||
console.log(`${err}`.bgRed);
|
||||
console.log(`${err}`);
|
||||
|
||||
res.status(err.statusCode || 500).json({
|
||||
success: false,
|
||||
|
|
11
package.json
11
package.json
|
@ -5,10 +5,13 @@
|
|||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"server": "nodemon server.js",
|
||||
"client": "npm start --prefix client",
|
||||
"dev": "concurrently \"npm run server\" \"npm run client\"",
|
||||
"dev-lines": "git ls-files | grep -v '.json' | xargs wc -l"
|
||||
"init-server": "echo Instaling server dependencies && npm install",
|
||||
"init-client": "cd client && echo Instaling client dependencies && npm install",
|
||||
"dev-init": "npm run init-server && npm run init-client",
|
||||
"dev-server": "nodemon server.js",
|
||||
"dev-client": "npm start --prefix client",
|
||||
"dev": "concurrently \"npm run dev-server\" \"npm run dev-client\"",
|
||||
"build": "docker build -t flame ."
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
|
|
12
server.js
12
server.js
|
@ -1,3 +1,4 @@
|
|||
require('dotenv').config();
|
||||
const http = require('http');
|
||||
const { connectDB } = require('./db');
|
||||
const api = require('./api');
|
||||
|
@ -5,12 +6,15 @@ const jobs = require('./utils/jobs');
|
|||
const Socket = require('./Socket');
|
||||
const Sockets = require('./Sockets');
|
||||
const associateModels = require('./models/associateModels');
|
||||
const initConfig = require('./utils/initConfig');
|
||||
|
||||
require('dotenv').config();
|
||||
const PORT = process.env.PORT || 5005;
|
||||
|
||||
connectDB();
|
||||
associateModels();
|
||||
connectDB()
|
||||
.then(() => {
|
||||
associateModels();
|
||||
initConfig();
|
||||
});
|
||||
|
||||
// Create server for Express API and WebSockets
|
||||
const server = http.createServer();
|
||||
|
@ -21,5 +25,5 @@ const weatherSocket = new Socket(server);
|
|||
Sockets.registerSocket('weather', weatherSocket);
|
||||
|
||||
server.listen(PORT, () => {
|
||||
console.log(`Server is running on port ${PORT} in ${process.env.NODE_ENV} mode`.yellow.bold);
|
||||
console.log(`Server is running on port ${PORT} in ${process.env.NODE_ENV} mode`);
|
||||
})
|
36
utils/initConfig.js
Normal file
36
utils/initConfig.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
const { Op } = require('sequelize');
|
||||
const Config = require('../models/Config');
|
||||
|
||||
const initConfig = async () => {
|
||||
// Config keys
|
||||
const keys = ['WEATHER_API_KEY', 'lat', 'long', 'isCelsius'];
|
||||
const values = ['', 0, 0, true];
|
||||
|
||||
// Get config values
|
||||
const configPairs = await Config.findAll({
|
||||
where: {
|
||||
key: {
|
||||
[Op.or]: keys
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Get key from each pair
|
||||
const configKeys = configPairs.map((pair) => pair.key);
|
||||
|
||||
// Create missing pairs
|
||||
keys.forEach(async (key, idx) => {
|
||||
if (!configKeys.includes(key)) {
|
||||
await Config.create({
|
||||
key,
|
||||
value: values[idx],
|
||||
valueType: typeof values[idx]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
console.log('Initial config created');
|
||||
return;
|
||||
}
|
||||
|
||||
module.exports = initConfig;
|
|
@ -2,6 +2,7 @@ const schedule = require('node-schedule');
|
|||
const getExternalWeather = require('./getExternalWeather');
|
||||
const Sockets = require('../Sockets');
|
||||
|
||||
// Update weather data every 15 minutes
|
||||
const weatherJob = schedule.scheduleJob('updateWeather', '0 */15 * * * *', async () => {
|
||||
try {
|
||||
const weatherData = await getExternalWeather();
|
||||
|
@ -11,3 +12,8 @@ const weatherJob = schedule.scheduleJob('updateWeather', '0 */15 * * * *', async
|
|||
console.log(err.message);
|
||||
}
|
||||
})
|
||||
|
||||
// Clear old weather data every 4 hours
|
||||
const weatherCleanerJob = schedule.scheduleJob('clearWeather', '0 0 */4 * * *', async () => {
|
||||
console.log('clean')
|
||||
})
|
Loading…
Reference in a new issue