When running applications in docker containers, it can make sense to put a proxy server in front. It’s relatively simple to setup an nginx server to sit in front of any application which I’ll demonstrate in this article.
Configuration
In order to get started, we’ll use the nginx image hosted up on dockerhub. This particular image allows us to specify a configuration file to a web server relatively simply.
To setup the scenario, we have a node.js application running on port 3000 of the host machine that we’d look to proxy through the nginx proxy. Here’s how the configuration would look, over port 80:
There’s even a rewrite here that takes the my-api part of the original request URI out of the forwarded request, so that the node.js application can be treated directly off the root.
Start me up!
To now get this started, we need to sub-in this configuration file as if it were part of the running container.
docker run -ti --rm -v $(pwd)/default.conf:/etc/nginx/conf.d/default.conf -p 80:80 nginx
Security
Yep. Now we need to use SSL and put the application over 443! First up, let’s create a self-signed certificate using OpenSSL.
In a previous post, we setup a really simple route and server executing some Clojure code for us. In today’s post, we’re going to use a library called Compojure to fancy-up a little bit of that route definition.
This should make defining our web application a bit more fun, anyway.
Getting started
Again, we’ll use Leiningen to kick our project off:
lein new webapp-1
We’re going to add some dependencies to the project.clj folder for compojure and http-kit. http-kit is the server that we’ll be using today.
(defprojectwebapp-1"0.1.0-SNAPSHOT":description"FIXME: write description":url"http://example.com/FIXME":license{:name"Eclipse Public License":url"http://www.eclipse.org/legal/epl-v10.html"}:dependencies[[org.clojure/clojure"1.8.0"][compojure"1.1.8"][http-kit"2.1.16"]])
And then, installation.
lein deps
Hello!
To get started, we’ll define a root route to greet us.
In today’s post, we’re going to use the Clojure HTTP server abstraction called ring to stand a web server up, and attach some some routes. This allows us to expose our Clojure functions over the web in a relatively simple fashion.
Getting started
This blog post is mainly centered around the getting started guide from the ring documentation pages, found here.
We’re going to get started by creating a project using lein.
lein new jetty-test
After this process finishes, you’ll end up with a directory called jetty-test that has a project structure something like this:
Now we need to make our newly created project depend on ring. We need to add references to ring-core and ring-jetty-adapter in the project.clj file. So it should read something like this:
(defprojectjetty-test"0.1.0-SNAPSHOT":description"FIXME: write description":url"http://example.com/FIXME":license{:name"Eclipse Public License":url"http://www.eclipse.org/legal/epl-v10.html"}:dependencies[[org.clojure/clojure"1.8.0"][ring/ring-core"1.5.0"][ring/ring-jetty-adapter"1.5.0"]])
We can now install these dependencies into the project.
lein deps
Server code
We can start writing our route code now that the server will respond to. We’ll define a function that simply returns the current date and time:
(defnnow[](java.util.Date.))
We’ll also create a route that will use this function, and send back the text each time the route is requested:
That’s it for the server code. We still need to fire up Jetty and attach the handler to it. We need to import ring.adapter.jetty as it contains run-jetty for us:
Apache HBase is a data storage technology that allows random, realtime read/write access to your big stores. It’s modelled on Google’s Bigtable paper and is available for use with Apache Hadoop. In today’s article, I’ll walk through some very simple usage of this technology.
Installation
First up, we’ll need to get some software installed. From the downloads page, you can grab a release. Once this is downloaded, get it unpacked onto your machine. In this instance, we’ll be using HBase in standalone mode
This is the default mode. Standalone mode is what is described in the Section 1.2, “Quick Start - Standalone HBase” section. In standalone mode, HBase does not use HDFS – it uses the local filesystem instead – and it runs all HBase daemons and a local ZooKeeper all up in the same JVM. Zookeeper binds to a well known port so clients may talk to HBase.
If you need to perform any further configuration, the /conf folder holds the xml files required. To put your root folders into more sane places, you can change the values of conf/hbase-site.xml:
$ ./bin/start-hbase.sh
starting master, logging to /opt/hbase-1.2.3/bin/../logs/hbase--master-0f0ebda04483.out
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/hbase-1.2.3/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/local/hadoop-2.7.0/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
Shell!
Now that HBase is running, we can shell into it and have a poke around.
$ ./bin/hbase shell
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/hbase-1.2.3/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/local/hadoop-2.7.0/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shell
Version 1.2.3, rbd63744624a26dc3350137b564fe746df7a721a4, Mon Aug 29 15:13:42 PDT 2016
hbase(main):001:0>
First up, we’ll create a table called person with a column family of `name’:
hbase(main):002:0> create 'person', 'name'
0 row(s) in 1.5290 seconds
=> Hbase::Table - person
Now we can insert some tables into our table:
hbase(main):004:0> put 'person', 'row1', 'name:first', 'John'
0 row(s) in 0.1430 seconds
hbase(main):005:0> put 'person', 'row2', 'name:first', 'Mary'
0 row(s) in 0.0150 seconds
hbase(main):006:0> put 'person', 'row3', 'name:first', 'Bob'
0 row(s) in 0.0080 seconds
hbase(main):007:0> scan 'person'
ROW COLUMN+CELL
row1 column=name:first, timestamp=1475030956731, value=John
row2 column=name:first, timestamp=1475030975840, value=Mary
row3 column=name:first, timestamp=1475030988587, value=Bob
Values can also be read out of our table:
hbase(main):009:0> get 'person', 'row1'
COLUMN CELL
name:first timestamp=1475030956731, value=John
1 row(s) in 0.0250 seconds
Now, we can clean up our test:
hbase(main):011:0> disable 'person'
0 row(s) in 2.3000 seconds
hbase(main):012:0> drop 'person'
0 row(s) in 1.2670 seconds
Following up
Now that we can start to work with HBase, further posts will focus on designing schemas and processing data into the store.
Servlets are java applications that are run on the server, responding to different requests made by clients. They most commonly are setup to respond to web-based requests although they are not limited to this scope.
A servlet is a Java programming language class used to extend the capabilities of servers that host applications accessed by means of a request-response programming model. Although servlets can respond to any type of request, they are commonly used to extend the applications hosted by web servers. For such applications, Java Servlet technology defines HTTP-specific servlet classes.
The javax.servlet and javax.servlet.http packages provide interfaces and classes for writing servlets. All servlets must implement the Servlet interface, which defines lifecycle methods. When implementing a generic service, you can use or extend the GenericServlet class provided with the Java Servlet API. The HttpServlet class provides methods, such as doGet and doPost, for handling HTTP-specific services.
In today’s post, I’ll walkthrough the creation of a servlet.
Setup
First up, we’re going to use Maven to generate the project infrastructure required to support our servlet.
The hello.war file can now be deployed to our application server of choice for testing. In my example here, I’m using Jetty inside of a docker container.
docker run -ti--rm-p 8080:8080 \-v$(pwd)/target/hello.war:/var/lib/jetty/webapps/hello.war \
jetty