Miningcore Guide


Miningcore is a modern mining pool software that you can use to solo mine many cryptocurrencies to nodes on your local network, or even run your own publicly accessible pool. In this guide, we'll cover getting Miningcore setup and running, as well as how to update it, as there are constantly new algorithms being added to it.

NOTE: This walkthrough assumes you are running a system on Ubuntu Linux and are already connected to a shell window either directly on the system or via a SSH session and that you are also already running a Postgres database server. If you need to setup Postgres, I have a Guide for that here

  1. We'll start by first making sure we have our packages up to date and then install docker and git

    sudo apt update -y
    sudo apt install docker.io git -y

  2. Next, we'll create folders to store our miningcore application files and also pool config file in. I'll be placing this at /apps and /data paths. You may want to replace those paths if you have multiple drives with different mount points.

    sudo mkdir -p /data/.miningcore
    sudo mkdir -p /apps

  3. Now, we'll clone the Miningcore Github repository to a local folder and then move into that folder

    sudo git clone https://github.com/xiaolin1579/miningcore.git /apps/miningcore
    cd /apps/miningcore/

  4. Now that we have miningcore downloaded, we are going to compile it into a local docker image. We are using docker here because the Miningcore crypotographic source code files don't play nicely with Ubuntu 24.04 and higher. Compiling this way with Docker will allow use to run it on any Linux distrubtion version that supports docker. Please be patient as this step may take 15-20 minutes or more depending on your hardware.

    sudo docker build -t miningcore .


  5. We now need to create a baseline miningcore file and download the coins list. Ultimately, this is where we will put our individual coin configuration of cryptocurrencies that we want to mine, but for know why will do just the baseline setup

    sudo wget https://raw.githubusercontent.com/xiaolin1579/miningcore/refs/heads/dev/src/Miningcore/coins.json -O /data/.miningcore/coins.json
    sudo nano /data/.miningcore/config.json
    Paste the following text and then do ctrl+x followed by Y and then press the Enter key. This will save and exit. Adjust any of these settings as you need to and take note of the Postgres host, database name, username, and password. In the next step we will be creating this database and the login account for it
    {
      "logging": {
        "level": "info",
        "enableConsoleLog": true,
        "enableConsoleColors": true,
        "logFile": "",
        "apiLogFile": "",
        "logBaseDirectory": "",
        "perPoolLogFile": true
      },
      "banning": {
        "manager": "Integrated",
        "banOnJunkReceive": true,
        "banOnInvalidShares": false
      },
      "notifications": {
        "enabled": false,
        "email": {
          "host": "smtp.example.com",
          "port": 587,
          "user": "user",
          "password": "password",
          "fromAddress": "info@yourpool.org",
          "fromName": "support"
        },
        "admin": {
          "enabled": false,
          "emailAddress": "user@example.com",
          "notifyBlockFound": true
        }
      },
      "persistence": {
        "postgres": {
          "host": "127.0.0.1",
          "port": 5432,
          "user": "miningcore",
          "password": "P@ssw0rd",
          "database": "miningcore"
        }
      },
      "paymentProcessing": {
        "enabled": true,
        "interval": 600,
        "shareRecoveryFile": "recovered-shares.txt",
        "coinbaseString": "Mined by Retro Mike Tech"
      },
      "api": {
        "enabled": true,
        "listenAddress": "*",
        "port": 4000,
        "metricsIpWhitelist": [],
        "rateLimiting": {
          "disabled": true,
          "rules": [
            {
              "Endpoint": "*",
              "Period": "1s",
              "Limit": 5
            }
          ],
          "ipWhitelist": [
            ""
          ]
        }
      },
      "pools": []
    }
  6. Navigate to your PGAdmin Web URL and login, login, . Populate with the following details:
    1. Right click on your Postgres server
    2. Select Create -> Login/Group Role
    3. On the General Tab, populate the Name field with: miningcore (or with whatever you set in the config file earlier)
    4. On the Definition Tab, populate the Password field with: P@ssw0rd (or with whatever you set in the config file earlier)
    5. On the Privileges Tab, toggle on "Can login?"
    6. Click Save
    7. Right click on your Postgres server
    8. Select Create -> Database
    9. On the General Tab, populate the Database field with: miningcore (or with whatever you set in the config file earlier)
    10. On the General Tab, change the Owner to "miningcore" (or whichever name you chose when creating the login)
    11. Click Save
    12. In the Object explorer tree view, expand the Postgres Server
    13. Expand Databases
    14. Expand the miningcore database
    15. Right click on the miningcore database
    16. Select CREATE Script
    17. Clear all of the contents of the query window and paste in the following CREATE Script and press the F5 key to execute it. This creates the Miningcore database schema

      SET ROLE miningcore;
      
      CREATE TABLE shares
      (
          poolid TEXT NOT NULL,
          blockheight BIGINT NOT NULL,
          difficulty DOUBLE PRECISION NOT NULL,
          networkdifficulty DOUBLE PRECISION NOT NULL,
          miner TEXT NOT NULL,
          worker TEXT NULL,
          useragent TEXT NULL,
          ipaddress TEXT NOT NULL,
          source TEXT NULL,
          created TIMESTAMPTZ NOT NULL
      );
      
      CREATE INDEX IDX_SHARES_POOL_MINER on shares(poolid, miner);
      CREATE INDEX IDX_SHARES_POOL_CREATED ON shares(poolid, created);
      CREATE INDEX IDX_SHARES_POOL_MINER_DIFFICULTY on shares(poolid, miner, difficulty);
      
      CREATE TABLE blocks
      (
          id BIGSERIAL NOT NULL PRIMARY KEY,
          poolid TEXT NOT NULL,
          blockheight BIGINT NOT NULL,
          networkdifficulty DOUBLE PRECISION NOT NULL,
          status TEXT NOT NULL,
          type TEXT NULL,
          confirmationprogress FLOAT NOT NULL DEFAULT 0,
          effort FLOAT NULL,
              minereffort FLOAT NULL,
          transactionconfirmationdata TEXT NOT NULL,
          miner TEXT NULL,
          reward decimal(28,12) NULL,
          source TEXT NULL,
          hash TEXT NULL,
          created TIMESTAMPTZ NOT NULL
      );
      
      CREATE INDEX IDX_BLOCKS_POOL_BLOCK_STATUS on blocks(poolid, blockheight, status);
      CREATE INDEX IDX_BLOCKS_POOL_BLOCK_TYPE on blocks(poolid, blockheight, type);
      
      CREATE TABLE balances
      (
          poolid TEXT NOT NULL,
          address TEXT NOT NULL,
          amount decimal(28,12) NOT NULL DEFAULT 0,
          created TIMESTAMPTZ NOT NULL,
          updated TIMESTAMPTZ NOT NULL,
      
          primary key(poolid, address)
      );
      
      CREATE TABLE balance_changes
      (
          id BIGSERIAL NOT NULL PRIMARY KEY,
          poolid TEXT NOT NULL,
          address TEXT NOT NULL,
          amount decimal(28,12) NOT NULL DEFAULT 0,
          usage TEXT NULL,
          tags text[] NULL,
          created TIMESTAMPTZ NOT NULL
      );
      
      CREATE INDEX IDX_BALANCE_CHANGES_POOL_ADDRESS_CREATED on balance_changes(poolid, address, created desc);
      CREATE INDEX IDX_BALANCE_CHANGES_POOL_TAGS on balance_changes USING gin (tags);
      
      CREATE TABLE miner_settings
      (
          poolid TEXT NOT NULL,
          address TEXT NOT NULL,
          paymentthreshold decimal(28,12) NOT NULL,
          created TIMESTAMPTZ NOT NULL,
          updated TIMESTAMPTZ NOT NULL,
      
          primary key(poolid, address)
      );
      
      CREATE TABLE payments
      (
          id BIGSERIAL NOT NULL PRIMARY KEY,
          poolid TEXT NOT NULL,
          coin TEXT NOT NULL,
          address TEXT NOT NULL,
          amount decimal(28,12) NOT NULL,
          transactionconfirmationdata TEXT NOT NULL,
          created TIMESTAMPTZ NOT NULL
      );
      
      CREATE INDEX IDX_PAYMENTS_POOL_COIN_WALLET on payments(poolid, coin, address);
      
      CREATE TABLE poolstats
      (
          id BIGSERIAL NOT NULL PRIMARY KEY,
          poolid TEXT NOT NULL,
          connectedminers INT NOT NULL DEFAULT 0,
          poolhashrate DOUBLE PRECISION NOT NULL DEFAULT 0,
          sharespersecond DOUBLE PRECISION NOT NULL DEFAULT 0,
          networkhashrate DOUBLE PRECISION NOT NULL DEFAULT 0,
          networkdifficulty DOUBLE PRECISION NOT NULL DEFAULT 0,
          lastnetworkblocktime TIMESTAMPTZ NULL,
          blockheight BIGINT NOT NULL DEFAULT 0,
          connectedpeers INT NOT NULL DEFAULT 0,
          created TIMESTAMPTZ NOT NULL
      );
      
      CREATE INDEX IDX_POOLSTATS_POOL_CREATED on poolstats(poolid, created);
      
      CREATE TABLE minerstats
      (
          id BIGSERIAL NOT NULL PRIMARY KEY,
          poolid TEXT NOT NULL,
          miner TEXT NOT NULL,
          worker TEXT NOT NULL,
          hashrate DOUBLE PRECISION NOT NULL DEFAULT 0,
          sharespersecond DOUBLE PRECISION NOT NULL DEFAULT 0,
          created TIMESTAMPTZ NOT NULL
      );
      
      CREATE INDEX IDX_MINERSTATS_POOL_CREATED on minerstats(poolid, created);
      CREATE INDEX IDX_MINERSTATS_POOL_MINER_CREATED on minerstats(poolid, miner, created);
      CREATE INDEX IDX_MINERSTATS_POOL_MINER_WORKER_CREATED_HASHRATE on minerstats(poolid,miner,worker,created desc,hashrate);


  7. Now we are able to test run our miningcore instance. Hop back on over to your terminal session and run the following:

    sudo docker run --rm --network host -v /data/.miningcore/coins.json:/app/coins.json -v /data/.miningcore/config.json:/app/config.json miningcore
    You should see a message that there are No Pools Enabled. This is because we haven't set up any coins yet (we will do that in the next guide), but now lets set it up so it will auto start itself.
    sudo docker run -d --name miningcore --restart always --log-opt max-size=10m --network host -v /data/.miningcore/coins.json:/app/coins.json -v /data/.miningcore/config.json:/app/config.json miningcore

  8. Congrats, you now have Miningcore setup and just need to add your first pool, which we will cover in the next and future guides. If you find youself wanting to update to the latest version of Miningcore at some point in the future, you can run these commands:

    sudo rm /data/.miningcore/coins.json
    sudo wget https://raw.githubusercontent.com/xiaolin1579/miningcore/refs/heads/dev/src/Miningcore/coins.json -O /data/.miningcore/coins.json
    cd /apps/miningcore
    sudo git pull
    sudo docker build -t miningcore .
    docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --run-once miningcore

  9. The last step is to setup the Web UI for Miningcore. One single command will get it up and running for you. Just replace "192.168.1.100" with the IP address of your system you installed Miningcore on. If you are going to host over the internet, you can set the STRATUM_HOST param to your domain name or public IP address

    sudo docker run -d -p 80:8080 --name miningcore-webui --restart always --log-opt max-size=10m -e API_BASE_URL=http://192.168.1.100:4000/api -e STRATUM_HOST=192.168.1.100 -e POOL_NAME="Self-Hosted Mining Pool" theretromike/miningcorewebui

  10. You can now navigate to your IP address in a web browser to access the web ui. You won't see any coins listed until you setup some which we'll cover in upcoming Guides
    i.e., http://192.168.1.100


  11. You may want to also configure watchtower. Anytime I update the Web UI, watchtower can automatically update it, as well as update any other hosted containers (only applies to those hosted on dockerhub and not ones you compiled locally)

    sudo docker run -d --name watchtower --restart always --log-opt max-size=10m -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower


If you found this guide valueable, please consider donating to help me continue to create similar guides

Cryptocurrency & Bitcoin donation button by NOWPayments