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

如何使用sh打开Docker容器中的端口?,docker,docker-compose,port,ethereum,Docker,Docker Compose,Port,Ethereum,我正在Docker容器中运行私有以太坊网络。因为我是战俘,我需要生成DAG,大约需要10分钟。我需要向主机发出信号,它不知怎么地完成了,所以我决定打开一个端口5555。所以在我的init脚本中,我尝试这样做: docker-compose.yml: version: "3" services: eth_miner: image: ethereum/client-go:v1.7.3 ports: - "8545:8545" - "5555:5555"

我正在Docker容器中运行私有以太坊网络。因为我是战俘,我需要生成DAG,大约需要10分钟。我需要向主机发出信号,它不知怎么地完成了,所以我决定打开一个端口5555。所以在我的init脚本中,我尝试这样做:

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}
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 "opening port 5555 to show DAG is ready "
nc -l 5555 &
echo "... done"

echo "running 'geth $@'"
geth "$@"
#!/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 "$@"
如果我将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)
那么,有可能使用这种方法吗


更新:如果“以太坊/客户端go”Docker图像在golang:1.10-alpine as builder图像上有意义,我宁愿使用基于文件的方法。正如您所看到的,docker守护进程打开此端口,即使容器中没有侦听器

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}
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 "opening port 5555 to show DAG is ready "
nc -l 5555 &
echo "... done"

echo "running 'geth $@'"
geth "$@"
#!/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 Push将其推送到docker hub下的docker注册表xyz配置文件

#>docker push xyz/custom-client-go

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

您需要的是从容器到主机的通信?我认为没有简单的方法可以做到这一点。你不能把所有的东西都包装在容器中吗?我认为你最多可以共享一个unix套接字,然后通过这个套接字进行通信。如果可能的话,你可以尝试扩展映像并暴露所需的端口5555?@fly2matrix暴露端口是文档,这并没有改变docker的行为。我喜欢你的方法,尽管它不是我问题的答案,所以+1。事实上,我已经通过解析docker输出解决了这个问题。我没有测试它,因为我已经通过解析docker输出解决了这个问题,但是看起来不错。