# 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 <DeviceAtlas C++ API folder>/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-<version> folder modify the ./configure command with: ```sh ./configure --with-compat --add-dynamic-module=<DeviceAtlas C++ API folder>/nginx \ --with-cc-opt='[copy from nginx -V]' --with-ld-opt='[copy from nginx -V] -Wl,-rpath,<DeviceAtlas C++ API folder>/api' make ``` To load the module from Nginx Plus use following directive for the Nginx config file. ``` load_module <DeviceAtlas C++ API folder>/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-<version> or ngx_openresty-<version> folder: ```sh ./configure --add-module=<DeviceAtlas C++ API folder>/nginx --with-ld-opt=-Wl,-rpath,<DeviceAtlas C++ API folder>/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 <DeviceAtlas C++ API folder>/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=<DeviceAtlas C++ API folder>/nginx \ --with-ld-opt=-Wl,-rpath,<DeviceAtlas C++ API folder>/api ``` Which would make your configure command look like this: ``` ./configure \ --add-dynamic-module=<DeviceAtlas C++ API folder>/nginx \ --with-ld-opt=-Wl,-rpath,<DeviceAtlas C++ API folder>/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 _ <!-- HTML+JS for document formatting when opened in browser --> <div class="btn-group" id="main-menu" style="float:right"><a class="btn dropdown-toggle" data-toggle="dropdown" href="#">Menu<span class="caret"></span></a><ul class="dropdown-menu"><li><a href="README.html">Main</a></li><li class="divider"></li><li><a href="README.DeviceApi.html">Device Detection API</a></li><li><a href="README.DeviceApi-Config.html">Device Detection API Config</a></li><li><a href="README.CarrierApi.html">Carrier Identification API</a></li><li class="divider"></li><li class="disabled"><a href="README.Nginx.html">C++ API and Nginx Module Installation</a></li><li><a href="README.Windows.html">C++ API and Windows</a></li><li><a href="README.ClientSide.html">Client-side Component</a></li><li><a href="README.ConnectivityAnalyser.html">Connectivity Analyser</a></li><li class="divider"></li><li><a href="ApiDocs/index.html">DeviceAtlas ApiDocs</a></li></ul></div>