Search code examples
chainlink

Setting Chainlink Keystore Password in Docker-Compose


I'm trying to spin up a chainlink node using docker-compose and am running into this error:

error authenticating keystore: No password provided

I didn't see an environment variable to set this password. The tutorial (https://docs.chain.link/docs/running-a-chainlink-node/#set-the-remote-database_url-config) uses docker and exec directly into the container to set this based on a prompt. Anyone know a solution that doesn't require manual input when bringing up the container?

Here is my docker-compose.yml

version: '2.1'

x-logging:
  &default-logging
  options:
    max-file: '1'
    compress: 'false'
  driver: local

networks:
  monitor-net:
    driver: bridge

volumes:
    postgres_data: {}

services:
  chainlink-node:
    image: smartcontract/chainlink:0.10.8
    container_name: chainlink
    depends_on:
      - postgres
    environment:
      LOG_LEVEL: ${LOG_LEVEL}
      ETH_CHAIN_ID: ${ETH_CHAIN_ID}
      ETH_URL: ${ETH_URL}
      ETH_HTTP_URL: ${ETH_HTTP_URL}
      DATABASE_URL: postgresql://${DB_USER}:${DB_PW}@postgres:5432/${CHAINLINK_DB_NAME}
      MIN_OUTGOING_CONFIRMATIONS: "${MIN_OUTGOING_CONFIRMATIONS}"
      LINK_CONTRACT_ADDRESS: "${LINK_CONTRACT_ADDRESS}"
      CHAINLINK_TLS_PORT: "${CHAINLINK_TLS_PORT}"
      SECURE_COOKIES: "${SECURE_COOKIES}"
      GAS_UPDATER_ENABLED: "${GAS_UPDATER_ENABLED}"
      ALLOW_ORIGINS: "${ALLOW_ORIGINS}"
    expose:
      - 6688
    ports:
      - "6688:6688"
networks:
      - monitor-net
    restart: unless-stopped
    logging: *default-logging
  postgres:
    image: postgres:13.1
    container_name: postgres
    command: ["postgres", "-c", "max_connections=1000", "-c", "shared_buffers=256MB", "-c", "shared_preload_libraries=pg_stat_statements"]
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${DB_USER:-username}
      POSTGRES_PASSWORD: ${DB_PW:-password}
      POSTGRES_DB: ${CHAINLINK_DB_NAME:-chainlink-db}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - monitor-net
    expose:
 - 5432
    logging: *default-logging

And my .env file

DB_USER=<username>
DB_PW=<password>
CHAINLINK_DB_NAME=chainlink-db
LOG_LEVEL=debug
ETH_CHAIN_ID=4
ETH_URL=wss://rinkeby.infura.io/ws/v3/<>
ETH_HTTP_URL=https://rinkeby.infura.io/v3/<>
MIN_OUTGOING_CONFIRMATIONS=2
LINK_CONTRACT_ADDRESS=0x01BE23585060835E02B77ef475b0Cc51aA1e0709
CHAINLINK_TLS_PORT=0
SECURE_COOKIES=false
GAS_UPDATER_ENABLED=true
ALLOW_ORIGINS=*\" > ~/chainlink-rinkeby/.env

EDIT:

After some messing around I found a configuration for the docker-compose.yml file which allowed the chainlink container to start in a stable state.

services:
  chainlink-node:
    image: smartcontract/chainlink:0.10.8
    container_name: chainlink
    command: ["local", "n", "-p", "/chainlink/password", "-a", "/chainlink/api"]
    volumes:
      - ./passwords:/chainlink

Solution

  • The chainlink node requires different credentials to initialize. These are the key-store password, which is needed to create and access the network-related wallets (primary & emergency) and the API-credentails with which you can reach the graphical user interface (GUI) of the Chainlink node.

    These credentials are queried during initialization and entered manually when the Chainlink node is started for the first time. If the chainlink node is started in detached mode (-d flag) or as a docker-compose file, these credentials must be mounted as volumes and added as arguments/commands.

    With Docker-compose you have different ways to integrate those credentials in order to enable initialisation. I would recommend the following steps:

    1. create the file keystore password: Please ensure that you have minimum 3 capital letters
    echo "my_wallet_password" > ~/.chainlink-rinkeby/.password
    
    1. create the API credentials:
    echo "[email protected]" > ~/.chainlink-rinkeby/.api
    
    echo "password" >> ~/.chainlink-rinkeby/.api
    
    1. adjust the docker-compose.yml:

    You now need to mount both files (.api & .password) by adding .chainlink-rinkeby as a volume and set those credentials as arguments (command:)

    chainlink-node:
        image: smartcontract/chainlink:0.10.8
        container_name: chainlink
        command: ["-p /chainlink/.password","-a /chainlink/.api"]
        volumes:
          - ~/.chainlink-rinkeby:/chainlink
        depends_on:
          - postgres
        environment:
          LOG_LEVEL: ${LOG_LEVEL}
          ETH_CHAIN_ID: ${ETH_CHAIN_ID}
          ETH_URL: ${ETH_URL}
          ETH_HTTP_URL: ${ETH_HTTP_URL}
          DATABASE_URL: postgresql://${DB_USER}:${DB_PW}@postgres:5432/${CHAINLINK_DB_NAME}
          MIN_OUTGOING_CONFIRMATIONS: "${MIN_OUTGOING_CONFIRMATIONS}"
          LINK_CONTRACT_ADDRESS: "${LINK_CONTRACT_ADDRESS}"
          CHAINLINK_TLS_PORT: "${CHAINLINK_TLS_PORT}"
          SECURE_COOKIES: "${SECURE_COOKIES}"
          GAS_UPDATER_ENABLED: "${GAS_UPDATER_ENABLED}"
          ALLOW_ORIGINS: "${ALLOW_ORIGINS}"
        expose:
          - 6688
        ports:
          - "6688:6688"
    

    In addition you find here the official Chainlink documentation related to this topic: https://docs.chain.link/docs/miscellaneous/