Мы все получили плохую новость о том, что Heroku больше не будет иметь бесплатного уровня. К счастью, есть отличная альтернатива под названием Render, которая также имеет отличный опыт работы с разработчиками, а также может быть более чем на 50% дешевле, если вы хотите развернуть свой сервис на производстве.
Если вы зайдете на их сайт, то увидите, что у них нет поддержки Java-приложений из коробки, но есть поддержка Docker. Но если вы новичок в Docker, как я, вы подумаете: Хорошо, это не проблема. Я возьму Dockerfile из интернета и разверну свой сервис с его помощью. Итак, вы идете в Google, ищете Spring Boot Dockerfile и, возможно, получаете что-то похожее на это:
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Легко, скажете вы. Затем вы продвигаете свой код, Render обнаруживает изменения, вы проверяете журналы и… О, нет. Вы получаете ошибку:
Итак, что же здесь произошло? Как я уже говорил, Render не поддерживает Java-приложения, а этот Dockerfile предполагает, что у вас на хосте установлен Maven и вы выполнили mvn install
.
Итак, что вы можете сделать дальше? Есть два способа решить эту проблему:
1. Использовать образ Maven Docker
Поскольку в Render не установлен Maven, вам придется установить его на ваш контейнер следующим образом:
FROM maven:3.8.6-jdk-8-slim AS MAVEN_TOOL_CHAIN
COPY pom.xml /tmp/
COPY src /tmp/src/WORKDIR /tmp/
RUN mvn package FROM openjdk:8-jdk-alpine
COPY --from=MAVEN_TOOL_CHAIN /tmp/target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Вот и все. Как только вы запустите этот Dockerfile, ваше приложение запустится.
2. Использовать обертку Maven
Для второго способа вам потребуется установить Maven на локальной машине и выполнить эту команду в корне вашего проекта:
mvn -N wrapper:wrapper
И вы заметите, что эти файлы добавлены в ваш проект:
Эта команда встроит Maven в ваш проект. Таким образом, вы сможете выполнять команды Maven без его установки. Только убедитесь, что вы не включили эти файлы в свой файл .gitignore
.
А теперь вам нужно изменить ваш Dockerfile следующим образом:
FROM openjdk:8-jdk-alpine as build
WORKDIR /workspace/app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN ./mvnw install -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.package.Application"]
Обязательно замените "com.package.Application"
на имя вашего пакета и основного класса, а также суффикс Kt
, если это Kotlin-приложение, вот так: "com.package.ApplicationKt"
.
Внесите изменения, и вы увидите, что ваше приложение работает на Render.
И это все, что вам нужно для развертывания Spring Boot на Render.com.
Я уверен, что есть еще много способов оптимизации Docker-файлов, которые я представил в этой статье, но, как я уже говорил, я все еще не эксперт по Docker, поэтому не стесняйтесь писать любые предложения в разделе комментариев.
Надеюсь, я был полезен, и спасибо за чтение.