Guide to Deploying Applications to Akash DeCloud

Learn to deploy any containerized application on the decentralized cloud

Wilson Louie
Coinmonks
Published in
8 min readDec 19, 2020

--

Photo by Edurne Chopeitia on Unsplash

I recently came upon a promising blockchain-based alternative to traditional cloud platforms called Akash. Akash Network is building the first decentralized cloud (DeCloud) computing marketplace, which enables any computer with unused compute cycles to become a cloud provider, and allows developers to easily and securely access cloud compute at costs much lower than (allegedly up to 10x!) those provided by current market providers such as AWS, Google Cloud, and Microsoft Azure. If you’re not familiar with Decentralized Cloud (DeCloud) or Akash, you can check out their website, their whitepapers, their blogs, and other blogs. The project is still fairly young, but their recent Akashian Challenge 3 showcases an impressive beta version of their deployment platform.

In this guide (based on the official documentation), I’m going to show you how easy it is to deploy a containerized application to Akash. As you’ll see, the hardest part is writing and containerizing your application, which is something you would probably do anyway irrespective of the cloud provider you choose. After some one time setup, deploying to Akash simply involves writing a small configuration file and executing a couple of commands.

Prerequisites

This guide should work for Mac users, (most) Linux users, and maybe for Windows users (see supported platforms). This guide also assumes basic command line comfortability and some familiarity with Docker.

The Docker image used in this guide is available here under the username wlouie1, but if you want to create one yourself, you will need to install Docker and have an account on Docker Hub.

To deploy to Akash DeCloud, you will need to:

  1. Install Akash.
  2. Choose Your Akash Network. We will be using edgenet, which is the Testnet with deployment capabilities that will reflect their next Mainnet version.
  3. Fund Your Account with Akash Tokens (AKTs), to pay for deployment. For edgenet, Akash provides an AKT faucet to fund test deployments.

Containerizing your Application

(The Docker image for the application described in this section is available here, so feel free to skip straight to the Deploying to Akash section below.)

Writing the Application

For demonstration purposes, we’ll use this web application that enables exploring UFO sightings around the world:

UFO Sightings Around the World, 1906–2014. Image by Author

Clone the application by:

git clone https://github.com/wlouie1/UFO-Sightings.git
cd UFO-Sightings/

As you can see, the application consists purely of static HTML/Javascript/CSS files. If you were to start up a server locally, e.g. with the following if you have Python 3 installed:

python -m http.server 8000

then you can navigate to http://localhost:8000 and view the application.

Containerizing with Docker

Since all we need is a server to serve the static files of our web application, we can create a simple Docker image that bundles our static files with a web server such as Nginx.

Inside the UFO-Sightings directory, create a file called Dockerfile with the following content:

FROM nginx:alpine
COPY . /usr/share/nginx/html

Build the Docker image (we’ll name it ufo-data-vis and tag it as latest for simplicity; beware of the “latest” tag in practice though) via:

docker build -t ufo-data-vis:latest .

To test it, run the image as a container, with the host’s port 80 forwarded to the container’s port 80 (default port of Nginx):

docker run -p 80:80 ufo-data-vis:latest

If everything works, you should be able to view the application at http://localhost:80.

Push Image to Docker Registry

Once we have a built Docker image, we need to make it publicly available so that the Akash deployment process can pull the image (private containers support is on their roadmap). If you have a Docker Hub account with username USERNAME, create a repository called ufo-data-vis, and then tag and push the image with:

docker tag ufo-data-vis:latest USERNAME/ufo-data-vis:latest
docker push USERNAME/ufo-data-vis:latest

..and we’re done! The Docker image representing our containerized application is now publicly available, and we can move on to deployment to Akash.

Consider the Docker Compose File

Deploying to Akash involves writing a Stack Definition Language (SDL) file that defines the deployment configuration (more details in the Create Deployment Configuration section below). The SDL documentation is here. You may notice that the SDL format is extremely similar to that of a Docker Compose file!

If we were to construct a Docker Compose file that utilizes the public Docker image of our web application, it would look something like this:

version: "3.8"
services:
web:
image: USERNAME/ufo-data-vis:latest
ports:
- "80:80"

To verify, you can save this file as docker-compose.yml under the UFO-Sightings directory, and run the container using docker-compose (make sure to stop any previously running container):

docker-compose up --build

and navigate to http://localhost:80 to confirm.

As you’ll see in the Create Deployment Configuration section, writing the SDL file essentially becomes a direct translation.

Deploying to Akash

After writing and containerizing your application, you’re done with the hardest part! Aside from some one-time setup, deploying to Akash simply involves writing a small configuration file and executing a couple of commands.

Environment Setup

Set the following shell variables, using export VARNAME=… :

  • AKASH_NODE : Akash network configuration base URL. See here.
  • AKASH_CHAIN_ID : Chain ID of the Akash network connecting to. See here.
  • ACCOUNT_ADDRESS : The address of your account. See here.
  • KEY_NAME : The name of the key you will be deploying from. See here if you haven’t yet set up a key.

You can check whether your account has sufficient balance by running:

akash query bank balances --node $AKASH_NODE $ACCOUNT_ADDRESS

You should see a response similar to:

balances:
- amount: "93000637"
denom: uakt
pagination:
next_key: null
total: "0"

Please note the balance indicated is denominated in uAKT (AKT * 10^-6). In the above example, the account has a balance of 93 AKT. We’re now set up to deploy.

Create Deployment Configuration

