Развертывание исполняемого кода на сервере (деплой, от англ. – deploy), где ему предстоит работать, часто вызывает массу вопросов у начинающих разработчиков и системных администраторов. В этом материале мы собрали необходимый гайд, способный помочь развернуть проект без участия коллег с большим опытом. Понятно, что он не совсем универсальный, в ряде случаев придется интерпретировать информацию по-своему, с ориентиром на специфику системы.
Эксперименты можно проводить на облачных серверах провайдера Timeweb Cloud, у которого есть различные тарифы. Есть предложения по готовым решениям и чистые виртуальные машины. Для деплоя Java-приложения на сервер понадобится работающее приложение, созданное на Java с использованием фреймворка Spring Boot. Предполагаем, что разработка ведется на платформе Windows 10 с установленными PostgreSQL, Apache, Maven, Git Bash.
На удаленном хосте должны быть установлены Ubuntu, Nginx, сертификат SSL и панель управления Vesta. Сразу отметим, что в зависимости от версии Java возможны «нестыковки» с операционкой, поэтому при использовании другого релиза вы, возможно, столкнетесь с ошибками. Тогда каждый разбирается в ситуации самостоятельно или с помощью специалистов техподдержки провайдера.
Использовать для деплоя Java-приложений допускается любую панель управления. Но в данном случае остановимся на варианте Vesta Control Panel. И будем подключаться к хосту через утилиту Putty, поддерживающую защищенные соединения по протоколу SSH. В ней есть особенность – при вводе пароля курсор стоит на месте, но, на самом деле, он вводится. Итак, подключимся к пользователю с правами root. На экране монитора пользователь увидит следующее:
root@2.124.31.10
После знака @ будет отображен настоящий IP-адрес хоста, к которому мы подключились. Теперь введем команды:
sudo apt update
sudo apt-get install wget
Сразу зададим настройки панели управления:
sudo nano /usr/local/vesta/conf/vesta.conf
Если текстовый редактор nano еще не установлен, сделаем это командой:
sudo apt-get install nano
Кому больше нравится редактор vi, редактируйте конфигурацию с его помощью:
sudo vi /usr/local/vesta/conf/vesta.conf
В открытом файле добавим строку FILEMANAGER_KEY = 'ILOVEREO' (в самый конец). И еще одну – DB_SYSTEM – меняем на DB_SYSTEM=‘mysql,pgsql’. Закроем файл с сохранением и сразу же перезапустим веб-версию панели Vesta с выходом и повторным входом в аккаунт.
Теперь установим PostgreSQL. Выполняется это командой:
sudo apt-get install postgresql postgresql-contrib phppgadmin
Следом скачаем файлы конфигурации Vesta Control Panel:
wget http://c.vestacp.com/0.9.8/ubuntu/pg_hba.conf -O /etc/postgresql/*/main/pg_hba.conf
Перезагрузим процесс PostgreSQL:
service postgresql restart
Есть альтернативная команда:
systemctl restart postgresql
И зайдем в систему под пользователем postgres:
su – postgres
Пароль устанавливается разными способами. Вот один из них:
psql -c “ALTER USER postgres WITH PASSWORD ‘pgp4sw0rd'”
Вот второй:
\password postgres
При запросе вводим желаемый пароль. Например, то же буквосочетание pgp4sw0rd. Исходя из выбранного варианта возвращаемся к пользователю root. Если запутались, проще подключиться к хосту заново под нужным аккаунтом.
Зарегистрируем PostgreSQL в Vesta:
v-add-database-host pgsql localhost postgres pgp4sw0rd
Скачаем настроечные файлы для phppgadmin:
wget http://c.vestacp.com/0.9.8/ubuntu/pga.conf -O /etc/phppgadmin/config.inc.php
wget http://c.vestacp.com/0.9.8/ubuntu/apache2-pga.conf -O /etc/apache2/conf.d/phppgadmin
И перезапустим веб-модули:
service apache2 restart
service vesta restart
service nginx restart
dbaas
Java нужна для запуска тестового проекта, собранного в JAR. Инсталляция произойдет по команде:
sudo apt update
sudo apt install openjdk-8-jdk
Проверим версию Java:
java --version
На экране появится примерно следующее:
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (build 1.8.0_292-8u292-b10-0ubuntu1~18.04-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)
Если установили не ту версию, ее легко удалить (на примере 1.8):
sudo apt-get remove --auto-remove openjdk
sudo apt-get autoremove openjdk-8-jre
sudo apt-get autoremove openjdk-8-jdk
sudo apt-get purge openjdk
Панель управления Vesta представляет собой продукт с графическим интерфейсом, где легко разобраться даже без инструкции. И на первом шаге создадим в ней новый аккаунт. Войдите в веб-версию панели под администратором, имеющим право на регистрацию других пользователей. Во вкладке USER создайте нового, указав его название в поле [username]. После сохранения настроек надо зайти в панель управления уже под ним.
Последующие шаги:
ns1.yourdomain.ru
5. Приобретем и настроим SSL-сертификат. Здесь мы предположим, что тот уже есть у нас, и остается только настроить его. Кликнем на вкладку Web, далее Edit и поставим галочку на SSL support. Заполним открывшиеся поля. Нажмем Save для завершения процедуры.
Очередной этап пригодится тем, кто планирует запускать программы через нестандартные порты вместо стандартного 8080. В нашем эксперименте изменим значение в в файле application.properties
на server.port=8099
. Порт 80 обычно занят Nginx или Apache. При желании есть возможность создать переадресацию через файл .htaccess.
Теперь подключимся по протоколу SSH к удаленному хосту с использованием аккаунта root. И сразу проверим каталог созданного ранее пользователя, точно ли он существует:
ls -l /home/YOURUSER/conf/web/
Система выдаст примерно такое сообщение:
ssl.yourdomain.ca
ssl.yourdomain.crt
ssl.yourdomain.key
ssl.yourdomain.pem
yourdomain.apache2.conf
yourdomain.apache2.ssl.conf
yourdomain.nginx.conf
yourdomain.nginx.ssl.conf
Раз мы установили сертификат SSL, нужно настроить редирект с HTTP на HTTPS. Поэтому откроем файл nginx.conf:
sudo nano /home/YOURUSER/conf/web/YOURDOMAIN.nginx.conf
И в конце внесем строку (перед закрывающей скобкой):
return 301 https://YOURDOMAIN$request_uri;
Также включим перенаправление портов:
sudo nano /home/YOURUSER/conf/web/YOURDOMAIN.nginx.ssl.conf
В блоке location/, в поле proxy_pass меняем значение на предложенное выше – 8099.
location / {
proxy_pass https://7.12.12.01:8099;
То же надо сделать в блоке location@fallback proxy_pass:
location @fallback {
proxy_pass https:// 7.12.12.01:8099;
}
Выйдите из файла с сохранением изменений. И перезапустите процессы:
service apache2 restart
service vesta restart
service nginx restart
Мы подошли к моменту настройки приложения Java. На этом этапе чаще и возникают ситуации, когда ряд настроек не подходит. Если это так, вам придется подбирать их самостоятельно. Здесь же придерживаемся нашего плана. А в нем подразумевается, что инсталлирована система Windows без дополнительных компонентов. Если что-то из перечисленного ниже уже есть, пропускаем соответствующую инструкцию.
Последовательность действий:
server.port=8099 # Порт, на котором будет запущено приложение
server.ssl.key-store-type=PKCS12 # Метод шифрования
server.ssl.key-store=classpath:namefile.pfx # Путь к файлу pfx, где namefile – имя вашего домена (лучше не менять имя файла)
server.ssl.key-store-password=MyPassword # Пароль к файлу pfx указан на сайте, где вам выдавали сертификат
server.ssl.enabled=true # Включаем SSL
trust.store=classpath:namefile.pfx # Путь к файлу pfx, где namefile – имя вашего домена (лучше не менять имя файла)
trust.store.password=MyPassword # Пароль к файлу pfx указан на сайте, где вам выдавали сертификат
#log4j для логирования ошибок String //.
log4j.rootLogger=INFO
log4j.logger.org.hibernate.type.descriptor.sql=TRACE
trust.store исправляет в проекте некоторые проблемы с сертификацией.
5. Далее в файле pom.xml добавим зависимости:
<dependency>
<groupID>javax.xml.bild</groupID>
<artifactID>jaxb-api</artifactID>
<version>2.3.0</version>
</dependency>
<dependency>
<groupID>com.sun.xml.bind</groupID>
<artifactID>jaxb-core</artifactID>
<version>2.3.0</version>
</dependency>
<dependency>
<groupID>org.apache.httpcomponents</groupID>
<artifactID>httpclient</artifactID>
</dependency>
6. Перейдем в класс WebSecurityConfig и добавим строки:
@Value("${trust.store}")
private Resource trustStore;
@Value("${trust.store.password}")
private String trustStorePassword;
@Bean
public RestTemplate restTemplateWithTrustStore(RestTemplateBuilder builder) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(trustStore.getURL(), trustStorePassword.toCharArray())
.build();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory)
.build();
return builder
.requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient))
.build();
}
Теперь о самом интересном. Начнем с подготовки скрипта для сборки и развертывания приложения. Создадим файл deploy.sh и внесем в него строки:
#!/usr/bin/env bash
mvn clean package
echo 'Copy files...'
scp PATHTOTARGET/target/NAMEFILE.jar \
root@IP:/home/USER/web/DOMAIN/public_shtml
echo 'Restart server...'
ssh -t root@IP << EOF
pgrep java | xargs kill -9
nohup java -jar /home/USER/web/DOMAIN/public_shtml/NAMEFILE.jar > /home/USER/web/DOMAIN/log.txt &
EOF
echo 'Bye'
Подробнее об используемых переменных:
Важно! Лог-файлы, в которых система записывает события запуска и работы веб-приложений, найдутся в каталоге /home/USER/web/DOMAIN/log.txt.
Переходим к запуску созданного скрипта. Откроем ранее инсталлированный git bash, перейдем в каталог, где размещено приложение, и введем команду:
./scripts/deploy.sh
Начнется процесс запаковки при помощи maven. Если все ранее описанное сделано без ошибок, то оно пройдет безостановочно. Система пару раз запросит пароль пользователя root – для копирования и для развертывания приложения. Все, теперь смело открывайте его через браузер.
Разверните базу данных в облаке
Инструментарий для развертывания веб-приложений относительно «скромный», поэтому его легко освоить даже без опытных наставников. Важно учитывать, что перечисленные выше операции при отсутствии домена можно «заточить» на IP-адрес сервера. Работать приложение будет одинаково, разницу заметят только пользователи, которым удобнее вводить доменное имя.
Кстати, в официальном канале Timeweb Cloud собрали комьюнити из специалистов, которые говорят про IT-тренды, делятся полезными инструкциями и даже приглашают к себе работать.
А почему бы БД не в докера запустить?
Как написать deploy.sh, если у меня не Maven, а Gradle?
Добрый день! Не уверены, но возможно вам не потребуется ничего менять в этом скрипте, кроме путей к файлам. Всё зависит непосредственно от приложения, но вы его точно знаете лучше, чем мы :)