Customizing Appsody stacks: An introduction
Decide when to create a new stack or modify an existing stack, and when to use or modify a template
Appsody is an open source project that simplifies your cloud-native application development. Appsody’s primary component is a stack which builds a pre-configured Docker image that is ready for you to deploy in a cloud environment. These Docker images can include any amount of customized content and allow stack builders to decide which parts are fixed (stack image) and which parts stack users can modify or extend (templates).
This article gives you a quick introduction to Appsody repositories, stacks, and templates and helps you determine when to create a new stack, when to modify a stack, and when to use or modify a template.
Repositories, stacks, and templates
The hierarchy of objects in Appsody is made up of repositories at the top level, followed by stacks, which include a curated image full of technologies, and templates at the lowest level. Appsody repositories offer a central hub for you to use the Appsody stacks.
You can use the
appsody CLI to add or remove repositories and initialize new projects based on stacks. For example,
appsody repo add kabanero https://github.com/kabanero-io/collections/releases/download/v0.1.2/kabanero-index.yaml makes your local installation aware of a new remote stack repository, with its stacks and templates now available for local development.
As an example, here is the output of
appsody list when multiple repositories are registered in your local Appsody configuration (stored under
$ appsody list REPO ID VERSION TEMPLATES DESCRIPTION appsodyhub java-microprofile 0.2.13 *default Eclipse MicroProfile on Open Liberty & OpenJ9 using Maven appsodyhub java-spring-boot2 0.3.11 *default, kotlin Spring Boot using OpenJ9 and Maven appsodyhub nodejs 0.2.5 *simple Runtime for Node.js applications appsodyhub nodejs-express 0.2.5 *simple, skaffold Express web framework for Node.js appsodyhub nodejs-loopback 0.1.4 *scaffold LoopBack 4 API Framework for Node.js appsodyhub python-flask 0.1.3 *simple Flask web Framework for Python appsodyhub swift 0.1.4 *simple Runtime for Swift applications custom_stack my-stack-name 1.0.0 *default My custom stack experimental java-spring-boot2-liberty 0.1.8 *default Spring Boot on Open Liberty & OpenJ9 using Maven experimental nodejs-functions 0.1.3 *simple Serverless runtime for Node.js functions experimental quarkus 0.1.5 *default Quarkus runtime for running Java applications experimental vertx 0.1.1 *default Eclipse Vert.x runtime for running Java applications local_stack java-microprofile 0.2.6 *default Eclipse MicroProfile using OpenJ9 and Maven local_stack java-spring-boot2 0.3.2 *default Spring Boot using OpenJ9 and Maven local_stack nodejs 0.2.3 *simple Runtime for Node.js applications local_stack nodejs-express 0.2.3 *simple Express web framework for Node.js local_stack nodejs-loopback 0.1.0 * LoopBack API framework for Node.js local_stack swift 0.1.2 *simple Runtime for Swift applications my_local java-microprofile 0.2.6 *default, gdpr, restapi Eclipse MicroProfile on Open Liberty & OpenJ9 using Maven my_stacks java-microprofile 0.2.6 *default Eclipse MicroProfile using OpenJ9 and Maven my_stacks java-spring-boot2 0.3.2 *default Spring Boot using OpenJ9 and Maven my_stacks nodejs 0.2.3 *simple Runtime for Node.js applications my_stacks nodejs-express 0.2.3 *simple Express web framework for Node.js my_stacks nodejs-loopback 0.1.0 * LoopBack API framework for Node.js my_stacks swift 0.1.2 *simple Runtime for Swift applications
The first column is the repository, the second is the stack name, followed by the version of the stack, and a list of available templates. The Appsody CLI initializes an app through a combination of thes parts. For example, in this instance:
$ appsody init my_local/java-microprofile default
the CLI initializes an application based on the default Java MicroProfile template.
Decision tree for whether to use, modify, or create a stack
An Appsody application contains a Docker image created from a stack and injects the template and user files into it. Because Dockerfiles are part of the stack, they can’t be modified by a user accessing a stack. However, templates are copied into your working directory during the
appsody init process. Appsody users are free to make changes to anything that’s part of the template, which is combined with the stack image during the
appsody build phase.
Depending on your needs, you will either:
- Select an existing stack and base your application on one of its templates
- Modify or extend a stack
- Create an entirely new stack
The question is: how do you decide which option is best for your particular use case? We’ve created a decision tree to help you make that decision.
Creating or modifying stacks
Stacks may contain code that is always part of the application and cannot be modified, while templates contain code that users can modify. So, for example, suppose you decide that everyone in an organization that uses a private repository must have a set of dependencies and libraries in their microservice. In this scenario, you would want to build a set of customized stacks in a private repository.
Other examples of when you would want to create or modify a stack (or multiple stacks) include:
- Your organization needs to create a library of base images that come pre-built with certain common features (health checks, telemetry, security, logging, etc) that should be part of every microservice. These features are controlled by the Dockerfile that is stored in the Appsody repository. You can update the Dockerfile at any time, and the Appsody CLI will pull the latest available version during build time.
When a user initializes an instance of an Appsody template, the Dockerfile is not downloaded to the user’s sandbox as part of the initialization. The
appsody buildstep downloads it from the repository each time, compiling the user’s code and adding it to the appropriate path in the base image.
As an example, in this excerpt from the Java MicroProfile stack
Dockerfile, note that the stack Dockerfile copies the Java source code into the image and compiles it. This Dockerfile is only available as part of the stack and can’t be changed by developers who don’t have write access to the repository.
COPY . /project WORKDIR /project/user-app RUN mvn install -DskipTests RUN cd target && \ unzip *.zip && \ mkdir /config && \ mv wlp/usr/servers/*/* /config/
You can add dependencies into the container via language-dependent mechanisms without changing the stack. For example, you can modify
pom.xml and have Maven add dependencies to Java stacks or make changes to the
Pipfile to add dependencies in a Python stack.
If your stack doesn’t require a new function, you can work from one of our existing templates or create a new one to meet your needs. Templates can provide scaffolding code that’s suitable for starting a microservice for a specific task, for example, creating a REST API backend for a web or mobile application.
- are easy to create. You simply copy an existing stack and tweak it.
- allow you to build many variants of an existing stack for different use cases.
- give users a starting point from which to build their service, but won’t lock them into any particular requirement.
Appsody can speed the development of cloud-native applications by allowing you to building on existing stacks and templates optimized for specific use cases, instead of starting from scratch. Hopefully this article helped you understand about how the different parts of Appsody fit together and when you should create a new stack, modify an existing one, or just use or modify a template.
- Want to see Appsody in use? Check out the Spring Health Score app based on Appsody
- Read the documentation: Modify or create a new stack