воскресенье, 19 февраля 2012 г.

Деплоймент Clojure под Tomcat

Не так давно я взялся за небольшой проект с клиент-серверной архитектурой. JSON веб-сервис мне позволили реализовать на clojure, что я очень быстро и сделал при помощи библиотек: Noir, Lobos, Korma и Cheshire. Но зато была масса непоняток с деплойментом этого готового сервиса на хостинг. Во-первых, по непонятной причине, оригинальный сервер, поработав какое-то время, попросту отваливается. Я до сих теряюсь в догадках, что заставляет его так капризничать. Понятное дело, что я решил задеплоить всё на Tomcat.

Мне не удалось нигде найти нормальной инструкции о том, как деплоить noir-приложение под томкат, так что я решил восполнить этот пробел.

Данная инструкция рассчитана на веб-сайт, разработанный на clojure при помощи фреймворка Noir (опробовано на noir 1.3.0-alpha10).

1) Добавьте [lein-ring "0.5.4"] в :dev-dependencies вашего файла project.clj.
Внимание! [uk.org.alienscience/leiningen-war "0.0.13"] – это не то же самое, что lein-ring. Плагин lein-ring умеет создавать ring-handler для noir-приложения и запаковать все в war-ку. А плагин leiningen-war только создает war-ку, а ring-handler-а не создает.

2) В файле project.clj укажите ваш ring-handler и пространство имен для ahead-of-time компиляции.
:ring {:handler MyProject.server/handler}
:aot [MyProject.server]

3) Создайте ring-handler в server.clj:
(:require [noir.server :as server])
. . .
(def handler (server/gen-handler {:base-url "/myproject"}))
Внимание! Обязательно нужно указать :base-url, иначе редиректы и линки задеплоенного в томкат приложения будут указывать не на localhost:8080/myproject/, а на localhost:8080/ . Эпик фейл будет фееричный!

4) Уберите такую загрузку вьюх: (server/load-views "src/MyProject/views/") из файла server.clj. Вьюхи нужно загружать явно:  
(:require [noir.server :as server]
. . .
            [MyProject.views.pages])
Если этого не сделать, то после упаковки в war-ку и даже jar-ку, ни один ваш маршрут работать не будет.

5) Все линки и формы, если вы их генерите из hiccup, нужно создавать функциями:
(hiccup.form-helpers/form-to [:post "/myurl"] ...)
(hiccup.page-helpers/link-to "/myurl" …)
Если этого не сделать, то они будут вести на localhost:8080/ вместо localhost:8080/myproject.

6) Создайте war-ку командой lein ring uberwar.
Внимание! Команда lein ring uberwar поставляется с lein-ring-плагином, и в нашем случае она работает. Команда lein uberwar поставляется с плагином  leiningen-war, и здесь она не работает. Так что этот плагин вообще лучше не использовать с noir.

7) Скопируйте war-ку в webapps томката и переименуйте её в myproject.war.

Теперь, после запуска томката, по адреусу localhost:8080/myproject будет ваше приложение.

2 комментария:

  1. Где ж Вы были две недели назад? Впрочем, это мало что поменяло бы. :)

    >Мне не удалось нигде найти нормальной инструкции о том, как деплоить noir-приложение под томкат

    А я почему-то нашёл кучку форумов, списков рассылки, gist'ов, где написано что делать, хоть и не так пошагово. Или Вы на русском искали? ;)

    > :aot [MyProject.server]

    Интересно, но у меня и без него компилируется.

    > Обязательно нужно указать :base-url, иначе редиректы и линки задеплоенного в томкат приложения будут указывать не на localhost:8080/myproject/, а на localhost:8080/

    Вылечил при помощи mod_proxy. :)))
    Но спасибо, что рассказали - не придётся потом искать.

    >Уберите такую загрузку вьюх: (server/load-views "src/MyProject/views/")

    Как пишут, именно она и должна лечить проблему с war'ами, но по факту не лечит. :) Так что тоже сделал ручной импорт вьюх, но и эту строчку убирать не стал - не мешает же. :)

    > Скопируйте war-ку в webapps томката и переименуйте её в myproject.war

    А я через web деплою. :)))


    Надеюсь, следующие поколения Clojure web-программистов ещё выразят Вам благодарность - теперь всё расписано по шагам и по-русски.

    Спасибо! :)

    ОтветитьУдалить
  2. > А я почему-то нашёл кучку форумов, списков рассылки, gist'ов, где написано что делать, хоть и не так пошагово. Или Вы на русском искали? ;)

    Инфа, конечно, есть, но она размазана ровным слоем по разным форумам. Здесь я решил всё собрать в одном месте.

    ОтветитьУдалить