Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用nodejs&mysql&docker来搭建API服务 #5

Open
JayFate opened this issue Aug 3, 2023 · 1 comment
Open

使用nodejs&mysql&docker来搭建API服务 #5

JayFate opened this issue Aug 3, 2023 · 1 comment

Comments

@JayFate
Copy link
Owner

JayFate commented Aug 3, 2023

Docker提供轻量级容器来运行我们的服务,以便于快速开发/交付软件。在本文我们将探讨如何使用Docker Compose来集成 Nodejs Express 和 MySQL 应用。

Node.js 和 MySQL 与 Docker 概述

我们可以使用 docker compose 在容器中同时提供 nodejs API 服务和 mysql 数据库,具体的步骤为:

  • 创建一个使用 MySQL 数据库的 应用
  • 创建 nodejs 应用的 Dockerfile
  • 创建 docker-compose.yml
  • 设置 docker compose 的环境变量

目录结构:

docker-nodejs-mysql (main) $ tree 
.
├── README.md
├── docker-compose.yml
└── jayfate-app
    ├── Dockerfile
    ├── README.md
    ├── app
    │   ├── config
    │   │   └── db.config.js
    │   ├── controllers
    │   │   └── tutorial.controller.js
    │   ├── models
    │   │   ├── index.js
    │   │   └── tutorial.model.js
    │   └── routes
    │       └── turorial.routes.js
    ├── package.json
    └── server.js

创建 Nodejs 应用程序

jayfate-app 运行 npm init -y,并修改 package.json 的内容为:

jayfate-app/package.json

{
  "name": "nodejs-express-sequelize-mysql",
  "version": "1.0.0",
  "description": "Node.js Rest Apis with Express, Sequelize & MySQL",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "nodejs",
    "express",
    "rest",
    "api",
    "sequelize",
    "mysql"
  ],
  "author": "jayfate",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^10.0.0",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "mysql2": "^2.0.2",
    "sequelize": "^5.21.2"
  }
}

然后编写 jayfate-app/server.js

// 导入`dotenv` 用于设置`process.env`,用于设置端口
require("dotenv").config();
const express = require("express");
const cors = require("cors");

const app = express();

var corsOptions = {
  origin: "http://localhost:8081"
};

app.use(cors(corsOptions));

// parse requests of content-type - application/json
app.use(express.json());

// parse requests of content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));

const db = require("./app/models");

db.sequelize.sync();
// // drop the table if it already exists
// db.sequelize.sync({ force: true }).then(() => {
//   console.log("Drop and re-sync db.");
// });

// simple route
app.get("/", (req, res) => {
  res.json({ message: "Welcome to jayfate application." });
});

require("./app/routes/turorial.routes")(app);

