本文共 3324 字,大约阅读时间需要 11 分钟。
去年一门课程,用nodejs+mongodb重构了一个jsp+servlet+mysql的web网站(具体参见),但是网站是本地部署的,数据库也是本地先创建好的,想要把这个网站用docker-compose跑起来,需要写一些脚本、Dockerfile文件和对应的docker-compose文件。
(重点在于数据库的容器化,参考文章:)|- project |- Dockerfile |- ... (nodejs项目的其它所有目录和文件)|- mongo |- data |- xxx.json (用于初始化的数据库文件) |- Mongo-Dockerfile |- setup.sh|- data |- db (宿主机挂载目录)|- docker-compose.yaml
mongoexport -d-c -o
var mongoose = require('mongoose'), DB_URL = 'mongodb:/// ';mongoose.Promise = global.Promise;var reconnectTimeout = 5000; // ms./** * 连接 */// mongoose.connect(DB_URL, { useMongoClient: true, autoReconnect: true});function connect() { // Catch the warning, no further treatment is required // because the Connection events are already doing this // for us. mongoose.connect(DB_URL, { useMongoClient: true, autoReconnect: true }).catch(function(){ });}/** * 连接成功 */mongoose.connection.on('connected', function () { console.log('Mongoose connection open to ' + DB_URL);});/** * 连接异常 */mongoose.connection.on('error',function (err) { console.log('Mongoose connection error: ' + err); mongoose.disconnect();});/** * 连接断开 */mongoose.connection.on('disconnected', function () { console.log('Mongoose connection disconnected'); setTimeout(function(){ connect(); }, reconnectTimeout);});connect();module.exports = mongoose;
以为只要改DB_URL,但是发现docker-compose中的depends_on并不能保证mongo先启动好,service第一次尝试连接数据库会失败(挂载到宿主机、第一次初始化的时间还是需要一些时间的),然后就一直不连了。
尝试了mongoose在connect时加上option: autoReconnect:true,然而在第一次连接失败情况下它并不会重新连接!!!很坑好吧。最后按照stackoverflow上的解答,改了源码,在连接报错的时候显式关闭连接,已经关闭连接的时候隔5秒重新建立连接。
FROM mongoENV WORKSPACE /usr/local/workENV AUTO_RUN_DIR /docker-entrypoint-initdb.dENV INSTALL_MONGO_SHELL setup.shRUN mkdir -p $WORKSPACECOPY ./data/*.json $WORKSPACE/COPY ./$INSTALL_MONGO_SHELL $AUTO_RUN_DIR/RUN chmod a+x $AUTO_RUN_DIR/$INSTALL_MONGO_SHELL
#!/bin/bashmongo <;db.createCollection(" ");EOFmongoimport --db --collection --file $WORKSPACE/ .json
这里有一个坑,之前也踩过,但就是不长记性:) 在windows下编辑的.sh文件编码格式为dos,换行符为\r\n,放到centos7里面跑,需要修改编码格式为unix(换行符为\n):
vi setup.sh:set ff? #可以看到当前文件格式:set ff=unix #设置成unix格式:set ff=dos #设置成dos格式:wq #退出
FROM nodeMAINTAINER dingdingRUN mkdir -p /appWORKDIR /app# 我就很简单粗暴(主要是菜),在本地npm install把所有依赖包都下好,打镜像的时候就直接copy进去# 反正就是把项目所有需要的目录和文件都add进去~~ADD ./app.js /app/ADD ./package.json /app/ADD ./bin /app/binADD ./node_modules /app/node_modulesADD ./public /app/publicADD ./routes /app/routesADD ./views /app/viewsCMD [ "npm", "start" ]EXPOSE 3000
version: '3'services: petalk-mongo: build: context: petalk-mongo dockerfile: Mongo-Dockerfile image: petalk-mongo ports: - 27017:27017 volumes: # 宿主机目录:容器挂载目录 # ./是相对docker-compose文件的路径,/是容器内部的绝对路径 - "./data/db:/data/db" - "/etc/localtime:/etc/localtime" networks: - my-network petalk-service: build: petalk-service image: petalk-service restart: always ports: - 3000:3000 depends_on: - petalk-mongo networks: - my-networknetworks: my-network: driver: bridge
项目代码:
改进版本(build镜像时下载npm依赖):
转载地址:http://ookvb.baihongyu.com/