Search code examples
environment-variablesgitignoredotenv

Proper way to store DB credentials in a .env file before pushing to GitHub


I am quite new to using github etc. basically my situation is I have my development and production DB's wired up through a knexfile.js (I am using knex and PostgreSQL). The credentials for my production DB is okay:


  production: {
    client: 'postgresql',
    connection: {
      connectionString: process.env.DATABASE_URL, //get from heroku
      ssl: { rejectUnauthorized: false },
    },
    pool: {
      min: 2,
      max: 10,
    },
    migrations: {
      tableName: 'knex_migrations',
    },
  },
}

But my development DB has my credentials written into it - I obviously don't want these going up to GitHub.


  development: {
    client: 'postgresql',
    connection: {
      database: 'biblion',
      user: 'USERNAME',
      password: 'PASSWORD',
    },
    pool: {
      min: 2,
      max: 10,
    },
    migrations: {
      tableName: 'knex_migrations',
    },
  },

I tried putting my knexfile.js into .gitignore but that broke things so I had to do a hard reset to an earlier git commit and now I am a bit stuck about how to proceed. I believe I may have to use a .env file but I am uncertain about the process for doing this, properly adding the credentials to the .env calling those in the knexfile.js then safely pushing this up to GitHub.

I'd be grateful for some guidance!


Solution

  • What about changing those to process.env as you suggested ?

    development: {
        client: 'postgresql',
        connection: {
          database: 'biblion',
          user: process.env.USERNAME,
          password: process.env.PASSWORD,
        },
        ...
      },
    

    You could either start your script with those passed USERNAME=abc PASSWORD=123 node script.js

    Or use dotenv, through an .env file

    You could then :

    • Either use https://github.com/dkundel/node-env-run, to make sure it loads your node env variables locally before running the script

    • Or require dotenv in the knexfile.js ( I am not sure if this would actually work or create issues with knex )


    Other idea would be to have a different file to load for development, you keep the knexfile for your production and as it is for other env, but have a different filename that you don't commit to github for your dev env

    const env = process.env.NODE_ENV;
    let config;
    if (env === 'production') {
        config = require('../knexfile.js')[env];
    } else {
        config = require('../local-knexfile.js')[env];
    }
    

    This is not ideal since you'd end up with 2 files to maintain