How do I serve clojure pages with nginx

1011 views
Skip to first unread message

Zeynel

unread,
Dec 17, 2013, 7:44:34 AM12/17/13
to clo...@googlegroups.com
I've set up a home server with ubuntu and nginx and I can serve static pages. Now I want to add clojure but I am not sure what I need to do. I asked the same question in StackOverflow but for some reason it is voted to be closed: http://stackoverflow.com/questions/20632987/how-to-serve-clojure-pages-with-nginx

Can you please direct me to documentation where I can read about this? Some issues that I don't understand are: how do I tell nginx that I am using clojure? Where do I install clojure, in the server? Where do I create the clojure files? Thanks.

Dave Della Costa

unread,
Dec 17, 2013, 8:02:19 AM12/17/13
to clo...@googlegroups.com
I have not done this specifically with Nginx but I suspect you probably
want something like what I set up with Apache + Jetty:

https://github.com/ddellacosta/Clojure-under-Jetty-and-Apache#setting-up-jetty-with-apache-httpd

That is, set up Nginx to act as a proxy for Jetty:

http://nginx.org/en/docs/beginners_guide.html#proxy

One difference with how I would do it these days (vs. what I wrote in
the piece above) is that I would probably simply push out an uberjar
with lein which I would run with Java via an init script--for example,
if using Ubuntu:

http://upstart.ubuntu.com/cookbook/#run-a-java-application

So, I would imagine the basic construction would be something like: ring
app w/jetty or http-kit, packaged as an uberjar (lein uberjar), then set
up to run via an init script (via upstart in your case) on an
alternative port, which is proxied by Nginx as in the link above.

Hope this helps--

DD
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to clojure+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Zeynel

unread,
Dec 17, 2013, 9:57:54 AM12/17/13
to clo...@googlegroups.com
Yes, this is helpful. I think this will be a good starting point for me once I read the references that you gave. I also heard about Immutant and I'm investigating it but do you think it may be helpful? I am not sure at this point exactly what it does. Thanks.

Toby Crawley

unread,
Dec 17, 2013, 10:51:42 AM12/17/13
to clo...@googlegroups.com
From an HTTP perspective, Immutant will behave similarly to Jetty - you
would need to use Nginx as a proxy.

Where Immutant differs from Jetty is when your application needs services
beyond the web: scheduled jobs, messaging, XA transactions,
etc. Immutant bundles those services and simplifies clustering them when
you need horizontal scalability.

If your clojure app just handles HTTP requests and doesn't need any of
the extra features provided by Immutant, then using Immutant won't give
you much more than Jetty.
>> > To post to this group, send email to clo...@googlegroups.com<javascript:>
>> > Note that posts from new members are moderated - please be patient with
>> > your first post.
>> > To unsubscribe from this group, send email to
>> > clojure+u...@googlegroups.com <javascript:>
>> > For more options, visit this group at
>> > http://groups.google.com/group/clojure?hl=en
>> > ---
>> > You received this message because you are subscribed to the Google
>> > Groups "Clojure" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> > an email to clojure+u...@googlegroups.com <javascript:>.
>> > For more options, visit https://groups.google.com/groups/opt_out.
>>
>
> --


--
Toby Crawley
http://immutant.org | http://torquebox.org

Zeynel

unread,
Dec 17, 2013, 10:59:49 AM12/17/13
to clo...@googlegroups.com
Great, thanks. In that case I'll concentrate on Jetty.

Zeynel

unread,
Dec 18, 2013, 3:13:30 PM12/18/13
to clo...@googlegroups.com


On Tuesday, December 17, 2013 9:02:19 AM UTC-4, David Della Costa wrote:
...I would probably simply push out an uberjar
with lein which I would run with Java via an init script--for example,
if using Ubuntu:

http://upstart.ubuntu.com/cookbook/#run-a-java-application

I want to try this but I still cannot put the pieces together about how to do it. Can you give more details? Let's say I created the uberjar with lein uberjar, then how do I tell nginx to run that?

Curtis Gagliardi

unread,
Dec 18, 2013, 5:35:11 PM12/18/13
to clo...@googlegroups.com
I build an uberjar of a web server that uses jetty with compojure and run it on port 3000, then I have nginx configured to proxy it like so:

https://gist.github.com/cgag/8031034

Curtis Gagliardi

unread,
Dec 18, 2013, 5:40:51 PM12/18/13
to clo...@googlegroups.com
I don't know how to configure an init script, but I just run the command `java -jar mywebserver.jar` in a tmux session manually and then detach.

For how to setup an uberjar to run a web server, there's a nice tutorial on clojure-doc.  You just need to make sure you have your :main class specified in project.clj and have :gen-class on the right files.   Check out the deploy your webapp section: http://clojure-doc.org/articles/tutorials/basic_web_development.html