// set port, listen for requests
const PORT = process.env.NODE_DOCKER_PORT || 8080;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}.`);
});

然后编写 mysql 数据库的配置

app/config/db.config.js

module.exports = {
  HOST: process.env.DB_HOST,
  USER: process.env.DB_USER,
  PASSWORD: process.env.DB_PASSWORD,
  DB: process.env.DB_NAME,
  port: process.env.DB_PORT,
  dialect: "mysql",
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
};

app/models/index.js

onst dbConfig = require("../config/db.config.js");

const Sequelize = require("sequelize");
const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
  host: dbConfig.HOST,
  dialect: dbConfig.dialect,
  port: dbConfig.port,
  operatorsAliases: false,

  pool: {
    max: dbConfig.pool.max,
    min: dbConfig.pool.min,
    acquire: dbConfig.pool.acquire,
    idle: dbConfig.pool.idle
  }
});

const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;

db.tutorials = require("./tutorial.model.js")(sequelize, Sequelize);

module.exports = db;

编写 jayfate-app/.env.sample 来设置环境变量

jayfate-app/.env.sample

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=123456
DB_NAME=jayfate_db
DB_PORT=3306

NODE_DOCKER_PORT=8080

编写 Dockerfile

编写我们的 nodejs 应用的 Dockerfile

jayfate-app/Dockerfile

FROM node:14

WORKDIR /jayfate-app
COPY package.json .
RUN npm install
COPY . .
CMD npm start

其中:

  • FROM:指定 Node.js的镜像
  • WORKDIR:工作目录
  • COPYCOPY package.json .package.json 文件复制到容器中,COPY . . 复制项目中的所有文件。
  • RUN:在容器内执行命令 npm install安装package.json中的依赖项。
  • CMD: 镜像构建后运行 npm start

编写 Docker Compose 配置

在项目目录的根目录中创建 docker-compose.yml

docker-compose.yml

让我们来实现细节。

docker-compose.yml

version: '3.8'

services:
  mysqldb:
    image: mysql:5.7
    restart: unless-stopped
    env_file: ./.env
    environment:
      - MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD
      - MYSQL_DATABASE=$MYSQLDB_DATABASE
    ports:
      - $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
    volumes:
      - db:/var/lib/mysql
  app:
    depends_on:
      - mysqldb
    build: ./jayfate-app
    restart: unless-stopped
    env_file: ./.env
    ports:
      - $NODE_LOCAL_PORT:$NODE_DOCKER_PORT
    environment:
      - DB_HOST=mysqldb
      - DB_USER=$MYSQLDB_USER
      - DB_PASSWORD=$MYSQLDB_ROOT_PASSWORD
      - DB_NAME=$MYSQLDB_DATABASE
      - DB_PORT=$MYSQLDB_DOCKER_PORT
    stdin_open: true
    tty: true

volumes: 
  db:
  • version:将使用 Docker Compose 文件格式版本

  • services:指定隔离容器中的单独服务,我们有两个服务:app(Nodejs)和mysqldb(MySQL 数据库)

  • volumes:命名卷在重新启动后使我们的数据保持活动状态

  • mysqldb

    • image:指定 Docker 镜像

    • restart:配置重启策略

    • env_file:指定 .env 的路径

    • environment:指定环境变量

    • ports:指定端口

    • volumes:映射卷文件夹

  • app

    • depends_on:指定 app 服务依赖 mysqldb 服务先启动

    • build:在构建时应用的配置选项,我们在 Dockerfile 中使用相对路径定义

    • environment:指定Node 应用程序的环境变量

    • stdin_opentty:构建容器后保持终端开启

请注意,主机端口 ( LOCAL_PORT) 和容器端口 ( DOCKER_PORT) 是不同的。docker compose 内部各服务之间通信使用容器端口,我们外部访问使用主机端口。

定义 MySQL 的环境变量

使用 .env 定义MySQL的环境变量:

.env

MYSQLDB_USER=root
MYSQLDB_ROOT_PASSWORD=123456
MYSQLDB_DATABASE=jayfate_db
MYSQLDB_LOCAL_PORT=3307
MYSQLDB_DOCKER_PORT=3306

NODE_LOCAL_PORT=6868
NODE_DOCKER_PORT=8080

运行 Docker Compose 应用

可以通过一下命令来运行 Docker Compose 应用

docker-compose up
# 或者以后台方式运行
docker-compose up -d

运行时日志如下:

$ docker-compose up -d
Creating network "node-mysql_default" with the default driver
Creating volume "node-mysql_db" with default driver
Pulling mysqldb (mysql:5.7)...
5.7: Pulling from library/mysql
...
...
`docker-compose build` or `docker-compose up --build`.
Creating node-mysql_mysqldb_1 ... done
Creating node-mysql_app_1     ... done

可以使用 docker ps 查看当前运行中的容器:

$ docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED         STATUS              PORTS                                                  NAMES
b8b12819d371   node-mysql_app   "docker-entrypoint.s…"   2 minutes ago   Up About a minute   0.0.0.0:6868->8080/tcp, :::6868->8080/tcp              node-mysql_app_1
b0d665c00073   mysql:5.7        "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes        33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   node-mysql_mysqldb_1

docker images 查看 Docker 镜像:

$ docker images
REPOSITORY            TAG            IMAGE ID       CREATED         SIZE
node-mysql_app        latest         9d0109ff706c   5 minutes ago   965MB
node                  14             e0ab58ea4a4f   6 minutes ago   944MB
mysql                 5.7            8cf625070931   6 minutes ago   448MB

停止应用程序

通过一下命令停止 docker-compose 服务

docker-compose down

或者停止 docker-compose 服务并删除所有容器和镜像

docker-compose down --rmi all

结论

今天我们已经成功为 MySQL 和 Nodejs 应用程序创建了 Docker Compose 文件。现在我们可以通过非常简单的方式使用 Docker 部署 Nodejs Express 和 MySQL:docker-compose.yml

源码

可以在Github上查看本文对应的源码

https://www.bezkoder.com/docker-compose-nodejs-mysql/

@JayFate JayFate changed the title 使用nodejs-mysql和docker来搭建API服务 使用nodejs&mysql&docker来搭建API服务 Aug 6, 2023
@JayFate
Copy link
Owner Author

JayFate commented Aug 7, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant