-
Notifications
You must be signed in to change notification settings - Fork 14
Applying Custom BDE Styles (Integrator UI CSSWrapper Tutorial)
Integrator UI is an application, which simply put together available web interfaces from BDI Stack. In this tutorial we show how to enhance the BDI Stack with Integrator UI and CSSWrapper, which is a required component for Integrator UI.
This tutorial will use docker snippets available on Big Data Europe Github repository. We start by taking docker-compose snippet of the most ubiquitous component of big data applications: Apache Hadoop.
version: "2"
services:
namenode:
image: bde2020/hadoop-namenode:1.1.0-hadoop2.7.1-java8
container_name: namenode
volumes:
- hadoop_namenode:/hadoop/dfs/name
environment:
- CLUSTER_NAME=test
env_file:
- ./hadoop.env
resourcemanager:
image: bde2020/hadoop-resourcemanager:1.1.0-hadoop2.7.1-java8
container_name: resourcemanager
depends_on:
- namenode
- datanode1
- datanode2
env_file:
- ./hadoop.env
historyserver:
image: bde2020/hadoop-historyserver:1.1.0-hadoop2.7.1-java8
container_name: historyserver
depends_on:
- namenode
- datanode1
- datanode2
volumes:
- hadoop_historyserver:/hadoop/yarn/timeline
env_file:
- ./hadoop.env
nodemanager1:
image: bde2020/hadoop-nodemanager:1.1.0-hadoop2.7.1-java8
container_name: nodemanager1
depends_on:
- namenode
- datanode1
- datanode2
env_file:
- ./hadoop.env
datanode1:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
container_name: datanode1
depends_on:
- namenode
volumes:
- hadoop_datanode1:/hadoop/dfs/data
env_file:
- ./hadoop.env
datanode2:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
container_name: datanode2
depends_on:
- namenode
volumes:
- hadoop_datanode2:/hadoop/dfs/data
env_file:
- ./hadoop.env
datanode3:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
container_name: datanode3
depends_on:
- namenode
volumes:
- hadoop_datanode3:/hadoop/dfs/data
env_file:
- ./hadoop.env
volumes:
hadoop_namenode:
hadoop_datanode1:
hadoop_datanode2:
hadoop_datanode3:
hadoop_historyserver:
For the purpose of this tutorial, we will trim the contents of the docker-compose definition to contain just one namenode and one datanode:
version: "2"
services:
namenode:
image: bde2020/hadoop-namenode:1.1.0-hadoop2.7.1-java8
container_name: namenode
volumes:
- hadoop_namenode:/hadoop/dfs/name
environment:
- CLUSTER_NAME=test
env_file:
- ./hadoop.env
datanode:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
container_name: datanode1
depends_on:
- namenode
volumes:
- hadoop_datanode:/hadoop/dfs/data
env_file:
- ./hadoop.env
volumes:
hadoop_namenode:
hadoop_datanode:
The next step is to unpack ./hadoop.env into docker-compose to have the environmental variables in one place for quick tweaking. As you see below the environmental variables define defaultFS for hadoop and hue user/group for Hue filebrowser (not used in this tutorial). We also remove "container_name" for datanode to enable horizontal scaling with docker-compose scale command.
version: "2"
services:
namenode:
image: bde2020/hadoop-namenode:1.1.0-hadoop2.7.1-java8
container_name: namenode
volumes:
- hadoop_namenode:/hadoop/dfs/name
environment:
- CLUSTER_NAME=test
- CORE_CONF_fs_defaultFS=hdfs://namenode:8020
- CORE_CONF_hadoop_http_staticuser_user=root
- CORE_CONF_hadoop_proxyuser_hue_hosts=*
- CORE_CONF_hadoop_proxyuser_hue_groups=*
- HDFS_CONF_dfs_webhdfs_enabled=true
- HDFS_CONF_dfs_permissions_enabled=false
datanode:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
depends_on:
- namenode
volumes:
- hadoop_datanode:/hadoop/dfs/data
environment:
- CORE_CONF_fs_defaultFS=hdfs://namenode:8020
- CORE_CONF_hadoop_http_staticuser_user=root
- CORE_CONF_hadoop_proxyuser_hue_hosts=*
- CORE_CONF_hadoop_proxyuser_hue_groups=*
- HDFS_CONF_dfs_webhdfs_enabled=true
- HDFS_CONF_dfs_permissions_enabled=false
volumes:
hadoop_namenode:
hadoop_datanode:
The next step is to add CSSWrapper proxy:
version: "2"
services:
csswrapper:
image: bde2020/nginx-proxy-with-css:latest
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
- "constraint:node==akswnc4.aksw.internal"
namenode:
image: bde2020/hadoop-namenode:1.1.0-hadoop2.7.1-java8
container_name: namenode
volumes:
- hadoop_namenode:/hadoop/dfs/name
environment:
- CLUSTER_NAME=test
- CORE_CONF_fs_defaultFS=hdfs://namenode:8020
- CORE_CONF_hadoop_http_staticuser_user=root
- CORE_CONF_hadoop_proxyuser_hue_hosts=*
- CORE_CONF_hadoop_proxyuser_hue_groups=*
- HDFS_CONF_dfs_webhdfs_enabled=true
- HDFS_CONF_dfs_permissions_enabled=false
datanode:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
depends_on:
- namenode
volumes:
- hadoop_datanode:/hadoop/dfs/data
environment:
- CORE_CONF_fs_defaultFS=hdfs://namenode:8020
- CORE_CONF_hadoop_http_staticuser_user=root
- CORE_CONF_hadoop_proxyuser_hue_hosts=*
- CORE_CONF_hadoop_proxyuser_hue_groups=*
- HDFS_CONF_dfs_webhdfs_enabled=true
- HDFS_CONF_dfs_permissions_enabled=false
volumes:
hadoop_namenode:
hadoop_datanode:
It is exposes port 80 to the outside world through host machine and thus should be allocated on the host with public IP address. It can also be simply a host where URLs of services will be resolved to. In our case it is akswnc4.aksw.internal.
The CSSWrapper needs to know (a) which URL corresponds to which service and (b) which CSS to inject (or not) there. We configure it using VIRTUAL_HOST (URL), VIRTUAL_PORT (if differs from 80) and CSS_SOURCE environmental variables. CSSWrapper requires that docker image contain EXPOSE closes for VIRTUAL_PORT, otherwise it will fail to work. To ensure this, we define expose clauses explicitly in the docker-compose definition.
version: "2"
services:
csswrapper:
image: bde2020/nginx-proxy-with-css:latest
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
- "constraint:node==akswnc4.aksw.internal"
namenode:
image: bde2020/hadoop-namenode:1.1.0-hadoop2.7.1-java8
container_name: namenode
expose:
- "50070"
volumes:
- hadoop_namenode:/hadoop/dfs/name
environment:
- CLUSTER_NAME=test
- CORE_CONF_fs_defaultFS=hdfs://namenode:8020
- CORE_CONF_hadoop_http_staticuser_user=root
- CORE_CONF_hadoop_proxyuser_hue_hosts=*
- CORE_CONF_hadoop_proxyuser_hue_groups=*
- HDFS_CONF_dfs_webhdfs_enabled=true
- HDFS_CONF_dfs_permissions_enabled=false
- VIRTUAL_HOST="namenode.big-data-europe.aksw.org"
- VIRTUAL_PORT="50070"
- CSS_SOURCE="hadoop"
datanode:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
depends_on:
- namenode
expose:
- "50075"
volumes:
- hadoop_datanode:/hadoop/dfs/data
environment:
- CORE_CONF_fs_defaultFS=hdfs://namenode:8020
- CORE_CONF_hadoop_http_staticuser_user=root
- CORE_CONF_hadoop_proxyuser_hue_hosts=*
- CORE_CONF_hadoop_proxyuser_hue_groups=*
- HDFS_CONF_dfs_webhdfs_enabled=true
- HDFS_CONF_dfs_permissions_enabled=false
- VIRTUAL_HOST="datanode.big-data-europe.aksw.org"
- VIRTUAL_PORT="50075"
- CSS_SOURCE="hadoop"
volumes:
hadoop_namenode:
hadoop_datanode:
The last step is to add Integrator UI. First thing, you should not use build definitions in your docker-compose files when deploying to swarm. For example, this is wrong:
version: "2"
services:
integrator-ui:
build: ./integrator-ui
environment:
VIRTUAL_HOST: "integrator-ui.big-data-europe.aksw.org"
...
We should create a git repository on github, build our custom integrator UI image and push it to docker hub. Go and create one, we will name this one integrator-tutorial. You can simply extend integrator UI image as follows:
FROM bde2020/integrator-ui:0.3.0
COPY user-interfaces /app/config/user-interfaces
In the root of the repository, create a user-interfaces file containing the URLs of your services and labels to be displayed in the header. The labels can be arbitrary, we define "Namenode" and "Datanode" here. The base-url parameters should correspond to VIRTUAL_HOST environmental variable, so that it can be resolved to the actual service.
{ "data": [
{
"id": 1,
"type": "user-interfaces",
"attributes": {
"label": "Namenode",
"base-url": "http://namenode.big-data-europe.aksw.org/",
"append-path": ""
}
},
{
"id": 2,
"type": "user-interfaces",
"attributes": {
"label": "Datanode",
"base-url": "http://datanode.big-data-europe.aksw.org/",
"append-path": ""
}
}
]
}
Now we need to go to Docker Hub and create and automated build for this repository. We named ours integrator-tutorial. And now we finally can include it into docker-compose definition:
version: "2"
services:
integrator-ui:
image: earthquakesan/integrator-tutorial
environment:
- VIRTUAL_HOST="integrator-ui.big-data-europe.aksw.org"
csswrapper:
image: bde2020/nginx-proxy-with-css:latest
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
- "constraint:node==akswnc4.aksw.internal"
namenode:
image: bde2020/hadoop-namenode:1.1.0-hadoop2.7.1-java8
container_name: namenode
expose:
- "50070"
volumes:
- hadoop_namenode:/hadoop/dfs/name
environment:
- CLUSTER_NAME=test
- CORE_CONF_fs_defaultFS=hdfs://namenode:8020
- CORE_CONF_hadoop_http_staticuser_user=root
- CORE_CONF_hadoop_proxyuser_hue_hosts=*
- CORE_CONF_hadoop_proxyuser_hue_groups=*
- HDFS_CONF_dfs_webhdfs_enabled=true
- HDFS_CONF_dfs_permissions_enabled=false
- VIRTUAL_HOST="namenode.big-data-europe.aksw.org"
- VIRTUAL_PORT="50070"
- CSS_SOURCE="hadoop"
datanode:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
depends_on:
- namenode
expose:
- "50075"
volumes:
- hadoop_datanode:/hadoop/dfs/data
environment:
- CORE_CONF_fs_defaultFS=hdfs://namenode:8020
- CORE_CONF_hadoop_http_staticuser_user=root
- CORE_CONF_hadoop_proxyuser_hue_hosts=*
- CORE_CONF_hadoop_proxyuser_hue_groups=*
- HDFS_CONF_dfs_webhdfs_enabled=true
- HDFS_CONF_dfs_permissions_enabled=false
- VIRTUAL_HOST="datanode.big-data-europe.aksw.org"
- VIRTUAL_PORT="50075"
- CSS_SOURCE="hadoop"
volumes:
hadoop_namenode:
hadoop_datanode:
Simply copy the last docker-compose snippet and save it as docker-compose.yml. Then run docker-compose -H :4000 up