【问题标题】:How to open port in Docker container with sh?如何使用 sh 打开 Docker 容器中的端口?
【发布时间】:2018-11-11 07:18:52
【问题描述】:

我正在 Docker 容器中运行私有以太坊网络。由于我在 PoW 上,我需要生成 DAG,大约需要 10 分钟。我需要通知主机它以某种方式完成,所以我决定打开一个端口 5555。所以在我的初始化脚本中我正在尝试这样做:

docker-compose.yml:

version: "3"

services:
  eth_miner:
    image: ethereum/client-go:v1.7.3
    ports:
      - "8545:8545"
      - "5555:5555" # required?
    volumes:
      - ${DATA_DIR}:/root/.ethereum
      - ${HASH_DIR}:/root/.ethash
      - ${GENESIS_FILE}:/opt/genesis.json
      - ${INIT_FILE}:/opt/init-script.sh
    entrypoint: sh /opt/init-script.sh
    command: --rpc --rpcaddr=0.0.0.0 --rpcapi=db,eth,net,web3,personal --rpccorsdomain "*" --nodiscover --cache=512 --verbosity=4 --mine --minerthreads=3 --networkid 15 --etherbase="${ETHERBASE}" --gasprice=${GASPRICE}

init-script.sh:

#!/bin/sh

# check for genesis file
if [ ! -f /root/.ethereum/.init ]; then
    echo "running 'geth init /opt/genesis.json' ..."
    geth init /opt/genesis.json
    touch /root/.ethereum/.init
    echo "... done"
fi

# check for DAG generated
if [ ! -f /root/.ethash/full-R23-0000000000000000 ]; then
    echo "running 'geth makedag 10000 /root/.ethash' ..."
    geth makedag 10000 /root/.ethash
    echo "... done"
fi

echo "opening port 5555 to show DAG is ready "
nc -l 5555 &
echo "... done"

echo "running 'geth $@'"
geth "$@"

如果我将5555:5555 映射留在docker-compose.yml 中,那么它会在启动后立即打开并且不能作为信号:

CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                                                                                  NAMES
808a5453bf57        ethereum/client-go:v1.7.3   "sh /opt/init-script…"   4 seconds ago       Up 11 seconds       0.0.0.0:5555->5555/tcp, 8546/tcp, 0.0.0.0:8545->8545/tcp, 30303/tcp, 30303-30304/udp   7f8680be_eth_miner_1

即使它没有打开(记录到 docker 容器):

/ # netstat -lntu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 127.0.0.11:39593        0.0.0.0:*               LISTEN      
tcp        0      0 0.0.0.0:42033           0.0.0.0:*               LISTEN      
tcp        0      0 :::30303                :::*                    LISTEN      
tcp        0      0 :::8545                 :::*                    LISTEN      
udp        0      0 127.0.0.11:56580        0.0.0.0:*  

如果我从docker-compose.yml 中删除它,那么我显然无法在测试中访问它:

java.lang.IllegalArgumentException: No internal port '5555' for container 'eth_miner': Suppliers.memoize(com.palantir.docker.compose.connection.Container$$Lambda$46/1692550316@5ac2447d)

那么可以用这种方法吗?

更新:如果有意义的话,'ethereum/client-go' Docker 映像是 based on golang:1.10-alpine as builder 映像

【问题讨论】:

  • 你想要的是从容器到主机的通信?
  • 我认为没有简单的方法可以做到这一点。你不能把所有东西都装在容器里吗?
  • 充其量,我认为您可以共享一个 unix 套接字,然后通过此套接字进行通信
  • 如果可以的话,可以试试扩展镜像,暴露需要的端口(5555)?
  • @fly2matrix 暴露端口是文档,它不会改变 docker 的行为。

标签: docker docker-compose port ethereum


【解决方案1】:

我建议通过扩展父镜像来创建您自己的 docker 镜像。
创建自己的 Dockerfile

FROM ethereum/client-go:v1.7.3
EXPOSE 5555

构建它并生成一个新的 docker 镜像

#>docker build -t custom-client-go -t xyz/custom-client-go .

使用 docker push 将其推送到您的 docker 注册表(docker-hub 下的 xyz 配置文件)。

#>docker push xyz/custom-client-go

然后更新 docker-compose.yml (image-name -> xyz/custom-client-go

【讨论】:

  • 没有测试它,因为我通过解析 docker 输出解决了它,但看起来不错。
【解决方案2】:

我宁愿使用基于文件的方法。正如您所见,即使容器中没有侦听器,docker daemon 也会打开此端口。

docker-compose.yml:

version: "3"

services:
  eth_miner:
    image: ethereum/client-go:v1.7.3
    ports:
      - "8545:8545"

    volumes:
      - /var/run/geth:/var/run/geth
      - ${DATA_DIR}:/root/.ethereum
      - ${HASH_DIR}:/root/.ethash
      - ${GENESIS_FILE}:/opt/genesis.json
      - ${INIT_FILE}:/opt/init-script.sh
    entrypoint: sh /opt/init-script.sh
    command: --rpc --rpcaddr=0.0.0.0 --rpcapi=db,eth,net,web3,personal --rpccorsdomain "*" --nodiscover --cache=512 --verbosity=4 --mine --minerthreads=3 --networkid 15 --etherbase="${ETHERBASE}" --gasprice=${GASPRICE}

init-script.sh:

#!/bin/sh

# check for genesis file
if [ ! -f /root/.ethereum/.init ]; then
    echo "running 'geth init /opt/genesis.json' ..."
    geth init /opt/genesis.json
    touch /root/.ethereum/.init
    echo "... done"
fi

# check for DAG generated
if [ ! -f /root/.ethash/full-R23-0000000000000000 ]; then
    echo "running 'geth makedag 10000 /root/.ethash' ..."
    geth makedag 10000 /root/.ethash
    echo "... done"
fi

echo "Writing file to show DAG is ready "
touch /var/run/geth/ready
echo "... done"

# Trap signals to remove /var/run/geth/ready on exit
trap "rm /var/run/geth/ready TERM; exit $?" TERM
trap "rm /var/run/geth/ready EXIT; exit $?" EXIT

echo "running 'geth $@'"
geth "$@"

【讨论】:

  • 我喜欢你的方法,虽然它不是我问题的答案(所以 +1)。实际上我已经通过解析令牌的 docker 输出来解决它。
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 2021-05-13
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多