Search code examples
dockerdocker-composedockerfileethereumgo-ethereum

Unable to get env variable from docker compose in dockerfile


I am working on dockerfile for ethereum chain deployment. I finished dockerfile with hardcoded parameters, but when I reference this parameters as environment variables some unclear issues have been rose.

Here is a Dockerfile:

FROM ethereum/client-go:v1.10.1

COPY ./chain/accounts/swap.ethash.genesis.json /tmp

COPY ./chain/accounts/boot.key /tmp

RUN mkdir -p /tmp/keystore

COPY ./chain/accounts/keystore/${NODE_ACCOUNT_PWD_FILENAME} /tmp/keystore

RUN geth --datadir /tmp init /tmp/swap.ethash.genesis.json \
    && rm -f ~/.ethereum/geth/nodekey 

COPY ./test-pwd.sh /tmp 
RUN chmod +x ./tmp/test-pwd.sh && ./tmp/test-pwd.sh

RUN geth --unlock 0x367103555b34Eb9a46D92833e7293D540bFd7143 --password /tmp/pwd.txt --keystore /tmp/keystore

ENTRYPOINT ["geth"]

I would like to avoid hardcoded parameters and put them into .env file which is referenced under the docker compose:

version: '3.8'

services:
  geth-bootnode:
    hostname: geth-bootnode
    env_file:
      - .env
    image: geth-client
    build:
      context: .
      args:
        - ACCOUNT_PASSWORD=${ACCOUNT_PASSWORD}
        - NODE_ACCOUNT_PWD_FILENAME=${NODE_1_ACCOUNT_PWD_FILENAME}
        - NODE_ACCOUNT_PWD=${NODE_1_ACCOUNT_PWD}
        - NODE_ACCOUNT=${NODE_1_ACCOUNT}
    command:
      --nodekeyhex="c26d705bd5933bc2be72813f1b74f140aa6b3726d2a71a43b163a5c084e9dcb4"
      --nodiscover
      --ipcdisable
      --networkid=${NETWORK_ID}
      --netrestrict="172.16.254.0/28"
    networks:
      priv-eth-net:
networks:
  priv-eth-net:
    driver: bridge
    ipam:
      config:
      - subnet: 172.16.254.0/28

Reference this env var, e.g. geth --unlock ${NODE_ACCOUNT}, gives an error of missed parameter:

> [9/9] RUN geth --unlock ${NODE_ACCOUNT} --password /tmp/pwd.txt --keystore /tmp/keystore:
#0 0.397 invalid command: "/tmp/pwd.txt"

Some users mentioned it should be converted into ENV variable to be available under Runtime, but it gives similar error.

Similar issue happened with ENV var for a password and this is a reason why preparation of pwd.txt was wrapped into a shell script. .env file parameters names and actual values are double checked.

In my perspective, reference variables like ${NODE_ACCOUNT} and ${NODE_PWD} should be enough; if the runtime visibility scope is an issue, then ENV node_acc=${NODE_ACCOUNT} and ENV node_pwd=${NODE_PWD} should work. However, neither any of this options doesn't give me successful account unlock and terminate container with an error. Do I miss something here?


Solution

  • The final solution would look like this:

    FROM ethereum/client-go:v1.10.1
    
    ARG NODE_ACCOUNT
    ARG NODE_ACCOUNT_PWD
    
    COPY ./chain/accounts/swap.ethash.genesis.json /tmp
    
    COPY ./chain/accounts/boot.key /tmp
    
    RUN mkdir -p /tmp/keystore
    
    COPY ./chain/accounts/keystore/${NODE_ACCOUNT_PWD_FILENAME} /tmp/keystore
    
    RUN geth --datadir /tmp init /tmp/swap.ethash.genesis.json \
        && rm -f ~/.ethereum/geth/nodekey 
    
    RUN echo ${NODE_ACCOUNT_PWD} >> /tmp/pwd.txt
    
    COPY ./chain/accounts/entrypoint.sh /tmp
    
    RUN chmod +x ./tmp/entrypoint.sh
    
    ENV NODE_ACCOUNT=${NODE_ACCOUNT}
    
    # This way entrypoint usage would ignore OS signals sent the container. That might cause some issues
    # Is it root cause of issue to unable 'geth attach <ip address>'?
    ENTRYPOINT ./tmp/entrypoint.sh ${NODE_ACCOUNT} 
    

    ENV vars from docker-compose.yaml should be mirrored in a Dockerfile. ARG serves as an entrypoint variable for ENV variables. Thank you, @larsks, for point out on this!