Can't use in-line shell in CMD

I’m trying to build a spring boot app with the swarm:

services:
  db:
    image: mysql:5.7
    volumes:
      - mysql_master_data_db:/var/lib/mysql
      - mysql_master_conf:/etc/mysql/conf.d
      - mysql_master_log:/var/log/mysql
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db-password
    deploy:
      mode: replicated
      replicas: 1 # 单实例
      placement:
        constraints: [node.role == manager] # 只允许管理者
    networks:
      - baas_network
    secrets:
      - db-password
    configs:
      - source: mysql-master-conf
        target: /etc/mysql/my.cnf
  backend:
    image: 192.168.1.24:5000/demo:latest
    depends_on:
      - db
    networks:
      - baas_network
    ports:
      - "18887:9797"
    command:
      - --spring.profiles.active=container-image
      - --primary.jdbc.url=jdbc:mysql://db:3306/baas_dev?useSSL=false&characterEncoding=utf8&allowMultiQueries=true&allowPublicKeyRetrieval=true
      - --primary.jdbc.password=$$(</run/secrets/db-password)
      - --primary.jdbc.username=root
      - --vault.uri=http://vault:8200
    secrets:
      - db-password
    deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 5
        window: 120s
secrets:
  db-password:
    file: ./sql/db_password

at line

- --primary.jdbc.password=$$(</run/secrets/db-password)

I expect it to read the password of mysql,and it actually works as I expect on my pc,

$ java -jar demo-0.0.1-SNAPSHOT.jar --primary.jdbc.password=$(</d/cert.cert)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.7.RELEASE)

2022-03-16 17:30:29.197  INFO 2212 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication on DESKTOP-T8UDM03 with PID 2212 (E:\code\Java\demo_\target\demo-0.0.1-SNAPSHOT.jar started by dong in E:\code\Java\demo_\target)
2022-03-16 17:30:29.200  INFO 2212 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
-----BEGIN
2022-03-16 17:30:29.674  INFO 2212 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 0.805 seconds (JVM running for 1.161)

("-----BEGIN CERTIFICATE-----…" is the content of /d/cert.cert)

but while I trying to deploy the stack, it didn’t work


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.7.RELEASE)

2022-03-16 17:15:16.641  INFO 1 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication on 038c2d47d9cd with PID 1 (/opt/service/app.jar started by root in /)
2022-03-16 17:15:16.646  INFO 1 --- [           main] com.example.demo.DemoApplication         : The following profiles are active: container-image
$(</run/secrets/db-password)
2022-03-16 17:15:17.577  INFO 1 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.642 seconds (JVM running for 2.438)

read file command was turn directly to text as $(</run/secrets/db-password)

The command don’t looks like to have any problem

[root@node23 ~]# docker ps -a --no-trunc|grep app
038c2d47d9cd8565e527f55aee3cde3ddb9979732e8d6b15003ef54cf14c5dc4   192.168.1.24:5000/demo:latest@sha256:a480eb4635672326f340954dd048c99d0f5058df848ccd4ef6d7732d583a3dd7                      "java -Djava.security.egd=file:/dev/./urandom -jar /opt/service/app.jar --spring.profiles.active=container-image --primary.jdbc.url=jdbc:mysql://db:3306/baas_dev?useSSL=false&characterEncoding=utf8&allowMultiQueries=true&allowPublicKeyRetrieval=true --primary.jdbc.password=$(</run/secrets/db-password) --primary.jdbc.username=root --vault.uri=http://vault:8200"   23 seconds ago   Exited (0) 19 seconds ago                                                                    baas_backend.1.jhd3acvkmbktebej3h41mi5fp

and I’ve connected the container, /run/secrets/db-password do exist.

What should I do to solve this? Or is there any better way to set the config?

The syntax you want to use is a bash syntax. If the entrypoint defined in your image is not bash, that syntax won’t work. Actually, you probably don’t even have any shell. You can see in the full command that “java” is running directly as the main process in that container.

Possible solutions:

  1. Either your app has a parameter like --primary.jdbc.password_file
  2. or you change the entrypoint to bash and also change the command like this:
    entrypoint:
      - bash
      - -c
    command:
      - java
      - -Djava.security.egd=file:/dev/./urandom
      - -jar
      - /opt/service/app.jar
      - --spring.profiles.active=container-image
      - --primary.jdbc.url=jdbc:mysql://db:3306/baas_dev?useSSL=false&characterEncoding=utf8&allowMultiQueries=true&allowPublicKeyRetrieval=true
      - --primary.jdbc.password=$$(</run/secrets/db-password)
      - --primary.jdbc.username=root
      - --vault.uri=http://vault:8200
    
    It will work only if your container has a bash. I haven’t tested it, so you might have to fix it, but this is the idea

Thanks for your help!
I end up solve this problem by change entrypoint to below:

    entrypoint:
      - bash
      - -c
      - java -Djava.security.egd=file:/dev/./urandom -jar /opt/service/app.jar --primary.jdbc.username=root --vault.uri=http://vault:8200 --spring.profiles.active=container-image --primary.jdbc.password=$$(</run/secrets/db-password) --primary.jdbc.url="jdbc:mysql://db:3306/baas_dev?useSSL=false&characterEncoding=utf8&allowMultiQueries=true&allowPublicKeyRetrieval=true"

use arguments in command cause another error, so I directly write them in entrypoint