Skip to main content

Managing and deploying containerized applications

Starting a containerized application

To start a container via the mStudio, follow these steps:

  1. Navigate to the project that you want to create the container in.
  2. Select the "Containers" menu item in the sidebar.
  3. Click the "Create Container" button.
  4. In the installation wizard, select the container image that should be used to start your application and complete the wizard, by providing the desired configuration regarding environment variables, volumes and network ports.

The internal DNS name of your container will be derived from the name of the container. For example, if you create a container named My container, the internal DNS name will be my-container. You can observe the internal DNS name in the UI after the container has been created.

Using private registries

If your container image should be loaded from a private registry, you first need to define this registry for the respective project. You can create a registry as follows:

To create a new container registry via the mStudio, follow these steps:

  1. Navigate to the project that you want to create the container in.
  2. Select the "Containers" menu item in the sidebar.
  3. Switch to the "Registries" tab.
  4. Click the "Add registry" button.
  5. Configure registry URL and credentials for the registry.

Deployment strategies

When using containers for deployment, you will typically roll out new versions of your application by creating a new container image and deploying it to the same container stack. This is a common practice in containerized environments, as it allows for easy versioning and rollback.

There are two variants of this approach:

  1. Immutable deployment: Each new version of the application is deployed to a new container image, and the old image is kept for rollback purposes. This is the most common approach in containerized environments.
  2. Mutable deployment: The same container image (in the easiest case, the latest tag) is used for all versions of the application, and each new version replaces the old one.

Both of these strategies can be implemented using mStudio containers. The following sections describe how to implement them.

Pushing a new tag for each release

Using this strategy, you will create a new container image for each release of your application. Using docker commands, this might look like this (the v1.0.1 tag is just an example for a tag that might increase its version number with each release):

docker build -t my-registry/my-container:v1.0.1 .
docker push my-registry/my-container:v1.0.1

After the image is built, you can deploy it to your container stack.

Managing containers via the CLI is currently not supported. Please upvote the respective feature request.

Updating a mutable tag

Using this strategy, you will typically update the same container image tag over and over again. Using docker commands, this might look like this:

docker build -t my-registry/my-container:latest .
docker push my-registry/my-container:latest

By default, container images are not automatically updated when the image tag is not changed. You can use the POST/v2/stacks/{stackId}/services/{serviceId}/actions/pull/ operation to pull the latest image for the container stack. This will update the image tag to the latest version.

Using volumes

To manage persistent data in your containerized application, you can use volumes. Volumes are a way to store data outside of the container, so that it is not lost when the container is stopped or removed.

You can use two different types of volumes:

  1. The project volume is a volume that is created for each project and can be accessed by all containers and all managed apps in that project. This is useful for sharing data between containers and apps.
  2. You can also declare volumes as part of a stack. These are bound to the container stack and are not accessible from other stacks. This is useful for storing data that is only needed by a specific container stack.

Using the project volume

To use the project volume, use a volume declaration like this:

PUT /v2/stacks/{stackId} HTTP/1.1
Host: api.mittwald.de
Content-Type: application/json

{
"services": {
"mycontainer": {
"image": "my-registry/my-container:v1.0.1",
"volumes": [
"/home/p-XXXXX/html:/var/www"
]
}
}
}
See full request reference at: PUT/v2/stacks/{stackId}/

Declaring volumes in stacks

To declare a volume within the stack, use a volume declaration like this:

PUT /v2/stacks/{stackId} HTTP/1.1
Host: api.mittwald.de
Content-Type: application/json

{
"services": {
"mycontainer": {
"image": "my-registry/my-container:v1.0.1",
"volumes": [
"myvolume:/var/www"
]
}
},
"volumes": {
"myvolume": {}
}
}
See full request reference at: PUT/v2/stacks/{stackId}/

Backup & recovery

All volumes (both project volumes and stack volumes) are backed up automatically as part of the project backup. This means that you can restore your data in case of a failure or data loss.

However, a simple filesystem backup might not be sufficient for all application workloads. For example, if your application is using a database, you should ensure that the database is in a consistent state before taking a backup. This can be done by using the database's built-in backup functionality or by using a third-party backup solution.

Network connectivity between containers and apps

Managed applications and containers are connected to the same network. This means that you can access managed applications from your containers and vice versa. The hostname of the container is the map key of the container in the stack; if you created the container via the GUI, the hostname is derived from the name of the container. For example, if you create a container named My container, the internal DNS name will be my-container. You can observe the internal DNS name in the UI after the container has been created.

To make a container port accessible from within your project, you can use the ports property in the container declaration. This will create a port mapping between the container port and service that is exposed within your hosting environment. For example, to make port 80 of the container accessible for other workloads running in the same project (be it other containers, or managed apps), you can use the following declaration:

PUT /v2/stacks/{stackId} HTTP/1.1
Host: api.mittwald.de
Content-Type: application/json

{
"services": {
"mycontainer": {
"image": "my-registry/my-container:latest",
"ports": [
"80:80/tcp"
]
}
}
}
See full request reference at: PUT/v2/stacks/{stackId}/

Making containers accessible from the internet via HTTP

In order to make a container HTTP port accessible from the internet, you need to define an Ingress resource which maps to the given container.

Managing containers via the CLI is currently not supported. Please upvote the respective feature request.