среда, 4 ноября 2015 г.

OpenShift - разворачивание java приложения с обновлением базы данных через liqubase

Недавно в работе над небольшим сайтом появилась потребность найти дешевый - в идеале бесплатный - хостинг, чтобы развернуть там java приложение. Выбор пал на OpenShift - проект компании RedHat. После регистрации на бесплатном тарифном плане можно получить возможность развенуть до 3 маленьких приложения, каждое со своей базой данный. В целом получается довольно удобно, есть ssh, есть консоль администрирования. Есть специальные тарифные планы для opensource и некоммерческих проектов.(актуально только на 2015 год для OpenShift 2, в 2017 бесплатные планы ушли в прошлое, так что заметка уже устарела)

Опишу, что же пришлось доделать, чтобы без проблем разворачивать проект и его обновления. Проект мобирается maven'ом в ROOT.war

Вся настройка процесса происходит через скрипты, находящиеся в директории .openshift/action_hooks Мне был нужен скрипт с именем deploy Там необходимо прописать следующие строки

cd $OPENSHIFT_REPO_DIR
mvn -s $OPENSHIFT_REPO_DIR/.openshift/config/settings.rhcloud.xml liquibase:update -P update_db
cp -f $OPENSHIFT_HOMEDIR/app-root/runtime/repo/target/ROOT.war $OPENSHIFT_DEPENDENCIES_DIR/jbossews/webapps/ROOT.war


первая команда запускает maven, в котором прописан специальный профиль, названный update_db, это по сути и есть запуск liquibase и обновление базы данных. Данная технология позволяет избавиться от зависимости к драйверу postgres в самом приложении и оставить эту библиотеку только в библиотеках tomcat
профиль update_db
        <profile>
            <id>update_db</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.liquibase</groupId>
                        <artifactId>liquibase-maven-plugin</artifactId>
                        <version>3.4.1</version>
                        <configuration>
                            <verbose>true</verbose>
                            <changeLogFile>src/main/resources/db/changelog.xml</changeLogFile>
                            <driver>org.postgresql.Driver</driver>
                            <url>
                                jdbc:postgresql://${OPENSHIFT_POSTGRESQL_DB_HOST}:${OPENSHIFT_POSTGRESQL_DB_PORT}/${OPENSHIFT_APP_NAME}
                            </url>
                            <username>${OPENSHIFT_POSTGRESQL_DB_USERNAME}</username>
                            <password>${OPENSHIFT_POSTGRESQL_DB_PASSWORD}</password>
                            <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
                        </configuration>
                        <executions>
                            <execution>
                                <phase>process-resources</phase>
                                <goals>
                                    <goal>update</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <dependencies>
                <dependency>
                    <groupId>org.postgresql</groupId>
                    <artifactId>postgresql</artifactId>
                    <version>9.2-1003-jdbc4</version>
                </dependency>
                <dependency>
                    <groupId>org.liquibase</groupId>
                    <artifactId>liquibase-core</artifactId>
                    <version>3.4.1</version>
                </dependency>
            </dependencies>
        </profile>

Вызов liquibase плагина нельзя помещать в профиль openshift, который используется при сборке, поскольку в момент сборки постгрес еще не запущен и выполнение плагина завершится с ошибкой. Переменные, описанные в конфигурации: ${OPENSHIFT_POSTGRESQL_*} уже настроены в сборочной среде окружения. 
Сам datasource описан в настройках tomcat и доступен по-умолчанию, с именем jdbc/PostgreSQLDS но драйвера postgres в библиотеках tomcat нет. Его нужно добавить следующим образом: зайти по ssh на сервер, и поместить postrgesql-${version}.jar в директорию app-root/data поскольку в директорию tomcat/lib прав на запись нет.

А в файле .openshift/config/catalina.properties дописать к строке
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
путь к добавленному драйверу, через запятую ${catalina.home}../app-root/data/*.jar

Почему именно app-root/data? Потому что эта директория предназначена для хранения пользовательских данных и не очищается между перезагрузками сервера и при обновлениях ПО.

Вторая команда deploy скрипта производит копирование ROOT.war из директории сборки в директорию webapps томката, это почему-то не происходит автоматически.

После проведенных манипуляций проект будет доступен примерно по такому адресу: http://projectname-projectdomain.rhcloud.com Чтобы он был доступен по вашему доменному имени, нужно прописать alias в проекте, который бы указывал на ваше доменное имя. Также нужно найти DNS провайдера, который позволяет устанавливать CNAME запись. Из бесплатных можно посоветовать https://dns.he.net/