jypma / LB3210

Microservices with Java
Creative Commons Attribution Share Alike 4.0 International
0 stars 0 forks source link

Add absolute minimum docker build to pom.xml #9

Open jypma opened 3 years ago

jypma commented 3 years ago

Let's add the absolute minimum to pom.xml to be able to build a docker container for this application.

For reference, this is what you'd need with SBT:

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.6.1")

and then sbt docker:publishLocal will do the trick.

To how many lines can we trim down the maven way? :-)

jbendsen commented 3 years ago

One way of doing it is adding a Dockerfile to the project: FROM openjdk:8-jdk-alpine ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"]

And then use maven like this: ./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=lb/demo-spring-boot-docker

jbendsen commented 3 years ago

I'll research an alternative solution with no Dockerfile.

jbendsen commented 3 years ago

I've been looking around and found an alternative using jkube which is the new fabric8 maven plugin. See jkube site.

I've found that this will build a docker image and deploy i to kubernetes: mvn org.eclipse.jkube:kubernetes-maven-plugin:build org.eclipse.jkube:kubernetes-maven-plugin:resource "-Djkube.enricher.jkube-service.type=NodePort" org.eclipse.jkube:kubernetes-maven-plugin:apply

No Dockerfile needed. It seems to work on java 8+ (i've tested with java 11). The boot app starts but fails due to lack of database connectivity. I guess the spring boot container has to be on the same network as the database container. @jypma, let me know if I should investigate this further.

jbendsen commented 3 years ago

I've worked out a new solution that seems to work without a Dockerfile.

Given this command: mvn spring-boot:build-image -Dspring-boot.build-image.imageName=logb/demo-project3

And this docker-compose.yml file:

version: '3.1'

services:
  app:
    image: logb/demo-project3
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/demo
      SPRING_DATASOURCE_USERNAME: demo
      SPRING_DATASOURCE_PASSWORD: example
      SPRING_RABBITMQ_HOST: rabbitmq
      SPRING_RABBITMQ_PORT: 5672
    ports:
      - 8080:8080
    depends_on:
      - db
      - rabbitmq
  db:
    image: postgres:13.2-alpine
    # Uncomment this to have the DB come up when you start docker / your laptop:
    #restart: always
    environment:
      POSTGRES_USER: demo
      POSTGRES_DB: demo
      POSTGRES_PASSWORD: example

    ports:
      - 5432:5432

  rabbitmq:
    image: rabbitmq:3.8.16-alpine
    # Uncomment this to have the DB come up when you start docker / your laptop:
    #restart: always
    ports:
      - 5672:5672    # AMQP
      - 15672:15672  # Web UI

Then

docker-compose up -d will start the spring boot app.

Is this an acceptable solution?

jypma commented 3 years ago

Looks nice, and seems to be the idiomatic way with spring boot, even though it seems you can't set command-line java options. Let's assume that basic command-line arguments do make it through :-)

jbendsen commented 3 years ago

Yes, it seems to be the simplest way of doing it.

I guess that we don't want the docker-compose.yml file to contain the spring boot app. One option is to make another compose file and use it like this: docker-compose -f ./docker-compose-with-spring-app.yml up -d Then the original docker-compose.yml file is left untouched. Should I make a PR with this solution?

jypma commented 3 years ago

In my experience, when developing a microservice, you really don't want to run it in docker. Run cycles are much slower that way, and everything it in the way of debugging / log files. Use docker-compose for dependencies, and run the service plain.

Being able to create a docker container is for deployment, release, and potentially integration testing. All of those would have their own docker-compose files, as they'd have very different dependency needs than development.