A JBoss Project
Red Hat

Latest posts

So you’ve heard the buzzwords and all the hype around Docker, but you haven’t had the chance to play around with it yet or see if it fits your needs. You’re already an avid user of JBoss Tools, and are fairly familiar with starting and stopping your local or remote Wildfly installation, and deploying web applications to it.

If this describes you, and you’re interested in trying out Docker, then this blog is targeted to you.

Docker Installation

Docker’s installation method differs based on your platform. You’ll want to review Docker’s Installation guides for your respective platforms.

To make things unified across the various platform, we recommend you go and map dockerhost to the ip of where your docker instance is running.

By default on Linux that will be 127.0.0.1, so you would add the following line to your /etc/hosts file:

127.0.0.1 dockerhost

But on OSX and Windows it will be a unique IP you can get by running boot2docker ip (i.e. 192.168.59.122). In that case the following should be added:

192.168.59.122 dockerhost

From now on you can use dockerhost in all your applications and get to it no matter what OS you are running on.

Running the default wildfly image

Wildfly has published their docker images for public consumption. You can browse them at the docker registry, or go to http://www.jboss.org/docker/ for more information.

These images are JBoss' standard Docker images and they do not expose more features than just the bare minimum for production and reuse. This first blog will show how to use them as-is, but going forward we will show how to configure them to be a bit more useful for development use cases.

To make sure your docker installation has worked, and that Wildfly can start without any errors, you can do the following:

docker run -it -p 8080:8080 jboss/wildfly

This command will run the Docker image for jboss/wildfly in its default state, no customizations and map port 8080 on your dockerhost to 8080 of the running jboss/wildfly container.

Once this is run, the command will not only start up your container, but also launch the server in standalone mode, and connect a terminal to it so you can see the output.

terminal wf docker

You should also now be able to see WildFly default startup page on http://dockerhost:8080.

Assuming you see the console output, and the server runs with no errors and you can access the welcome browser via dockerhost then you’re set up and ready for the next step.

To terminate the container, you can simply press Ctrl+C. If, for some reason, your image has frozen, and Ctrl+C isn’t working, you can also run the following commands to kill it forcefully.

First list running containers:

[root@localhost docker]$ docker ps
CONTAINER ID        IMAGE                  COMMAND                CREATED             STATUS              PORTS                    NAMES
f70149043400        jboss/wildfly:latest   "/opt/jboss/wildfly/   58 seconds ago      Up 58 seconds       0.0.0.0:8080->8080/tcp   ecstatic_darwin

Here I only have one container running; you might have more. But to kill any container, you execute docker kill f70149043400, replacing the given hash with your value from CONTAINER ID column.

Externally Managed Local Server With Deployment Folder Mapping

Since the Docker image in this example does not have SSH enabled, and the Wildfly server is not exposing the Management port, we will need to configure JBoss Tools to use custom filesystem deployments. The way to do this is to map in a local folder from our host into our container.

And since we start Wildfly via the Docker image, on the command-line. we’ll want to configure our Server Adapter in JBoss Tools to be an externally managed server, so it will not manage the start nor stop of the server.

Mapping a deployment folder

For this example, we’ll make a temporary directory somewhere on our host, and tell our Docker container to treat that as the standalone/deployments folder inside the container. In this way, changes made to the folder can be visible in both the host and container.

Mapping Folders may cause IO errors for SELinux!* To ensure your container can actually read and write to the folder, you’ll need to run setenforce 0 to disable SELinux, or, alternatively, give Docker the permissions and exceptions in SELinux. See this stackoverflow post for more information.
[root@localhost jbds_wf_external]$  mkdir /home/rob/tmp/dockertest1
[root@localhost jbds_wf_external]$  docker run -it -p 8080:8080 \
-v /home/rob/tmp/dockertest1:/opt/jboss/wildfly/standalone/deployments/:rw  jboss/wildfly

