Introducing tools.gptscript.ai, a website for automatically documenting, sharing, and finding tools.
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.
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.
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
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://
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.
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.
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.
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.
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.
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.