14 ноября 2024
Тэги: gradle, Java, Linux, maven, Nginx, PostgreSQL, Spring, SQL, руководство.
Если Вам интересно, как настроить сервер для хостинга JVM приложения, то предлагаю вашему вниманию следующую инструкцию. Предположим, вы только что получили доступ к чистому VPS серверу, на котором крутится Ubuntu и вы хотите на нём развернуть полноценное JVM приложение, основанное на Spring. Для полноты картины мы настроим также локальный postgres и доступ извне по http.
Прежде всего обновляем индекс менеджера пакетов apt. У вас должно быть достаточно прав для выполнения sudo, а также ваш сервер должен иметь доступ в Интернет.
Для работы нашего jvm-приложения сначала требуется установить виртуальную машину Java. Ставим последнюю LTS (long-term support – длительная поддержка) версию. На данный момент это Java 17.
JDK – это Java Development Kit, т.е. версия Java для разработчиков. Включает в себя компилятор. JRE – это Java Runtime Environment, т.е. среда исполнения. Причём JDK включает в себя JRE. На сервере чаще всего достаточно поставить именно JRE.
Опционально можно вручную настроить переменную окружения JAVA_HOME в файле /etc/environment. Добавляем в конце файла на новой строке:
Ставим postgres.
При создании пользователя вам будет задан только один вопрос. Создать его как суперпользователя? То есть наделить его всей полнотой полномочий для работы с БД. Выбираем yes.
Что касается имени пользователя и базы, то называйте их как-то похожим образом. Например, mydb и mydb_user.
Теперь заходим в сам postgres, выполнив команду psql. По сути psql – это консольный вариант клиента БД, который позволяет выполнять любые sql команды при наличии прав.
Установим для только что созданного пользователя хороший пароль (не забывайте точку с запятой в конце):
Кстати, генератор паролей доступен на данном сайте в разделе «Утилиты».
Выходим из psql командой \q.
Теперь в конце файла /etc/postgresql/номер_версии/main/pg_hba.conf добавляем:
Не забудьте заменить на свои имена базы и пользователя. Так мы указываем, что авторизация данного пользователя происходит именно по паролю, который мы задали выше.
Теперь если нам требуется подключаться к данной БД снаружи, а не только из самого приложения, работающего на этом же хосте, находим в файле /etc/postgresql/номер_версии/main/postgresql.conf
следующую закомментированную строку и раскомментируем её:
Так мы разрешаем подключаться к БД снаружи с любого ip-адреса. При необходимости вы можете задать специальную маску, ограничив до нужной подсети.
Чтобы все изменения вступили в силу, перезапускаем postgres:
Для начала нам нужно, чтобы имя jar-файла, которое получается в результате компиляции нашего Spring-приложения, не менялось от версии к версии. Задать его в явном виде в gradle можно так:
Если вы используете maven, то используйте следующую настройку:
Предположим, у нас уже есть скомпилированное jvm-приложение, которое умеет слушать порт 8080. Чтобы это приложение всё время работало на сервере и автоматически запускалось при старте сервера, нужно зарегистрировать его как linux-сервис.
Для этого с помощью scp копируем jar-файл (если их несколько, копируем тот, который больше) на сервер. Например, в папку /var/имя_приложения/имя_приложения.jar
Затем в папке /etc/systemd/system/ создаём файл имя_приложения.service со следующим содержимым:
Тут в параметре User указывайте, под каким пользователем системы следует запускать сервис. Разумеется, у него должны быть права на это.
В параметрах Environment вы можете задавать различные переменные окружения в формате «ключ=значение». В данном примере уже задан часовой пояс (TZ) и путь до папки с логами (LOGGING_FILE_PATH). Именно здесь вы можете указать профиль приложения test или prod.
В ExecStart указывается команда для запуска приложения. Здесь просто подставьте ваши значения.
Сохраняем файл, после чего активируем сервис и запускаем его:
Теперь наш сервис будет запускаться автоматически даже при перезагрузке сервера.
Если будете менять какие-то настройки в service-файле, не забывайте выполнять команду systemctl daemon-reload, чтобы изменения вступали в силу.
Поскольку наш сервис слушает порт 8080, вы уже можете обращаться к нему снаружи, указав имя хоста или ip-адрес и порт 8080. Но как сделать так, чтобы порт не нужно было указывать в явном виде? В этом нам поможет Nginx, который будет проксировать все запросы с дефолтного порта 80 на порт нашего приложения 8080.
Теперь открываем конфигурацию /etc/nginx/nginx.conf и находим там секцию http. Внутри неё нужно разместить секцию server:
listen 80 указывает, что мы хотим слушать порт 80. Секция «location /» говорит о том, что все запросы с корня url мы перенаправляем на localhost на порт 8080 (параметр proxy_pass).
Теперь в урле при обращении к нашему сервису порт указывать не нужно.
Если у вас настроен https с помощью сертификата Let's Encrypt или какого-то другого, имеет смысл на уровне nginx также настроить переадресацию, чтобы по умолчанию пользователей перекидывало с http на https. Также желательно настроить переадресацию с www в корень. Это полезно и с точки зрения индексации поисковиками, и с точки зрения удобства пользователей.
Для этого немного модифицируем секцию server в конфиге nginx.
Не забудьте вместо «домен» подставить ваш домен. И тогда после перезагрузки nginx вы получите автоматический 301 редирект с http на https, а также редирект с поддомена www на основной домен.
Напоследок было бы неплохо настроить хоть какую-то защиту нашего сервера. Воспользуемся стандартным брандмауэром UFW (Uncomplicated Firewall). По умолчанию он разрешает все подключения изнутри наружу и запрещает все подключения снаружи к серверу. Установка и настройка его предельно проста.
Команда вида «ufw allow протокол» позволяет разрешить подключения на определённый порт извне. Прежде всего, не забудьте разрешить ssh-подключение. Если вы забудете это сделать, то после активации ufw вы потеряете доступ к серверу.
Разрешим ещё несколько протоколов:
После активации брандмауэра все запрещённые порты окажутся недоступны!
Мы рассмотрели вопросы установки Java и postgres на сервер с Ubuntu. Также разобрались как запускать наше Spring-приложение в качестве linux-сервиса. После этого научились пробрасывать запросы с порта 80 на порт нашего приложения с помощью Nginx. Узнали, как сделать 301 редирект с http на https в случае, если у вас установлен сертификат. Ну и, напоследок, ограничили доступ к серверу с помощью брандмауэра UFW.
Если вы обнаружите неточности или у вас есть дополнения – пишите их в комментах.
Kotlin, Java, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Linux, Hibernate, Collections, Stream API, многопоточность, файлы, Nginx, Apache, maven, gradle, JUnit, YouTube, новости, руководство, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml.
25.05.2022 12:34 Артур
Супер, замечательная, подробная статья!
Такую бы статью встретить чуть пораньше, сэкономил бы часть времени)
Большое спасибо!
18.11.2024 23:48 devmark
Добавил раздел "Настройка переадресации с www и http на https" в nginx.