Привет всем!
Я столкнулся с проблемой при попытке обратиться к контейнеру по его хостнейму и внутреннему порту из другого контейнера, которые находятся в одном и том же файле docker-compose. При использовании httpClient для обращения по адресу hostname:port я получил следующую ошибку:
`System.Net.Http.HttpRequestException: Name or service not known (keycloak:8080) ---> System.Net.Sockets.SocketException (0xFFFDFFFF): Name or service not known`
Вот фрагмент кода, который я использовал для вызова:
<pre><code class="cs">var metadata = _configuration["Authentication:MetadataAddress"]; // http://keycloak:8080/realms/keycloak-auth/.well-known/openid-configuration
using var response = await _httpClient.GetAsync(metadata!);
response.EnsureSuccessStatusCode();
var jsonResponse = await response.Content.ReadAsStringAsync();
Log.Information($"{jsonResponse}\n");
return Ok(jsonResponse);</code></pre>
Файл docker-compose выглядит следующим образом:
<pre><code class="yaml">keycloak:
image: quay.io/keycloak/keycloak:26.0.0
container_name: keycloak
command: start-dev
environment:
- KC_HEALTH_ENABLE=true
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=passwd
volumes:
- ./.containers/identity:/opt/keycloak/data
ports:
- "10001:8080"
post_service:
container_name: post_service
image: post_service
environment:
- ASPNETCORE_ENVIRONMENT=Development
build:
context: .
ports:
- "8082:8080"
networks:
- keycloak_network
- posts_postgres_network
depends_on:
- keycloak
- post_postgres</code></pre>
Буду благодарен за любые советы по решению этой проблемы!
Проблема, с которой вы столкнулись, может быть связана с несколькими факторами. Давайте рассмотрим несколько аспектов, которые могут помочь решить вашу проблему:
1. **Сетевые настройки в Docker Compose**:
Убедитесь, что контейнеры находятся в одной сети, чтобы они могли видеть друг друга по имени. В вашем примере `keycloak` и `post_service` имеют определенные сети, но вы не указали явным образом, в какой сети должен находиться `keycloak`. Добавьте их в одну сеть:
```yaml
networks:
keycloak_network:
driver: bridge
posts_postgres_network:
driver: bridge
services:
keycloak:
...
networks:
- keycloak_network
post_service:
...
networks:
- keycloak_network
- posts_postgres_network
```
2. **Использование правильного URL**:
Убедитесь, что в вашем конфиге вы используете правильный URL. Поскольку Keycloak работает на внутреннем порту 8080, вызывайте его с помощью `http://keycloak:8080/realms/keycloak-auth/.well-known/openid-configuration`.
3. **Проверка порядка запуска**:
Использование `depends_on` гарантирует только порядок запуска, но не гарантирует, что сервис будет готов к приему запросов. Возможно, Keycloak просто еще не запустился, когда ваш `post_service` пытается его вызвать. Для решения этой проблемы вы можете добавить механизм ожидания (например, использовать `wait-for-it.sh` или аналогичный скрипт).
4. **Проверка наличия служебного имени**:
Убедитесь, что внутри вашего контейнера `post_service` вы можете разрешить имя `keycloak`. Вы можете сделать это, запустив временный контейнер с `bash` и используя команду `ping` или `curl` для проверки доступности Keycloak:
```bash
docker-compose run --rm post_service sh -c "ping keycloak"
```
5. **Логи и диагностика**:
Проверьте логи вашего контейнера Keycloak, чтобы убедиться, что он запустился без ошибок. Это можно сделать с помощью команды:
```bash
docker-compose logs keycloak
```
Если после всех этих проверок проблема сохраняется, предоставьте, пожалуйста, дополнительные сведения, такие как логи контейнеров или дополнительные настройки, которые могут быть полезны для диагностики.
Контейнеру keycloak нужно указать в networks хотя бы одну сеть, в которую добавлен post_service. Сейчас они у вас в разных сетях (keycloak в дефолтной для проекта, так как не указана никакая, а post_service только в тех, которые перечислены) и потому друг друга не видят.