Zeynel

unread,
Dec 18, 2013, 7:28:11 PM12/18/13
to clo...@googlegroups.com
I am following your tutorial, but I am stuck with Jetty configuration. My installation does not seem to have a /contexts directory. Where is it?


On Tuesday, December 17, 2013 9:02:19 AM UTC-4, David Della Costa wrote:

Dave Della Costa

unread,
Dec 20, 2013, 8:39:07 AM12/20/13
to clo...@googlegroups.com
Hi Zeynel,

I don't know if setting things up the way I've laid out there is such a
great idea. What I would do instead is set the port and whatnot in the
jetty configuration inside of ring, assuming that's what you're using
(this assumes a lot about how your app is set up, so let me know if this
doesn't match your setup):

http://ring-clojure.github.io/ring/ring.adapter.jetty.html

Then, I would compile an uberjar with lein, like so:

$ lein uberjar

In your startup script, as Curtis laid out, call the jar file using
something like:

/path/to/java -jar /path/to/uberjar

That will be much simpler than what I have in my tutorial...which I
should really update, now that you mention it!

DD
> <javascript:>
> > Note that posts from new members are moderated - please be patient
> with
> > your first post.
> > To unsubscribe from this group, send email to
> > clojure+u...@googlegroups.com <javascript:>
> > For more options, visit this group at
> > http://groups.google.com/group/clojure?hl=en
> <http://groups.google.com/group/clojure?hl=en>
> > ---
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To unsubscribe from this group and stop receiving emails from it,
> send
> > an email to clojure+u...@googlegroups.com <javascript:>.
> > For more options, visit https://groups.google.com/groups/opt_out
> <https://groups.google.com/groups/opt_out>.

Zeynel

unread,
Dec 25, 2013, 6:42:00 AM12/25/13
to clo...@googlegroups.com
Ok, I worked through the tutorial referenced http://clojure-doc.org/articles/tutorials/basic_web_development.html#build-and-run-it and I created a jar file and ran it with $ java -jar -my-webapp.jar. This works. But my understanding is that this is would not work for production. I need to use nginx as proxy to jetty (or immutant?). I am trying to figure out the correct configuration for jetty and nginx. Each tutorial appears to be different and so far I couldn't make it work.

James Reeves

unread,
Dec 25, 2013, 9:06:58 AM12/25/13
to clo...@googlegroups.com
I currently serve a web app on a Ubuntu server. Here's the configuration I use:

In "/etc/nginx/sites-available/<app-name>":

server {
    listen 80;

    location / {
        proxy_set_header  X-Real-IP        $remote_addr;
        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header  Host             $http_host;
        proxy_redirect    off;
        proxy_pass        http://127.0.0.1:4000;
    }
}

Then I enable this configuration by adding a symbolic link:

cd /etc/nginx/sites-enabled
ln -s <app-name> ../sites-available/<app-name>

Then I create an upstart job to run the server in "/etc/init/<app-name>.conf:

description "<description of server>"
author "<your name>"

start on startup
stop on shutdown

setuid deploy
chdir /deploy
console log

env PORT=4000
exec java -jar <name of uberjar file>.jar

The jar file I place in "/deploy", a directory I've added in at the top level.

If all goes according to plan, then I can reload nginx and start my server:

reload nginx
start <app-name>

Hope that helps.

- James

Malcolm Sparks

unread,
Dec 26, 2013, 8:24:59 AM12/26/13
to clo...@googlegroups.com
Here's an article I wrote that takes you through the full process of running nginx and and a Clojure web app.

https://juxt.pro/articles/manual-clojure-deployment.html

Justin Smith

unread,
Dec 26, 2013, 10:03:35 AM12/26/13
to clo...@googlegroups.com
java -jar is fine in production. Jetty, Tomcat, or Immutant will offer some conveniences but are not necessary. What is needed (for security reasons) is an nginx proxy.

Alexis Gallagher

unread,
Dec 27, 2013, 6:22:12 PM12/27/13
to clo...@googlegroups.com
It's not free, but Kevin Lynagh sells a collection of nicely packaged and documented examples of basic dev ops setups. The package on server config illustrates exactly what you are asking for: deploying a Clojure web app behind nginx, with some monitoring, server-hardening, etc.. It's at: https://thedevop.com

A

Zeynel

unread,
Dec 27, 2013, 7:27:58 PM12/27/13
to clo...@googlegroups.com, ja...@booleanknot.com
Thank you, this is great, exactly what I was looking for. I had a few issues but I solved them and it is all set as you described, but I am unable to run it with $ start <app-name>.

I created /etc/init/nomilkfor.me.conf (this is the domain name) and this is what is in the file:

description "ubuntu 13.10 on Samsung laptop"
author "zeynel"
                                                   
start on startup
stop on shutdown
                                                   
setuid deploy
chdir /deploy
console log
                                                   
env PORT=4000
exec java -jar my-webapp-0.1.0-standalone.jar

I reload nginx with

$ sudo nginx -s reload

and I try

$ start nomilkfor.me

but I get 

start: Unknown job: nomilkfor.me

It looks like I am doing something wrong with the conf file. Any ideas? Thanks again. I hope this will work.

James Reeves

unread,
Dec 27, 2013, 8:20:25 PM12/27/13
to Zeynel, clo...@googlegroups.com
Perhaps try nomilkforme.conf instead of nomilkfor.me.conf ?

- James

Ahmet Zeynel

unread,
Dec 27, 2013, 8:33:45 PM12/27/13
to James Reeves, clo...@googlegroups.com
I just tried it but I got the same error. Do I need to add exec or script in the conf file? Thanks.

James Reeves

unread,
Dec 27, 2013, 8:44:10 PM12/27/13
to Ahmet Zeynel, clo...@googlegroups.com
The script looks fine... Are you executing "start nomilkforme" as root or with sudo? Do you have a "deploy" user and a "/deploy" directory?

- James

Ahmet Zeynel

unread,
Dec 27, 2013, 9:09:22 PM12/27/13
to James Reeves, clo...@googlegroups.com
I don't think I have a "deploy" user but I have a /deploy directory with the following content:

z@ubuntu:/deploy$ ll
total 8164
drwxr-xr-x  2 z    z       4096 Dec 27 08:20 ./
drwxr-xr-x 24 root root    4096 Dec 27 08:09 ../
-rw-r--r--  1 z    z    8351715 Dec 27 08:20 my-webapp-0.1.0-standalone.jar

I tried "start nomilkforme" both with sudo and as root, I got the same error with both. Thanks!

Zeynel

unread,
Dec 28, 2013, 9:36:29 AM12/28/13
to clo...@googlegroups.com, Ahmet Zeynel, ja...@booleanknot.com
I am still unable to "start nomilkforme". I get this error:

z@ubuntu:/tmp$ sudo start nomilkforme
start: Job failed to start

When I try $ init-checkconf -d /etc/init/nomilkforme.conf I get

z@ubuntu:/deploy$ init-checkconf -d /etc/init/nomilkforme.conf
DEBUG: upstart_path=/sbin/init
DEBUG: initctl_path=/sbin/initctl
DEBUG: confdir=/tmp/init-checkconf.fS7LRafn7i
DEBUG: file=/etc/init/nomilkforme.conf
DEBUG: job=nomilkforme
DEBUG: ok - no other running instances detected
DEBUG: upstart_out=/tmp/init-checkconf-upstart-output.UQ8JfJbG7n
DEBUG: upstart_cmd=/sbin/init --session --no-sessions --no-startup-event --verbose --confdir /tmp/init-checkconf.fS7LRafn7i
DEBUG: Waiting for Upstart to reply over D-Bus (attempt 1)
DEBUG: Waiting for Upstart to reply over D-Bus (attempt 2)
DEBUG: Waiting for Upstart to reply over D-Bus (attempt 3)
DEBUG: Waiting for Upstart to reply over D-Bus (attempt 4)
DEBUG: Waiting for Upstart to reply over D-Bus (attempt 5)
ERROR: failed to ask Upstart to check conf file
DEBUG: stopping secondary Upstart (running with PID 17391)

The problem appears to be related to the issue mentioned here http://scriptogr.am/mwhiteley/post/dbus-init-checkconf

"The problem is that init-checkconf is assuming you have a dbus-daemon running and the related environment variables set to find it. A graphical login session generally will start a dbus session for the user, but on a server install you are most likely running without one."

Does this make sense? I am running a server install as he mentions.

And do you know how I can run the script that he mentions?

Zeynel

unread,
Dec 28, 2013, 9:46:21 AM12/28/13
to clo...@googlegroups.com, Ahmet Zeynel, ja...@booleanknot.com
Is there another way to start the server besides using upstart?


On Friday, December 27, 2013 9:44:10 PM UTC-4, James Reeves wrote:

Zeynel

unread,
Dec 28, 2013, 9:53:29 AM12/28/13
to clo...@googlegroups.com, ja...@booleanknot.com
Can I deploy this as explained here http://www.luminusweb.net/docs/deployment.md#running_standalone with

java -jar myapp-0.1.0-SNAPSHOT-standalone.jar

On Wednesday, December 25, 2013 10:06:58 AM UTC-4, James Reeves wrote:

Zeynel

unread,
Dec 28, 2013, 10:12:42 AM12/28/13
to clo...@googlegroups.com
Thanks, I just sent them an email asking more info.

Zeynel

unread,
Dec 28, 2013, 10:15:13 AM12/28/13
to clo...@googlegroups.com
Ok, I am having problems starting nginx with upstart as mentioned by James Reeves. Would starting with tmux work as well. Can you give more info?

Zeynel

unread,
Dec 28, 2013, 12:08:23 PM12/28/13
to clo...@googlegroups.com, ja...@booleanknot.com
I tried it like this and it seems to work:

z@ubuntu:/etc/nginx/sites-available$ export PORT=4000
z@ubuntu:/etc/nginx/sites-available$ java -jar /deploy/my-webapp-0.1.0-standalone.jar
2013-12-28 11:58:16.307:INFO:oejs.Server:jetty-7.x.y-SNAPSHOT
2013-12-28 11:58:16.409:INFO:oejs.AbstractConnector:Started SelectChann...@0.0.0.0:4000

What's wrong with deploying it like this?

James Reeves

unread,
Dec 28, 2013, 12:16:31 PM12/28/13
to Zeynel, clo...@googlegroups.com
Upstart gives you useful tools like respawning failed services, log rotation, and starting on server boot.

Have you checked the logs in /var/log/upstart/nomilkforme.log? Perhaps it's got something to do with the permissions of the deploy directory.

- James

Zeynel

unread,
Dec 28, 2013, 12:24:43 PM12/28/13
to clo...@googlegroups.com, Zeynel, ja...@booleanknot.com
Yes, but I don't see nomilkforme.log file. There are only .gz files:

z@ubuntu:/var/log/upstart$ ls
console-setup.log.1.gz
container-detect.log.1.gz
module-init-tools.log.1.gz
networking.log.1.gz
network-interface-eth0.log.1.gz
procps.log.1.gz
procps-static-network-up.log.1.gz
procps-virtual-filesystems.log.1.gz
rsyslog.log.1.gz
ureadahead.log.1.gz
ureadahead-other.log.1.gz

Is there a way to tell upstart to include nomilkforme.log?

James Reeves

unread,
Dec 28, 2013, 12:38:19 PM12/28/13
to Zeynel, clo...@googlegroups.com
Logs are automatically gzipped up after a while, I believe. You can use something like zcat to take a look inside.

- James

Ahmet Zeynel

unread,
Dec 28, 2013, 1:00:32 PM12/28/13
to James Reeves, clo...@googlegroups.com
Great, I used zcat to look at them but I think they are too long to post here, do you know which one(s) would be relevant?

z@ubuntu:/var/log/upstart$ ls
console-setup.log.1.gz
container-detect.log.1.gz
module-init-tools.log.1.gz
networking.log.1.gz
network-interface-eth0.log.1.gz
procps.log.1.gz
procps-static-network-up.log.1.gz
procps-virtual-filesystems.log.1.gz
rsyslog.log.1.gz
ureadahead.log.1.gz
ureadahead-other.log.1.gz

James Reeves

unread,
Dec 28, 2013, 1:40:38 PM12/28/13
to Ahmet Zeynel, clo...@googlegroups.com
The one with the name of your app, if there is one. There's a log file per upstart service.

- James

Ahmet Zeynel

unread,
Dec 28, 2013, 2:18:12 PM12/28/13
to James Reeves, clo...@googlegroups.com
Earlier I changed the permissions in /deploy but now I put it back to root and now I have:

z@ubuntu:/deploy$ ll
total 8164
drwxr-xr-x  2 root root    4096 Dec 27 08:20 ./
drwxr-xr-x 24 root root    4096 Dec 27 08:09 ../
-rw-r--r--  1 root root 8351715 Dec 27 08:20 my-webapp-0.1.0-standalone.jar

and now when try to start as root I get this:

root@ubuntu:/deploy# start nomilkforme
start: Job failed to start

James Reeves

unread,
Dec 28, 2013, 5:13:52 PM12/28/13
to Ahmet Zeynel, clo...@googlegroups.com
The script I included in my example assumes that there is a "deploy" user that owns the "/deploy" directory and everything in it.

- James

Mark Mandel

unread,
Dec 28, 2013, 5:24:20 PM12/28/13
to clojure, Ahmet Zeynel

I have found in the past I needed to  reload-configuration of initctl.  Maybe try that?

Mark

Sent from my mobile doohickey

Ahmet Zeynel

unread,
Dec 28, 2013, 5:59:18 PM12/28/13
to James Reeves, clo...@googlegroups.com
Thanks so much! That worked:

deploy@ubuntu:~$ sudo start nomilkforme
[sudo] password for deploy: 
nomilkforme start/running, process 19945
deploy@ubuntu:~$ 

One more question: When I go to www.nomilkfor.me I see the 'jetty' favicon on the browser tab. Is it because ring is using jetty? I assume that I don't have to get involved with jetty anymore? Correct.

Thanks again, for all your help.
Reply all
Reply to author
Forward
0 new messages