Mining Ethereum with AMD 6600 XT on Ubuntu Linux

Warning: Ethereum(ETH) will migrate to PoS(Proof of Stake) algorithm in near future, maybe in a year. So jumping into ETH mining now might or might not be profitable. Also, I do NOT condone crypto mining with fossil fuel based energy source!

Prerequisite: A PC running on Ubuntu 20.04 with stable Internet connection

AMD RX 6600 XT is latest addition to the Big Navi product family. Below are the steps I managed to do ETH mining with a 6600 XT on Ubuntu 20.04.

Installing AMD Radeon Pro driver

The driver for 6600 XT can be downloaded here, and the official instructions for installing the pro driver is here. And the exact commands I used to install are below

# after the driver is downloaded, extract it with tar
$ tar -xvf amdgpu-pro-21.30-1290604-ubuntu-20.04.tar.xz
# install the pro version with OpenCL support
$ cd amdgpu-pro-21.30-1290604-ubuntu-20.04/
$ ./amdgpu-pro-install -y --opencl=rocr,legacy
# add current user to video and render group
$ sudo usermod -a -G video $LOGNAME
$ sudo usermod -a -G render $LOGNAME
# reboot to load the driver
$ sudo reboot
# install clinfo to check if OpenCL is enabled properly
$ sudo apt install clinfo
$ clinfo
Number of devices                                 1
  Device Name                                     gfx1032
# success!

Build rocm_smi_lib to set power limit, memory clock speed, etc

With nVidia’s Linux driver, there’s a bundled tool nvidia-smi to control the card’s power limit, etc. But that’s missing from AMD’s driver bundle. Thanks to Radeon Open Compute the rocm_smi_lib is here. It’s source code so I need to build it myself, but it’s quite straight forward.

# install dependencies 
$ sudo apt install cmake g++
# clone the github repo
$ git clone
# start the build
$ cd rocm_smi_lib/
$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install
# set max power to 55W for the first card
$ /opt/rocm/bin/rocm-smi -d 0 --setpoweroverdrive 55
# check result
$ /opt/rocm/bin/rocm-smi
======================= ROCm System Management Interface =======================
================================= Concise Info =================================
GPU  Temp   AvgPwr  SCLK    MCLK     Fan     Perf  PwrCap  VRAM%  GPU%  
0    55.0c  54.0W   920Mhz  1000Mhz  22.75%  auto  55.0W    61%   99%   
============================= End of ROCm SMI Log ==============================

Install and Start TeamRed Miner

This is the most easy part but has to be done the last 🙂 The latest release can be downloaded here and commands to get the mining started are below

# in Downloads directory
$ tar xvf teamredminer-v0.8.4-linux.tgz
$ mv teamredminer-v0.8.4-linux ~/
$ cd ~/teamredminer-v0.8.4-linux/
# in, replace the ETH wallet address to yours otherwise you will be mining for someone else :)
$ vim
# start mining!
$ ./
[2021-08-22 10:06:25] Pool received new job. (job_id: 0x65d72f5b396..., diff 1.000 / 4295 MH)

If this actually helped you, you’re welcome to support my blogging by running your mining rig with my wallet( 0x0016a5e2d5a32d40f89475218427d35798d05d8a ) for a few hours. Or maybe just click on an ad. which is much easier.


EDIT: It seemed when 2 6600 XT cards are plugged in only 1 of them becomes available to OpenCL.

Combine GitHub Actions with FluxCD

I started my hobby project SausLink( a tinyURL like URL shortener ) a while ago, as it was really boring during covid lockdowns. The web app itself isn’t anything cutting-edge but I intended to implement full git-ops for this project.

For the CI pipeline, I chose GitHub Actions because it’s easy and also free for open source projects( for a limited builds per day ). The pipeline will be triggered by pushing to dev branch and will build a docker image and then tag it with a GitHub Actions job number. The last step will update the kustomize patch file to refer to the latest tag.

Here’s the pipeline definition along with my comments

# this is .github/workflows/dev.yaml
name: Build the dev image

    branches: [ dev ]
    branches: [ dev ]

    runs-on: [ ubuntu-20.04 ]
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/[email protected]

      # save a tag like dev-123 to environment variable called build_number
      - name: build number
        run: |
          echo "build_number=dev-${GITHUB_RUN_ID}" >> $GITHUB_ENV

      # build the docker image and tag it with build_number
      - name: Docker build saus-gunicorn
        run: |
          docker build -t$build_number .

      # login to and push the docker image
      - name: Docker push
        run: |
          echo ${{ secrets.GHCR_PAT }} | docker login -u $GITHUB_ACTOR --password-stdin
          docker push$build_number

      # update the kustomize patch to use the latest tag, using sed command and regex capture
      - name: Update deployment version
        run: |
          sed -i -E "s|(image:*|\1$build_number|g" .kustomize/

      # add an auto commit with the updated patch file, so the FluxCD can pick it up and deploy with the latest tag
      - name: Auto commit & push changes
        run: |
          git config --global 'raynix Bot'
          git config --global '[email protected]'
          git commit -am "Automated commit"
          git push