Deployment services, data centers, pricing, etc., are described by a YAML configuration file using Stack Definition Language (SDL). Writing this configuration file is very similar to writing a Docker Compose file plus some extra stuff. For our web application, an SDL may look something like this (see the Consider the Docker Compose File section above for the analogous Docker Compose file):

---
version: "2.0"
services:
web:
image: USERNAME/ufo-data-vis:latest
expose:
- port: 80
as: 80
to:
- global: true
profiles:
compute:
web:
resources:
cpu:
units: 0.1
memory:
size: 512Mi
storage:
size: 512Mi
placement:
westcoast:
attributes:
organization: ovrclk.com
signedBy:
anyOf:
- "akash1vz375dkt0c60annyp6mkzeejfq0qpyevhseu05"
pricing:
web:
denom: uakt
amount: 1000
deployment:
web:
westcoast:
profile: web
count: 1

The above specifies a Docker Compose-like specification under services (in our case, we just have one workload called web, which builds our web application image), how much computational resources to allocate for each service under profiles.compute, named datacenter profiles under profiles.placement, and a map between datacenter profiles and compute profiles under deployment.

Save this file as deploy.yml. Just a couple more commands and the application will be deployed!

Deploy!

The syntax for deployment is akash tx deployment create <config-path> --from <key-name>. More specifically in our case:

akash tx deployment create deploy.yml --from $KEY_NAME --node $AKASH_NODE --chain-id $AKASH_CHAIN_ID -y

This posts your deployment and triggers the Akash marketplace to try to match you with a provider via auction. This can take a few seconds. You can check the status of your lease by running:

akash query market lease list --owner $ACCOUNT_ADDRESS --node $AKASH_NODE --state active

Once you’re matched with a provider, you should see a response similar to:

- lease_id:
dseq: "19553"
gseq: 1
oseq: 1
owner: akash1j8s87w3fctz7nlcqtkl5clnc805r240443eksx
provider: akash15ql9ycjkkxhpc2nxtnf78qqjguwzz8gc4ue7wl
price:
amount: "186"
denom: uakt
state: active
pagination:
next_key: null
total: "0"

In the above example, the lease is created using 0.00000186 AKT per block to execute the container.

For convenience and clarity, extract the below set of values to shell variables based on the returned lease information from the above step:

  • PROVIDER : akash15ql9ycjkkxhpc2nxtnf78qqjguwzz8gc4ue7wl in our example above.
  • DSEQ : 19553 in our example above.
  • OSEQ : 1 in our example above.
  • GSEQ : 1 in our example above.

The last step after getting a lease is to kick off image building on the provider machine. This is done by uploading the manifest via:

akash provider send-manifest deploy.yml --node $AKASH_NODE --dseq $DSEQ --oseq $OSEQ --gseq $GSEQ --owner $ACCOUNT_ADDRESS --provider $PROVIDER

While your image builds on the provider machine, you can view the application logs to watch progress or to debug:

akash provider service-logs --node $AKASH_NODE --dseq $DSEQ --oseq $OSEQ --gseq $GSEQ --provider $PROVIDER --owner $ACCOUNT_ADDRESS --service $SERVICE_NAME

where $SERVICE_NAME is the name of the service defined in your SDL. In our case, this is web.

Finally, you can retrieve the access details by running:

akash provider lease-status --node $AKASH_NODE --dseq $DSEQ --oseq $OSEQ --gseq $GSEQ --provider $PROVIDER --owner $ACCOUNT_ADDRESS

Which gives you a response similar to:

{
"services": {
"web": {
"name": "web",
"available": 1,
"total": 1,
"uris": [
"6veev7chcfmnclgqklegcc.provider4.akashdev.net"
],

"observed-generation": 0,
"replicas": 0,
"updated-replicas": 0,
"ready-replicas": 0,
"available-replicas": 0
}
},
"forwarded-ports": {}
}

In the above example, under uris, our application is accessible at http://6veev7chcfmnclgqklegcc.provider4.akashdev.net. Try to navigate to whatever link you see under uris, and you should see our web application!

Close Deployment

Closing your deployment means your container will be deprovisioned, and token transfer will stop. If you want to close the deployment, create a deployment-close transaction by:

akash tx deployment close --node $AKASH_NODE --chain-id $AKASH_CHAIN_ID --dseq $DSEQ --owner $ACCOUNT_ADDRESS --from $KEY_NAME -y

You can query the market to check if your lease is closed successfully:

akash query market lease list --owner $ACCOUNT_ADDRESS --node $AKASH_NODE

Which should return a response similar to:

leases:
- lease_id:
dseq: "19553"
gseq: 1
oseq: 1
owner: akash1j8s87w3fctz7nlcqtkl5clnc805r240443eksx
provider: akash15ql9ycjkkxhpc2nxtnf78qqjguwzz8gc4ue7wl
price:
amount: "186"
denom: uakt
state: closed
pagination:
next_key: null
total: "0"

As shown above, your lease should be marked state: closed.

Conclusion

As demonstrated, deploying an application to Akash is fairly straightforward. Since this is the beta version of the Akash deployment platform, we can expect more features and further simplified workflows in the future.

If you’re interested in hearing about machine learning on Akash, please also check out my other series (Part 1, Part 2, and Part 3) detailing my experiments with training, serving, and deploying a deep learning web application, all on Akash!

Also, Read

Get Best Software Deals Directly In Your Inbox

--

--

Wilson Louie
Coinmonks

Software Engineer | Machine Learning Enthusiast | Web Developer | Computational Biologist | Constantly learning and eager to spread the knowledge.