0
votes

Goal:

I am currently trying to set up a staging and demo environment for my application. I am using Google App Engine and deploy to a different URL and App Engine project for all of them. The Idea is that every Instance connects to their own URL based on the environment.

Problem:

The problem currently is that even though I can see in console logs that the Apps do get the correct Environment Variables every instance does try to read and write to the production database.

The Console even logs "Connected to Database: Demo / Staging on the demo environment or staging environment. Still I get the collections and data from the production database.

This is not true for running the app locally where it does connect to the staging database. (The environment variable for NODE_ENV is undefined when run locally)

Code:

My production instance is deploying to a google app engine project using this configuration.

production.yaml

runtime: nodejs10
env: standard
instance_class: F1
handlers:
  - url: /favicon\.ico
    static_files: favicon.ico
    upload: favicon.ico

  - url: /static
    static_dir: public

  - url: /.*
    secure: always
    redirect_http_response_code: 301
    script: auto

automatic_scaling:
  min_idle_instances: 1
  max_idle_instances: 3
  min_instances: 1
  min_pending_latency: automatic
  max_pending_latency: automatic
network: {}
env_variables:
  NODE_ENV: production
  LOGIN_PAGE: https://login.myproductionurl.com/
  API_ENDPOINT: https://myproductionurl.appspot.com/
  PORT: 8080

Demo and Staging have a similar set up with the change of the environment variables set for their case.

demo.yaml

...
env_variables:
  NODE_ENV: demo
  LOGIN_PAGE: https://login.mydemourl.com/
  API_ENDPOINT: https://mydemourl.appspot.com/
  PORT: 8080

staging.yaml

...
env_variables:
  NODE_ENV: staging
  LOGIN_PAGE: https://login.mystagingurl.com/
  API_ENDPOINT: https://mystagingurl.appspot.com/
  PORT: 8080

In the Express server itself I then try to connect to a different MongoDB database within Cloud Atlas based on the environment variable.

Database connection in server.js

 if (process.env.NODE_ENV === "demo") {
    console.log("Connecting to Database: Demo");
    mongoose.connect(
     "mongodb+srv://(myusername):(mypassword)@(myucluster).mongodb.net/demo",
      { useNewUrlParser: true }
    );
  } else if (process.env.NODE_ENV === "production") {
    console.log("Connecting to Database: Production");
    mongoose.connect(
      "mongodb+srv://(myusername):(mypassword)@(myucluster).mongodb.net/production",
      { useNewUrlParser: true }
    );
  } else {
    console.log("Connecting to Database: Staging");
    mongoose.connect(
      "mongodb+srv://(myusername):(mypassword)@(myucluster).mongodb.net/staging",
      { useNewUrlParser: true }
    );
  }

  const db = mongoose.connection;
  db.on("error", (error) => console.error(error));
  db.once("open", () => console.log("connected to database"));

  server.set("database", db);

Additional Info:

There are no connections specified anywhere else in the project. enter image description here

1
Are you sure you are not using another connection from another file to perform the operations? Your code seems fine and the console.log statements too.leonardfactory
Unfortunately not - there are no other connections opened anywhere in the project. Edited and attached a screenshot to the question so this is clarified. I am out of ideas, could it be that the connection is cached somewhere as production was the first environment I accessed.Stefan Januschke
Could you try to log, on database connected event, the connection name with mongoose.connection.name?leonardfactory
Sure let me try that!Stefan Januschke
It logs: undefinedStefan Januschke

1 Answers

2
votes

Seems like DB Name for clusters is different as mongoose doc says

You should use, instead of dbname in connection string, use the dbName option:

mongoose.connect('mongodb+srv://(un):(pw)@(cluster).mongodb.net/staging', { dbName: 'staging' });

Related answer is Fail to connect Mongoose to Atlas