Getting started with Acorn and WordPress

by | Aug 4, 2022

Spread the word

Intro

WordPress is one of the most popular CMS systems on the internet, so this is the obligatory running WordPress with Acorn blog. In this post we are going to walk through building an Acorn image that has mariadb and wordpress and running it on a Kubernetes cluster.

We will make use of Acorn’s built in secret generation, storage, and runtime to deploy our new blogging site.

Prerequisites

If you would like to follow along with this article, you will need access to a Kubernetes cluster with cluster-admin privilege. For this, we recommend Rancher Desktop, Docker Desktop, k3s, or any other Kubernetes cluster you might have for testing purposes.

Setting up our environment

First we should install the Acorn cli on our system and initialize our cluster. For a brew install on macOS or Linux, you can run:

brew install acorn-io/cli/acorn

You can also download the latest release from GitHub. Download the artifact for your system.

Once the Acorn CLI is downloaded, we can install Acorn on the Kubernetes cluster like so:

acorn install

For more info on installing Acorn

Writing our WordPress Acorn

First, lets review the WordPress architecture. There is a MySQL database layer, and a web server frontend that hosts WordPress.

First let’s start with the database layer, WordPress won’t start without it being present.

Lets open our editor and create an Acornfile. We will review each section.

containers: {
    mariadb: {
        image: "mariadb:10.6.8-focal"
        ports: "3306/tcp"
        env: {
            MARIADB_ROOT_PASSWORD: "secret://db-root-password/token"
            MARIADB_USER:          "secret://db-user/username"
            MARIADB_PASSWORD:      "secret://db-user/password"
            MARIADB_DB:            "wordpress"
        }
    }
}

secrets: {
    "db-root-password": {
        type: "token"
        data: {
            token: ""
        }
    }
    "db-user": {
        type: "basic"
        data:{
            username: ""
            password: ""
        }
    }
}

A few things going on there, lets dissect this file.

First there is the containers object, this is where all containers for the app stack are defined. We created our first container mariadb and set the image name, port to expose, and some environment variables. This is the minimum setup needed for this container to start.

Some of the environment variables are set to secret:// URIs. This is one of the most powerful features of Acorn. These URIs reference the secrets created in the secrets block. The general form of the URI is secret://<secret-name>/<key in data field>. So in our Acornfile we are setting the value of MARIADB_ROOT_PASSWORD to secret://db-root-password/token. For this secret type when the token value is the empty string "", Acorn will automatically generate the secret when it deploys. Our db-user secret will generate a username and password randomly at runtime because these values are set to the empty string.

Testing our database

Let’s test what we have so far. In your terminal run the following command in the same folder as your Acornfile.

acorn run -i .

This command will build the acorn and run it in dev mode. The log output from the container will stream to the terminal. To stop the app, press ctrl-C.

Adding WordPress

Now lets add our WordPress container. Open our editor and lets add to our Acornfile, we will dissect the new container.

containers: {
    wp: {
        image: "wordpress:latest"
        ports: publish: "80/http"
        env: {
            WORDPRESS_DB_HOST:     "mariadb"
            WORDPRESS_DB_USER:     "secret://db-user/username"
            WORDPRESS_DB_PASSWORD: "secret://db-user/password"
            WORDPRESS_DB_NAME:     "wordpress"
        }
    }
    mariadb: {
        image: "mariadb:10.6.8-focal"
        ports: "3306/tcp"
        env: {
            MARIADB_ROOT_PASSWORD: "secret://db-root-password/token"
            MARIADB_USER:          "secret://db-user/username"
            MARIADB_PASSWORD:      "secret://db-user/password"
            MARIADB_DATABASE:      "wordpress"
        }
    }
}

secrets: {
    "db-root-password": {
        type: "token"
        data: {
            token: ""
        }
    }
    "db-user": {
        type: "basic"
        data:{
            username: ""
            password: ""
        }
    }
}

The main addition was the wp container to the containers block. Here we have specified our wordpress image name. We are using the latest tag to call out once the Acorn image is built, the wordpress image is included and will always be reference by it’s specific SHA. So if latest moves upstream or in the registry, this Acorn will always get the same version. The wp container is also making use of the db-user secret values. The nice thing here is that as a user, you never have to manage the credentials.

Now lets start our app, run our acorn run command again in the same directory as the Acornfile.