The ':rw' at the end is important, since without it the docker container cannot write to it, only read.

If you were to now place a .war file inside /home/rob/tmp/dockertest1, it will be picked up by the deployment scanner, and visible in a web browser. Take note of the folder, since we’ll use that in the configuration of the Server Adapter.

Making your Server Adapter

The final step of this example is to create your Wildfly 8.2 server adapter in JBoss Tools, and to create and deploy a web application to your temporary folder, which in my case is /home/rob/tmp/dockertest1

First, we’ll open the Servers View and create a new Wildfly 8.x server adapter. Since we’re exposing our container’s ports on dockerhost, we need to set the host to dockerhost.

local fs 0

The server should still be marked as Local and Controlled by Filesystem and shell operations as shown below.

local fs 1

Since we’re hacking a Local Filesystem server adapter to work for Docker, we’ll still need a local runtime in this example, so point it to any locally installed WildFly server you have.

In JBIDE-19388 we are looking at ways to avoid requiring this step.

Configuring your Server Adapter

Once your server is created, you’ll find it in the Servers View, where we can double-click it to open the Server Editor. From here, we can make what configuration changes we’ll need. First, we’ll need to make sure the server is Externally Managed. This means JBoss Tools will not attempt to start and stop it from Eclipse, it is expecting you the user handles that via Docker.

local fs externally managed

Next, we’ll need to disable the tooling for keeping deployment scanners in sync with the locations JBoss Tools expects to be deploying. Since we’ve already mapped the folder in via the Docker command line, we won’t need any additions to the deployment scanners at all.

local fs scanners

And finally, on the Deployment tab of the Server Editor, we’ll want to mark the default deploy folder to be a Custom location, and choose the folder that we previously mapped in via Docker’s command line, as shown below:

local fs deploy

Once all this is done, we can save the editor, and our server adapter is configured properly.

Make a Web Project

In this example, we can create a very simple web project by browsing to File → New → Dynamic Web Project, Once the web project is created, we can create a simple index.html in the WebContent folder.

Starting the Server

Now that everything’s set up in Eclipse, we can start our Docker container as we mentioned before:

docker run -it -p 8080:8080 -v /home/rob/tmp/dockertest1:/opt/jboss/wildfly/standalone/deployments/:rw  jboss/wildfly

Starting the Server Adapter

In Eclipse, we can now right-click our server, and select Start. This shouldn’t launch any commands, since we marked the server as Externally Managed. The server adapter is configured to check dockerhost:8080 to see if the server is up or not, so it should quickly move to a state of [Started, Synchronized].

Deploying the Web Application

We can now right-click on our index.html project, and select Run As → Run On Server and follow the on-screen directions to deploy our web application. We should then notice the Eclipse internal browser pop up and display the content of our index.html files.

Congratulations - you just used JBoss Tools to deploy a local running Docker hosted WildFly server.

What could be better ?

The default docker image is restricted by default. This means it does not have the Management port exposed, nor JMX nor file system access via SSH.

All this means that currently you have to go through some setup to use them from existing tools, but luckily we are doing two things:

  1. we will post more blogs explaning how to enable some of these features to use todays tools (not just JBoss Tools) with 'raw' docker.

  2. we are working on making the steps simpler when using Docker 'raw'

Conclusion

In this first example, we’ve seen how to install and configure the default Wildfly Docker images.

To summarize, here are the steps needed:

  1. Start Docker with 8080 mapped and with /opt/jboss/wildfly/standalone/deployments mounted as volume

  2. Configure server to run on dockerhost, be externally managed and Custom deploy to the volume above

In future examples, we’ll see how to extend those images for Management or SSH/SCP usecases.

Rob Stryker

In this blog I would like to discuss probably the most important issue CordovaSim / Ripple users might face:

The $.ajax GET / POST / PUT / DELETE does not fire from inside of CordovaSim / Ripple - but it does via the IOS Simulator and from a real Android Device. How am I supposed to handle it?
— CordovaSim user

