# DeviceAtlas C++ API and Nginx Module Installation #
Instructions on how to build and run Nginx with DeviceAtlas module.
1. Dependencies
2. Make the DeviceAtlas API and Nginx module
3. Configure Nginx
4. Run module
### Dependencies ###
DeviceAtlas API and Nginx module do not have third-party dependencies.
### Make the DeviceAtlas API and Nginx module ###
- Recommended Nginx version: 1.10.1+, or r11+ for Nginx Plus
- Compilation options: Static or Dynamic (DSO)
** Get the package **
Download and extract the files.
```sh
tar -zxvf deviceatlas_cpp-nginx_{version}.tar.gz
cd deviceatlas_cpp-nginx_{version}
```
** Build static module **
By default, cmake will pull down the Nginx 1.10.1 source version and build it with DeviceAtlas.
```sh
cmake .
make
```
** Build dynamic (.so) module **
Use dynamic module flag to build a dynamic module.
```sh
cmake -DNGINX_DYN_MODULE=1
make
```
To load the module from Nginx use following directive for the Nginx config file.
```
load_module /nginx-{version}/objs/mtld_http_devatlas_module.so;
```
For use of the compiled DSO module with the Nginx binary package coming from the Linux distributions be aware that
the module must be compiled with the DeviceAtlas dynamic module --add-dynamic-module or --add-module.
You can find more details about it in the section below.
** Nginx Plus **
To build the module we need to find out Nginx Plus configuration flags and the version by using:
```sh
nginx -V
```
Then, run cmake:
```sh
cmake -DNGINX_VERSION=[copy version from nginx -V, e.g. 1.11.5] -DNGINX_DYN_MODULE=1
make
```
Then, in the nginx- folder modify the ./configure command with:
```sh
./configure --with-compat --add-dynamic-module=/nginx \
--with-cc-opt='[copy from nginx -V]' --with-ld-opt='[copy from nginx -V] -Wl,-rpath,/api'
make
```
To load the module from Nginx Plus use following directive for the Nginx config file.
```
load_module /nginx-{version}/objs/mtld_http_devatlas_module.so;
```
** Custom Nginx version **
For a custom Nginx builds (e.g. 1.8.0), use the following commands:
```sh
cmake -DNGINX_VERSION=1.8.0
make
```
** OpenRESTY (or from an existing NGINX personal build) **
The nginx module works as well with OpenRESTY.
Once the archive is downloaded and extracted, cmake can be typed as follow:
(OpenRESTY only)
```sh
cmake -DNGINX_CFLAGS="-DNDK_SET_VAR=1 -DNDK_UPSTREAM_LIST"
make
```
Then, in the nginx- or ngx_openresty- folder:
```sh
./configure --add-module=/nginx --with-ld-opt=-Wl,-rpath,/api
make
```
### Configure Nginx ###
Nginx must be configured with the data file paths prior to using the DeviceAtlas module. That configuration will depend
on whether the user want to use the device detection, carrier identification or both.
** A snippet from nginx.conf **
```
# Uncomment the next line if using nginx dynamic module (DSO) (replace the {version} with your nginx version
# load_module /nginx-{version}/objs/mtld_http_devatlas_module.so;
http {
# Device Detection
devatlas_db /PATH/TO/JSON;
# Carrier Identification
carrierapi_db /PATH/TO/DATA
# Client Side Component (optional)
# To use the Client Side Component with the Nginx module, the Javascript
# file located in ExtraTools/ClientSideProperties/ must be included on every webpage.
# The client side component will create a cookie with the client properties. The
# Nginx module reads this cookie and merges the properties with the server
# side detected properties.
# The name of the cookie containing the client properties must be enabled
devatlas_properties_cookie DAPROPS;
# Each DeviceAtlas properties are prefixed with da_
# and are available as a NGINX's variable
# and all dot are replaced with underscores
# for example
server {
location / {
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
# Device Detection properties
fastcgi_param DA_IS_BROWSER $da_isBrowser;
fastcgi_param DA_VENDOR $da_vendor;
fastcgi_param DA_MODEL $da_model;
# Carrier Identification properties (optional)
# fastcgi_param DA_CARRIERAPI_MNC $da_carrierapi_mnc;
# fastcgi_param DA_CARRIERAPI_NETWORK_BRAND $da_carrierapi_NetworkBrand;
# More Nginx properties here
}
location ~ \.css$ {
root ./www/app;
add_header Content-Type text/css;
}
location ~ \.js$ {
root ./www/app;
add_header Content-Type application/x-javascript;
}
}
}
```
### Example module ###
#### Data file ####
To use the module, you will need to download the required data file, save it locally and set the path from **nginx.conf**.
- To get a data file for Device Detection, please see the [DeviceApi](README.DeviceApi.html) readme file.
- To get a data file for Carrier Identification, please see the [CarrierApi](README.CarrierApi.html) readme file.
#### Run Nginx server ####
```sh
sh ./run_nginx.sh
```
Nginx is now up and running on port 8080.
#### Run example app (python3) ####
1. Open up new terminal
There is a very simple example app bundled with the source code which
demonstrates how properties are passed back to your application. It is located
in the nginx/app.py and you will need a python Flup module to run it.
2. Install Flup (if not installed already)
```sh
easy_install3 flup
```
3. Run example app directly with python:
```sh
python3 nginx/run/www/app/app.py
```
Then, when you access the URL http://yourhost:8080/app/, it will display all
values from the device property list you have specified in the **nginx.conf**.
If you change the user-agent in your browser settings, you can then see the
device properties for that device being reported. Similarly if the originating
IP changes, the Carrier Identification properties will reflect this also.
The NGINX module prefixes all device property names with "X-DeviceAtlas-" when
setting the properties in the environment variables.
For example the property "mobileDevice" becomes a header called
"X-DeviceAtlas-mobileDevice".
#### Sample configuration file ####
There is a sample configuration file in nginx/run/conf/nginx.conf where you
can see sample DeviceAtlas configuration for Nginx server. By default it sets
only six DA properties - isBrowser, vendor, model, isTablet, isMobilePhone and
displayWidth. The properties for the Carrier Identification API are commented
out which can be used also.
To enable all the properties simply comment-out all the "devatlas_property" lines.
** Optional **
To use the Client Side Component with the Nginx module, the Javascript file
located in ExtraTools/ClientSideProperties/ must be included on every webpage.
The client side component will create a cookie with the client properties. The
Nginx module automatically reads this cookie and merges the properties with
the server side detected properties.
### DSO module with Nginx binary package ###
If you are trying to load a dynamic module (DSO) and you're getting following error,
you need to re-compile the module based on the binary package configure command.
```
nginx: [emerg] module "/usr/local/nginx/modules/mtld_http_devatlas_module.so" is not binary compatible in /etc/nginx/nginx.conf
```
** Binary package configure arguments **
Use following command to find the flags Nginx was built with:
```sh
/usr/sbin/nginx -V
```
Change /usr/sbin/nginx to your system Nginx location if needed. You can easily find Nginx location by typing `which nginx`.
You will get output like this:
```
configure arguments: \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--with-http_perl_module=dynamic \
--add-dynamic-module=debian/extra/njs-1c50334fbea6/nginx \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-http_slice_module \
--with-mail \
--with-mail_ssl_module \
--with-file-aio \
--with-ipv6 \
--with-http_v2_module \
--with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2' \
--with-ld-opt='-Wl,-z,relro -Wl,--as-needed
```
With the modules given you need to add following two configuration lines:
```
--add-dynamic-module=/nginx \
--with-ld-opt=-Wl,-rpath,/api
```
Which would make your configure command look like this:
```
./configure \
--add-dynamic-module=/nginx \
--with-ld-opt=-Wl,-rpath,/api \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--with-http_perl_module=dynamic \
--add-dynamic-module=debian/extra/njs-1c50334fbea6/nginx \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-http_slice_module \
--with-mail \
--with-mail_ssl_module \
--with-file-aio \
--with-ipv6 \
--with-http_v2_module \
--with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2' \
--with-ld-opt='-Wl,-z,relro -Wl,--as-needed
```
Once you run the configure you can proceeed with the simple make.
```sh
make
```
Please be aware that for building Nginx with some of the modules it might be necessary to install additional libraries on your system e.g. openssl, libxml2, GD library...
It's always good to only build with modules which are necessary for your application and reduce unused modules.
-------------------------------------------------------------------------------
_ (c) 2021 DeviceAtlas Limited. All rights reserved. https://deviceatlas.com _