skip to Main Content

I have a spring framework web application and I’m trying to deploy it into production using tomcat with docker image.

I searched about this error and found out there are two possible errors. The first one is incorrect database url format and I check mine and it’s correct. The database url is like this

jdbc:postgresql://localhost:5432/postgres?currentSchema=volga&stringtype=unspecified

The second possible problem is the Postgres db library file is not included in war file. So I run bash command inside the running tomcat container and check for Postgres library file and it exists in the war file. I also tried to copy the Postgres library into tomcat lib folder and it’s not working.

I create a repo with minimum code to reproduce the error.
https://github.com/ap30422/spring-boot.git

Please clone the repo and change directory to compete directory.
Run mvn clean install package to build the app.
Then run Docker build . to build the image.
Run Docker image with docker run #insert_image_id. -p 8080:8080

If you check http://localhost:8080, you will see the Down text and the error log in the docker container log.

2

Answers


  1. The current issue you’re encountering may be attributed to either the absence of JDBC drivers or misconfigurations in your Spring Boot application or Tomcat Docker image. Here are a few steps you can follow to address and potentially resolve the problem:

    1. Verify Dependency Management.

    Confirm that the PostgreSQL JDBC driver is included in your pom.xml file as a dependency. If it’s not already there, add the following lines

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>your_postgresql_version</version>
    </dependency>
    

    2. Check the Classpath in Spring Boot.

    While Spring Boot should automatically load the JDBC driver into the classpath, you can explicitly specify the driver class in either the application.properties or application.yml file

    spring.datasource.driver-class-name=org.postgresql.Driver
    

    3. Verify Database Connection URL

    Ensure that the database connection URL is correct. If the database is on a different server, use the appropriate hostname or IP address. Also, confirm that Tomcat can resolve "localhost" if that’s part of the URL.

    4. Docker Image Build

    When creating the Docker image, make sure to copy the PostgreSQL JDBC driver to the correct location within the image. For instance, you can copy it to a "lib" folder. Modify your Dockerfile as follows:

    FROM tomcat:latest
    COPY target/spring-boot.war /usr/local/tomcat/webapps/
    COPY target/dependency/*.jar /usr/local/tomcat/lib/
    

    By following these steps, you should be able to address potential issues related to JDBC drivers and configurations in your Spring Boot application and Tomcat Docker image.

    Login or Signup to reply.
  2. The problem is that you are trying very hard to work around all the things that Spring Boot offers.

    1. You don’t use the auto-configured DataSource but try to do things yourself.
    2. You aren’t using the embedded Tomcat but instead try to deploy the application.

    Use the frameworks and tools you have to there advantage instead of working around things.

    Use the Spring Boot DataSource

    In your application.properties (should be in src/main/resources) add the following

    spring.datasource.url=jdbc:postgresql://localhost:5432/postgres?currentSchema=volga&stringtype=unspecified
    spring.datasource.username=ni
    spring.datasource.password=ni
    

    Next modify your HelloController to use a DataSource or even better a JdbcTemplate.

    @RestController
    public class HelloController {
    
      private final JdbcTemplate jdbc;
    
      public HelloController(JdbcTemplate jdbc) {
        this.jdbc=jdbc;
      }
    
      @GetMapping("/")
      public String index() {
      
        try {
          String hello = jdbc.queryForObject("select 'hello'", String.class);
          return "UP";
        } catch (DataAccessException dae) {
          return "DOWN";
        }
      }
    }
    

    Now you are properly using the Spring Boot configured DataSource and Spring Boot will load the correct driver (if it is on the classpath).

    The application will probably fail to start as I doubt that in the container you are building for this application there is a PostgreSQL database available.

    Use embedded tomcat

    Spring Boot already provides Tomcat as the default provider and should be used to run it. Change your applicatation to a jar and not a war. And modify your Dockerfile to launch the application instead of using Tomcat and deploy the application.

    FROM eclipse-temurin:8-jre-alpine
    ADD target/*.jar /app.jar
    
    EXPOSE 8080
    ENTRYPOINT ["java","-jar","/app.jar"]
    

    This will just launch the application you have created and utilize the embedded tomcat instance.

    NOTE: This is not the best Dockerfile for a Spring Boot application, you want to use more layers so you can enable reuse. See the Spring Boot Docker Guide.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search