Firstly, let’s discuss the root of the problem…​

Same Origin Policy (SOP)

In computing, the Same Origin Policy is an important security concept for a number of browser-side programming languages, such as JavaScript. The policy permits scripts running on pages originating from the same site to access each other’s methods and properties with no specific restrictions, but prevents access to most methods and properties across pages on different sites. Basically, if the web application sends request to the same server, then there will be no restrictions and everything will work like a charm. However, if the request is sent to another server (Cross-domain request - XDR), the browser will block it with the following error:

No 'Access-Control-Allow-Origin' header error

How to workaround Same Origin Policy (SOP)?

In the general case there are several ways to do it:

  • Proxy - one can create a proxy and have it to fetch data from the remote server instead of sending request directly. To the browser it seems that web application exchanging the data on the same server:

No 'Access-Control-Allow-Origin' header error
  • JSON with padding (JSONP) - this approach takes advantage of the fact that <script> tags are not subject to the Same-Origin policy. For instance, JavaScript libraries like jQuery can be included to the web page even if they are hosted on another server. More information about JSONP can be found in the following article.

  • Cross-Origin Resource Sharing (CORS) - W3C standard that allows Cross-Domain communication from the browser. CORS support requires coordination between both the server and client. The basic idea behind CORS is to use custom HTTP headers to allow both the browser and the server to know enough about each other to determine if the request or response should succeed or fail. Cross-Origin Resource Sharing can be used as a modern alternative to the JSONP pattern. While JSONP supports only the GET request method, CORS also supports other types of HTTP requests. More information about CORS can be found in the following blog.

Ripple and CordovaSim use Proxy approach for handling Cross-domain AJAX.

Cross-domain AJAX in CordovaSim

There is a Cross Domain Proxy setting in CordovaSim / Ripple. Basically, Cross-domain AJAX work depends drastically on it. User can choose between three options:

  • Disabled - CordovaSim / Ripple will not proxy HTTP requests. This option should be used only if the remote server supports CORS. If it is not, Cross-domain requests will be restricted by the Same Origin Policy.

  • Local (default) - local proxy will be used for handling HTTP requests. However, local proxy is implemented differently in Ripple and CordovaSim. Ripple has local Node.js proxy server, whereas CordovaSim uses Jetty ProxyServlet for that purpose. Nonetheless, from the user perspective there are no differences at all.

  • Remote - both Ripple and CordovaSim will use the following remote server for HTTP requests proxying.

Proxy settings
In most cases "Remote" and "Local" options can be used interchangeably for remote server calls. However, if the server is running locally one must use either "Local" or "Disabled" option depending on the local server configuration (i.e. CORS compatibility).

Security note for "Remote" proxy

In the 4.2.3.Beta1 and 4.3.0.Alpha1 releases a security warning for "Remote" proxy was added.

Remote
If the app is transferring sensitive data (authentication tokens, credentials etc.), it is strongly recommended to use "Local" proxy (enabled by default) instead of the "Remote" one. The "Remote" proxy is cloud-hosted and there is a potential leak threat. Nonetheless, if the hybrid app has no sensitive data, one can safely use "Remote" proxy without any risk.

Conclusion

To put it in a nutshell, there is no silver bullet for handling all Cross-domain AJAX requests in CordovaSim / Ripple, due to the fact that it dramatically depends on the server side setup. So, if one has faced the issue coupled with the Same Origin Policy / Cross-Domain AJAX (i.e. GET / POST / PUT / DELETE requests the hybrid app is trying to perform are either blocked by the browser or server returns 5XX error), the first thing they should do is to "play" with Cross Domain Proxy settings. Using one of the options must definitely tackle the problem.
Have fun!

Ilya Buziuk
@ilyabuziuk

Looking for older posts ? See the Archived entries.
back to top