Search code examples
springdockerspring-bootdocker-composedocker-swarm

Docker Stack "configs" with Spring Boot 2


This is a fairly simple question I think, however I haven't seen too many examples or really anything that explains the connection between using docker configs (v 3.3+) and loading that config into Spring Boot for reference.

sample docker-stack.yml

version: '3.3'
services:
  test-service:
    image: myrepo/test-service:1.0.0
    configs:
      - service-config
    networks:
      - test-network
configs:
  service-config:
    external:true

networks:
  test-network:

sample swarm "service-config".

I entered this as a new "configs" entry in Portainer.

services:
  test-service:
    key1: sample value
    key2: sample two

What I'm trying to do it load this config into Spring such that I can reference the values from this config within a component.

Either via @ConfigurationProperties

@ConfigurationProperties("services.test-service")
public MyBeanName myBean() { return new MyBeanName(); }

or via the @Value:

@Value("${services.test-service.key1}")
private String key1;

How can I get this docker "configs" configuration loaded into Spring. This has got to be simple enough.. lol. Thanks!


Solution

  • Sorry for the delay in responding to this question, or at least posting the solution...

    It took a bit more digging into how configs work with docker, however as it turns out you need to specify a target for the "config" held within your "configs" entries in your swarm cluster, and then map it into your container, and load as an external config to your spring application. In my case, I didn't want to override the the application.yml in my spring boot app, just wanted to pick up additional configs. So I went with the setting:

    --spring.config.additional-location=file:/configs/sample-config.yml
    

    Lets say I create a docker configs entry with the name "sample-config" and having the following data:

    Configs Entry => "sample-config" 
    
    services:
      test-service:
        key1: sample value
        key2: sample two
    

    Then on my compose/stack file I need to reference the "configs" entry, and provide a target file that corresponds to the file I specified in my "spring.config.additional-location" setting.

    version: '3.3'
    
    services:
    
      test-service:
        image: myrepo/test-service:1.0.0
        configs:
          - source: sample-config
            target: /configs/sample-config.yml
        networks:
          - test-network
    
    configs:
      sample-config:
        external:true
    
    networks:
      test-network:
    

    In my Dockerfile then, I'd specify the following to essentially load the "sample-config" configs entry when starting the jar/app:

    ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar", "--spring.config.additional-location=file:/configs/sample-config.yml"]
    

    This allowed me to access the configuration entries, loaded externally to my spring application, with the @Value and @ConfigurationProperties annotations.