Deploying Stateful Web Apps with Acorn

Dec 16, 2022 by Janakiram MSV
Deploying Stateful Web Apps with Acorn

This is the first in a series of articles on using Acorn with Azure AKS. Part one explains how to get started building out an Acorn environment on Azure AKS, and part two explains how to use TLS certificates to secure endpoints.

Gitea is a popular open source and lightweight source code management (SCM) tool written in Go. It supports a variety of databases, including SQLite, MySQL, and PostgreSQL, to store the metadata. This tutorial will guide you to leverage the Acorn deployment framework to run Gitea as a secure, self-hosted SCM in the cloud.

This tutorial aims to highlight running a stateful application packaged as an Acorn. Before proceeding further, complete the tutorial on hosting TLS-enabled Acorn web applications. We will use the same AKS infrastructure, and the steps explained in it.

Step 1 – Exploring the Environment

We use an AKS cluster with three nodes running NGINX ingress and certificate manager.



The public IP address of the load balancer exposing the ingress controller is associated with the DNS record.


Acorn is installed with DNS disabled and the custom domain pointing to

--ingress-class-name nginx \ --acorn-dns disabled \ --cluster-domain

A certificate issuer and a certificate are created in the acorn namespace to generate the TLS certificates for the domain

kind: ClusterIssuer metadata: name: le namespace: acorn spec: acme: server: email: [email protected] privateKeySecretRef: name: letsencrypt-prod-issuer solvers: - http01: ingress: class: nginx apiVersion: kind: Certificate metadata: name: web-cert namespace: acorn spec: dnsNames: - issuerRef: kind: ClusterIssuer name: le secretName: git-tls-secret


If you want to understand the setup in detail, please refer to the TLS tutorial. The remaining steps of this guide are dependent on having this environment configured.

Step 2 – Defining the PostgreSQL backend deployment

As Gitea depends on PostgreSQL, we will start by defining the database in an Acornfile.

db :{ image: "postgres:alpine" env: [ "POSTGRES_USER=secret://db-user/username", "POSTGRES_PASSWORD=secret://db-user/password", "POSTGRES_DB=gitea" ] dirs: "/var/lib/postgresql/data":"volume://db?subpath=data" ports: { expose: "5432/tcp" } } } secrets: { "db-user": { type: "basic" data:{ username: "" password: "" } } } volumes: { db: {} }

We start by creating the container with the name db based on an image from Docker Hub. The next section defines an array of environment variables the container expects to run. It defines the username, password, and database name initialized when the container is launched.

Since we don’t want to hardwire the username and password into the Acornfile, we refer to the secret with the values username and password. By leaving them blank, we let Acorn runtime generate the values during the deployment. Refer to the Acorn documentation for details on defining and using secrets.

The PostgreSQL database needs a persistent storage volume to store the data. In the dirs section, we map the directory /var/lib/postgresql/data to a sub-path within the volume named db. Refer to the Acorn documentation for details on defining and consuming volumes.

Finally, we open up the TCP port 5432 for internal clients through the expose moniker. The Acorn documentation has details on exposing ports for internal and external clients.

This is a valid Acornfile that you can run. Since it doesn’t have a frontend, there is not much we can do with it. To validate the Acornfile, run the below command:

acorn run -n db .


You may delete the app with acorn rm db.

Step 3 – Adding the Gitea Frontend to Acornfile

With the PostgreSQL database already in place, let’s define the Gitea deployment and associate it with the database.

Within the containers section of Acornfile, add the below content:

image: "gitea/gitea:latest" env: [ "DB_TYPE=postgres", "DB_HOST=db:5432", "DB_NAME=gitea", "DB_USER=secret://db-user/username", "DB_PASSWD=secret://db-user/password" ] dirs: "/data": "git" ports: { publish: "3000/http" } dependsOn: ["db"] }

Similar to the PostgreSQL definition, we define the image, a set of environment variables, volumes, and ports. Notice that the DB_HOST variable is pointed to the host db, which is the name of the PostgreSQL container. We then use the same values as the database to ensure connectivity between the containers.

The dirs section mounts the volume git, which is defined within the volumes section. Since the web application needs to be available as an HTTP(S) endpoint, we use the publish moniker to map it to the NGINX ingress. Finally, the dependsOn section makes the container wait until the database is ready.

The final Acornfile looks like the below file:

db :{ image: "postgres:alpine" env: [ "POSTGRES_USER=secret://db-user/username", "POSTGRES_PASSWORD=secret://db-user/password", "POSTGRES_DB=gitea" ] dirs: "/var/lib/postgresql/data":"volume://db?subpath=data" ports: { expose: "5432/tcp" } } gitea: { image: "gitea/gitea:latest" env: [ "DB_TYPE=postgres", "DB_HOST=db:5432", "DB_NAME=gitea", "DB_USER=secret://db-user/username", "DB_PASSWD=secret://db-user/password" ] dirs: "/data": "git" ports: { publish: "3000/http" } dependsOn: ["db"] } } secrets: { "db-user": { type: "basic" data:{ username: "" password: "" } } } volumes: { db: {} git: {} }

It’s time to run the Acornfile by passing the custom domain name to generate a secure HTTPS endpoint.

acorn run -p -n scm .

Within a few minutes, Acorn will print the URL of the web application.


Visiting the URL, opens up the Gitea configuration UI.


Update the Server Domain with and the Gitea Base URL with Click on Install Gitea to complete the installation.

Once you sign up and log in, Gitea shows a familiar interface to manage the code repositories.


Congratulations! You have successfully deployed a stateful Acorn application. To learn more about using acorn, visit our getting started guide , or join us for an upcoming meetup or training.

Janakiram is a practicing architect, analyst, and advisor focusing on emerging infrastructure technologies. He provides strategic advisory to hyperscalers, technology platform companies, startups, ISVs, and enterprises. As a practitioner working with a diverse Enterprise customer base across cloud native, machine learning, IoT, and edge domains, Janakiram gains insight into the enterprise challenges, pitfalls, and opportunities involved in emerging technology adoption. Janakiram is an Amazon, Microsoft, and Google certified cloud architect, as well as a CNCF Ambassador and Microsoft Regional Director. He is an active contributor at Gigaom Research, Forbes, The New Stack, and InfoWorld.