├── .env.example
├── .gitignore
├── LICENSE
├── README.md
├── app
├── .env.example
├── Dockerfile
├── db
│ └── sequelize.js
├── index.js
├── models
│ └── sequelize
│ │ └── user.model.js
└── package.json
└── docker-compose.yaml
/.env.example:
--------------------------------------------------------------------------------
1 | MYSQL_ROOT_PASSWORD=root
2 | MYSQL_DATABASE=example_db
3 | MYSQL_LOCAL_PORT=3306
4 | MYSQL_DOCKER_PORT=3306
5 |
6 | NODE_LOCAL_PORT=3000
7 | NODE_DOCKER_PORT=3000
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Nyoman Frastyawan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Docker-NodeJS-MySQL
2 |
3 | Dokerized NodeJS app with MySQL Database
4 |
5 |
How to run
6 |
7 | - Clone this repository
8 | -
9 | Run this command
docker-compose up
10 |
11 | -
12 | Access
localhost:3000
in your browser and empty json will be shown
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/.env.example:
--------------------------------------------------------------------------------
1 | MYSQL_USERNAME=root
2 | MYSQL_ROOT_PASSWORD=root
3 | MYSQL_DATABASE=example_db
4 | MYSQL_HOST=mysqldb
5 | MYSQL_LOCAL_PORT=3306
6 | MYSQL_DOCKER_PORT=3306
7 |
8 | NODEJS_LOCAL_PORT=3000
--------------------------------------------------------------------------------
/app/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:14
2 |
3 | WORKDIR /app
4 |
5 | COPY /app/package.json .
6 |
7 | RUN npm install
8 |
9 | COPY /app .
10 |
11 | EXPOSE 3000
12 |
13 | CMD [ "npm", "start" ]
14 |
--------------------------------------------------------------------------------
/app/db/sequelize.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const Sequelize = require('sequelize');
4 |
5 | // Connection Option 2: Passing parameters separately (other dialects)
6 | const sequelize = new Sequelize(
7 | process.env.MYSQL_DATABASE,
8 | process.env.MYSQL_USERNAME,
9 | process.env.MYSQL_ROOT_PASSWORD,
10 | {
11 | dialect: 'mysql',
12 | host: process.env.MYSQL_HOST || 'localhost',
13 | port: process.env.MYSQL_LOCAL_PORT,
14 | logging: false,
15 | }
16 | );
17 |
18 | const db = {};
19 | const models = path.join(__dirname, '../models/sequelize'); // path to a models' folder
20 |
21 | fs.readdirSync(models)
22 | .filter(function (file) {
23 | return file.indexOf('.') !== 0 && file.slice(-3) === '.js';
24 | })
25 | .forEach(function (file) {
26 | const model = require(path.join(models, file))(
27 | sequelize,
28 | Sequelize.DataTypes
29 | );
30 | db[model.name] = model;
31 | });
32 |
33 | Object.keys(db).forEach(function (modelName) {
34 | if (db[modelName].associate) {
35 | db[modelName].associate(db);
36 | }
37 | });
38 |
39 | // This creates the table if it doesn't exist (and does nothing if it already exists)
40 | sequelize
41 | .sync()
42 | .then((_result) => {
43 | console.log('Sequelize: All models were synchronized successfully.');
44 | })
45 | .catch((err) => {
46 | console.log(err);
47 | });
48 |
49 | db.sequelize = sequelize;
50 | db.Sequelize = Sequelize;
51 |
52 | module.exports = db;
53 |
--------------------------------------------------------------------------------
/app/index.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 | const express = require('express');
3 |
4 | // Databases
5 | require('./db/sequelize');
6 |
7 | const app = express();
8 |
9 | const { user: UserModel } = require('./db/sequelize');
10 |
11 | app.route('/').get(async (req, res) => {
12 | try {
13 | const users = await UserModel.findAll({ logging: console.log });
14 | res.send(users);
15 | } catch (e) {
16 | throw e;
17 | }
18 | });
19 |
20 | const port = process.env.NODEJS_LOCAL_PORT || 3000;
21 | app.listen(port, () => {
22 | console.log(`Worker: process ${process.pid} is up on port ${port}`);
23 | });
24 |
--------------------------------------------------------------------------------
/app/models/sequelize/user.model.js:
--------------------------------------------------------------------------------
1 | module.exports = (sequelize, DataTypes) => {
2 | const User = sequelize.define(
3 | 'user', // table name
4 | {
5 | // Model attributes are defined here
6 | id: {
7 | type: DataTypes.STRING(50),
8 | allowNull: false,
9 | primaryKey: true,
10 | },
11 | fullname: {
12 | type: DataTypes.STRING(100),
13 | allowNull: false,
14 | },
15 | },
16 | {
17 | // Other model options go here
18 | }
19 | );
20 |
21 | return User;
22 | };
23 |
--------------------------------------------------------------------------------
/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-mysql-app",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [
11 | "docker",
12 | "mysql",
13 | "nodejs"
14 | ],
15 | "author": "FrasNym",
16 | "license": "ISC",
17 | "dependencies": {
18 | "dotenv": "^8.2.0",
19 | "express": "^4.17.1",
20 | "mysql2": "^2.2.5",
21 | "sequelize": "^6.5.0"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '3.8'
2 |
3 | services:
4 | mysqldb:
5 | image: mysql
6 | restart: always
7 | env_file: ./.env
8 | environment:
9 | MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
10 | MYSQL_DATABASE: $MYSQL_DATABASE
11 | ports:
12 | - $MYSQL_LOCAL_PORT:$MYSQL_DOCKER_PORT
13 | volumes:
14 | - db-config:/etc/mysql
15 | - db-data:/var/lib/mysql
16 | - ./db/backup/files/:/data_backup/data
17 | app:
18 | build:
19 | context: .
20 | dockerfile: ./app/Dockerfile
21 | image: node-mysql-app
22 | env_file: ./.env
23 | ports:
24 | - $NODE_LOCAL_PORT:$NODE_DOCKER_PORT
25 | volumes:
26 | - ./app:/app
27 | - app/node_modules
28 | depends_on:
29 | - mysqldb
30 | stdin_open: true
31 | tty: true
32 |
33 | volumes:
34 | db-config:
35 | db-data:
--------------------------------------------------------------------------------