Search code examples
spring-bootdockerdocker-composeredis

Unable to connect to correct redis host from application


I'm working on a Spring Boot project where I use Redis. I was able to run it in a separate Docker container, and it worked well. However, after adding the Spring Boot application, Redis, and MariaDB to a docker-compose.yml file and running it, all containers started successfully. The problem is that when I make Redis-based API calls, I receive the following error:

org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis

After reviewing the logs, I found the following records:

io.lettuce.core.RedisClient : Resolved SocketAddress localhost/<unresolved>:6379 using redis://localhost

io.lettuce.core.AbstractRedisClient : Connecting to Redis at localhost/<unresolved>:6379

This indicates that even though I specified the hostname as "redis" and the relevant port in both the docker-compose.yml and application.properties, the application is still trying to connect to the localhost API.

Could you please help?

docker-compose.yml

 version: "3.8"
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    volumes:
      - .:/app
      - ~/.m2:/root/.m2 
    environment:
      - MAVEN_OPTS=-Xmx512m
      - SPRING_DATASOURCE_URL=my_db_url?useSSL=false  
      - SPRING_DATASOURCE_USERNAME=my_user
      - SPRING_DATASOURCE_PASSWORD=my_pass
      - SPRING_REDIS_HOST=redis
      - SPRING_REDIS_PORT=6379
    depends_on:
      - redis
      - mariadb
    networks:
      - app-network

  redis:
    image: redis:latest
    ports:
      - "6379:6379"
    volumes:
      - ./redis.conf:/usr/local/etc/redis/redis.conf 
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
    networks:
      - app-network

  mariadb:
    image: mariadb:latest
    environment:
      - MYSQL_ROOT_PASSWORD=my_pass
      - MYSQL_DATABASE=my_db
    ports:
      - "3306:3306" 
    volumes:
      - mariadb_data:/var/lib/mysql
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  mariadb_data:

application.properties

spring.redis.host=redis
spring.redis.port=6379

Also I have created a redis.conf file.

bind 0.0.0.0
protected-mode no

Solution

  • I fixed the issue by overriding the hostname by adding a RedisConfig when the application starts.

    application.properties

    spring.redis.host=redis
    spring.redis.port=6379
    

    RedisConfig

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    
    @Configuration
    public class RedisConfig {
    
        @Value("${spring.redis.host}")
        private String redisHost;
    
        @Value("${spring.redis.port}")
        private int redisPort;
    
        @Bean
        public LettuceConnectionFactory redisConnectionFactory() {
            return new LettuceConnectionFactory(new RedisStandaloneConfiguration(redisHost, redisPort));
        }
    }