From a4815ec11d8f3b981bd999b54d69d3273154d146 Mon Sep 17 00:00:00 2001 From: Charlie Drage Date: Fri, 4 Mar 2016 10:17:02 -0500 Subject: [PATCH] Major update to README and documentation --- CONTRIBUTING.md | 50 +++++++- README.md | 113 +++++++++-------- docs/images/logo.png | Bin 0 -> 77293 bytes docs/nulecule.md | 240 ++++++++++++++++++++++++++++++++++++ docs/quick_start.md | 153 +++++++++++++++++++++++ docs/start_guide.md | 288 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 790 insertions(+), 54 deletions(-) create mode 100644 docs/images/logo.png create mode 100644 docs/nulecule.md create mode 100644 docs/quick_start.md create mode 100644 docs/start_guide.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b53c5a99..a7a09e53 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,6 +7,48 @@ which is hosted in the [Project Atomic Organization](https://github.com/projecta These are just guidelines, not rules, use your best judgment and feel free to propose changes to this document in a pull request. +## Initial dev environment + +First of all, clone the github repository: `git clone https://github.com/projectatomic/atomicapp`.. + +### Installing Atomic App locally +Simply run + +``` +make install +``` + +If you want to do some changes to the code, I suggest to do: + +``` +cd atomicapp +export PYTHONPATH=`pwd`:$PYTHONPATH +alias atomicapp="python `pwd`/atomicapp/cli/main.py" +``` + +### Building for containerized execution +``` +docker build -t [TAG] . +``` + +Use 'docker build' to package up the application and tag the resulting image. + +### Fetch and run +``` +atomicapp [--dry-run] [-v] [-a answers.conf] fetch|run|stop|genanswers [--provider docker] [--destination DST_PATH] APP|PATH +``` + +Pulls the application and its dependencies. If the last argument is +existing path, it looks for `Nulecule` file there instead of pulling anything. + +* `--provider docker` Use the Docker provider within the Atomic App +* `--destination DST_PATH` Unpack the application into given directory instead of current directory +* `APP` Name of the image containing the application (ex. `projectatomic/apache-centos7-atomicapp`) +* `PATH` Path to a directory with installed (ex. result of `atomicapp fetch...`) app + +Action `run` performs `fetch` prior to its own tasks if an `APP` is provided. Otherwise, it will use its respective `PATH`. When `run` is selected, providers' code is invoked and containers are deployed. + + ## Submitting Issues * You can create an issue [here](https://github.com/projectatomic/atomicapp/issues/new), include as many details as possible with your report. @@ -33,13 +75,11 @@ Before you submit your pull request consider the following guidelines: * Include documentation that either describe a change to a behavior of atomicapp or the changed capability to an end user of atomicapp. * Commit your changes using **a descriptive commit message**. If you are fixing an issue please include something like 'this closes issue #xyz'. -* Additionally think about implementing a git hook, as flake8 is part of the [travis-ci tests](https://travis-ci.org/projectatomic/atomicapp) it will help you pass the CI tests. +* Make sure your tests pass! As we use [travis-ci](https://travis-ci.org/projectatomic/atomicapp) with __flake8__ it's recommended to run both commands before submitting a PR. ```shell - $ cat .git/hooks/pre-push - #!/bin/bash - - flake8 -v atomicapp + make syntax-check + make test ``` * Push your branch to GitHub: diff --git a/README.md b/README.md index 79585f2e..d70ce9e6 100644 --- a/README.md +++ b/README.md @@ -1,87 +1,102 @@ # Atomic App -Atomic App is a reference implementation of the [Nulecule specification](https://github.com/projectatomic/nulecule). It can be used to bootstrap packaged container environments and then run them. Atomic App is designed to be ran within a container. +![](docs/images/logo.png "Project Atomic") -Examples of this tool may be found within the [Nulecule library repo](https://github.com/projectatomic/nulecule/tree/master/examples). +Atomic App is a reference implementation of the [Nulecule](https://github.com/projectatomic/nulecule) specification. Packaged Atomic App containers are "Nuleculized" and each component of the package is a "Nulecule". -## Getting Started +Atomic App is used to bootstrap packaged container environments and run them on multiple container orchestrators. It is designed from the ground-up to be portable and provider pluggable. -Atomic App itself is packaged as a container. End-users typically do not install the software from source. Instead use the `atomicapp` container as the `FROM` line in a Dockerfile and package your application on top. For example: + - __A "packaged installer" for all container-based environments and applications.__ Replace all those bash and Ansible scripts with one container-based deployment tool. -``` -FROM projectatomic/atomicapp - -MAINTAINER Your Name - -ADD /Nulecule /Dockerfile README.md /application-entity/ -ADD /artifacts /application-entity/artifacts -``` + - __Target multiple providers:__ Specify the provider you want the Atomic App to run on. It supports Kubernetes, OpenShift, Mesos+Marathon and Docker. -For more information see the [Nulecule getting started guide](https://github.com/projectatomic/nulecule/blob/master/docs/getting-started.md). + - __Inherit already packaged containers:__ Create composite applications by referencing other Nulecule-compliant applications. For example, plugging in an alternative well-orchestrated database in another referenced container image. -## Developers + - __Fetch and run entire environments:__ Use `atomicapp fetch` and `atomicapp run` to run pre-packaged Nuleculized containers. -First of all, clone the github repository: `git clone https://github.com/projectatomic/atomicapp`. +## Installing Atomic App +From Linux: +```sh +git clone https://github.com/projectatomic/atomicapp && cd atomicapp +make install +``` -### Installing Atomic App locally -Simply run +_or_ -``` +Download a pre-signed .tar.gz from [download.projectatomic.io](https://download.projectatomic.io) / [GitHub](https://github.com/projectatomic/atomicapp/releases): +```sh +export RELEASE=0.4.2 +wget https://github.com/projectatomic/atomicapp/releases/download/$RELEASE/atomicapp-$RELEASE.tar.gz +tar -xvf atomicapp-$RELEASE.tar.gz && cd atomicapp-$RELEASE.tar.gz make install ``` -If you want to do some changes to the code, I suggest to do: +## Documentation -``` -cd atomicapp -export PYTHONPATH=`pwd`:$PYTHONPATH -alias atomicapp="python `pwd`/atomicapp/cli/main.py" -``` +This README contains some high level overview information on Atomic App. The detailed documentation for Atomic App resides in the [docs](docs) directory. The index provided conveniently links to each section below: -### Building for containerized execution -``` -docker build -t [TAG] . -``` +1. [Quick start](docs/quick_start.md) +2. [Getting started](docs/start_guide.md) +3. [Providers](docs/providers.md) + 1. [Docker](docs/providers/docker/overview.md) + 2. [Kubernetes](docs/providers/kubernetes/overview.md) + 3. [OpenShift](docs/providers/openshift/overview.md) +4. [CLI](docs/cli.md) +5. [Nulecule file](docs/nulecule.md) +6. [Atomic App lifecycle](docs/atomicapp_lifecycle.md) +7. [File handling](docs/file_handling.md) +8. [Specification coverage](docs/spec_coverage.md) +9. [Contributing](CONTRIBUTING.md) +10. [Dependencies](docs/requirements.md) -Use 'docker build' to package up the application and tag the resulting image. -### Fetch and run -``` -atomicapp [--dry-run] [-v] [-a answers.conf] fetch|run|stop|genanswers [--provider docker] [--destination DST_PATH] APP|PATH -``` +## Getting started -Pulls the application and its dependencies. If the last argument is -existing path, it looks for `Nulecule` file there instead of pulling anything. +Atomic App can be used either natively on your OS __or__ ran via the [atomic](https://github.com/projectatomic/atomic) command on [Fedora or CentOS Atomic hosts](https://www.projectatomic.io/download/). -* `--provider docker` Use the Docker provider within the Atomic App -* `--destination DST_PATH` Unpack the application into given directory instead of current directory -* `APP` Name of the image containing the application (ex. `projectatomic/apache-centos7-atomicapp`) -* `PATH` Path to a directory with installed (ex. result of `atomicapp fetch...`) app +__Detailed instructions on [getting started](docs/start_guide.md) are available.__ Alternatively, use the [quick start guide](docs/quick_start.md) to get a Nuleculized application running immediately. -Action `run` performs `fetch` prior to its own tasks if an `APP` is provided. Otherwise, it will use its respective `PATH`. When `run` is selected, providers' code is invoked and containers are deployed. +An extended guide on the `Nulecule` file format is [also available](docs/nulecule.md). -## Providers +## Real-world examples +Atomic App can be used to launch a cluster of containers (application servers, databases, etc.). -Providers represent various deployment targets. They can be added by placing the artifact within the respective in `provider/` folder. For example, placing `deploy_pod.yml` within `providers/kubernetes/`. For a detailed description of all providers available see [docs/providers.md](docs/providers.md). +For a list of already packaged examples, visit the [nulecule-library](https://github.com/projectatomic/nulecule-library) repo. -## Dependencies +## Providers -See [REQUIREMENTS](https://github.com/projectatomic/atomicapp/blob/master/docs/requirements.md) for current Atomic App dependencies. +We currently support: -##Communication channels + - Docker + - Kubernetes + - OpenShift 3 + - Marathon (Mesos) -* IRC: #nulecule (On Freenode) -* Mailing List: [container-tools@redhat.com](https://www.redhat.com/mailman/listinfo/container-tools) +Providers represent various deployment targets. They can be added by placing the artifact within the respective in `artifacts/` folder. For example, placing `deploy_pod.yml` within `artifacts/kubernetes/`. -# The Badges +For a detailed description of all providers available see [docs/providers.md](docs/providers.md). +## Contributing to Atomic App [![Code Health](https://landscape.io/github/projectatomic/atomicapp/master/landscape.svg?style=flat)](https://landscape.io/github/projectatomic/atomicapp/master) [![Build Status](https://travis-ci.org/projectatomic/atomicapp.svg?branch=master)](https://travis-ci.org/projectatomic/atomicapp) [![Coverage Status](https://coveralls.io/repos/projectatomic/atomicapp/badge.svg?branch=master&service=github)](https://coveralls.io/github/projectatomic/atomicapp?branch=master) [![Issue Stats](http://issuestats.com/github/projectatomic/atomicapp/badge/pr)](http://issuestats.com/github/projectatomic/atomicapp) [![Issue Stats](http://issuestats.com/github/projectatomic/atomicapp/badge/issue)](http://issuestats.com/github/projectatomic/atomicapp) -# Copyright +First of all, awesome! We have [a development guide to help you get started!](CONTRIBUTING.md) + +If you have any issues or get stuck, feel free to open a GitHub issue or reach us at our communication channels (see below). + +## Dependencies + +See [REQUIREMENTS.md](docs/requirements.md) for a list of current Atomic App dependencies. + +## Communication channels + +* IRC: __#nulecule__ on irc.freenode.net +* Mailing List: [container-tools@redhat.com](https://www.redhat.com/mailman/listinfo/container-tools) + +## Copyright Copyright (C) 2016 Red Hat Inc. diff --git a/docs/images/logo.png b/docs/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a28fc9c0f2468652308373e2f75d81e0f1f8cc5e GIT binary patch literal 77293 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

j_ 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 z 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/tcp default_centos-httpd_ec75a2fe2a50 +``` + +__Runnning Apache on Kubernetes:__ +```sh +▶ sudo atomicapp run projectatomic/helloapache +2016-02-25 15:03:04,341 - [INFO] - main.py - Action/Mode Selected is: run +2016-02-25 15:03:04,343 - [INFO] - base.py - Unpacking image: projectatomic/helloapache to /var/lib/atomicapp/projectatomic-helloapache-c0dd79b5e757 +2016-02-25 15:03:07,983 - [INFO] - container.py - Skipping pulling Docker image: projectatomic/helloapache +2016-02-25 15:03:07,984 - [INFO] - container.py - Extracting nulecule data from image: projectatomic/helloapache to /var/lib/atomicapp/projectatomic-helloapache-c0dd79b5e757 +886e10a3244f982f3302ab9058ab7b377c6f83e2cf63f001e1ba011358d0b471 +2016-02-25 15:03:08,332 - [INFO] - kubernetes.py - Using namespace default +2016-02-25 15:03:08,332 - [INFO] - kubernetes.py - trying kubectl at /usr/bin/kubectl +2016-02-25 15:03:08,332 - [INFO] - kubernetes.py - trying kubectl at /usr/local/bin/kubectl +2016-02-25 15:03:08,332 - [INFO] - kubernetes.py - found kubectl at /usr/local/bin/kubectl +2016-02-25 15:03:08,332 - [INFO] - kubernetes.py - Deploying to Kubernetes +... + +Your application resides in /var/lib/atomicapp/projectatomic-helloapache-c0dd79b5e757 +Please use this directory for managing your application + +▶ kubectl get po +NAME READY STATUS RESTARTS AGE +helloapache 1/1 Running 0 2m +k8s-etcd-127.0.0.1 1/1 Running 0 1d +k8s-master-127.0.0.1 4/4 Running 0 1d +k8s-proxy-127.0.0.1 1/1 Running 0 1d +``` + +__Fetch, edit and run Apache on Kubernetes:__ +```sh +▶ mkdir ./localdir + +▶ sudo atomicapp fetch projectatomic/helloapache --destination ./localdir/ +2016-02-25 15:35:41,439 - [INFO] - main.py - Action/Mode Selected is: fetch +2016-02-25 15:35:41,440 - [INFO] - base.py - Unpacking image: projectatomic/helloapache to helloapache +2016-02-25 15:35:45,067 - [INFO] - container.py - Skipping pulling Docker image: projectatomic/helloapache +2016-02-25 15:35:45,067 - [INFO] - container.py - Extracting nulecule data from image: projectatomic/helloapache to helloapache +c12d2047fab44f2906b9cbee3ac86c6c6499921ce33a90085e8765491b44f447 + +Your application resides in localdir +Please use this directory for managing your application + +▶ cd localdir + +▶ cat Nulecule +... + - name: hostport + description: The host TCP port as the external endpoint + default: 80 +... + +▶ vim Nulecule # edit port 80 to 8080 + +▶ cat Nulecule +... + - name: hostport + description: The host TCP port as the external endpoint + default: 8080 +... + +▶ sudo atomicapp run . + +OR + +▶ docker build -t myapp +▶ sudo atomicapp run myapp +``` + +### Quickstart: Atomic App on Atomic Host + +__Running Apache on Docker:__ +```sh +▶ sudo atomic run projectatomic/helloapache --provider=docker +docker run -it --rm --privileged -v /home/wikus:/atomicapp -v /run:/run -v /:/host --net=host --name helloapache -e NAME=helloapache -e IMAGE=projectatomic/helloapache projectatomic/helloapache run --provider=docker +docker run -it --rm --privileged -v /home/wikus:/atomicapp -v /run:/run -v /:/host --net=host --name helloapache -e NAME=helloapache -e IMAGE=projectatomic/helloapache projectatomic/helloapache run --provider=docker +2016-03-01 20:54:37,617 - [INFO] - main.py - Action/Mode Selected is: run +2016-03-01 20:54:37,618 - [INFO] - base.py - Unpacking image: projectatomic/helloapache to /host/var/lib/atomicapp/projectatomic-helloapache-a68057164f09 +2016-03-01 20:54:38,357 - [INFO] - container.py - Skipping pulling Docker image: projectatomic/helloapache +2016-03-01 20:54:38,358 - [INFO] - container.py - Extracting nulecule data from image: projectatomic/helloapache to /host/var/lib/atomicapp/projectatomic-helloapache-a68057164f09 +6eedd332f9938c7b4bacca694fdc77309ca5b43aabb05a1cb644ff8a0b713012 +2016-03-01 20:54:38,558 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:54:38,558 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:54:38,602 - [INFO] - docker.py - Deploying to provider: Docker +a98d9a3305496803c38a90a9ef65c52030dc23dae4b04f36ce167ff98335395f + +Your application resides in /var/lib/atomicapp/projectatomic-helloapache-a68057164f09 +Please use this directory for managing your application +``` + +__Runnning Apache on Kubernetes:__ +```sh +▶ sudo atomic run projectatomic/helloapache +docker run -it --rm --privileged -v /home/wikus:/atomicapp -v /run:/run -v /:/host --net=host --name helloapache -e NAME=helloapache -e IMAGE=projectatomic/helloapache projectatomic/helloapache run +docker run -it --rm --privileged -v /home/wikus:/atomicapp -v /run:/run -v /:/host --net=host --name helloapache -e NAME=helloapache -e IMAGE=projectatomic/helloapache projectatomic/helloapache run +2016-03-01 20:58:03,396 - [INFO] - main.py - Action/Mode Selected is: run +2016-03-01 20:58:03,397 - [INFO] - base.py - Unpacking image: projectatomic/helloapache to /host/var/lib/atomicapp/projectatomic-helloapache-89e975ea7438 +2016-03-01 20:58:04,153 - [INFO] - container.py - Skipping pulling Docker image: projectatomic/helloapache +2016-03-01 20:58:04,153 - [INFO] - container.py - Extracting nulecule data from image: projectatomic/helloapache to /host/var/lib/atomicapp/projectatomic-helloapache-89e975ea7438 +c85cbb2d28857f2b283e23a72a70e077daceeb2b72f6964605af6f7efa8fbc2f +2016-03-01 20:58:04,387 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:58:04,388 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:58:04,388 - [INFO] - kubernetes.py - Using namespace default +2016-03-01 20:58:04,388 - [INFO] - kubernetes.py - trying kubectl at /host/usr/bin/kubectl +2016-03-01 20:58:04,388 - [INFO] - kubernetes.py - trying kubectl at /host/usr/local/bin/kubectl +2016-03-01 20:58:04,388 - [INFO] - kubernetes.py - found kubectl at /host/usr/local/bin/kubectl +2016-03-01 20:58:04,388 - [INFO] - kubernetes.py - Deploying to Kubernetes + +Your application resides in /var/lib/atomicapp/projectatomic-helloapache-89e975ea7438 +Please use this directory for managing your application +``` + +__Stopping Apache on Kubernetes:__ +```sh +▶ sudo atomic stop projectatomic/helloapache /var/lib/atomicapp/projectatomic-helloapache-89e975ea7438 +docker run -it --rm --privileged -v /home/wikus:/atomicapp -v /run:/run -v /:/host --net=host --name helloapache -e NAME=helloapache -e IMAGE=projectatomic/helloapache projectatomic/helloapache stop /var/lib/atomicapp/projectatomic-helloapache-89e975ea7438 +2016-03-01 20:59:57,067 - [INFO] - main.py - Action/Mode Selected is: stop +2016-03-01 20:59:57,075 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:59:57,075 - [WARNING] - plugin.py - Configuration option 'providerconfig' not found +2016-03-01 20:59:57,075 - [INFO] - kubernetes.py - Using namespace default +2016-03-01 20:59:57,075 - [INFO] - kubernetes.py - trying kubectl at /host/usr/bin/kubectl +2016-03-01 20:59:57,075 - [INFO] - kubernetes.py - trying kubectl at /host/usr/local/bin/kubectl +2016-03-01 20:59:57,075 - [INFO] - kubernetes.py - found kubectl at /host/usr/local/bin/kubectl +2016-03-01 20:59:57,075 - [INFO] - kubernetes.py - Undeploying from Kubernetes +``` diff --git a/docs/start_guide.md b/docs/start_guide.md new file mode 100644 index 00000000..c47692c2 --- /dev/null +++ b/docs/start_guide.md @@ -0,0 +1,288 @@ +# Getting Started + +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. + +## Basic commands + +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](docs/cli.md). + +## Atomic App on Project Atomic hosts + +If you are on a [Project Atomic host](https://projectatomic.io/download) 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. + +`atomicapp fetch projectatomic/helloapache` + +vs + +`atomic run projectatomic/helloapache --mode fetch` + +`atomicapp run projectatomic/helloapache` + +vs + +`atomic run projectatomic/helloapache` + +`atomicapp stop ./myappdir` + +vs + +`atomic stop projectatomic/helloapache ./myappdir` + +`atomicapp genanswers ./myappdir` + +vs + +`atomic run projectatomic/helloapache ./myappdir --mode genanswers` + +## Building your first Atomic App + +A typical Atomic App or "Nulecule" container consists of the following files: +```sh +~/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](https://github.com/projectatomic/nulecule-library/tree/master/helloapache) example from the [nulecule-library](https://github.com/projectatomic/nulecule-library) repo. + +In order to follow along, fetch the container and `cd` into the directory: +```sh +atomicapp fetch --destination localdir projectatomic/helloapache +cd localdir +``` + +### ./localdir/Dockerfile +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: + + +```Dockerfile +FROM projectatomic/atomicapp + +MAINTAINER Your Name + +ADD /Nulecule /Dockerfile README.md /application-entity/ +ADD /artifacts /application-entity/artifacts +``` + +Within `helloapache` we specify a bit more within our labels: +```Dockerfile +FROM projectatomic/atomicapp:0.4.2 + +MAINTAINER Red Hat, Inc. + +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. + +### ./localdir/Nulecule + +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. +```yaml +--- +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 +``` + +##### Spec and id information +```yaml +--- +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 +```yaml +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 + +```yaml +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. + +```yaml +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. + +```yaml +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. + +```yaml +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. + +### ./localdir/artifacts/docker/hello-apache-pod_run +```sh +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. + +### ./localdir/artifacts/kubernetes/hello-apache-pod.json +```json +"image": "$image", +"name": "helloapache", +"ports": [ + { + "containerPort": 80, + "hostPort": $hostport, + "protocol": "TCP" + } +``` + +Similarly, the kubernetes provider uses both `$image` and `$hostport` variables for pod deployment. + +### ./localdir/answers.conf.sample + +`answers.conf.sample` is an answers file generated while fetching. It is a generated ini file that provides parameter answers for non-interactive deployments. + +```ini +[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: +```sh +cp answers.conf.sample answers.conf +sudo atomicapp run -a answers.conf . +``` + +### Conclusion + +Now you know how to build your very own first app! After you have created the necessary files go ahead and build/run it! + +```sh +docker build -t myapp . +sudo atomicapp run myapp +``` + +Atomic App is portable and hence you can also deploy regardless of the host: +```sh +# 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](docs/nulecule.md).