0

I am learning docker to use on my project. However, I could not understand on using environment variable when using docker.

Here is my mongo setup process

const mongoose = require('mongoose');
const Promise = require("bluebird");
const mongodb = require('mongodb');
const uuidv4 = require('uuid/v4');
const MongoClient = mongodb.MongoClient;
const utilityHelper = require('../helpers/utility');

const {
  DATABASE_HOST,
  DATABASE_PORT,
  DATABASE_DBNAME,
  DATABASE_DBUSER,
  DATABASE_DBPASS
} = require('../configs');

const connectDb = () => {
  const user = encodeURIComponent(DATABASE_DBUSER);
  const password = encodeURIComponent(DATABASE_DBPASS);

  // Connection URL
  let dbUrl = `mongodb://${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_DBNAME}`;
  let options={
    useNewUrlParser: true,
    useCreateIndex: true
  };
  if (user !== "undefined" && password !== "undefined") {
    options.user = user;
    options.pass = password;
    dbUrl = dbUrl + `?authSource=${DATABASE_DBNAME}`;
  } 
  return mongoose.connect(
    dbUrl,
    options,
    (err, data) => {
      if (err) {
        console.error(err.stack);
      } else {
        console.log("Database is connected..")
      }
    }
  );
};

const dbConnector = async (app) => {
  try {
    return new Promise((resolve, reject) => {
      const user = encodeURIComponent(DATABASE_DBUSER);
      const password = encodeURIComponent(DATABASE_DBPASS);

      // Connection URL
      let dbUrl="";
      if (user !== "undefined" && password !== "undefined") {
        dbUrl = `mongodb://${user}:${password}@${DATABASE_HOST}:${DATABASE_PORT}/?authSource=${DATABASE_DBNAME}`
      } else {
        dbUrl = `mongodb://${DATABASE_HOST}:${DATABASE_PORT}`;
      }
      const options = {
          promiseLibrary: Promise,
          connectTimeoutMS: 60000,
          useNewUrlParser: true,
          useUnifiedTopology: true,
      };

      const client = new MongoClient(dbUrl, options);

      client.connect(async(err, client) => {
        if(err) reject(err);
        const db = client.db(DATABASE_DBNAME);
        app.locals.db = db;
        if (process.env.RUN_FIRST_TIME === 'true') await createUsersWithRoles(db);
        console.log('database connection success');
        resolve(db);
      });
    })
  } catch(err) {
    throw new Error(err);
  }
}

const createUsersWithRoles = async(db) => {
  const adminRole = {
    _id: uuidv4(),
    name: 'Admin',
    code: 'A',
    createdAt: new Date(),
    updatedAt: new Date()
  };

  const guideRole = {
    _id: uuidv4(),
    name: 'Guide',
    code: 'G',
    createdAt: new Date(),
    updatedAt: new Date()
  };

  const user1 = {
    _id: uuidv4(),
    email: '[email protected]',
    firstName: "Admin",
    lastName: "Account",
    slug: 'admin-account',
    fullName: "Admin" + " " + "Account",
    password: await utilityHelper.hashPassword('Test@123'),
    gender: 'M',
    role: adminRole
  };

  await db.collection('Role').insertMany([adminRole, guideRole, travellerRole]);
  await db.collection('User').insertOne(user1);
};

module.exports = { 
  connectDb,
  dbConnector
}

.env

DATABASE_HOST=localhost
DATABASE_PORT=27017
DATABASE_DBUSER=travel
DATABASE_DBPASS=travel123
DATABASE_DBNAME=travel_db

Dockerfile

# Use a node.js image from Docker.
FROM node:12-alpine

# Create app directory, this is where our source code will live
WORKDIR /usr/src/app

RUN apk update && apk upgrade && apk add --no-cache bash git python3
# RUN apt-get install -y build-essential python
RUN npm install --global npm node-gyp

# We need to install our npm package in the container image
COPY package*.json ./

# now we will install the package
RUN npm install

# copy your application source into a src folder
COPY ./src /usr/src/app/src
COPY pm2.json ./
COPY .env ./.env

EXPOSE 8000

CMD ["npm", "start"]

docker-compose.yml

version: "3.7"

# Lets define all our services (i.e. our containers to run)
services:
    # create a mongodb database
    travel-db:
        image: mongo
        container_name: "travel-db"
        volumes:
            - mongodb:/data/db/
        # opening mongodb port so that it can be connected from host
        ports:
            - "27017:27017"
    # create redis-server
    travel-redis-server:
        image: redis:latest
        container_name: "travel-redis-server"
        volumes:
            - redis:/data/
        ports:
            - "6379:6379"

    # express app
    travel-express-server:
        image: "travel-express-server"
        container_name: "travel-express-server"
        ports:
            - "8000:8000"

volumes:
    travel-db:
    travel-redis-server:

I want to know how can i utilize environment variable on setting up mongodb when it is done using docker. Do i need to have separate env variables for docker?

1 Answer 1

1

It isn't really a good practice to have your env variables in image itself. It should rather be provided like this:

env_file:
        - ./.env

in your docker-compose. And remove the relevant COPY command from your Dockerfile. Just keep one .env for all the variables you need across different services in the docker-compose.

Also, you won't be able to access localhost like this. You would need to change your DATABASE_HOST to travel-db and do the same for all other services like REDIS.

Sign up to request clarification or add additional context in comments.

9 Comments

when used env_file then i don't need to use environment key right?
Yeah, you dont need to
Thank you for your solution. I could not test it so I can mark it as correct as I am getting ERROR: pull access denied for travel-express-server, repository does not exist or may require 'docker login': denied: requested access to the resource is denied error.
You just need to do docker login, the repository might not be public. You are getting error because of this.
it's a local nodejs repository.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.