如何使用 sh 打开 Docker 容器中的端口?

How to open port in Docker container with sh?

我在 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}

初始化-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 "$@"

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

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/1692550316@5ac2447d)

那么可以使用这种方法吗?

更新:如果有意义 'ethereum/client-go' Docker 图片在 golang:1.10-alpine as builder 图片

based

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

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}

初始化-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 "$@"

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

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

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

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

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

#>docker push xyz/custom-client-go

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