简体   繁体   中英

How do you resolve a docker alias using node?

Say you have two environments in your node app: local, and docker.

If you want to run the app in local you will run it with

env=local node app.js

And if you want to run it in a docker container you would do

env=docker node app.js

Your node app connects to a simple database. You link the name of the database to something eg. "database-server". How do you figure out what this ip address is in your app to store it in a variable? I imagine

console.log(database-server) 

will return "database-server not defined"
I basically want some code similar to:

If(process.env.env === "docker") {process.env.database-ip = database-server} 
Else {process.env.database-ip = localhost}

Except with this code database-server will be undefined.

I understand db.connect(database-server:port) will generally autoresolve the ip address. But my app connects to the database in multiple files

docker-compose.yml

version: '3'

services:
  myapp:
        build: .
        container_name: "myapp"
        links:
            - mongoserver
            - ipfs
        depends_on:
            - mongoserver
            - ipfs
        environment:
          - ENV=docker-dev
  mongoserver:
    image: 'mongo:3.7.9'
    container_name: "mongodb"
    ports:
      - '27017:27017'
    volumes:
      - 'data-volume:/data/db'
  ipfs:
    image: 'jbenet/go-ipfs:latest'
    container_name: "ipfs"
    ports:
     - "5001:5001"
     - "4001:4001"
     - "8080:8080"

volumes:
  data-volume:

Dockerfile in root directory

FROM node

RUN mkdir -p /usr/src/app
ADD server.js /usr/src/app
ADD package.json /usr/src/app
WORKDIR /usr/src/app

# install the dependencies from the package.json file
RUN npm install

EXPOSE 9000
CMD [ "node", "/usr/src/app/server.js" ]

TL:DR how do you store a docker network alias in a variable?

I think You need loading of config depending on environment.

1) Dockerfile:

FROM node:8-alpine
ARG EXPOSE=5005
ENV PORT $EXPOSE
ENV EXPOSE_PORT $EXPOSE
EXPOSE $EXPOSE_PORT
RUN apk add --no-cache curl
ADD ./ /app
WORKDIR /app
RUN npm i
CMD ["npm", "start"]

2) start script in package.json file:

"start": "NODE_ENV=production node server.js",
"development": "NODE_ENV=development node server.js",

3) config folder with multiple environment configs:

配置文件夹

4) index.js that detects NODE_ENV and loads necessary json and replaces PORT (see last lines) and etc external variables:

'use strict';

const nconf = require('nconf');
const path = require('path');
const fs = require('fs');

nconf.env().argv();

const environments = [
  'development',
  'production',
  'local',
  'test'
];

if (!nconf.get('NODE_ENV')) {
  throw new Error('NODE_ENV parameter not defined! \nPlease consider to use one of these environments: ' + environments.join(', '));
}

if (environments.indexOf(nconf.get('NODE_ENV')) < 0) {
  throw new Error('NODE_ENV parameter is not valid! \nPlease consider to use one of these environments: ' + environments.join(', '));
}

try {
  const envConfigFileName = 'config.' + nconf.get('NODE_ENV') + '.json';
  const configFile = path.join(__dirname, envConfigFileName);
  const hiddenConfigFile = path.join(__dirname, '.' + envConfigFileName);
  let currentConfigFile = configFile;

  if (!fs.existsSync(configFile)) {
    if (!fs.existsSync(hiddenConfigFile)) {
      throw new Error('Cannot locate ' + nconf.get('NODE_ENV') + ' environment configuration file');
    }
    currentConfigFile = hiddenConfigFile;
    console.log('\n\n');
    console.log('WARNING READING HIDDEN (dot-file) CONFIG FILE: ' + hiddenConfigFile);
    console.log('MAKE SURE TO HAVE LOCAL COPY OF IT WITHOUT dot (.) SYMBOL AS PREFIX IN FILE NAME');
    console.log('\n\n');
  }

  nconf.file(currentConfigFile);
} catch (exception) {
  throw new Error(exception);
}

if (process.env.PORT) nconf.set('app:http:port', process.env.PORT);
if (process.env.HOST) nconf.set('app:http:host', process.env.HOST);
if (process.env.HTTPS_PORT) nconf.set('app:https:port', process.env.HTTPS_PORT);
if (process.env.HTTPS_HOST) nconf.set('app:https:host', process.env.HTTPS_HOST);

process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
// if(nconf.get('NODE_ENV') !== 'production') process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;

module.exports = nconf;

5) example usage of config module in app.js :

const config = require('./config');

consd db = require('./database');
db.connect(config.get('db:uri'));

const express = require('express');
const app = express();
app.get('/', (req, res) => res.status(204).send());

const listenHost = config.get('app:http:host');
const listenPort = config.get('app:http:port');
const httpServer = http.createServer(app);

httpServer.listen(listenPort, listenHost,
  () => logger.info('App listening at http://%s:%s', listenHost, listenPort));

Since you're using docker-compose and links inside of it, you can access any of the other services by their service name. For example, your database, you can do db.connect('mongoserver:27017') and docker will resolve mongoserver into it's actual IP.

You should be able to access the 'mongoserver' in any of your files where it expects some type of hostname, IP address, etc. in your node.js app. Please let me know if this works out.

Docker aliases are resolved through local dns. Therefore most of the time you don't need to resolve them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM