14 ноября 2024
Тэги: devops, 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, H2, Linux, Hibernate, Collections, Stream API, многопоточность, чат-боты, нейросети, файлы, devops, Docker, 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.