countly-server icon indicating copy to clipboard operation
countly-server copied to clipboard

Setting up authentication in the Compose file does not work

Open efrecon opened this issue 4 years ago • 2 comments

Expected Behavior

The Docker compose example file does not provide an example of how to protect access to the mongo database using users and passwords. There ought to be a guide in order to favour secure setups.

Current Behavior

Attempting to setup authentication in the bitnami mongodb image using the MONGODB_ROOT_PASSWORD, MONGODB_USERNAME, MONGODB_PASSWORD and MONGODB_DATABASE documented variables, and using the same values in the configuration of the countly containers, e.g. using the COUNTLY_CONFIG__MONGODB variable does not work.

Screenshots (if appropriate):

Possible Solution

Part of the problem seems to be the necessity to create more than just a database called countly. The mongo logs shows that the API container tries to access databases called countly_fs and countly_out. Running a mongo shell prompt (in a container on the same network), as root and entering the two commands below seems to fix the problem, but this should really be automated and/or documented in some way.

db.getSiblingDB('countly_fs').createUser({ user: 'countly', pwd: 'JvvLGXmNdcPvlVszSBqky3Ov', roles: [{role: 'readWrite', db: 'countly_fs'}] }')
db.getSiblingDB('countly_out').createUser({ user: 'countly', pwd: 'JvvLGXmNdcPvlVszSBqky3Ov', roles: [{role: 'readWrite', db: 'countly_out'}] })

Steps to Reproduce (for bugs)

Running the following compose file leads to an API container that does not want to properly start once it has performed its initialisation. (passwords are randomly generated for the sake of this example).

version: "3.7"

volumes:
  mongodb_data:

networks:
  countly:

services:
  mongodb:
    image: 'bitnami/mongodb:4.4.7'
    volumes:
      - 'mongodb_data:/bitnami/mongodb'
    networks:
      countly:
    environment:
      - MONGODB_ROOT_PASSWORD=O3wpVF0YR7EP1VyhZi5SdJFu
      - MONGODB_USERNAME=countly
      - MONGODB_PASSWORD=JvvLGXmNdcPvlVszSBqky3Ov
      - MONGODB_DATABASE=countly

  countly-api:
    image: 'countly/api:20.11.2'
    # Enterprise Edition: image: 'gcr.io/countly-01/api:20.11.2'
    environment:
      - COUNTLY_PLUGINS=mobile,web,desktop,plugins,density,locale,browser,sources,views,enterpriseinfo,logger,systemlogs,populator,reports,crashes,push,star-rating,slipping-away-users,compare,server-stats,dbviewer,assistant,times-of-day,compliance-hub,video-intelligence-monetization,alerts,onboarding,consolidate
      # Enterprise Edition: - COUNTLY_PLUGINS=mobile,web,desktop,plugins,density,locale,browser,sources,views,drill,funnels,retention_segments,flows,cohorts,surveys,remote-config,ab-testing,formulas,activity-map,concurrent_users,revenue,logger,systemlogs,populator,reports,crashes,push,geo,block,restrict,users,star-rating,slipping-away-users,compare,server-stats,assistant,dbviewer,crash_symbolication,crashes-jira,groups,white-labeling,alerts,times-of-day,compliance-hub,onboarding,active_users,performance-monitoring,config-transfer,consolidate,data-manager,hooks,dashboards
      - "COUNTLY_CONFIG__MONGODB=mongodb://countly:JvvLGXmNdcPvlVszSBqky3Ov@mongodb:27017/countly"
      - COUNTLY_CONFIG__LOGGING_DEFAULT=debug
    deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 400s
    networks:
      countly:
    depends_on:
      - mongodb

  countly-frontend:
    image: 'countly/frontend:20.11.2'
    # Enterprise Edition: image: 'gcr.io/countly-01/frontend:20.11.2'
    environment:
      - COUNTLY_PLUGINS=mobile,web,desktop,plugins,density,locale,browser,sources,views,enterpriseinfo,logger,systemlogs,populator,reports,crashes,push,star-rating,slipping-away-users,compare,server-stats,dbviewer,assistant,times-of-day,compliance-hub,video-intelligence-monetization,alerts,onboarding,consolidate
      # Enterprise Edition: - COUNTLY_PLUGINS=mobile,web,desktop,plugins,density,locale,browser,sources,views,drill,funnels,retention_segments,flows,cohorts,surveys,remote-config,ab-testing,formulas,activity-map,concurrent_users,revenue,logger,systemlogs,populator,reports,crashes,push,geo,block,restrict,users,star-rating,slipping-away-users,compare,server-stats,assistant,dbviewer,crash_symbolication,crashes-jira,groups,white-labeling,alerts,times-of-day,compliance-hub,onboarding,active_users,performance-monitoring,config-transfer,consolidate,data-manager,hooks,dashboards
      - "COUNTLY_CONFIG__MONGODB=mongodb://countly:JvvLGXmNdcPvlVszSBqky3Ov@mongodb:27017/countly"
      - COUNTLY_CONFIG__LOGGING_DEFAULT=debug
    networks:
      countly:
    depends_on:
      - mongodb
    deploy:
      # There is usually no need in multiple frontends, so throttling down resources for it
      mode: global
      resources:
        limits:
          cpus: '0.5'
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 400s

  nginx:
    image: 'bitnami/nginx'
    ports:
      - '80:8080'
    volumes:
      - './bin/docker/nginx.server.conf:/opt/bitnami/nginx/conf/server_blocks/countly.conf:ro'
    networks:
      countly:
    depends_on:
      - countly-api
      - countly-frontend

More Description

I tried the same type of configuration in k8s, using the bitnami helm chart for mongoDB. As I could not understand why my settings would not work, I migrated to test them with compose in order to better understand the problem.

Your Environment

I run this in WSL2, but I believe that this is a generic problem.

efrecon avatar Jul 28 '21 10:07 efrecon

I have a potential fix here: https://github.com/efrecon/countly-server/tree/feature/authenticated-mongodb. However, I think that the entire fix makes much more sense to be pushed at the Bitnami's MongoDB repo. I am going to propose a PR there instead.

efrecon avatar Jul 28 '21 13:07 efrecon

You can create a .js file, let's say mongodb-init.js

db.getSiblingDB('countly').createUser({
    user: 'MY_COUNTLY_USER',
    pwd: 'MY_COUNTLY_PASSWORD',
    roles: [{
        role: 'readWrite',
        db: 'countly'
    }]
});
db.getSiblingDB('countly_fs').createUser({
    user: 'MY_COUNTLY_USER',
    pwd: 'MY_COUNTLY_PASSWORD',
    roles: [{
        role: 'readWrite',
        db: 'countly_fs'
    }]
});
db.getSiblingDB('countly_out').createUser({
    user: 'MY_COUNTLY_USER',
    pwd: 'MY_COUNTLY_PASSWORD',
    roles: [{
        role: 'readWrite',
        db: 'countly_out'
    }]
});

and then mount it on mongodb like this:


    volumes:
      - ./mongodb-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro

it will get executed the first time it runs (I'm not sure but maybe ONLY the first time it starts).

LivingWithHippos avatar Aug 23 '21 08:08 LivingWithHippos