At the CD pipeline run by FluxCD v2, a Kustomization resource is defined as follow

# this is the definition of the git repo where the kustomize templates are located
kind: GitRepository
  name: saus-dev
  namespace: flux-system
  interval: 4m0s # check the repo every 4 minutes, don't be greedy
    branch: dev # fixed to dev branch for dev environment

# this is the kustomization definition
kind: Kustomization
  name: saus-dev
  namespace: flux-system
  - kind: Deployment
    name: saus
    namespace: saus-dev
  interval: 4m0s # reconcile the deployment every 4 minutes
  path: .kustomize/ # directory where the main kustomization.yaml resides in
  prune: true
    kind: GitRepository
    name: saus-dev
  timeout: 2m0s
  validation: client
  force: true # force to re-deploy objects which have immutable fields such as jobs

For more FluxCD experiments please see my previous post here. The SausLink’s source code is here. Feel free to fork it and host your own URL shortener 🙂

1-Step Away From Fossil Fuel: Sanden Heat Pump

Sanden Heat Pump Hot Water system freshly installed

After weeks of waiting, thanks to lock downs in Victoria, I finally have a 315L Sanden Heat Pump installed, replacing my who-knows-how old gas instantaneous water heater. The job has been done professionally by SolarFlow, kudos to the team!

I can label myself an environmentalist who keeps trying to minimize my own carbon footprint but this heat pump is also a logical and economical decision.

First of all, a heat pump works like a reverse air conditioner: it extracts heat from the outside and heats up inside. In other words, unlike gas or old school electric water heater, heat pump doesn’t use energy to generate heat but only transfer it. During my little research on heat pump products, I noticed that amongst all heat pumps Sanden stands out as the most efficient one: with 1 unit of energy consumed it can transfer up to 6 units of energy, a 600% coefficient of performance(COP)! This means comparing to my gas water heater which probably has <60% of efficiency the heat pump is a tenfold more efficient. And high efficiency means less running cost.

With solar panels the perk of being an electric appliance is that when the sun is shining, the heat pump runs(almost) for free. Just to be clear, I still need to pay for water regardless weather. With a rough calculation, I paid about 500 dollars a year for hot water with the old gas heater, so this heat pump can possibly pay for itself in 10 years. ( I found it interesting when it is a V8 diesel SUV no one asks if it will pay for itself later but people do ask this question if it’s renewable related products )

Fingers crossed though, the tank is warranted for 15 years but the heat pump itself only has 6 years of warranty.

The temperature of the hot water out of the tank feels like 60°C, which means it needs to mix with some cold water to achieve a comfortable temperature, so the 315L tank practically can supply me much more than 315L of hot water depending on the desired temperature.

Last but not least it’s also quieter when running. I could definitely tell if the gas heater was running 5 meters away from it, but won’t be so sure about the heat pump.

Overall I’m quite pleased with this upgrade 🙂

Use Variables with Kustomize, Part 2

I was looking at the Kustomize variable trick I did a year ago and I think I’ve learned some new tricks worth noting down.

Variables are very handy most of the times, here’s a pattern to define a variable to be used in Kustomize templates and set its value via annotations.

# base/gateway.yaml
kind: Gateway
  name: wordpress-gateway
    istio: ingressgateway
  - hosts:
    # the domain name will be set by the variable
    - $(DOMAIN)
      mode: SIMPLE
      credentialName: $(CERT)
      name: https
      number: 443
      protocol: HTTPS

# base/virtual-service.yaml
kind: VirtualService
  name: wordpress-vs
    - wordpress-gateway
    # same domain here so no need to repeat the domain name, also the virtual service will always match the gateway
    - $(DOMAIN)
    - route:
      - destination:
          host: wordpress

# base/config.yaml, ensure variables are enabled for Istio resources
  - path: spec/hosts
    kind: VirtualService
  - path: spec/servers/hosts
    kind: Gateway
  - path: spec/servers/tls/credentialName
    kind: Gateway

# at last the base/kustomize.yaml which defines 2 variables: DOMAIN and CERT
kind: Kustomization
  - config.yaml
  - gateway.yaml
  - virtual-service.yaml
  # the content of deployment isn't given here, any valid deployment resource should do
  - deployment.yaml 
  - name: DOMAIN
      apiVersion: apps/v1
      kind: Deployment
      name: wordpress
      fieldpath: metadata.annotations.domain
  - name: CERT
      apiVersion: apps/v1
      kind: Deployment
      name: wordpress
      fieldpath: metadata.annotations.cert

# the above templates form a base Kustomize template and any Kustomize template extending the above base can have the variables set for real values
# site1/kustomize.yaml
kind: Kustomization
namespace: wordpress-1
  - ../base

  cert: site1-blog-cert

There you have it: When building the overlay template site1, variable DOMAIN will have the value of; and CERT variable will be set to site1-blog-cert.