Compose specification #
levv uses YAML files, as defined in the compose specification, to launch applications.
The elements within the specification can determine service characteristics such as disk volumes, networking, environment variables, etc. However, levv uses only a subset of these to launch applications, depending on what it can offer to the user at a given time.
Next to that, levv also makes use of annotations (defined as labels) to indicate characteristics or behaviors, such as defining a container size, and exposing services to the internet.
This document provides information on these characteristics.
Applications #
An application is composed by one or more services. Each service resides within the services
section of the file.
We can consider, as a base definition, an application with one service and one replica, launched from a public docker image, and that does not require any interaction with the world nor any specific configuration settings.
services:
frontend:
image: nginx
deploy:
replicas: 1
frontend
corresponds to the service name, unique within each compose file.image
is the docker image used to create the containerdeploy
specifies the configuration for the deployment of servicesreplicas
indicates that only one container replica is desired for this service.
Container size #
The container size for a service can be set explicitly by defining the label io.levv.size
within the service.labels
section. When the container size is not specified, levv creates a deployment with nano size by default.
services:
frontend:
image: nginx
deploy:
replicas: 1
labels:
io.levv.size: "large"
When specified, levv will translate the given size into specific resource quotas as described in this table. If the provided value is incorrect, an error is generated and the deployment cannot be launched.
Service Ports #
Exposed service ports can be defined within its ports
section. Each entry consists on a service_port:container_port
pair.
services:
db:
image: redis
deploy:
replicas: 1
ports:
- 6379:6379
ports
entries can also be specified as a string, using the same format, e.g. "6379:6379"
Public services #
levv supports exposing HTTP services publicly. When a service requires such functionality, a label io.levv.public
needs to be set to "true"
for that service, and a ports
mapping defined.
Only HTTP is currently supported, therefore the ports
mapping for a public service requires an entry with "80"
at the left side (HTTP service port), and the container port that handles HTTP requests on the right side.
services:
frontend:
image: nginxdemos/nginx-hello:plain-text
deploy:
replicas: 2
labels:
io.levv.size: "medium"
io.levv.public: "true"
ports:
- "80:8080" # ServicePort:ContainerPort
When launched through the cli, the public URL is displayed as part of the success message.
Secrets #
Secrets allow to securely expose sensitive information within containers. The sources for this information are defined globally, within the secrets
section of the file, which is composed of a list of secret keys and their definitions depending on its type. Secrets can be either of file
or environment
type.
file
will create a secret from the contents of the file at the specified path.environment
will create a secret from the value of an environment variable already defined in the system.
Each service within the specification, can require zero or more secrets, depending on the definition within its own secrets
section. Each definition requires to indicate the source
as the secret key to be mounted.
services:
nginx-secrets:
image: nginx
deploy:
replicas: 1
secrets:
- source: secret_file
- source: secret_env
db:
image: redis
deploy:
replicas: 1
secrets:
- source: secret_env
secrets:
secret_file:
file: /home/user/secret.txt
secret_env:
environment: "SECRET_TOKEN"
In the example above, two secrets, identified as secrets_file
and secret_env
, are created. And both are required by the nginx-secrets
service. When launched, secrets are accessible to the container via environment variables.
Secrets are project scoped which implicates that different applications within the same project can access the information. It also means that you could overwrite secrets if you reuse the secret names within a specific project.
Environment Variables #
You can define environment variables to be set in a container by using the environment
section within a specific service. Each entry within this section corresponds to a key-value pair for each variable.
services:
nginx-environment:
image: nginx
deploy:
replicas: 1
environment:
DEPLOYMENT: production
LOG_LEVEL: debug
Volumes #
Volumes are persistent data stores for your applications running on levv cloud. Top-level volumes
declaration let you list volumes that can be reused across services and applications. Each service requiring the volume must specify it within the volumes
attribute, together with its mounting point on the container’s file system.
services:
nginx:
image: nginx
deploy:
replicas: 1
labels:
io.levv.size: "micro"
io.levv.public: "true"
ports:
- "80:80" # ServicePort:ContainerPort
volumes:
- disk-one:/usr/share/nginx/html
- disk-two:/usr/local/extra
writer:
image: myrepo/myimage:latest
deploy:
replicas: 1
volumes:
- disk-one:/usr/local/data
volumes:
disk-one:
disk-two:
In the example above, we require two volumes hosted on levv cloud: disk-one
and disk-two
, which are then mounted in the corresponding services.
Volumes are project scoped which implicates that different applications within the same project can mount and access the information within these volumes.
Full Example #
services:
backend:
image: myrepo/myimage:latest
deploy:
replicas: 2
labels:
io.levv.size: "small"
environment:
DEPLOYMENT: production
LOG_LEVEL: debug
secrets:
- source: storage_keys
volumes:
- files-disk:/usr/local/data
db:
image: redis
deploy:
replicas: 1
labels:
io.levv.size: "medium"
secrets:
- source: token
ports:
- 6379:6379
frontend:
image: nginx
deploy:
replicas: 2
labels:
io.levv.size: "micro"
io.levv.public: "true"
ports:
- "80:80"
secrets:
storage_keys:
file: /home/user/secret.txt
token:
environment: "MY_SECRET_TOKEN"
volumes:
files-disk: