Updated README.md and configure-script.js
This commit is contained in:
@@ -1,103 +1,84 @@
|
|||||||
//TODO: update this README
|
|
||||||
|
|
||||||
# MERN-template
|
# MERN-template
|
||||||
|
|
||||||
A website template using the MERN stack.
|
A website template using the MERN stack. The primary technology involved is:
|
||||||
|
|
||||||
# Setup Development
|
* React
|
||||||
|
* Nodejs
|
||||||
|
* MariaDB (with Sequelize)
|
||||||
|
* Docker
|
||||||
|
|
||||||
To set up this template, please ensure mariadb is running on the host computer, and run `npm install` as normal.
|
This template is designed to support the development of persistent browser based games (PBBGs), but it, and it's component microservices, can be used elsewhere.
|
||||||
|
|
||||||
1. Run `sql/create_database.sql`
|
This template is released under the zlib license (see LICENSE).
|
||||||
2. Run `cp .envdev .env` and enter your details into the new file
|
|
||||||
3. Execute `npm run dev`
|
|
||||||
|
|
||||||
This should get the template working in development mode.
|
|
||||||
|
|
||||||
# Setup Deployment
|
|
||||||
|
|
||||||
Eventually, a clean install will be this easy:
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone https://github.com/krgamestudios/MERN-template.git
|
|
||||||
npm run configure
|
|
||||||
docker-compose up --build
|
|
||||||
```
|
|
||||||
|
|
||||||
# Microservices
|
# Microservices
|
||||||
|
|
||||||
There are external components to this template referred to as "microservices". These can be omitted entirely by simply removing the React component that accesses them.
|
There are external components to this template referred to as "microservices". These can be omitted entirely by simply removing the React components that access them. These are also available via [docker hub](https://hub.docker.com/u/krgamestudios).
|
||||||
|
|
||||||
* News Server: https://github.com/krgamestudios/news-server
|
|
||||||
* Auth Server: https://github.com/krgamestudios/auth-server
|
* Auth Server: https://github.com/krgamestudios/auth-server
|
||||||
|
* News Server: https://github.com/krgamestudios/news-server
|
||||||
* Chat Server: https://github.com/krgamestudios/chat-server
|
* Chat Server: https://github.com/krgamestudios/chat-server
|
||||||
|
|
||||||
# TODO list
|
# Setup Deployment
|
||||||
|
|
||||||
- Account system
|
A clean install is this easy:
|
||||||
- A separate authentication server
|
|
||||||
- Administration Panel
|
|
||||||
- inspect aggregate user data
|
|
||||||
- Moderation tools for banning, suspending, or chat-banning users
|
|
||||||
- Chat system (microservice)
|
|
||||||
- Based on usernames
|
|
||||||
- Chat logs
|
|
||||||
- Custom emoji
|
|
||||||
- Moderation tools
|
|
||||||
- Global chat channels
|
|
||||||
- User-created chat channels with an invite/search system
|
|
||||||
- Private messages
|
|
||||||
- Icons/roles next to username
|
|
||||||
- Better compression for client files
|
|
||||||
- Some form of bot/alt account detection?
|
|
||||||
- A payment system
|
|
||||||
- Backend for energy systems
|
|
||||||
- Backend for trading and leaderboards
|
|
||||||
- inventory
|
|
||||||
- stats
|
|
||||||
- shop
|
|
||||||
- currency
|
|
||||||
- random events
|
|
||||||
- Dcumentation and tutorials
|
|
||||||
- Server-side actions to allow offline progress or progress on spotty internet connections
|
|
||||||
- Full tutorial for setting up and using the site
|
|
||||||
- Start here page
|
|
||||||
- Security holes
|
|
||||||
- HTTPS
|
|
||||||
- Default admin account
|
|
||||||
- Information about legal requirements of the developers using this template
|
|
||||||
- Privacy policy & data collection notices
|
|
||||||
|
|
||||||
# DONE list
|
```
|
||||||
|
git clone https://github.com/krgamestudios/MERN-template.git
|
||||||
|
node run configure-script.js
|
||||||
|
docker-compose up --build
|
||||||
|
```
|
||||||
|
|
||||||
- Legal Requirements:
|
# Setup Development
|
||||||
- ~~Physical Mailing Address Config (for emails)~~
|
|
||||||
- ~~Opt-out option (for emails)~~
|
To set up this template in development mode:
|
||||||
- ~~Privacy policy & data collection notices~~
|
|
||||||
- ~~LICENSE file~~
|
1. Ensure mariadb is running in your development environment
|
||||||
- ~~annoying "This site uses cookies" message~~
|
2. Run `mariadb sql/create_database.sql` as the root user
|
||||||
- Account system
|
3. Run `npm install`
|
||||||
- ~~sign up~~
|
4. Run `cp .envdev .env` and enter your details into the `.env` file
|
||||||
- ~~validate email~~
|
5. Execute `npm run dev`
|
||||||
- ~~login (with cookies)~~
|
6. Navigate to `http://localhost:3001` in your web browser
|
||||||
- ~~logout (with cookies)~~
|
|
||||||
- ~~account deletion~~
|
# Features List
|
||||||
- ~~Change passwords~~
|
|
||||||
- Administration Panel
|
- Fully Featured Account System
|
||||||
- ~~Default admin account~~
|
- Email validation
|
||||||
- ~~Exclusive to admin accounts~~
|
- Logging in and out
|
||||||
- News blog system (microservice)
|
- Account deletion
|
||||||
- ~~build the microservice to provide the news feed~~
|
- Password management
|
||||||
- ~~access an external news feed~~
|
- Fully Featured Administration Panel
|
||||||
- ~~admin panel for publishing and editing news~~
|
- A default admin account (if desired)
|
||||||
- ~~"created at" and "updated at" in the response~~
|
- News Blog
|
||||||
- Configuraton Script:
|
- Optional microservice
|
||||||
|
- Secure publishing and editing of articles
|
||||||
|
- Easy To Use Configuraton Script:
|
||||||
- ~~Default UUID keys~~
|
- ~~Default UUID keys~~
|
||||||
- ~~Docker, docker, docker.~~
|
- ~~Docker, docker, docker.~~
|
||||||
|
|
||||||
# Email settings
|
# Coming Soon
|
||||||
|
|
||||||
Some of the external requirements can be tricky, so let me outline what is needed. If you decide to use gmail as your email provider, then use the following `.env` settings:
|
- Full documentation
|
||||||
|
- Setup tutorial
|
||||||
|
- Fully Featured Chat System
|
||||||
|
- Optional microservice
|
||||||
|
- Chat logs
|
||||||
|
- Custom emoji
|
||||||
|
- Global and room-based chat
|
||||||
|
- Private messaging?
|
||||||
|
- Broadcasting to all channels
|
||||||
|
- Badges next to usernames?
|
||||||
|
- Moderation tools for banning, suspending, or chat-banning users
|
||||||
|
|
||||||
|
# Coming Eventually
|
||||||
|
- Better compression for client files
|
||||||
|
- Backend for energy systems
|
||||||
|
- Backend for leaderboards
|
||||||
|
- Backend for items, shops, trading and currency
|
||||||
|
|
||||||
|
# Gmail Email Settings
|
||||||
|
|
||||||
|
If you decide to use gmail as your email provider (as I do), then use the following `.env` settings:
|
||||||
|
|
||||||
MAIL_SMTP=smtp.gmail.com
|
MAIL_SMTP=smtp.gmail.com
|
||||||
MAIL_USERNAME=you@gmail.com
|
MAIL_USERNAME=you@gmail.com
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import LazyRoute from './lazy-route';
|
|||||||
import Markdown from './panels/markdown';
|
import Markdown from './panels/markdown';
|
||||||
|
|
||||||
//styling
|
//styling
|
||||||
//TODO: styling import
|
//import a styling template here
|
||||||
|
|
||||||
//common components
|
//common components
|
||||||
import Header from './panels/header.jsx';
|
import Header from './panels/header.jsx';
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { Redirect } from 'react-router-dom';
|
|||||||
|
|
||||||
import { TokenContext } from '../utilities/token-provider';
|
import { TokenContext } from '../utilities/token-provider';
|
||||||
|
|
||||||
|
const validateEmail = require('../../../common/utilities/validate-email');
|
||||||
|
|
||||||
const LogIn = props => {
|
const LogIn = props => {
|
||||||
//context
|
//context
|
||||||
const authTokens = useContext(TokenContext);
|
const authTokens = useContext(TokenContext);
|
||||||
@@ -55,7 +57,13 @@ const LogIn = props => {
|
|||||||
|
|
||||||
//DOCS: returns two values: err and authTokens
|
//DOCS: returns two values: err and authTokens
|
||||||
const handleSubmit = async (email, password) => {
|
const handleSubmit = async (email, password) => {
|
||||||
email = email.trim(); //TODO: validate email on login
|
email = email.trim();
|
||||||
|
|
||||||
|
const err = handleValidation(email, password);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return [err, false];
|
||||||
|
}
|
||||||
|
|
||||||
//send to the auth server
|
//send to the auth server
|
||||||
const result = await fetch(`${process.env.AUTH_URI}/login`, {
|
const result = await fetch(`${process.env.AUTH_URI}/login`, {
|
||||||
@@ -82,4 +90,18 @@ const handleSubmit = async (email, password) => {
|
|||||||
return [null, newTokens];
|
return [null, newTokens];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//returns an error message, or null on success
|
||||||
|
const handleValidation = (email, password) => {
|
||||||
|
if (!validateEmail(email)) {
|
||||||
|
return 'invalid email';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password.length < 8) {
|
||||||
|
return 'invalid password (Must be at least 8 characters long)';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export default LogIn;
|
export default LogIn;
|
||||||
@@ -4,8 +4,8 @@ import { Redirect } from 'react-router-dom';
|
|||||||
import { TokenContext } from '../utilities/token-provider';
|
import { TokenContext } from '../utilities/token-provider';
|
||||||
|
|
||||||
//utilities
|
//utilities
|
||||||
const validateEmail = require('../../../common/utilities/validate-email.js');
|
const validateEmail = require('../../../common/utilities/validate-email');
|
||||||
const validateUsername = require('../../../common/utilities/validate-username.js');
|
const validateUsername = require('../../../common/utilities/validate-username');
|
||||||
|
|
||||||
const SignUp = props => {
|
const SignUp = props => {
|
||||||
//context
|
//context
|
||||||
|
|||||||
@@ -4,4 +4,3 @@ MERN Template developed by Kayne Ruse, KR Game Studios
|
|||||||
|
|
||||||
[https://github.com/krgamestudios/MERN-template](https://github.com/krgamestudios/MERN-template)
|
[https://github.com/krgamestudios/MERN-template](https://github.com/krgamestudios/MERN-template)
|
||||||
|
|
||||||
TODO: generate the credits using config script
|
|
||||||
@@ -1,3 +1,2 @@
|
|||||||
# Privacy Policy
|
# Privacy Policy
|
||||||
|
|
||||||
TODO: generate the privacy policy using config script
|
|
||||||
+142
-82
@@ -1,5 +1,3 @@
|
|||||||
//TODO: update this file
|
|
||||||
|
|
||||||
//setup
|
//setup
|
||||||
const readline = require('readline');
|
const readline = require('readline');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
@@ -14,52 +12,92 @@ const rl = readline.createInterface({
|
|||||||
});
|
});
|
||||||
|
|
||||||
//manually promisify this (util didn't work)
|
//manually promisify this (util didn't work)
|
||||||
const question = (prompt, def) => {
|
const question = (prompt, def = null) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
rl.question(`${prompt} (${def}): `, answer => {
|
rl.question(`${prompt}${def ? ` (${def})` : ''}: `, answer => {
|
||||||
resolve(answer || def);
|
//loop on required
|
||||||
|
if (def === null && !answer) {
|
||||||
|
return resolve(question(prompt, def));
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolve(answer || def);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//questions
|
//questions
|
||||||
(async () => {
|
(async () => {
|
||||||
|
console.log(
|
||||||
|
`This configure script will generate the following files:
|
||||||
|
|
||||||
|
* docker-compose.yml
|
||||||
|
* Dockerfile
|
||||||
|
* startup.sql
|
||||||
|
|
||||||
|
Currently, all microservices are mandatory; you'll have to mess with the result
|
||||||
|
and the source code if you wish to be more selective. Microservices currently
|
||||||
|
impelented are:
|
||||||
|
|
||||||
|
* auth-server
|
||||||
|
* news-server
|
||||||
|
|
||||||
|
See https://github.com/krgamestudios/MERN-template/wiki for help.
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
//project configuration
|
//project configuration
|
||||||
const projectName = await question('Project Name', 'template');
|
const projectName = await question('Project Name', 'template');
|
||||||
const projectWebAddress = await question('Project Web Address', 'example.com');
|
const projectWebAddress = await question('Project Web Address', 'example.com');
|
||||||
const projectMailSMTP = await question('Project Mail SMTP', 'smtp.example.com');
|
|
||||||
const projectMailUser = await question('Project Mail Username', 'foobar@example.com');
|
const projectDBUser = await question('Project DB Username', projectName);
|
||||||
const projectMailPass = await question('Project Mail Password', 'foobar');
|
const projectDBPass = await question('Project DB Password', 'pikachu');
|
||||||
const projectMailPhysical = await question('Project Physical Mailing Address', '');
|
|
||||||
const projectDBUser = await question('Project Database Username', projectName);
|
|
||||||
const projectDBPass = await question('Project Database Password', 'pikachu');
|
|
||||||
|
|
||||||
//news configuration
|
//news configuration
|
||||||
const newsName = await question('News Name', 'news');
|
const newsName = await question('News Name', 'news');
|
||||||
const newsWebAddress = await question('News Web Address', 'news.example.com');
|
const newsWebAddress = await question('News Web Address', `${newsName}.${projectWebAddress}`);
|
||||||
const newsDBUser = await question('News Database Username', newsName);
|
const newsDBUser = await question('News DB Username', newsName);
|
||||||
const newsDBPass = await question('News Database Password', 'charizard');
|
const newsDBPass = await question('News DB Password', 'charizard');
|
||||||
const newsKey = await question('News Query Key', uuid());
|
|
||||||
|
|
||||||
//chat configuration
|
//auth configuration
|
||||||
const chatName = await question('Chat Name', 'chat');
|
const authName = await question('Auth Name', 'auth');
|
||||||
const chatWebAddress = await question('Chat Web Address', 'chat.example.com');
|
const authWebAddress = await question('Auth Web Address', `${authName}.${projectWebAddress}`);
|
||||||
const chatDBUser = await question('Chat Database Username', chatName);
|
const authDBUser = await question('Auth DB Username', authName);
|
||||||
const chatDBPass = await question('Chat Database Password', 'blastoise');
|
const authDBPass = await question('Auth DB Password', 'venusaur');
|
||||||
const chatKey = await question('Chat Reservation Key', uuid());
|
|
||||||
|
const emailSMTP = await question('Email SMTP', 'smtp.example.com');
|
||||||
|
const emailUser = await question('Email Address', 'foobar@example.com');
|
||||||
|
const emailPass = await question('Email Password', 'foobar');
|
||||||
|
const emailPhysical = await question('Physical Mailing Address', '');
|
||||||
|
|
||||||
|
//chat goes here
|
||||||
|
|
||||||
//database configuration
|
//database configuration
|
||||||
const databaseRootPassword = await question('Database Root Password', 'password');
|
const dbRootPassword = await question('Database Root Password', 'password');
|
||||||
const databaseTimeZone = await question('Database Timezone', 'Australia/Sydney');
|
const dbTimeZone = await question('Database Timezone', 'Australia/Sydney');
|
||||||
|
|
||||||
|
//joint configuration
|
||||||
|
const accessToken = await question('Access Token Secret', uuid(32));
|
||||||
|
const refreshToken = await question('Refresh Token Secret', uuid(32));
|
||||||
|
|
||||||
|
console.log('--Leave "Default User" blank if you don\'t want one--');
|
||||||
|
const defaultUser = await question('Default Admin User', '');
|
||||||
|
|
||||||
|
//MUST be at least 8 chars
|
||||||
|
let tmpPass = '';
|
||||||
|
while (defaultUser && tmpPass.length < 8) {
|
||||||
|
console.log('--All passwords must be at least 8 characters long--');
|
||||||
|
tmpPass = await question('Default Admin Pass', '');
|
||||||
|
}
|
||||||
|
const defaultPass = tmpPass;
|
||||||
|
|
||||||
//traefic configuration
|
//traefic configuration
|
||||||
const supportEmail = await question('Support Email', projectMailUser);
|
const supportEmail = await question('Support Email', emailUser);
|
||||||
|
|
||||||
//other random values
|
//misc. configuration
|
||||||
const sessionSecret = uuid(); //for session randomness
|
const projectPort = 3000;
|
||||||
const sessionAdmin = uuid(128); //for checking if user is admin
|
const newsPort = 3100;
|
||||||
|
const authPort = 3200;
|
||||||
//TODO: Implement chat-server as a docker container
|
//const chatPort = 3300;
|
||||||
|
|
||||||
const ymlfile = `
|
const ymlfile = `
|
||||||
version: "3.6"
|
version: "3.6"
|
||||||
@@ -67,33 +105,24 @@ services:
|
|||||||
${projectName}:
|
${projectName}:
|
||||||
build: .
|
build: .
|
||||||
ports:
|
ports:
|
||||||
- "3000"
|
- "${projectPort}"
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- traefik.enable=true
|
||||||
- "traefik.http.routers.${projectName}router.rule=Host(\`${projectWebAddress}\`)"
|
- traefik.http.routers.${projectName}router.rule=Host(\`${projectWebAddress}\`)
|
||||||
- "traefik.http.routers.${projectName}router.entrypoints=websecure"
|
- traefik.http.routers.${projectName}router.entrypoints=websecure
|
||||||
- "traefik.http.routers.${projectName}router.tls.certresolver=myresolver"
|
- traefik.http.routers.${projectName}router.tls.certresolver=myresolver
|
||||||
- "traefik.http.routers.${projectName}router.service=${projectName}service@docker"
|
- traefik.http.routers.${projectName}router.service=${projectName}service@docker
|
||||||
- "traefik.http.services.${projectName}service.loadbalancer.server.port=3000"
|
- traefik.http.services.${projectName}service.loadbalancer.server.port=${projectPort}
|
||||||
environment:
|
environment:
|
||||||
- WEB_PROTOCOL=https
|
|
||||||
- WEB_ADDRESS=${projectWebAddress}
|
|
||||||
- WEB_PORT=3000
|
- WEB_PORT=3000
|
||||||
- MAIL_SMTP=${projectMailSMTP}
|
|
||||||
- MAIL_USERNAME=${projectMailUser}
|
|
||||||
- MAIL_PASSWORD=${projectMailPass}
|
|
||||||
- MAIL_PHYSICAL=${projectMailPhysical}
|
|
||||||
- DB_HOSTNAME=database
|
- DB_HOSTNAME=database
|
||||||
- DB_DATABASE=${projectName}
|
- DB_DATABASE=${projectName}
|
||||||
- DB_USERNAME=${projectDBUser}
|
- DB_USERNAME=${projectDBUser}
|
||||||
- DB_PASSWORD=${projectDBPass}
|
- DB_PASSWORD=${projectDBPass}
|
||||||
- DB_TIMEZONE=${databaseTimeZone}
|
- DB_TIMEZONE=${dbTimeZone}
|
||||||
- SESSION_SECRET=${sessionSecret}
|
|
||||||
- SESSION_ADMIN=${sessionAdmin}
|
|
||||||
- NEWS_URI=https://${newsWebAddress}/news
|
- NEWS_URI=https://${newsWebAddress}/news
|
||||||
- NEWS_KEY=${newsKey}
|
- AUTH_URI=https://${authWebAddress}/auth
|
||||||
- CHAT_URI=https://${chatWebAddress}/chat
|
- SECRET_ACCESS=${accessToken}
|
||||||
- CHAT_KEY=${chatKey}
|
|
||||||
networks:
|
networks:
|
||||||
- app-network
|
- app-network
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -103,23 +132,57 @@ services:
|
|||||||
${newsName}:
|
${newsName}:
|
||||||
image: krgamestudios/news-server:latest
|
image: krgamestudios/news-server:latest
|
||||||
ports:
|
ports:
|
||||||
- "3100"
|
- ${newsPort}
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- traefik.enable=true
|
||||||
- "traefik.http.routers.${newsName}router.rule=Host(\`${newsWebAddress}\`)"
|
- traefik.http.routers.${newsName}router.rule=Host(\`${newsWebAddress}\`)
|
||||||
- "traefik.http.routers.${newsName}router.entrypoints=websecure"
|
- traefik.http.routers.${newsName}router.entrypoints=websecure
|
||||||
- "traefik.http.routers.${newsName}router.tls.certresolver=myresolver"
|
- traefik.http.routers.${newsName}router.tls.certresolver=myresolver
|
||||||
- "traefik.http.routers.${newsName}router.service=${newsName}service@docker"
|
- traefik.http.routers.${newsName}router.service=${newsName}service@docker
|
||||||
- "traefik.http.services.${newsName}service.loadbalancer.server.port=3100"
|
- traefik.http.services.${newsName}service.loadbalancer.server.port=3100
|
||||||
environment:
|
environment:
|
||||||
- WEB_PORT=3100
|
- WEB_PORT=3100
|
||||||
- DB_HOSTNAME=database
|
- DB_HOSTNAME=database
|
||||||
- DB_DATABASE=${newsName}
|
- DB_DATABASE=${newsName}
|
||||||
- DB_USERNAME=${newsDBUser}
|
- DB_USERNAME=${newsDBUser}
|
||||||
- DB_PASSWORD=${newsDBPass}
|
- DB_PASSWORD=${newsDBPass}
|
||||||
- DB_TIMEZONE=${databaseTimeZone}
|
- DB_TIMEZONE=${dbTimeZone}
|
||||||
- QUERY_LIMIT=10
|
- QUERY_LIMIT=10
|
||||||
- QUERY_KEY=${newsKey}
|
- SECRET_ACCESS=${accessToken}
|
||||||
|
networks:
|
||||||
|
- app-network
|
||||||
|
depends_on:
|
||||||
|
- database
|
||||||
|
- traefik
|
||||||
|
|
||||||
|
${authName}:
|
||||||
|
image: krgamestudios/news-server:latest
|
||||||
|
ports:
|
||||||
|
- ${authPort}
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.${authName}router.rule=Host(\`${authWebAddress}\`)
|
||||||
|
- traefik.http.routers.${authName}router.entrypoints=websecure
|
||||||
|
- traefik.http.routers.${authName}router.tls.certresolver=myresolver
|
||||||
|
- traefik.http.routers.${authName}router.service=${authName}service@docker
|
||||||
|
- traefik.http.services.${authName}service.loadbalancer.server.port=${authPort}
|
||||||
|
environment:
|
||||||
|
- WEB_PROTOCOL=https
|
||||||
|
- WEB_ADDRESS=${authWebAddress}
|
||||||
|
- WEB_PORT=${authPort}
|
||||||
|
- DB_HOSTNAME=database
|
||||||
|
- DB_DATABASE=${authName}
|
||||||
|
- DB_USERNAME=${authDBUser}
|
||||||
|
- DB_PASSWORD=${authDBPass}
|
||||||
|
- DB_TIMEZONE=${dbTimeZone}
|
||||||
|
- MAIL_SMTP=${emailSMTP}
|
||||||
|
- MAIL_USERNAME=${emailUser}
|
||||||
|
- MAIL_PASSWORD=${emailPass}
|
||||||
|
- MAIL_PHYSICAL=${emailPhysical}
|
||||||
|
- ADMIN_DEFAULT_USERNAME=${defaultUser}
|
||||||
|
- ADMIN_DEFAULT_PASSWORD=${defaultPass}
|
||||||
|
- SECRET_ACCESS=${accessToken}
|
||||||
|
- SECRET_REFRESH=${refreshToken}
|
||||||
networks:
|
networks:
|
||||||
- app-network
|
- app-network
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -128,39 +191,37 @@ services:
|
|||||||
|
|
||||||
#chat:
|
#chat:
|
||||||
# image: krgamestudios/chat-server
|
# image: krgamestudios/chat-server
|
||||||
# ports:
|
|
||||||
# - "3200:3200"
|
|
||||||
|
|
||||||
database:
|
database:
|
||||||
image: mariadb
|
image: mariadb
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: ${databaseRootPassword}
|
MYSQL_ROOT_PASSWORD: ${dbRootPassword}
|
||||||
volumes:
|
volumes:
|
||||||
- "./mysql:/var/lib/mysql"
|
- ./mysql:/var/lib/mysql
|
||||||
- "./startup.sql:/docker-entrypoint-initdb.d/startup.sql:ro"
|
- ./startup.sql:/docker-entrypoint-initdb.d/startup.sql:ro
|
||||||
networks:
|
networks:
|
||||||
- app-network
|
- app-network
|
||||||
|
|
||||||
traefik:
|
traefik:
|
||||||
image: "traefik:v2.4"
|
image: traefik:v2.4
|
||||||
container_name: "traefik"
|
container_name: traefik
|
||||||
command:
|
command:
|
||||||
- "--log.level=ERROR"
|
- --log.level=ERROR
|
||||||
- "--api.insecure=false"
|
- --api.insecure=false
|
||||||
- "--providers.docker=true"
|
- --providers.docker=true
|
||||||
- "--providers.docker.exposedbydefault=false"
|
- --providers.docker.exposedbydefault=false
|
||||||
- "--entrypoints.websecure.address=:443"
|
- --entrypoints.websecure.address=:443
|
||||||
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
|
- --certificatesresolvers.myresolver.acme.tlschallenge=true
|
||||||
- "--certificatesresolvers.myresolver.acme.email=${supportEmail}"
|
- --certificatesresolvers.myresolver.acme.email=${supportEmail}
|
||||||
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
|
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
|
||||||
- " traefik.docker.network=app-network"
|
- traefik.docker.network=app-network
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- 80:80
|
||||||
- "443:443"
|
- 443:443
|
||||||
volumes:
|
volumes:
|
||||||
- "./letsencrypt:/letsencrypt"
|
- ./letsencrypt:/letsencrypt
|
||||||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
networks:
|
networks:
|
||||||
- app-network
|
- app-network
|
||||||
|
|
||||||
@@ -175,7 +236,7 @@ WORKDIR "/app"
|
|||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm install
|
RUN npm install
|
||||||
COPY . /app
|
COPY . /app
|
||||||
EXPOSE 3000
|
EXPOSE ${projectPort}
|
||||||
ENTRYPOINT ["bash", "-c"]
|
ENTRYPOINT ["bash", "-c"]
|
||||||
CMD ["sleep 10 && npm start"]
|
CMD ["sleep 10 && npm start"]
|
||||||
`;
|
`;
|
||||||
@@ -189,9 +250,9 @@ CREATE DATABASE IF NOT EXISTS ${newsName};
|
|||||||
CREATE USER IF NOT EXISTS '${newsDBUser}'@'%' IDENTIFIED BY '${newsDBPass}';
|
CREATE USER IF NOT EXISTS '${newsDBUser}'@'%' IDENTIFIED BY '${newsDBPass}';
|
||||||
GRANT ALL PRIVILEGES ON ${newsName}.* TO '${newsDBUser}'@'%';
|
GRANT ALL PRIVILEGES ON ${newsName}.* TO '${newsDBUser}'@'%';
|
||||||
|
|
||||||
CREATE DATABASE IF NOT EXISTS ${chatName};
|
CREATE DATABASE IF NOT EXISTS ${authName};
|
||||||
CREATE USER IF NOT EXISTS '${chatDBUser}'@'%' IDENTIFIED BY '${chatDBPass}';
|
CREATE USER IF NOT EXISTS '${authDBUser}'@'%' IDENTIFIED BY '${authDBPass}';
|
||||||
GRANT ALL PRIVILEGES ON ${chatName}.* TO '${chatDBUser}'@'%';
|
GRANT ALL PRIVILEGES ON ${authName}.* TO '${authDBUser}'@'%';
|
||||||
|
|
||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
`;
|
`;
|
||||||
@@ -203,4 +264,3 @@ FLUSH PRIVILEGES;
|
|||||||
.then(() => rl.close())
|
.then(() => rl.close())
|
||||||
.catch(e => console.error(e))
|
.catch(e => console.error(e))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
//TODO: move this to the wiki?
|
|
||||||
|
|
||||||
# Setup Tutorial
|
# Setup Tutorial
|
||||||
|
|
||||||
Last Updated February 15th 2021
|
Last Updated February 15th 2021
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
//TODO: models
|
//import models
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
#TODO: move this into configure-script.js
|
|
||||||
|
|
||||||
#This file only needs to be run once, during initial development setup
|
#This file only needs to be run once, during initial development setup
|
||||||
#This file isnt needed for actual deployment
|
#This file isnt needed for actual deployment
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user