Having fun with XMR & AWS

Glenn Nagel
4 min readMar 23, 2019

--

For a fun weekend project I decided to play around with the XMR-STAK Monero miner: https://github.com/gnagel/xmr-stak

The purpose of the exercise was to see how difficult it was to build, test, and deploy the miner to AWS / Google Cloud.

# Initial Setup

  1. Fork the repo fireice-uk/xmr-stak to gnagel/xmr-stak
  2. Pull down the code locally
  3. Setup CLion to build the app in Docker
  4. Setup CircleCI to build a docker image
  5. Deploy the image to AWS

# CLion Setup

For C++ projects I like to use CLion. It is a powerful and flexible IDE that makes refactoring and debugging C++ applications very easy to do.

  1. Open the cloned repo in CLion
  2. Open the Preferences
  3. Select Build, Execution, Deployment -> Docker
  4. Click the + Button to create a new Docker profile
  5. Configure the paths as shown:

6. Now let’s configure the Dockerfile so it runs a benchmark when I boot the image. Open the dropdown shown below and select Edit Configurations...

7. Update the entrypoint to be bash and set the command to be:

/usr/local/bin/xmr-stak --benchmark 8 --currency monero --httpd 0 --url pool.usxmrpool.com:3333 --user x --pass x --rigid x

This will boot the docker image and run a simple benchmark test with the miner.

8. Now build the app with Docker. Select the xmr-stak/Docker file from the dropdown, then click the green Run button.

When I ran this the build failed because I don’t have CUDA installed in the Dockerfile. The temporary fix is to adjust the cmake flags in the docker image and skip CUDA (and SSL) for now.

9. Open the `Dockerfile` and replace:
`-DCUDA_ENABLE=ON`
with
`-DCUDA_ENABLE=OFF -DOpenSSL_ENABLE=OFF`

10. Delete the entrypoint and line from the Dockerfile

11. Now build and run the image again. Success, the image runs and has a benchmark of 15h/s!
Not too bad for an underpowered laptop but I think I can do better on some more powerful machines.

# Circle CI setup

CircleCi is pretty straight forward to setup.

  1. Create a .circleci/config.yml file in the repo with a basic docker-config:
version: 2
jobs:
build:
machine:
true

steps:
- checkout

- run:
name:
Build the docker image
command: docker build -t xmr-stak:$CIRCLE_BRANCH .

2. Verify the image can build successfully

3. Now let’s tweak the Docker and circle configs so they run the benchmarks too.

3.1. Update the Dockerfile to match this version: https://github.com/gnagel/xmr-stak/blob/fb3bca065e5588a00723ea7277db07cfbaec1703/Dockerfile

3.2. Add a script to run the benchmark: https://github.com/gnagel/xmr-stak/blob/fb3bca065e5588a00723ea7277db07cfbaec1703/scripts/xmr-benchmark.sh

3.3. Finally update the CircleCi config to run our new script: https://github.com/gnagel/xmr-stak/blob/fb3bca065e5588a00723ea7277db07cfbaec1703/.circleci/config.yml#L14

4. Now let’s push this up to Circle CI and see if I can get any better performance:

[2019–03–23 20:07:29] : Benchmark Total: 50.1 H/S

Not too shabby, that’s a bit better than our initial 15 h/s.

# Deploy the Image to AWS

This part is by and large covered by the AWS & CircleCi documentation. It’s a little scattered but these three docs covered most of the details:

Steps:

  1. Create IAM credentials for our Circle CI deployment: https://console.aws.amazon.com/iam/home?region=us-east-2
  2. Create an ECS Repository, this is where we will store our docker image
  3. Save the environment variables in the CircleCi: https://circleci.com/docs/2.0/ecs-ecr/#configure-circleci-environment-variables
    *AWS_ACCESS_KEY_ID
    *AWS_ACCOUNT_ID
    *AWS_ECR_ACCOUNT_URL (repository url)
    *AWS_SECRET_ACCESS_KEY
    *AWS_DEFAULT_REGION
    *AWS_REGION
  4. Update the Circle CI config to match
version: 2.1

orbs:
aws-ecr:
circleci/aws-ecr@3.0.0

workflows:
build_test_deploy:
jobs:
- build
- aws-ecr/build_and_push_image:
repo:
${CIRCLE_PROJECT_REPONAME}
requires:
- build

build_benchmark:
jobs:
- build
- benchmark

jobs:

build:
machine:
true
working_directory: /home/circleci/project
steps:
- checkout
- run:
name:
Build the docker image
command: docker build -t xmr-stak:$CIRCLE_SHA1 /home/circleci/project

benchmark:
machine:
true
working_directory: /home/circleci/project
steps:
- checkout
- run:
name:
Build the docker image
command: docker build -t xmr-stak:$CIRCLE_SHA1 /home/circleci/project
- run:
name:
Run a benchmark with Monero V8
command: docker run --rm -t xmr-stak:$CIRCLE_SHA1 /usr/local/bin/xmr-benchmark.sh

5. Go back to AWS and create a task using your repository: https://us-east-2.console.aws.amazon.com/ecs/home?region=us-east-2#/firstRun

6. Set the command to the same benchmark command we had before: /usr/local/bin/xmr-benchmark.sh

7. Finish the setup and start the task. This process can take 10–15m to complete

8. Once the server has fired up and run we can monitor the task and see how it performs.

9. Success! The miner booted up and successfully ran a benchmark, while it is lower than our local and CircleCI test runs it successfully completes the weekend project. I now have the XMR-STAK miner building with Circle CI and pushing a docker image to AWS.

[2019-03-23 22:25:55] : Benchmark Total: 10.9 H/S

# Conclusion

That wraps up the exercise for today. I’m going to write a followup article where I use Kubernetes to deploy to AWS, then hopefully Google Cloud next.

10. Let’s spin down the ECS task so we don’t build up a large AWS bill accidentally ;-)

--

--