---
title: "Container-Optimized Instances"
description: "Container-Optimized Instances are designed to run Docker containers at startup: your container is available on the Internet in a matter of seconds!"
date: 2020-11-23
author: "Marc Falzon"
tags: ["docker","container"]
url: https://www.exoscale.com/blog/container-optimized-instances/
---
# Container-Optimized Instances

> [!NOTE]
> **Out-of-date article warning**
>
> Our platform grew and evolved a lot since this article was written. Container-Optimized Instances have been deprecated.
> Please check our [product overview](https://www.exoscale.com/products/) to see all available services.

Nowadays, Kubernetes is the go-to way of running application containers, whether you're running an infrastructure on a cloud provider or on-premise. Although capable of running a wide range of workloads from a simple daily batch job to a complex micro-service like architecture, *k8s* may be overkill if all you need is running a single or a handful of containers, for example using [Docker Compose][docker-compose].

Today we're introducing a new, simpler way to run Docker containers on Exoscale: **Container-Optimized Instances**.


## Container-Optimized Instances

Container-Optimized Instances (COI) are [Compute instances][exo-compute] that use a template designed to run Docker containers at startup, with minimal overhead: in a matter of seconds after your instance has booted, your container is running and is available on the Internet.

In its simplest form, running a container on a COI comes down to this [`exo` CLI][exo-cli] command:

```
$ exo lab coi nginx --image nginxdemos/hello --port 80:80
# ... waiting a few seconds for the Compute instance to boot ...
$ curl $(exo vm show --output-template "{{.IPAddress}}" nginx) | head
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
...
```

The `exo lab coi` command essentially deploys a Compute instance configured to use the COI template using a [cloud-init userdata configuration][exo-cloudinit-doc] instructing it to run [Docker Compose][docker-compose] at the end of the boot process; once deployed, this instance can be managed like any other Compute instance.

Although COI has been designed with simplicity in mind (e.g. running a single container), it can go the extra mile by supporting more complex use cases by accepting a [Docker Compose configuration][docker-composefile] (either by specifying a local `docker-compose.yml` file or a URL to it):

```
exo lab coi my-cool-stack --docker-compose <path/to/docker-compose.yml>
```


## High Availability with Network Load Balancer and Container-Optimized Instances

In addition of running on a single Compute instance, COI can be considered in the context of an [Instance Pool][exo-instancepool-doc] used in a [Network Load Balancer][exo-nlb-doc] service: Container-Optimized Instances are an interesting alternative to [custom templates][blog-packer], enabling faster iteration times for software deployments. Moreover, exposing your application(s) behind a NLB ensures greater availability and scalability.

To deploy your containerized application on a COI-powered Instance Pool, use the `Container-Optimized Instance` template and add [cloud-init *userdata*][exo-cloudinit-doc] storing a Docker Compose configuration at the `/etc/docker-compose.yml` path on the Compute instances:

```sh
$ cat docker-compose.yml
version: '2'
services:
 nginx:
   image: nginxdemos/hello
   ports:
   - "80:80"

## Preparing the cloud-init configuration containing
## the Docker Compose configuration to deploy
$ printf "#cloud-config\n\nwrite_files:\n- path: /etc/docker-compose.yml\n  content: %s\n  encoding: b64\n  owner: root:root\n  permissions: '0600'\n" $(base64 -w0 docker-compose.yml) > cloud-init

## Creating the COI-powered Instance Pool
$ exo instancepool create my-app \
    --zone ch-gva-2 \
    --size 3 \
    --template 'Container-Optimized Instance' \
    --template-filter community \
    --service-offering medium \
    --security-group web \
    --cloud-init ./cloud-init

## Creating the NLB and registering a service for the application
$ exo nlb create my-lb --zone ch-gva-2
$ exo nlb svc add my-lb my-app \
    --instance-pool-id $(exo instancepool show --output-template {{.ID}} my-app) \
    --port 80 \
    --healthcheck-mode http \
    --healthcheck-uri /
    
## Testing the final setup
$ for i in {1..10}; do curl http://$(exo nlb show --output-template "{{.IPAddress}}" my-lb) | grep name ; sleep 1 ; done
<p><span>Server&nbsp;name:</span> <span>eba920ec1a38</span></p>
<p><span>Server&nbsp;name:</span> <span>eba920ec1a38</span></p>
<p><span>Server&nbsp;name:</span> <span>c11807a9cf41</span></p>
<p><span>Server&nbsp;name:</span> <span>c11807a9cf41</span></p>
<p><span>Server&nbsp;name:</span> <span>eba920ec1a38</span></p>
<p><span>Server&nbsp;name:</span> <span>c11807a9cf41</span></p>
<p><span>Server&nbsp;name:</span> <span>eba920ec1a38</span></p>
<p><span>Server&nbsp;name:</span> <span>eba920ec1a38</span></p>
<p><span>Server&nbsp;name:</span> <span>c11807a9cf41</span></p>
<p><span>Server&nbsp;name:</span> <span>c11807a9cf41</span></p>
```

> [!NOTE]
> Don't deploy *stateful* workloads on COI-powered Instance Pools, as you'd expose yourself to data inconsistency or corruption issues.


Exoscale Container-Optimized instances are a good show-case of the potential of using discrete Exoscale API facilities in combination. If you're looking for a way to quickly and easily deploy application containers with little to no operational complexity, COI might be a viable solution to your use case.

[docker-compose]: https://docs.docker.com/compose/
[docker-composefile]: https://docs.docker.com/compose/compose-file/
[exo-compute]: https://www.exoscale.com/compute/
[exo-cli]: https://github.com/exoscale/cli
[exo-instancepool-doc]: https://community.exoscale.com/documentation/compute/instance-pools/
[exo-nlb-doc]: https://community.exoscale.com/documentation/compute/network-load-balancer/
[exo-cloudinit-doc]: https://community.exoscale.com/documentation/compute/cloud-init/
[blog-packer]: https://www.exoscale.com/blog/exoscale-official-packer-plugin/