acorn run -i .
#=> [internal] load build context
# => => transferring context: 1.10kB
# => [1/1] COPY . /
# => exporting to image
# => => exporting layers
# ...
# => => pushing layers
# ...
#┌─────────────────────────────────────────────────────────────────────────────────────────────┐
#| STATUS: ENDPOINTS[http://wp.wordpress.local.on-acorn.io => wp:80] HEALTHY[2] UPTODATE[2] OK |
#└─────────────────────────────────────────────────────────────────────────────────────────────┘

Once the Acorn app comes up, you can click on the enpoint link, in this case http://wp.wordpress.local.on-acorn.io.

You should see the main WordPress getting started. Don’t fill it out just yet, first we will want to setup some volumes to persist data between app restarts.

Persisting data

Lets add volumes to our Acorn image to persist data for both the mariadb and our wp containers.

Lets open our Acornfile in our editor again, and add the volumes.

containers: {
    wp: {
        image: "wordpress:latest"
        ports: publish: "80/http"
        env: {
            WORDPRESS_DB_HOST:     "mariadb"
            WORDPRESS_DB_USER:     "secret://db-user/username"
            WORDPRESS_DB_PASSWORD: "secret://db-user/password"
            WORDPRESS_DB_NAME:     "wordpress"
        }
        dirs: {
            "/var/www/html": "volume://wp"
        }

    }
    mariadb: {
        image: "mariadb:10.6.8-focal"
        ports: "3306/tcp"
        env: {
            MARIADB_ROOT_PASSWORD: "secret://db-root-password/token"
            MARIADB_USER:          "secret://db-user/username"
            MARIADB_PASSWORD:      "secret://db-user/password"
            MARIADB_DATABASE:      "wordpress"
        }
        dirs: {
            "/var/lib/mysql": "volume://db"
        }
    }
}

volumes: {
    wp: {}
    db: {}
}

secrets: {
    "db-root-password": type: "token"
    "db-user": type: "basic"
}

In the Acorn we added a new top level block volumes which defines our volume. In the Acornfile it is best to just leave the defaults and allow the user to configure at runtime. By default volumes will be 10G and created from the default StorageClass in the cluster. Once we declared the volumes, we mount them into the appropriate containers under the dirs object in the container block. We use the volume:// URI syntax to reference them.

Now if we run our Acorn image we can start to tinker with our locally deployed site.

acorn run -i .
#=> [internal] load build context
# => => transferring context: 1.10kB
# => [1/1] COPY . /
# => exporting to image
# => => exporting layers
# ...
# => => pushing layers
# ...
#┌─────────────────────────────────────────────────────────────────────────────────────────────┐
#| STATUS: ENDPOINTS[http://wp.wordpress.local.on-acorn.io => wp:80] HEALTHY[2] UPTODATE[2] OK |
#└─────────────────────────────────────────────────────────────────────────────────────────────┘

Our site!

Now that we have an Acorn that can be deployed and persist data, lets package it up so it can be shared and run on other clusters.

Build the Acorn image

With the Acorn app stopped, we can now build our image. In the directory of our Acornfile run the build command.

acorn build -t index.docker.io/<user>/wp-acorn:latest .

In the command above we are building the Acorn image and tagging it to be pushed to Dockerhub. You can change this to any registry that you would like to push to.

Pushing the image

Now we can push the image built Acorn image to our registry. This is for Dockerhub but you can change it to use your own registry. We will need to login and then push to the registry.

acorn login index.docker.io
#? Username <username>
#? Password <password>
#index.docker.io
acorn push index.docker.io/<user>/wp-acorn:latest
# [331028264/331028264] ██████████████████████████████████████████████ 100% | 14s

Once that is complete, you can now run that image on other clusters supporting Acorn.

acorn run -p blog.cloudnautique.com:wp -v wp,size=1G -v db,size=5G index.docker.io/<user>/wp-acorn:latest

The run command above introduces some new options. Lets break them down here.

  • -p blog.cloudnautique.com:wp: This tells Acorn to assign the hostname blog.cloudnautique.com to the WordPress container.
  • -v wp,size=1G: Tells Acorn to provision a 1G volume for our WordPress container volume.
  • -v wp,size=5G: Tells Acorn to provision a 5G volume for our Mariadb container volume.

Now when our Acorn app comes up, it will be accessible on the assigned domain and ready to start blogging!

Wrapping up

In this post we learned how to build an Acorn image that has WordPress and Mariadb containers defined. We learned how to use Acorn’s generated secrets to create a secure closed loop for credentials. We demonstrated how to use persistent volumes for our containers. Then we learned how to share and run our app on other clusters.

This is just scratching the surface of what you can do with Acorn, find out more in our Acorn docs.


Spread the word

Recent Posts