Adding Acorn volumes in the VotingApp

Jan 11, 2023 by Luc Juggery
Adding Acorn volumes in the VotingApp

This is the third post in a series that uses the Docker Voting app to showcase how to use Acorn. in the previous post of the series we modified the Acornfile of the VotingApp adding Acorn secrets inside of it. In this step we will add a storage definition for both redis and db containers so both containers can persist their data.

As a reminder, we ended up with the following Acornfile:

voteui: { build: "./vote-ui" ports: publish : "80/http" } vote: { build: "./vote" ports: "5000/http" } redis: { image: "redis:7.0.5-alpine3.16" ports: "6379/tcp" } worker: { build: "./worker/go" env: { "POSTGRES_USER": "secret://db-creds/username" "POSTGRES_PASSWORD": "secret://db-creds/password" } } db: { image: "postgres:15.0-alpine3.16" ports: "5432/tcp" env: { "POSTGRES_USER": "secret://db-creds/username" "POSTGRES_PASSWORD": "secret://db-creds/password" } } result: { build: "./result" ports: "5000/http" env: { "POSTGRES_USER": "secret://db-creds/username" "POSTGRES_PASSWORD": "secret://db-creds/password" } } resultui: { build: "./result-ui" ports: publish : "80/http" } } secrets: { "db-creds": { type: "basic" data: { username: "" password: "" } } }

Both db and redis containers are databases but since we didn’t specify any storage related properties, each container’s data is stored in its own file system. When a container is deleted, data is lost, this may be fine in a development environment but certainly not what we want in production.

To ensure data is persisted for both containers we will use Acorn volumes which is an abstraction above Kubernetes PersistentVolume resource type.

Note: If you follow along this series of tutorials you need to ensure the Kubernetes cluster you are using has a default StorageClass defined. Under the hood Acorn uses a StorageClass to trigger the creation of a PersistentVolume.

Defining volumes in the Acornfile

The volumes property is another top level key we can use in an Acornfile. It allows you to define storage that will be referenced by the containers which need it. For our sample application we define 2 different volumes, one for each database. The following shows the volumes property that needs to be added in the Acornfile:

"db": { size: 100M } "redis": { size: 100M } }

By default a volume is created with the following characteristics, but this can be customized to one’s needs using the dedicated properties as well:

  • default StorageClass
  • a size of 10G
  • readWriteOnce access mode

Note: we only consider volumes created from an existing Kubernetes StorageClass in this post. Acorn also allows to specify ephemeral class thus creating emptyDir volumes. We’ll come back to ephemeral storage in the next post of the series, that one will be dedicated to Acorn development mode.

Once defined in the volumes top level key, we need to mount each volumes in the corresponding container knowing that:

  • postgres persists its data in /var/lib/postgresql/data
  • redis persists its data in /data db container should then be modifed as follows:
image: "postgres:15.0-alpine3.16" ports: "5432/tcp" env: { "POSTGRES_USER": "secret://db-creds/username" "POSTGRES_PASSWORD": "secret://db-creds/password" } dirs: { "/var/lib/postgresql/data": "volume://db" } }

redis container should follow the same logic:

image: "redis:7.0.5-alpine3.16" ports: "6379/tcp" dirs: { "/data": "volume://redis" } }

We can now update the application using this new version of the Acornfile:

acorn run -n vote --update .

As in the previous step, this command will return the http endpoints to access both vote-ui and result-ui frontend.

If you curious about what is happening under the hood, you could actually see 2 PersistentVolume resources have been created, one for each database container:

kubectl-get-pv-1024x202.png

Overriding a volume’s configuration

From the cli it’s possible to specify the characteristics of a volume already defined in the Acornfile. For instance we could run the application using the following command which specifies 200M of storage for each volume instead of the 100M defined in the Acornfile:

acorn run -n vote -v db,size=200M -v redis,size=200M --update .

Feel free to visit Acorn documentation to get more information on Acorn volumes

Wrapping up

In this short post, we explained how to use Acorn volumes to persist data for the 2 database containers of the VotingApp. In the next post of the series we’ll build on this example and introduce Acorn’s development mode, a handy feature in Acorn that allows a developper to make changes from the IDE and have them taken into account in real time by the application’s containers.

Luc Juggery is a software engineer with 18+ years of experience and co-founder of 2 startups located in Sophia-Antipolis, southern France. You can chat with him on Twitter, read more of his work on Medium, find his tutorials on YouTube, or take one of his Docker or Kubernetes training courses on Udemy.