This is a thorough start guide to show you each detail of an Atomic App. Teaching you the basic commands as well as the generation of your first Atomic App.
The four basic commands of atomicapp are:
atomicapp fetch: Retrieving a packaged container and exporting it to a directory.
ex. atomicapp fetch projectatomic/helloapache
atomicapp run: Running a packaged container on a specified provider. Unless a directory is specified, run
will also perform fetch
.
ex. atomicapp run projectatomic/helloapache --provider=kubernetes
atomicapp stop: Stopping a deployed Nulecule on a specified provider. Whether you're using Kubernetes, OpenShift or Docker, Atomic App will stop the containers.
ex. atomicapp stop ./myappdir --provider=kubernetes
atomicapp genanswers: By examing the Nulecule
file. Atomic App will generate an answers.conf
file to be used for non-interactive deployment.
ex. atomicapp genanswers ./myappdir
For more detailed information as well as a list of all parameters, use atomicapp --help
on the command line. Alternatively, you can read our CLI doc.
If you are on a Project Atomic host you can interact with atomicapp
via the atomic
cli command.
Some commands for atomicapp
on an atomic host are a bit different.
However. Regardless of the atomic run
command, a --mode
can be passed to change the functionality of the command.
Atomic App | Atomic CLI |
---|---|
atomicapp fetch projectatomic/helloapache |
atomic run projectatomic/helloapache --mode fetch |
atomicapp run projectatomic/helloapache |
atomic run projectatomic/helloapache |
atomicapp stop ./myappdir |
atomic stop projectatomic/helloapache ./myappdir |
atomicapp genanswers ./myappdir |
atomic run projectatomic/helloapache ./myappdir --mode genanswers |
A typical Atomic App or "Nulecule" container consists of the following files:
~/helloapache
▶ tree
.
├── answers.conf.sample
├── artifacts
│ ├── docker
│ │ └── hello-apache-pod_run
│ ├── kubernetes
│ │ └── hello-apache-pod.json
│ └── marathon
│ └── helloapache.json
├── Dockerfile
├── Nulecule
└── README.md
We will go through each file and folder as we build our first Atomic App container.
For this example, we will be using the helloapache example from the nulecule-library repo.
In order to follow along, fetch the container and cd
into the directory:
atomicapp fetch --destination localdir projectatomic/helloapache
cd localdir
Atomic App itself is packaged as a container. End-users typically do not install the software from source, instead using the atomicapp
container as the FROM
line in a Dockerfile and packaging your application on top. For example:
FROM projectatomic/atomicapp
MAINTAINER Your Name <you@example.com>
ADD /Nulecule /Dockerfile README.md /application-entity/
ADD /artifacts /application-entity/artifacts
Within helloapache
we specify a bit more within our labels:
FROM projectatomic/atomicapp:0.4.2
MAINTAINER Red Hat, Inc. <container-tools@redhat.com>
LABEL io.projectatomic.nulecule.providers="kubernetes,docker,marathon" \
io.projectatomic.nulecule.specversion="0.0.2"
ADD /Nulecule /Dockerfile README.md /application-entity/
ADD /artifacts /application-entity/artifacts
Optionally, you may indicate what providers you specifically support via the Docker LABEL command.
NOTE: The Dockerfile you supply here is for building a Nuleculized container image (often called an 'Atomic App'). It is not the Dockerfile you use to build your upstream Docker image. The actual atomicapp
code should already be built at this time and imported in the FROM projectatomic/atomicapp
line.
This is the Nulecule
file for Atomic App. The Nulecule
file is composed of graph and metadata in order to link one or more containers for your application.
---
specversion: 0.0.2
id: helloapache-app
metadata:
name: Hello Apache App
appversion: 0.0.1
description: Atomic app for deploying a really basic Apache HTTP server
graph:
- name: helloapache-app
params:
- name: image
description: The webserver image
default: centos/httpd
- name: hostport
description: The host TCP port as the external endpoint
default: 80
artifacts:
docker:
- file://artifacts/docker/hello-apache-pod_run
kubernetes:
- file://artifacts/kubernetes/hello-apache-pod.json
marathon:
- file://artifacts/marathon/helloapache.json
---
specversion: 0.0.2
id: helloapache-app
Here we indicate the specversion of our Atomic App (similar to a v1
or v2
of an API) as well as our ID.
metadata:
name: Hello Apache App
appversion: 0.0.1
description: Atomic app for deploying a really basic Apache HTTP server
Optionally, a good metadata section will indiciate to a user of your app what it does as well as what version it's on.
graph:
- name: helloapache-app
params:
- name: image
description: The webserver image
default: centos/httpd
- name: hostport
description: The host TCP port as the external endpoint
default: 80
artifacts:
docker:
- file://artifacts/docker/hello-apache-pod_run
kubernetes:
- file://artifacts/kubernetes/hello-apache-pod.json
marathon:
- file://artifacts/marathon/helloapache.json
Graph is the most important section. In here we will indicate all the default parameters as well as all associated artifacts.
params:
- name: image
description: The webserver image
default: centos/httpd
There will likely be many parameters that need to be exposed at deployment. It's best to provide defaults whenever possible. Variable templating is used within artifact files. For example: $image
within artifacts/kubernetes/hello-apache-pod.json
becomes centos/httpd
.
NOTE: Not providing a default variable will require Atomic App to ask the user. Alternatively, an answers.conf
file can be provided.
artifacts:
docker:
- file://artifacts/docker/hello-apache-pod_run
kubernetes:
- file://artifacts/kubernetes/hello-apache-pod.json
marathon:
- file://artifacts/marathon/helloapache.json
In order to use a particular provider, name as well as a file location required. Each file is a variable-subtituted template of how your Atomic App container is ran. We go more into detail below.
kubernetes:
- file://artifacts/kubernetes/hello-apache-pod.json
- file://artifacts/kubernetes/hello-apache-service.json
Multiple files may also be specified. For example, specifying a pod, service and replication controller for the kubernetes
provider.
docker run -d -p $hostport:80 $image
Each artifact uses variable replacement values. For our Docker provider, we substitute the port number with $hostport
as indicated by our graph in our Nulecule
file. The same as our $image
variable.
"image": "$image",
"name": "helloapache",
"ports": [
{
"containerPort": 80,
"hostPort": $hostport,
"protocol": "TCP"
}
Similarly, the kubernetes provider uses both $image
and $hostport
variables for pod deployment.
answers.conf.sample
is an answers file generated while fetching. It is a generated ini file that provides parameter answers for non-interactive deployments.
[helloapache-app]
image = centos/httpd
hostport = 80
[general]
namespace = default
provider = kubernetes
Default values such as the provider as well as the namespace can be provided.
In order to use an answers file, simply specify the location of the file when deploying:
cp answers.conf.sample answers.conf
sudo atomicapp run -a answers.conf .
Now you know how to build your very own first app! After you have created the necessary files go ahead and build/run it!
docker build -t myapp .
sudo atomicapp run myapp
Atomic App is portable and hence you can also deploy regardless of the host:
# Host 1
docker build -t myrepo/myapp .
docker push myrepo/myapp
# Host 2
docker pull myrepo/myapp
sudo atomicapp run myrepo/myapp
Although we have yet to cover every atomicapp
command. Feel free to use atomicapp [run/fetch/stop] --help
for a list of all options.
For an extended guide on the Nulecule
file, read our extended Nulecule doc.