Docker MongoDB — сокет открытия исключения из контейнерного приложения Spring Boot

По сути, у меня есть приложение Spring Boot (тестовый сервис). При запуске вне контейнера он может подключаться к обоим моим экземплярам MongoDB (неконтейнерным и контейнеризированным). Когда я запускаю приложение из контейнера, я получаю исключение.

Что не имеет смысла, так это то, что когда я врезаюсь в контейнер, в котором работает тестовая служба, я могу пропинговать контейнерную MongoDB.

Это сводит меня с ума, и я, вероятно, делаю что-то глупое. Вот копирование и вставка соответствующих фрагментов. Пожалуйста помоги...

трассировки стека

test-service  | 2023-04-15 01:31:14.099  INFO 1 --- [}-mongodb:27018] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server mongodb:27018
test-service  | 
test-service  | com.mongodb.MongoSocketOpenException: Exception opening socket
test-service  |        at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:70) ~[mongodb-driver-core-4.6.1.jar:na]
test-service  |        at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:180) ~[mongodb-driver-core-4.6.1.jar:na]
test-service  |        at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.lookupServerDescription(DefaultServerMonitor.java:193) ~[mongodb-driver-core-4.6.1.jar:na]
test-service  |        at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:157) ~[mongodb-driver-core-4.6.1.jar:na]
test-service  |        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
test-service  | Caused by: java.net.ConnectException: Connection refused: mongodb:27018
test-service  |        at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
test-service  |        at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
test-service  |        at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) ~[na:na]
test-service  |        at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597) ~[na:na]
test-service  |        at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
test-service  |        at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
test-service  |        at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:107) ~[mongodb-driver-core-4.6.1.jar:na]
test-service  |        at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:79) ~[mongodb-driver-core-4.6.1.jar:na]
test-service  |        at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:65) ~[mongodb-driver-core-4.6.1.jar:na]
test-service  |        ... 4 common frames omitted

докер-compose.yml

version: "3"
services:
  mongodb:
    image: mongo:6.0.5
    container_name: mongodb
    volumes:
      - mongodb:/data/db
    ports:
      - "27018:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: admin
      MONGO_INITDB_DATABASE: test-service
    platform: linux/arm64
  test-service:
    image: test-service:0.1.0
    container_name: test-service
    volumes:
      - $HOME/config/keystore:/var/keystore
    ports:
      - 8083:8083
    environment:
      MONGO_HOST: mongodb
      MONGO_PORT: 27018
      MONGO_USER: admin
      MONGO_PASSWORD: admin
      MONGO_AUTH_DB: admin
      KEYSTORE_PATH: /var/keystore/dev-env-cert.p12
    platform: linux/arm64
    depends_on:
      - mongodb
volumes:
  mongodb: {}

приложение.свойства

mongodb.host=${MONGO_HOST:localhost}
mongodb.port=${MONGO_PORT:27017}
mongodb.database=test-service
mongodb.authentication-database=${MONGO_AUTH_DB:admin}
mongodb.username=${MONGO_USER:admin}
mongodb.password=${MONGO_PASSWORD:admin}

Конфигурация Mongo (код Java) Я пробовал возиться с разными способами настройки соединения MongoDB, это мой последний...

@Configuration
public class MongoConfig extends AbstractMongoClientConfiguration {
    @Value("${mongodb.host}")
    private String dbHost;
    @Value("${mongodb.port}")
    private String dbPort;
    @Value("${mongodb.authentication-database}")
    private String dbAuthDb;
    @Value("${mongodb.username}")
    private String dbUsername;
    @Value("${mongodb.password}")
    private String dbPassword;
    @Value("${mongodb.database}")
    private String dbName;

    @Override
    protected String getDatabaseName() {
        return dbName;
    }

    @Override
    protected String getMappingBasePackage() {
        return "com.test.model";
    }

    @Override
    public MongoClient mongoClient() {
        MongoClientSettings settings = MongoClientSettings
            .builder()
            .applyConnectionString(new ConnectionString("mongodb://" + dbHost + ":" 
                + dbPort + "/" + dbName))
            .credential(MongoCredential.createScramSha256Credential(dbUsername, 
                dbAuthDb, dbPassword.toCharArray()))
            .applicationName(dbName)
            .build();
        MongoClient client = MongoClients.create(settings);

        return client;
    }
}

РЕДАКТИРОВАТЬ

Я хочу упомянуть, что я также проверил базу данных администратора контейнера, попытался предоставить дополнительные роли и протестировал с другим «тестовым» пользователем, но все равно не повезло.

admin> db.getUsers()
{
  users: [
    {
      _id: 'admin.admin',
      userId: new UUID("8730bf38-301c-4123-a8a3-1c651d7b1e4e"),
      user: 'admin',
      db: 'admin',
      roles: [
        { role: 'dbOwner', db: 'test-service' },
        { role: 'root', db: 'admin' }
      ],
      mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
    },
    {
      _id: 'admin.test',
      userId: new UUID("fb16d8e3-537b-4f67-a6fc-2b22faf6f242"),
      user: 'test',
      db: 'admin',
      roles: [ { role: 'dbOwner', db: 'test-service' } ],
      mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
    }
  ],
  ok: 1
}

Мое предположение, что ваша проблема в функции mongoClient. Попробуйте вернуть жестко заданный URI. как видите Exception in monitor thread while connecting to server mongodb:27018 приложение не идет в localhost

4EACH 15.04.2023 05:10

@4EACH Хорошо, я попробую, когда вернусь сегодня вечером. Хотя я не понимаю, почему я хочу, чтобы он указывал на localhost, когда mongodb — это имя службы контейнера MongoDB.

Molasses 15.04.2023 05:13
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я понял, что не так, и да, я был глуп...

Проблема была только в порте. Если вы посмотрите на мой файл компоновки, в службе mongodb у меня есть это

ports:
  - "27018:27017"

и моя служба тестового обслуживания имеет это

environment:
  MONGO_HOST: mongodb
  MONGO_PORT: 27018

Служба mongodb предоставляет порт 27017 в среде контейнера, а порт 27018 — для среды хоста. служба test-service находится в среде контейнера, поэтому мне следовало использовать 27017. Как только я это изменил, все заработало.

Кредит на этот другой ответ. Я нашел это, когда вчера гуглил...

Другие вопросы по теме