Countly is divided into two parts (Frontend and API), both of which have their own additional configuration options that you might want to change when installing Countly.
Location of configuration files:
- {countlydir}/frontend/express/config.js
- {countlydir}/api/config.js
Also, some plugins may have their own configuration files, for example:
- {countlydir}/plugins/drill/config.js
Copy or rename the config.sample.js files located at the same directory to easily create a configuration. Otherwise, the config.js files will be generated by installation scripts with default values.
File config.js by itself is a simple nodejs module file with config object properties inside. An example of config.js content appears as follows:
var countlyConfig = {
mongodb: {
host: "localhost",
db: "countly",
port: 27017,
max_pool_size: 500,
//username: test,
//password: test
},
/* or for a replica set
mongodb: {
replSetServers : [
'192.168.3.1:27017',
'192.168.3.2:27017'
],
db: "countly",
username: test,
password: test,
max_pool_size: 100
},
*/
/* or define as a url
//mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
mongodb: "localhost:27017/countly",
*/
web: {
port: 6001,
host: "localhost",
use_intercom: true
},
production: false,
path: "",
cdn: "",
session_timeout: 2*60*1000
};
module.exports = countlyConfig;Configuring Connection to MongoDB
The main thing you need to specify in config.js is the connection setting to your MongoDB in the mongodb property.
You may specify connection settings as a string whose format is described by MongoDB docs.
Here is an example:
mongodb:"mongodb://username:password@db1.example.net,db2.example.net:2500/dbname"
You may also define configuration as an object with properties such as:
mongodb: {
host: "localhost",
db: "countly",
port: 27017,
max_pool_size: 500,
username: "test",
password: "test"
}In addition, you may define replica sets:
mongodb: {
replSetServers : [
'192.168.3.1:27017',
'192.168.3.2:27017'
],
replicaName: "rs0",
db: "countly",
username: "test",
password: "test",
max_pool_size: 100
}Note that in order for the MongoDB server to handle incoming connections from a remote server, you will need to modify the bind_ip directive in /etc/mongodb.conf, so it can accept connections from the Countly server.
A Note About Remote Databases
If your Countly instance can successfully connect to the MongoDB instance, then there is no further configuration necessary. You don't need to create any databases or collections - Countly will take care of those.
Using Countly from a Subdirectory
If you don’t end up having a separate domain for the Countly installation or you can't use subdomains, you have the option to use Countly from a subdirectory, such as http://domain.com/countly.
Supported as of v25.03.46
Running Countly from a subdirectory is supported as of v25.03.46 (and backported to v24.05). In earlier versions, several absolute paths in the dashboard and some plugins were hardcoded to the root and would break when used under a subdirectory, so make sure you are on 25.03.46 or later before following these steps.
Set the path in both config files: Add the same subdirectory path to both the frontend and API config.js files ({countlydir}/frontend/express/config.js and {countlydir}/api/config.js):
path: "/countly"
The frontend uses this value to prefix every dashboard route and static asset, while the API uses it to strip the prefix from incoming /i and /o requests, so the value must match in both files.
Update your reverse proxy configuration: Route the subdirectory to the Countly frontend (port 6001) and API (port 3001).
Each API endpoint needs two location blocks: an exact match (/countly/i and /countly/o) and a prefix match for everything beneath it (/countly/i/ and /countly/o/). Otherwise, calls such as /countly/i/bulk will not reach the API. The nginx configuration is usually stored under /etc/nginx/sites-enabled/default:
server {
listen 80;
server_name localhost;
access_log off;
location = /countly/i {
proxy_pass http://127.0.0.1:3001;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location ^~ /countly/i/ {
proxy_pass http://127.0.0.1:3001;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location = /countly/o {
proxy_pass http://127.0.0.1:3001;
}
location ^~ /countly/o/ {
proxy_pass http://127.0.0.1:3001;
}
location /countly/ {
proxy_pass http://127.0.0.1:6001;
proxy_set_header Host $http_host;
}
}Reload NGINX so the new configuration takes effect:
/etc/init.d/nginx restart
Restart Countly so it reloads the updated config files:
countly restart
Browser Side Configuration
Additionally, there is the {countly}/frontend/express/public/javascripts/countly/countly.config.js file which provides some web end configurations such as:
countlyCommon.DEBUG = false;
countlyCommon.API_URL = countlyGlobal["path"] || "";
countlyCommon.API_PARTS = {
data:{
"w":countlyCommon.API_URL + "/i",
"r":countlyCommon.API_URL + "/o"
},
apps:{
"w":countlyCommon.API_URL + "/i/apps",
"r":countlyCommon.API_URL + "/o/apps"
},
users:{
"w":countlyCommon.API_URL + "/i/users",
"r":countlyCommon.API_URL + "/o/users"
}
};
countlyCommon.DASHBOARD_REFRESH_MS = 10000;
countlyCommon.DASHBOARD_IDLE_MS = 3000000;
countlyCommon.GRAPH_COLORS = ["#88BBC8", "#ED8662", "#A0ED62", "#ed6262", "#edb762", "#ede262", "#62edb0", "#62beed", "#6279ed", "#c162ed", "#ed62c7", "#9A1B2F"];
countlyCommon.CITY_DATA = true;As you can see, you may set the refresh rate, set some graph colors, or define the API URL end points from this file.
Configure the Shared File System Between Multiple Countly Servers
In cases when you have multiple Countly servers behind a load balancer, you will want them to share files.
If not, then uploading a file, such as an app icon or symbolication file, will only be uploaded to a random server. Also, it might request it from another server which does not have that file.
This is why servers should share these files through a common database named countly_fs, which uses MongoDB GridFS to store and retrieve files.
To do so, you must complete these changes on each Countly server you have behind the load balancer:
1) Edit file countly/api/config.js. You will need to change the property fileStorage value from fs to gridfs inside countly/api/config.js.
2) Restart the Countly process by running the following:
countly restart
3) Transfer existing uploads (if any) to GridFS
To transfer all existing uploaded files that are already on a disk into a shared filesystem in the database (gridfs), you will need to run the following:
countly fs migrate fs gridfs
Now all servers will be uploading and taking files from MongoDB’s shared file system, called GridFS.
Configure DNS
While the Countly server will work without a DNS, it's suggested that you assign a DNS A record to your server, so you won’t have to memorize an IP address, such as countly.yourserver.com.
Configure Email Delivery
Due to potential spam issues, you need to ensure that you configure your DNS records (explained below), so that emails sent from Countly (e.g. when you add a new user or daily/weekly email reports) can be sent and not caught by SPAM preventions.
Here are a few important things you should check first:
- Ensure your ISP has a reverse DNS record entered to associate the domain names and IP addresses from which you send mail. Test your Reverse PTR record here. If your ISP does not enter the proper reverse DNS pointer record, it's very unlikely any of your emails will be delivered.
- Is your domain's SPF record correct? Test your SPF record here. Note that TXT is the correct official record type for SPF.
- Is your domain's DKIM record correct? This will significantly improve email deliverability. Test your DKIM record here.
- If you run your own mail server, check to ensure your mail server IPs are not on any email blacklists. Also, verify that it is definitely sending a fully qualified hostname that resolves in DNS in its HELO message. If not, this will cause your email to be rejected by many mail services.
We highly recommend you send a test email to mail-tester.com to verify that everything mentioned above is working correctly.
Using a Third-party Email Server
- Rename this file (countly/extend/mail.example.js in your Countly directory) to countly/extend/mail.js.
- Add your email server information. An example has been provided below:
module.exports = function(mail){
//define this if you need to send email from some third party service
mail.smtpTransport = nodemailer.createTransport(smtpTransport({
host: "example-mailserver-host.com",
secureConnection: true,
port: 2525,
auth: {
user: "your-mailserver-username",
pass: "your-mailserver-password"
}
}));
Configure Server Monitoring
When your server has a problem (e.g. lack of enough RAM, lack of swap space, running out of disk, etc.), chances are that Linux kernel will kill some of the processes or Countly won't work properly. In order to ensure you have a healthy and stable server, we suggest using a monitoring and alerting solution, such as Server Density, Nagios, or New Relic.
Monitoring Metrics
CPU and Memory (both in Countly and MongoDB Servers)
We don't have any specific threshold for CPU and memory so you can try to start with your team's standard threshold. However, note that you may get false positives most of the times since the CPU on Countly servers and the memory on MongoDB servers could cause usage spikes with resource-hungry, short-term features - like Push - or increasing incoming requests on an app.
Boot Disk (both in Countly and MongoDB Servers)
Customers can set a threshold for a boot disk based on the capacity of the boot disk and the response time of the IT team. Alerts for boot disk monitoring shouldn't be triggered if everything is OK with log rotations.
Note: You may need to enlarge the boot disk over time for Countly servers if Crash Symbolication is enabled.
Data Disk (MongoDB Servers)
We always suggest a size for data disks in MongoDB servers based on the customers' usage plan and data retention policy but consider that the capacity needs for data disks are open to change since business choices may change over time.
Suggested thresholds are 5GB space for disks <= 100GB & 15GB space for disks > 100GB. Again, the customer can tune it based on the response time of the IT team.
'mongod' Process (MongoDB Servers)
MongoDB, for sure, must be running all the time. Having a failing MongoDB service over and over again may indicate an issue on the system such as kernel limits, etc. MongoDB should be restarted immediately and the infra team should inspect the server and logs for the root cause of service interruption. You can integrate this command into your monitoring system if you don't have any MongoDB-specific helper on your system. You can also check the exit code of this command; MongoDB is running if it is 0 and not running if it is 1.
ps aux | grep -v grep | grep -q /usr/bin/mongod
Making Countly More Secure
We have a list of security and privacy recommendations, together with guidelines, on how to ensure secure deployment. Read more here.