#docker #docker-compose #dockerfile
#docker #docker-compose #dockerfile
Вопрос:
Я буквально не могу объяснить вам, как трудно мне разобраться в желании создать контейнер docker, в котором будет запущен docker, на котором будет запущен мой веб-сервер, который будет иметь доступ к моему внешнему хосту docker.
Итак, что я знаю на данный момент:
- У меня есть dockerfile, который при выполнении вне docker compose и тестировании с помощью я вижу, что он подключается к моему хост-демону docker!
- Затем я перехожу к своей настройке docker-compose и понимаю, что у меня, должно быть, проблема из-за сети, которая возникает внутри файлов docker-compose. Но у меня 0 сетевых возможностей docker-compose, поэтому я спрашиваю, как я могу также подключить свой контейнер к сети по умолчанию один раз внутри этой настройки?
Мой скрипт Bash (точка входа):
#!/bin/sh
set -e
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- docker "$@"
fi
# if our command is a valid Docker subcommand, let's invoke it through Docker instead
# (this allows for "docker run docker ps", etc)
if docker help "$1" > /dev/null 2>amp;1; then
set -- docker "$@"
fi
# if we have "--link some-docker:docker" and not DOCKER_HOST, let's set DOCKER_HOST automatically
if [ -z "$DOCKER_HOST" -a "$DOCKER_PORT_2375_TCP" ]; then
export DOCKER_HOST='tcp://docker:2375'
fi
if [ "$1" = 'dockerd' ]; then
cat >amp;2 <<-'EOW'
📎 Hey there! It looks like you're trying to run a Docker daemon.
You probably should use the "dind" image variant instead, something like:
docker run --privileged --name some-overlay-docker -d docker:stable-dind --storage-driver=overlay
See https://hub.docker.com/_/docker/ for more documentation and usage examples.
EOW
sleep 3
fi
docker version
dotnet ApiServer.dll
Мой файл compose:
version: '3.4'
services:
apiserver:
image: ${DOCKER_REGISTRY-}apiserver
build:
context: ./
dockerfile: ./ApiServer/Dockerfile
volumes:
- /var/run/docker.sock:/tmp/docker.sock
Наконец, мой dockerfile: (На самом деле это не должно быть нужно, но вот оно)
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-alpine AS base
COPY /ApiServer/modprobe.sh /usr/local/bin/modprobe
COPY /ApiServer/docker-entrypoint.sh /usr/local/bin/
RUN dos2unix -u /usr/local/bin/modprobe
RUN dos2unix -u /usr/local/bin/docker-entrypoint.sh
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-alpine AS build
WORKDIR /src
COPY ["ApiServer/ApiServer.csproj", "ApiServer/"]
COPY ["SharedLibs/SharedLibs.csproj", "SharedLibs/"]
RUN dotnet restore "ApiServer/ApiServer.csproj"
COPY . .
WORKDIR "/src/ApiServer"
RUN dotnet build "ApiServer.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "ApiServer.csproj" -c Release -o /app
FROM base AS docker
## Docker Setup
RUN apk add --no-cache
ca-certificates
# set up nsswitch.conf for Go's "netgo" implementation (which Docker explicitly uses)
# - https://github.com/docker/docker-ce/blob/v17.09.0-ce/components/engine/hack/make.sh#L149
# - https://github.com/golang/go/blob/go1.9.1/src/net/conf.go#L194-L275
# - docker run --rm debian:stretch grep '^hosts:' /etc/nsswitch.conf
RUN [ ! -e /etc/nsswitch.conf ] amp;amp; echo 'hosts: files dns' > /etc/nsswitch.conf
ENV DOCKER_CHANNEL stable
ENV DOCKER_VERSION 18.09.3
# TODO ENV DOCKER_SHA256
# https://github.com/docker/docker-ce/blob/5b073ee2cf564edee5adca05eee574142f7627bb/components/packaging/static/hash_files !!
# (no SHA file artifacts on download.docker.com yet as of 2017-06-07 though)
RUN set -eux;
# this "case" statement is generated via "update.sh"
apkArch="$(apk --print-arch)";
case "$apkArch" in
x86_64) dockerArch='x86_64' ;;
armhf) dockerArch='armel' ;;
aarch64) dockerArch='aarch64' ;;
ppc64le) dockerArch='ppc64le' ;;
s390x) dockerArch='s390x' ;;
*) echo >amp;2 "error: unsupported architecture ($apkArch)"; exit 1 ;;
esac;
if ! wget -O docker.tgz "https://download.docker.com/linux/static/${DOCKER_CHANNEL}/${dockerArch}/docker-${DOCKER_VERSION}.tgz"; then
echo >amp;2 "error: failed to download 'docker-${DOCKER_VERSION}' from '${DOCKER_CHANNEL}' for '${dockerArch}'";
exit 1;
fi;
tar --extract
--file docker.tgz
--strip-components 1
--directory /usr/local/bin/
;
rm docker.tgz;
dockerd --version;
docker --version
FROM docker AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["../usr/local/bin/docker-entrypoint.sh"]
Ответ №1:
Ваш Dockerfile
предоставляет порт 80, но вы не отображаете его в своем docker-compose.yml
файле.
Попробуйте обновить docker-compose-yml
файл следующим образом:
docker-compose-yml
version: '3.4'
services:
apiserver:
image: ${DOCKER_REGISTRY-}apiserver
build:
context: ./
dockerfile: ./ApiServer/Dockerfile
volumes:
- /var/run/docker.sock:/tmp/docker.sock
ports:
- 8080:80
Клавиша ports отобразит порты с вашего хост-компьютера на контейнер. Упрощенный синтаксис:
ports:
- <hostport>:<containerport>
При запуске контейнера с помощью docker-compose docker создаст новую связующую сеть для вашего стека приложений. Контейнеры в этой сети недоступны с хоста, и контейнеры внутри сети также не могут обращаться к хосту. Вот почему вам нужно сопоставление портов — оно сопоставит порт 8080
на хост-компьютере с портом 80
контейнера.
Затем вы можете обратиться к открытой службе в контейнере с помощью http://localhost:8080 с хост-компьютера.
Обновить
Из вашего комментария я понял, что на хосте могут быть запущены другие службы, к которым вы хотите иметь возможность подключаться из контейнера ApiServer, например, из базы данных. Я думаю, есть одно быстрое решение этой проблемы, и это подключение нового контейнера к сети «хост».
Вы можете попробовать обновить свой файл docker-compose.yml до этого:
docker-compose-yml
version: '3.4'
services:
apiserver:
image: ${DOCKER_REGISTRY-}apiserver
build:
context: ./
dockerfile: ./ApiServer/Dockerfile
volumes:
- /var/run/docker.sock:/tmp/docker.sock
ports:
- 8080:80
network_mode: "host"
Результатом этого является то, что при разрешении localhost
и 127.0.0.1
изнутри вашего контейнера вы фактически получите hostmachine. Однако это не сработает, если вы развернете свой контейнер в swarm.
Комментарии:
1. Итак, моя проблема в том, что мой контейнерный apiservice должен иметь возможность подключаться к хост-ОС не через сопоставление, а находиться в той же сети. Это потому, что у моего приложения в конечном итоге будет база данных и тому подобное, и поэтому сейчас оно находится внутри compose. Мой apiservice должен быть подключен к новой мостовой сети и исходной мостовой сети по умолчанию уровня хоста.
2. Если вы получаете конкретную ошибку, пожалуйста, укажите ее.
3. Проблема не в этом: / если я запускаю контейнер вне docker-compose, я получаю то, что ищу. Если я запускаю контейнер с помощью docker-compose, он просто никогда не подключается к моему демону хоста.
4. Какую команду вы используете при запуске без docker-compose?
5. Вы решили эту проблему? Могу ли я что-нибудь сделать, чтобы помочь? Была ли информация / решение полезными?