157
APPUiO User Documentation Documentation Release 1.0 APPUiO Community Jun 06, 2017

APPUiO User Documentation Documentation - Read the … · 29 Persistant Storage 71 29.1 Resize Gluster Volumes ... Red Hat Enterprise Linux ... APPUiO currently uses GlusterFS based

  • Upload
    lyhanh

  • View
    246

  • Download
    1

Embed Size (px)

Citation preview

  • APPUiO User DocumentationDocumentation

    Release 1.0

    APPUiO Community

    Jun 06, 2017

  • User Documentation

    1 Getting Started 31.1 Web Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 APPUiO Sample Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.4 APPUiO - Techlab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.5 OpenShift Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

    2 APPUiO Public Platform Specifics 52.1 Versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 URLs and Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.3 Persistent Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.4 Quotas and Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.5 Secure Docker Builds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.6 Lets Encrypt Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.7 Email Gateway . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.8 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

    3 APPUiO Secure Docker Builder 93.1 Rationale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93.2 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93.3 User-customizable builder configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.4 Build VMs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.5 Build Hooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.6 Known Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

    4 Lets Encrypt Integration 13

    5 How Tos 155.1 How to access the OpenShift registry from outside . . . . . . . . . . . . . . . . . . . . . . . . . . . 155.2 How to run scheduled jobs on APPUiO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165.3 How to access an internal service while developing . . . . . . . . . . . . . . . . . . . . . . . . . . . 165.4 How to use a private repository (on e.g. Github) to run S2I builds . . . . . . . . . . . . . . . . . . . 16

    6 Troubleshooting 196.1 Read Logs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196.2 Common Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

    i

  • 7 FAQ (Technical) 217.1 Can I run Containers/Pods as root? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217.2 What do we monitor? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217.3 What do we backup? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217.4 What DNS entries should I add to my custom domain? . . . . . . . . . . . . . . . . . . . . . . . . . 217.5 How can I secure the access to my web application? . . . . . . . . . . . . . . . . . . . . . . . . . . 22

    8 PHP Source to Image Sample 23

    9 PHP Docker Build Sample App 25

    10 PHP 7 with Apache Source to Image Example 2710.1 Build Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2710.2 Deploy App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

    11 PHP 7 with Nginx Source to Image Example 2911.1 Build Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2911.2 Deploy App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

    12 MySql Backup Image 31

    13 PostgreSQL Backup Image (the manual way) 33

    14 Spring Boot Application 3514.1 Dockerfile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3514.2 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3614.3 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

    15 Spring Boot Application with Angular 2 Frontend 3715.1 Dockerfile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3715.2 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3815.3 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

    16 Java EE Source to Image 3916.1 Deployment via oc Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3916.2 Deployment via webconsole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3916.3 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4016.4 Speed up your build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

    17 Docker Image 41

    18 Deploy Static Content to APPUiO 4318.1 Apache based image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4318.2 nginx based image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4518.3 Continuous Integration: Trigger Rebuild . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

    19 Binary Deployment in Wildfly 4719.1 Create a new project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4719.2 Create the deployment folder structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4719.3 Create a new build using the Wildfly image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4719.4 Start the build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4819.5 Create a new app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4819.6 Expose the service as route . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

    20 Custom Applications 49

    ii

  • 21 Node JS 6 Example 5121.1 How to deploy to APPUiO / OpenShift Cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5121.2 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5121.3 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

    22 More OpenShift Sample Apps 53

    23 Central Logging 5523.1 Elasticsearch Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5523.2 Elasticsearch Retention (Curator) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5723.3 Central logging monitoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

    24 Node Maintenance 5924.1 Prepare for maintenance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

    25 Backup of Cluster Components 6125.1 etcd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

    26 Monitoring 6326.1 Read-only System Account . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

    27 OpenShift Cluster Troubleshooting 6527.1 Resources in OpenShift documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6527.2 Multi-master etcd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6527.3 Issues and their solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

    28 OpenShift Patch Operations 69

    29 Persistant Storage 7129.1 Resize Gluster Volumes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

    30 Custom Builder 7330.1 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

    31 Introduction 7531.1 Architecture of our shop application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7631.2 Structure of this documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7731.3 Where you can find the sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

    32 General Concepts 7932.1 Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7932.2 Continuous Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8132.3 OpenShift / Kubernetes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

    33 Webserver 8533.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8533.2 Building a container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8633.3 Running the container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8833.4 Implementing a CI Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8833.5 Preparing the APPUiO project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9333.6 Pushing to the APPUiO registry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9433.7 Implementing a deployment strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9633.8 Advanced Deployments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

    34 API 10734.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

    iii

  • 34.2 Building a container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10834.3 Running the container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11234.4 Implementing a CI pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

    35 Users 11935.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11935.2 Building a container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12035.3 Running the container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12335.4 Implementing a CI Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12535.5 Deploying to APPUiO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

    36 Orders 13136.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13136.2 Building and running the container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13236.3 Integrating Jenkins with APPUiO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13236.4 Implementing a CI Pipeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13736.5 Deploying to APPUiO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

    37 License 149

    38 Indices and tables 151

    iv

  • APPUiO User Documentation Documentation, Release 1.0

    This is the place where everything related to APPUiO gets documented. Feel free to contribute using pull requests onour Github project.

    User Documentation 1

    https://github.com/appuio/docs

  • APPUiO User Documentation Documentation, Release 1.0

    2 User Documentation

  • CHAPTER 1

    Getting Started

    Web Console

    Login to the Platform here: Console

    CLI

    You can download the OpenShift CLI Client (oc) matching the current OpenShift of APPUiO directly from APPUiO.

    Windows

    Mac OS X

    Linux

    Copy the oc client on your machine into a direcotry on the defined PATH

    For example: ~/bin

    Prerequisites

    For certain commands eg. oc new-app https://github.com/appuio/example-php-sti-helloworld.git a locally installed gitclient (git command) is required.

    Login

    oc login https://console.appuio.ch

    For more information please see Get Started with the CLI

    3

    https://console.appuio.ch/https://console.appuio.ch/console/extensions/clients/windows/oc.exehttps://console.appuio.ch/console/extensions/clients/macosx/ochttps://console.appuio.ch/console/extensions/clients/linux/ochttps://access.redhat.com/documentation/en/openshift-enterprise/version-3.2/cli-reference/#get-started-with-the-cli

  • APPUiO User Documentation Documentation, Release 1.0

    APPUiO Sample Applications

    If you want to deploy your first hello world example, see OpenShifts Developers: Web Console Walkthrough. Ordive right into some sample applications for APPUiO in our Application Tutorial section.

    APPUiO - Techlab

    The APPUiO - OpenShift techlab provides a hands on step by step tutorial that allows you to get in touch with thebasic concepts. Check out our german APPUiO Techlab .

    The german techlab covers:

    Quicktour and basic concepts

    install OpenShift CLI

    First Steps on the Platform (Source To Image deployment from github)

    Deploy a docker image from dockerhub

    Creating routes

    Scaling

    Troubleshooting

    Deploying a database

    Code changes and redeployments

    Attach persistent storage

    how to use application templates

    OpenShift Documentation

    Please find further documentation here: OpenShift docs

    4 Chapter 1. Getting Started

    https://docs.openshift.com/enterprise/latest/getting_started/developers_console.htmlhttp://docs.appuio.ch/en/latest/#application-tutorialshttps://github.com/appuio/techlabhttps://docs.openshift.com/enterprise/latest/welcome/index.html

  • CHAPTER 2

    APPUiO Public Platform Specifics

    APPUiO is based on OpenShift Container Platform. This page describes APPUiO specific OpenShift configurationsettings as well as features which were added to APPUiO that are not present in OpenShift.

    Versions

    Operating System: Red Hat Enterprise Linux (RHEL) 7

    OpenShift Container Platform: 3.3

    Docker: 1.10.3

    You can download matching clients directly from APPUiO: Getting Started.

    URLs and Domains

    Master URL: https://console.appuio.ch/

    Metrics URL: https://metrics.appuio.ch/

    Logging URL: https://logging.appuio.ch/

    Application Domain: appuioapp.ch

    Persistent Storage

    APPUiO currently uses GlusterFS based persistent storage. For now volumes with the following sizes are availableout of the box:

    1 GiB

    5 GiB

    5

    https://console.appuio.ch/https://metrics.appuio.ch/https://logging.appuio.ch/

  • APPUiO User Documentation Documentation, Release 1.0

    20 GiB

    50 GiB

    However you can contact us to get larger volumes: Contact. All volumes can be accessed with ReadWriteOnce (RWO)and ReadWriteMany (RWX) access modes. Please see Persistent Volumes for more information.

    Quotas and Limits

    The quotas are defined in the project size you ordered. The exact numbers can be found on the product site APPUiOPublic Platform

    Secure Docker Builds

    Usually Docker builds from Dockerfile have to be disabled on multi-tenant platforms for security reasons. How-ever, APPUiO uses its own implementation to securely run Docker builds in dedicated VMs: APPUiO Secure DockerBuilder

    Lets Encrypt Integration

    Lets Encrypt is a certificate authority that provides free SSL/TLS certificates which are accepted by most of todaysbrowser via an automated process. APPUiO provides integration with Lets Encrypt to automatically create, sign,install and renew certificates for your Domains running on APPUiO: Lets Encrypt Integration

    Email Gateway

    To send emails to external entities, you should SMTP relay via the email gateway at mxout.appuio.ch.

    To include the APPUiO email gateway in your existing SPF policy, you can include or redirect to spf.appuio.ch.

    Example DNS record:

    @ IN TXT "v=spf1 ... include:spf.appuio.ch ~all"

    Or if you send emails for your domain exclusivly from appuio:

    @ IN TXT "v=spf1 redirect=spf.appuio.ch"

    Features

    Most features are considered as stable. But there are some exceptions, mainly the following two features are not yetas stable as we want and therefore declare them as Beta:

    Metrics: The metrics storage fails from time to time and looses all its data. This is being fixed together withRed Hat.

    Logging: This is not yet as stable as it should be, were continuing to improve it.

    6 Chapter 2. APPUiO Public Platform Specifics

    http://appuio.ch/#contacthttps://docs.openshift.com/enterprise/latest/dev_guide/persistent_volumes.htmlhttps://appuio.ch/public.htmlhttps://appuio.ch/public.html

  • APPUiO User Documentation Documentation, Release 1.0

    Failover IP: The high availability of service IPs (application router and master loadbalancer) is not yet com-pletely automated. Were also continue to work on that.

    2.8. Features 7

  • APPUiO User Documentation Documentation, Release 1.0

    8 Chapter 2. APPUiO Public Platform Specifics

  • CHAPTER 3

    APPUiO Secure Docker Builder

    Rationale

    Docker builds from Dockerfiles need access to the Docker Socket and are inherently insecure. For this reason mostmulti-tenant container platforms do not support Docker builds. While OpenShift Container Platform, on which AP-PUiO is based, improves the security of builds through the use of SELinux, they are still not secure enough to runon a multi-tenant platform. Indeed we have disabled the custom build strategy (custom builders) on APPUiO for thisreason.

    Features

    However, since we regard building Docker images from Dockerfiles as a vital feature, APPUiO provides its ownmechanism called the APPUiO secure Docker builder to offer this. APPUiO secure Docker builder has the followingfeatures:

    It provides the same user experience as the OpenShift Container Platform Docker builder.

    Builds run in virtual machines dedicated to a single APPUiO project, which in turn run on dedicated hosts,i.e. outside of APPUiOs OpenShift Container Platform. Therefore providing full isolation between builds andcustomer containers as well as between builds from different customers.

    Supports Docker cache for fast subsequent builds.

    All communication between APPUiOs OpenShift Container Platform and the dedicated build VMs is encrypted.

    To compensate the loss of custom builders it provides hooks to allow users to run a script before and/or afterdocker build.

    9

    https://docs.docker.com/engine/security/security/#/docker-daemon-attack-surfacehttps://docs.openshift.org/latest/admin_guide/securing_builds.htmlhttps://docs.openshift.com/container-platform/3.4/architecture/core_concepts/builds_and_image_streams.html#custom-build

  • APPUiO User Documentation Documentation, Release 1.0

    User-customizable builder configuration

    The source secret attached to the build strategy of a build configuration can be used to configure the build. As perusual in OpenShift secrets values must be encoded using Base64.

    Example

    $ oc export secrets example-source-authapiVersion: v1kind: Secretmetadata:

    name: example-source-authtype: Opaquedata:

    ssh-privatekey: LS0...Cg==ssh-known-hosts: Iwo=ssh-config: Iwo=

    The string Iwo= is #\n in Base64.

    ssh-privatekey

    Private SSH key; see OpenShift documentation.

    ssh-known-hosts

    If this attribute is set to anything, including the empty string, strict host key checking is enabled (seeStrictHostKeyChecking in ssh_config(5). The host keys for the following hosting services are alreadyincluded by default:

    GitHub

    GitLab

    Atlassian Bitbucket

    Other host keys can be added in Base64 format. Example retrieval command:

    $ ssh-keyscan git.example.net | base64Z2l[...]wo=

    ssh-config

    SSH configuration snippet; added after the built-in options. Useful to specify different configuration options for theSSH client (i.e. the Ciphers option; see ssh_config(5)).

    Build VMs

    RHEL and Docker versions in the build VMs are identical the ones on APPUiOs OpenShift Container Platform.

    10 Chapter 3. APPUiO Secure Docker Builder

    https://en.wikipedia.org/wiki/Base64https://docs.openshift.com/container-platform/3.4/dev_guide/builds.html#ssh-key-authenticationhttps://github.com/https://about.gitlab.com/https://bitbucket.org/

  • APPUiO User Documentation Documentation, Release 1.0

    Build Hooks

    Users can add .d2i/pre_build and/or .d2i/post_build scripts to the source repository where theirDockerfile resides. The scripts

    need to be executable and can be written in any language.

    have access to environment variables set in the BuildConfig object, the variables documented for customOpenShift builder images, DOCKERFILE_PATH (relative or absolute path to Dockerfile) and DOCKER_TAG(output Docker tag)

    pre_build is executed just before docker build and has read/write to the Docker context, including theDockerfile (use $DOCKERFILE_PATH; also passed as first argument); the output tag is given as the secondargument

    post_build is executed just after docker build and has access to the Docker context and the built image

    are executed in the build VM as root

    Build Hook Example

    Here youll find an example which uses a pre_build script to install Maven and uses it to download a .war filefrom an artefact repository: https://github.com/appuio/appuio-docker-builder-example. The Dockerfile picks upthe .war file downloaded by the pre_build script and adds to the image with an ADD instruction. In a real projectthe ARTIFACT environment variable would be configure in a BuildConfig. The example uses JBoss EAP, whichis only available to you if you ordered it. However this approach also works with other base images.

    Known Issues

    The OpenShift Container Platform Docker builder exposes environment variables via an ENV instruction at theend of Dockerfile. This is not yet implemented in the APPUiO secure Docker builder.

    Binary and image sources are currently not implemented.

    3.5. Build Hooks 11

    https://docs.openshift.com/container-platform/3.4/creating_images/custom.html#custom-builder-imagehttps://docs.openshift.com/container-platform/3.4/creating_images/custom.html#custom-builder-imagehttps://github.com/appuio/appuio-docker-builder-examplehttps://docs.openshift.com/container-platform/3.4/dev_guide/builds.html#binary-sourcehttps://docs.openshift.com/container-platform/3.4/dev_guide/builds.html#image-source

  • APPUiO User Documentation Documentation, Release 1.0

    12 Chapter 3. APPUiO Secure Docker Builder

  • CHAPTER 4

    Lets Encrypt Integration

    Lets Encrypt is a certificate authority that provides free SSL/TLS certificates via an automated process. Lets Encryptcertificates are accepted by most of todays browsers. APPUiO provides integration with Lets Encrypt to automaticallycreate, sign, install and renew certificates for your domains running on APPUiO.

    To create a certificate for one of your domains follow these steps:

    1. If you havent already done so create a route for the fully qualified domain name (FQDN), e.g. www.example.org, your application should run under

    2. Add a CNAME record (important!) for the FQDN to the DNS of your domain pointing to cname.appuioapp.ch. E.g. in BIND: www IN CNAME cname.appuioapp.ch. (the trailing dot is required)

    3. Visit https://letsencrypt.appuio.ch/ to create and install the certificate, e.g.https://letsencrypt.appuio.ch/www.example.org. Login with your APPUiO account.

    Creating certificates for the default domain appuioapp.ch is neither needed nor supported as APPUiO alreadyhas a wildcard certificate installed for *.appuioapp.ch. Without this wildcard certificate we would hit the LetsEncrypt rate limits on the appuioapp.ch domain sooner or later.

    Important: Always create a route before pointing a DNS entry to APPUiO and always remove the correspondingDNS entry before deleting a route for a domain of yours. Otherwise someone else could potentially create a route anda Lets Encrypt certificate for your domain.

    Please note:

    1. APPUiO automatically renews certificates created through https://letsencrypt.appuio.ch/ 30 days before theyexpire

    2. We are working to improve the user experience of the Lets Encrypt integration

    3. If you have more than one route for one hostname (FQDN) configured, i.e. path based routes, the certificate iscurrently only installed into one route. This will be resolved with the improved user experience.

    4. Lets encrypt can only create domain validated certificates, i.e. its not possible to add an organization name toa Lets Encrypt certificate.

    13

    https://letsencrypt.org/docs/rate-limits/https://letsencrypt.org/docs/rate-limits/https://letsencrypt.appuio.ch/https://en.wikipedia.org/wiki/Domain-validated_certificate

  • APPUiO User Documentation Documentation, Release 1.0

    14 Chapter 4. Lets Encrypt Integration

  • CHAPTER 5

    How Tos

    Contents

    How Tos

    How to access the OpenShift registry from outside

    How to run scheduled jobs on APPUiO

    How to access an internal service while developing

    How to use a private repository (on e.g. Github) to run S2I builds

    * 1. Create an SSH keypair

    * 2. Create a deploy key

    GitHub

    Gitlab

    * 3. Save the private key in an OpenShift secret

    * 4. Create a new build config in OpenShift

    How to access the OpenShift registry from outside

    To access the internal OpenShift registry from outside, you can use the following example:

    oc login https://console.appuio.chOCTOKEN=$(oc whoami -t)docker login -u MYUSERNAME -p $OCTOKEN registry.appuio.chdocker pull busyboxdocker tag busybox registry.appuio.ch/MYPROJECT/busybox

    15

  • APPUiO User Documentation Documentation, Release 1.0

    docker push registry.appuio.ch/MYPROJECT/busyboxoc get imagestreams -n MYPROJECT

    How to run scheduled jobs on APPUiO

    checkout the APPUiO Cron Job Example

    How to access an internal service while developing

    E.g. accessing a hosted PostgreSQL on port 5432 while developing locally.

    To access a service (a single pod, to be more specific) from your local machine, make sure you have installed theOpenShift CLI (as described in the official documentation).

    Login to the OpenShift CLI:

    $ oc login

    Get a list of your currently running pods:

    $ oc get podsNAME READY STATUS RESTARTS AGEplay-postgres-1-9ste1 1/1 Running 0 9s

    With the name of the pod running your service, run the oc port-forward command, also specifying the port youwould like to access:

    $ oc port-forward play-postgres-1-9ste1 5432Forwarding from 127.0.0.1:5432 -> 5432Forwarding from [::1]:5432 -> 5432

    Your service may now be accessed via localhost:port. For more advanced usage of oc port-forwardconsider the official documentation.

    How to use a private repository (on e.g. Github) to run S2I builds

    1. Create an SSH keypair

    Create an SSH keypair without passphrase:

    $ ssh-keygen -t rsa -b 4096 -C "[email protected]"Generating public/private rsa key pair.Enter file in which to save the key: id_rsaEnter passphrase (empty for no passphrase):Enter same passphrase again:Your identification has been saved in id_rsa.Your public key has been saved in id_rsa.pub.

    The private key has been saved as id_rsa, the public key as id_rsa.pub. You will need both of them, store themin a secure location.

    16 Chapter 5. How Tos

    https://github.com/appuio/example-cron-traditionalhttps://docs.openshift.org/latest/cli_reference/get_started_cli.htmlhttps://docs.openshift.org/latest/dev_guide/port_forwarding.html

  • APPUiO User Documentation Documentation, Release 1.0

    2. Create a deploy key

    To allow the newly generated key to pull your repository, you have to specify the public key as a deploy key for yourproject. This can be done as shown below:

    GitHub

    Gitlab

    For OpenShift to be able to access a private repository, the Gitlab instance needs to be configured for SSH access.

    5.4. How to use a private repository (on e.g. Github) to run S2I builds 17

  • APPUiO User Documentation Documentation, Release 1.0

    3. Save the private key in an OpenShift secret

    Add a new ssh secret to your OpenShift project, specyfing the path of your ssh private key:

    $ oc secrets new-sshauth sshsecret --ssh-privatekey=id_rsasecret/sshsecret

    A new secret called sshsecret has been added. In order to allow OpenShift to pull your repository, the newly savedsecret also has to be linked to the builder service account:

    $ oc secrets link builder sshsecret

    A more detailed explanation of this step can be found in the official documentation.

    4. Create a new build config in OpenShift

    Now that OpenShift knows your private key and the builder is able to use it, you can create a new S2I build configu-ration, specifying your private repository as a source.

    Create a new build config using the following command (while in your projects directory with git remotes defined):

    $ oc new-build s2i-builder-image~SSH_REPO_URL --name="new-bc"

    The s2i-builder-image above specifies the S2I-builder image OpenShift is going to use to build yourapplication source. SSH_REPO_URL should be replaced with the path of your repository, for [email protected]:john/example_project.git.

    As a final step, add the sshsecret to the newly created build config new-bc:

    $ oc set build-secret --source bc/new-bc sshsecret

    You should now be able to successfully run your source-to-image builds on OpenShift.

    All of those steps are also explained in the official documentation.

    18 Chapter 5. How Tos

    https://docs.openshift.org/latest/dev_guide/builds.html#ssh-key-authenticationmailto:[email protected]://docs.openshift.org/latest/dev_guide/builds.html#ssh-key-authentication

  • CHAPTER 6

    Troubleshooting

    Read Logs

    Pods

    To access Pod logs, there are several ways:

    Running Pod: oc logs or via Web Console

    Not running Pod (f.e. failed): oc logs --previous

    Builds

    To see build logs, use:

    oc logs bc/

    oc logs -f bc/

    Start a new build:

    oc start-build

    oc logs

    oc logs --help gives several examples and help for reading log files

    19

  • APPUiO User Documentation Documentation, Release 1.0

    Common Errors

    Build fails after successful push

    Problem: The Openshift project app and base image have the same name causing Openshift to use the sameImageStreamTag for source and destination. ` Pushed 13/13 layers, 100% complete Registryserver Address: Registry server User Name: serviceaccount Registry serverEmail: [email protected] Registry server Password: error: build error: Failed to push image: errors: manifest blob unknown:blob unknown to registry manifest blob unknown: blob unknown to registrymanifest blob unknown: blob unknown to registry manifest blob unknown: blobunknown to registry ` Solution: Use a different app name: oc new-app name. Since oc version 1.5/3.5 thenew-app command throws an error if there is a conflict.

    20 Chapter 6. Troubleshooting

  • CHAPTER 7

    FAQ (Technical)

    Can I run Containers/Pods as root?

    This is not possible due to security restrictions. For more information, see Root Access to Docker Images

    What do we monitor?

    The functionality of OpenShift and all involved services are completely monitored and operated by VSHN. Individualprojects are not monitored out of the box - but Kubernetes already has health checks integrated and running. Alsoreplication controllers make sure that Pods are running all the time. If you need a more complex monitoring for yourproject, feel free to contact us under support.

    More information can also be found here: Application Health

    What do we backup?

    We backup all data relevant to run the OpenShift cluster. Application data itself is not in the default backup and is theresponsibility of the user. However we can provide a backup service for individual projects. Please contact us undersupport for more information.

    What DNS entries should I add to my custom domain?

    When creating an application route, the platform automatically generates a URL which is immediately accessible,f.e. http://django-psql-example-my-project.appuioapp.ch due to wildcard DNS entries under*.appuioapp.ch. If you now want to have this application available under your own custom domain, follow thesesteps:

    1. Edit the route and change the hostname to your desired hostname, f.e. www.myapp.ch

    21

    https://forum.appuio.ch/topic/7/root-access-to-docker-imagesmailto:[email protected]://docs.openshift.com/enterprise/latest/dev_guide/application_health.htmlmailto:[email protected]

  • APPUiO User Documentation Documentation, Release 1.0

    2. Point your DNS entry using a CNAME resource record type (important!) to cname.appuioapp.ch

    Always create a route before pointing a DNS entry to APPUiO, otherwise someone else could create a matchting routeand serve content under your domain.

    How can I secure the access to my web application?

    OpenShift supports secure routes and everything is prepared on APPUiO to have it secured easily. Just edit the routeand change the termination type to edge. There is a default trusted certificate in place for *.appuioapp.ch whichis used in this case. If you want to use your own certificate, see Routes.

    Were actively working to get support for Lets Encrypt. Coming soon!

    22 Chapter 7. FAQ (Technical)

    https://docs.openshift.com/enterprise/latest/dev_guide/routes.html

  • CHAPTER 8

    PHP Source to Image Sample

    Check out the APPUiO PHP source-to-image sample app.

    23

    https://github.com/appuio/example-php-sti-helloworld

  • APPUiO User Documentation Documentation, Release 1.0

    24 Chapter 8. PHP Source to Image Sample

  • CHAPTER 9

    PHP Docker Build Sample App

    Check out the APPUiO PHP docker build sample app.

    25

    https://github.com/appuio/example-php-docker-helloworld

  • APPUiO User Documentation Documentation, Release 1.0

    26 Chapter 9. PHP Docker Build Sample App

  • CHAPTER 10

    PHP 7 with Apache Source to Image Example

    This is a PHP 7 Apache Source to image example based on the following s2i Builder

    https://github.com/getupcloud/sti-php.git

    Note: at the moment no official php 7 sti image is available: https://github.com/sclorg/s2i-php-container

    Build Builder

    To use the builder we need to build it first, since it is not yet available as official builder

    Create new Project and create app:

    oc new-project php7example

    Create Builder with oc client:

    oc new-app https://github.com/getupcloud/sti-php.git --strategy=docker --context-dir='7.0' --name="php7-apache-s2i"oc delete svc php7-apache-s2ioc delete dc php7-apache-s2i

    Create Builder by template, and build builder:

    oc new-app -f https://raw.githubusercontent.com/appuio/example-php-sti-helloworld/master/template/php7apaches2ibuilder-template.json

    You have to wait until the builder is ready

    Deploy App

    Build, deploy and create the PHP s2i App:

    27

    https://github.com/getupcloud/sti-php.githttps://github.com/sclorg/s2i-php-container

  • APPUiO User Documentation Documentation, Release 1.0

    oc new-app php7-apache-s2i~https://github.com/appuio/example-php-sti-helloworld.git

    28 Chapter 10. PHP 7 with Apache Source to Image Example

  • CHAPTER 11

    PHP 7 with Nginx Source to Image Example

    This is a PHP 7 Nginx Source to image example based on the following s2i Builder

    https://github.com/appuio/s2i-nginx-php7-container.git

    Note: at the moment no official php 7 sti image is available: https://github.com/sclorg/s2i-php-container

    Please consider this example as tech preview

    Build Builder

    To use the builder we need to build it first, since it is not yet available as official builder

    Create new Project and create app:

    oc new-project php7example

    Create Builder with oc client:

    oc new-app https://github.com/appuio/s2i-nginx-php7-container.git --strategy=docker --context-dir='7.0' --name="php7-nginx-s2i"oc delete svc php7-nginx-s2ioc delete dc php7-nginx-s2i

    Create Builder by template, and build builder:

    oc new-app -f https://raw.githubusercontent.com/appuio/example-php-sti-helloworld/master/template/php7nginxs2ibuilder-template.json

    You have to wait until the builder is ready

    29

    https://github.com/appuio/s2i-nginx-php7-container.githttps://github.com/sclorg/s2i-php-container

  • APPUiO User Documentation Documentation, Release 1.0

    Deploy App

    Build, deploy and create the PHP s2i App:

    oc new-app php7-nginx-s2i~https://github.com/appuio/example-php-sti-helloworld.git

    30 Chapter 11. PHP 7 with Nginx Source to Image Example

  • CHAPTER 12

    MySql Backup Image

    use the APPUiO MySql Backup Container to easily backup your MySql Databases inside an APPUiO project.

    checkout: https://github.com/appuio/mysql-simple-backup-container

    31

    https://github.com/appuio/mysql-simple-backup-container

  • APPUiO User Documentation Documentation, Release 1.0

    32 Chapter 12. MySql Backup Image

  • CHAPTER 13

    PostgreSQL Backup Image (the manual way)

    Use the Crunchy Data PostgreSQL Backup Container to easily backup your PostgreSQL Databases inside an APPUiOproject:

    git clone https://github.com/CrunchyData/crunchy-containers.gitcd examples/openshift/backup-job/

    The backup job requires a persistent volume type such as NFS be mounted by the backup container. APPUiO providesthe Persistent Volume (PV), so the first step to use the backup container is to create a Persistent Volume Claim (PVC).

    oc create -f backup-job-pvc.json

    First we need a admin user on the PostgreSQL database to be able to do a WAL backup. Therefore you should edit thedeployment config of the database container and add the following env variable:

    name: POSTGRESQL_ADMIN_PASSWORDvalue: yourPassword

    Create the backup job and container:

    oc process -f backup-job-nfs.json \-v CCP_IMAGE_TAG="1.2.1"\DATABASE_HOST="postgres",DATABASE_USER="postgres",\DATABASE_PASS="yourPassword",DATABASE_PORT=5432 \

    | oc create -f -

    Note, that the BACKUP_PASS value has to be the same password as configured in the postgres deployment descrip-tion.

    33

  • APPUiO User Documentation Documentation, Release 1.0

    34 Chapter 13. PostgreSQL Backup Image (the manual way)

  • CHAPTER 14

    Spring Boot Application

    This example describes how to deploy a Spring Boot Application to APPUiO. It is based on the following example:

    https://github.com/appuio/example-spring-boot-helloworld

    which is based on the docker build workflow and builds the java artifact during docker build step with gradle. Thesame concept applies if you want to use maven as your build too.

    Dockerfile

    During Docker build the following steps are executed

    1. install Java

    2. build Spring Boot Application

    3. deploy to correct location

    Dockerfile:

    FROM openshift/base-centos7

    ...

    EXPOSE 8080

    ...

    # Install JavaRUN INSTALL_PKGS="tar unzip bc which lsof java-1.8.0-openjdk java-1.8.0-openjdk-devel" && \

    yum install -y $INSTALL_PKGS && \rpm -V $INSTALL_PKGS && \yum clean all -y && \mkdir -p /opt/s2i/destination

    35

    https://github.com/appuio/example-spring-boot-helloworld

  • APPUiO User Documentation Documentation, Release 1.0

    USER 1001

    # add application source

    ADD ./gradlew /opt/app-root/src/ADD gradle /opt/app-root/src/gradleADD build.gradle /opt/app-root/src/ADD src /opt/app-root/src/src

    # buildRUN sh /opt/app-root/src/gradlew build# copy to correct locationRUN cp -a /opt/app-root/src/build/libs/springboots2idemo*.jar /opt/app-root/springboots2idemo.jar

    CMD java -Xmx64m -Xss1024k -jar /opt/app-root/springboots2idemo.jar

    Deployment

    Create new Project if needed:

    oc new-project example-spring-boot

    Create app and expose the service, to be able to reach the app from the internet:

    oc new-app https://github.com/appuio/example-spring-boot-helloworld.git --strategy=docker --name=appuio-spring-boot-exoc expose service appuio-spring-boot-ex

    Add ephemeral mysql Database, this step is optional, by default Spring Boot uses a ephemeral internal H2 Database:

    oc new-app mysql-ephemeral -pMYSQL_USER=appuio -pMYSQL_PASSWORD=appuio -pMYSQL_DATABASE=appuio -pDATABASE_SERVICE_NAME=mysql

    Warning: do use ephemeral databases only for testing purposes, use databases with persistent volumes attached forproduction environments

    Configuration

    basically Spring Boot Applications can be configured out of the box by setting environment variables. This meansthere is no wrapping mechanism needed to be able to set configuration values in your Spring Application. http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

    The only thing you have to do is to set the environment variables in the given Deployment Config.

    For example set the connection parameters for our database connection:

    oc env dc appuio-spring-boot-ex -e SPRING_DATASOURCE_URL=jdbc:mysql://mysql/appuio?autoReconnect=true \-e SPRING_DATASOURCE_USERNAME=appuio -e SPRING_DATASOURCE_PASSWORD=appuio \-e SPRING_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.jdbc.Driver

    36 Chapter 14. Spring Boot Application

    http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.htmlhttp://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

  • CHAPTER 15

    Spring Boot Application with Angular 2 Frontend

    This example describes how to deploy a Spring Boot Application to APPUiO. It is based on the following example:

    https://github.com/KeeTraxx/springboot-workshop

    which is based on the docker build workflow and builds the java artifact during docker build step with gradle. Thesame concept applies if you want to use maven as your build too.

    Dockerfile

    During Docker build the following steps are executed

    1. install Java

    2. build Spring Boot Application

    Dockerfile:

    FROM openshift/base-centos7

    EXPOSE 8080

    # Install JavaRUN INSTALL_PKGS="tar unzip bc which lsof java-1.8.0-openjdk java-1.8.0-openjdk-devel" && \

    yum install -y $INSTALL_PKGS && \rpm -V $INSTALL_PKGS && \yum clean all -y && \mkdir -p /opt/s2i/destination

    USER 1001

    # add application source

    ADD . /opt/app-root/src

    37

    https://github.com/KeeTraxx/springboot-workshop

  • APPUiO User Documentation Documentation, Release 1.0

    # buildRUN sh /opt/app-root/src/gradlew build

    CMD java -Xmx64m -Xss1024k -jar /opt/app-root/src/build/libs/*.jar

    Deployment

    Create new Project if needed:

    oc new-project spring-boot-angular

    Create app and expose the service, to be able to reach the app from the internet:

    oc new-app https://github.com/KeeTraxx/springboot-workshop.git --strategy=docker --name=spring-boot-angular-exoc expose service spring-boot-angular-ex

    Configuration

    Basically Spring Boot Applications can be configured out of the box by setting environment variables. This meansthere is no wrapping mechanism needed to be able to set configuration values in your Spring Application. http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

    The only thing you have to do is to set the environment variables in the given deployment config.

    For example set the connection parameters for our database connection:

    oc env dc spring-boot-angular-ex -e SPRING_DATASOURCE_URL=jdbc:mysql://mysql/appuio?autoReconnect=true \-e SPRING_DATASOURCE_USERNAME=appuio -e SPRING_DATASOURCE_PASSWORD=appuio \-e SPRING_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.jdbc.Driver

    38 Chapter 15. Spring Boot Application with Angular 2 Frontend

    http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.htmlhttp://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

  • CHAPTER 16

    Java EE Source to Image

    This example describes how to deploy a Java EE Application to APPUiO using the source to image workflow. It isbased on the following example:

    https://github.com/appuio/example-jee-s2i

    and uses maven as build tool.

    Deployment via oc Client

    Create new Project if needed:

    oc new-project example-jee-s2i

    Create app and expose the service, to be able to reach the app from the internet:

    oc new-app https://github.com/appuio/example-jee-s2i.git --name=appuio-jee-s2ioc expose service appuio-jee-s2i

    Deployment via webconsole

    1. create new Project

    2. Add to Project

    3. Choose wildfly

    4. enter a name and the repository URL: https://github.com/appuio/example-jee-s2i.git

    39

    https://github.com/appuio/example-jee-s2ihttps://github.com/appuio/example-jee-s2i.git

  • APPUiO User Documentation Documentation, Release 1.0

    Configuration

    To overwrite the default standalone configuration you can add your own standalone.xml in the source repository under

    ./cfg/

    Speed up your build

    With S2I you can use incremental builds to speed up the build. Build artifacts like maven dependencies will be cached.

    set incremental to true in your build config

    oc edit bc appuio-jee-s2i

    strategy:type: "Source"sourceStrategy:from:

    kind: "ImageStreamTag"name: "appuio-jee-s2i-image:latest"

    incremental: true

    40 Chapter 16. Java EE Source to Image

  • CHAPTER 17

    Docker Image

    This example shows how to deploy a pre built docker image to APPUiO. At the moment APPUiO only works withDocker schema 1 Docker Images.

    Create new Project if needed:

    oc new-project dockerimage

    Deploy Image from Dockerhub and expose the service, to be able to reach the app from the internet:

    oc new-app appuio/example-spring-boot --name=appuio-spring-boot-exoc expose service appuio-spring-boot-ex

    APPUiO downloads the Docker image with the given name and deploys the image.

    Please consider the image creation Guide: https://docs.openshift.com/enterprise/3.2/creating_images/guidelines.html

    Check out our Techlab for further infos https://github.com/appuio/techlab/blob/lab-3.2/labs/04_deploy_dockerimage.md

    41

    https://docs.openshift.com/enterprise/3.2/creating_images/guidelines.htmlhttps://github.com/appuio/techlab/blob/lab-3.2/labs/04_deploy_dockerimage.mdhttps://github.com/appuio/techlab/blob/lab-3.2/labs/04_deploy_dockerimage.md

  • APPUiO User Documentation Documentation, Release 1.0

    42 Chapter 17. Docker Image

  • CHAPTER 18

    Deploy Static Content to APPUiO

    This example describes how to deploy static content, like html files, images, videos, css, js to APPUiO.

    Apache based image

    As base image we are going to use the php:latest OpenShift base image, this image is supported and includes anApache. In our case it is going to serve the static content.

    The following two workflows are supported

    Source To image Workflow from Git Repository

    the simplest way to deploy static content to APPUiO is by using the source to image workflow

    The source to image deployment basically scans the git repository and decides based on some rules on how to buildthe source code located in the respository. In our case the static content does not need to be built, therefore it simplycopies the content to the correct location.

    /opt/app-root/src

    The source to image (S2I) workflow is very powerful, in our example we only use the basic build method. The S2Iworkflow can easily be extended, by running custom assemble and run scripts. Check out: https://docs.openshift.com/enterprise/latest/creating_images/s2i.html for further information

    CLI

    Creating a new App inside a project

    Note: please check the getting started guide for more information about creating an account, downloading the cli,login and on how to create a new APPUiO project.

    43

    https://docs.openshift.com/enterprise/latest/using_images/s2i_images/index.htmlhttps://docs.openshift.com/enterprise/latest/creating_images/s2i.htmlhttps://docs.openshift.com/enterprise/latest/creating_images/s2i.html

  • APPUiO User Documentation Documentation, Release 1.0

    oc new-app [builderimage]~[gitrepository]

    RHEL

    oc new-app rhscl/php-56-rhel7~https://github.com/appuio/example-php-sti-helloworld.git

    or in case you want to use the centos based image:

    oc new-app centos/php-56-centos7~https://github.com/appuio/example-php-sti-helloworld.git

    Note: use oc expose service [servicename]

    Webconsole

    You can also deploy the static content by using the webconsole.

    Navigate to your project overview

    click add to project

    choose base builder image php:latest

    enter git repository url where the static content is located: eg. https://github.com/appuio/example-php-sti-helloworld.git

    click create

    the app build is triggered and automatically deployed.

    Docker Build Workflow

    The second way to deploy your static content to APPUiO is the docker build. This approach is way more flexible,therefore you have the possibility to either install additional packages inside the image and to customize the buildprocess of your application.

    Anyway, in our case we simply add the static content which is located in the app directory in our repository to thedocker image:

    Dockerfile:

    FROM openshift/php-56-centos7

    ADD app /opt/app-root/src

    CMD $STI_SCRIPTS_PATH/run

    CLI

    Creating a new app inside a project

    oc new-app [builderimage] --strategy=docker

    for example:

    44 Chapter 18. Deploy Static Content to APPUiO

    https://github.com/appuio/example-php-sti-helloworld.githttps://github.com/appuio/example-php-sti-helloworld.git

  • APPUiO User Documentation Documentation, Release 1.0

    oc new-app https://github.com/appuio/example-php-docker-helloworld.git --strategy=docker

    nginx based image

    The deployment of your static content inside an nginx based container works similar to the apache based

    Source To image

    You can trigger the deployment with the following command

    oc new-app centos/nginx-18-centos7~https://github.com/appuio/example-nginx-helloworld.git

    Docker Build

    Just change the Base image to the centos nginx image in your Dockerfile

    Dockerfile:

    FROM centos/nginx-18-centos7

    ADD app /opt/app-root/src

    CMD $STI_SCRIPTS_PATH/run

    And create the app on APPUiO, which triggers a build and deployment.

    oc new-app https://github.com/appuio/example-nginx-helloworld.git --strategy=docker

    Continuous Integration: Trigger Rebuild

    If you want code changes to trigger rebuilds and redeployments of your application, you can simply add webhooks.APPUiO supports generic and github triggers.

    check out https://docs.openshift.com/enterprise/latest/dev_guide/builds.html#webhook-triggers for further informa-tion.

    18.2. nginx based image 45

    https://docs.openshift.com/enterprise/latest/dev_guide/builds.html#webhook-triggers

  • APPUiO User Documentation Documentation, Release 1.0

    46 Chapter 18. Deploy Static Content to APPUiO

  • CHAPTER 19

    Binary Deployment in Wildfly

    This example describes how to deploy a web archive (war) in Wildfly using the OpenShift client (oc) in binary mode.The example is inspired by Red Hats blog.

    Create a new project

    oc new-project my-wildfly-project

    Create the deployment folder structure

    One or more war can be placed in the deployments folder. In this example an existing war file is downloaded fromGitHub:

    mkdir deploymentswget -O deployments/ROOT.war 'https://github.com/appuio/hello-world-war/blob/master/repo/ch/appuio/hello-world-war/1.0.0/hello-world-war-1.0.0.war?raw=true'

    If the provided standalone.xml does not fit the needs, a custom file can be placed in the cfg folder.

    Create a new build using the Wildfly image

    The flag binary=true indicates that this build will use the binary content instead of the url to the source code.

    oc new-build --docker-image=openshift/wildfly-101-centos7 --binary=true --name=hello-world

    47

    https://blog.openshift.com/binary-input-sources-openshift-3-2/https://github.com/openshift-s2i/s2i-wildfly/blob/master/10.1/contrib/wfcfg/standalone.xml

  • APPUiO User Documentation Documentation, Release 1.0

    Start the build

    To trigger a build issue the command below. In a continuous deployment process this command can be repeatedwhenever there is a new binary or a new configuration available.

    oc start-build hello-world --from-dir=.

    Create a new app

    oc new-app hello-world

    Expose the service as route

    oc expose svc hello-world

    48 Chapter 19. Binary Deployment in Wildfly

  • CHAPTER 20

    Custom Applications

    Check out the OpenShift Creating New Applications Docs for other languages, frameworks and strategies.

    49

    https://docs.openshift.com/enterprise/3.2/dev_guide/new_app.html

  • APPUiO User Documentation Documentation, Release 1.0

    50 Chapter 20. Custom Applications

  • CHAPTER 21

    Node JS 6 Example

    This example describes how to deploy a Node.js to APPUiO. It is based on the following app:

    Easy file upload / download server: https://github.com/topaxi/tmpy

    How to deploy to APPUiO / OpenShift Cluster

    Create a new project

    oc new-project tmpy

    Create app, since tmpy uses Node 6 as runtime, and Node 6 is not yet available in the current scl source-to-imageimages (https://github.com/sclorg/s2i-nodejs-container) we use the origin version available under https://github.com/openshift-s2i/s2i-nodejs-community

    oc new-app ryanj/centos7-s2i-nodejs:6.3.1~https://github.com/topaxi/tmpy.git

    OpenShift Container Platform Version less than 3.3

    If you want to deploy your tmpy to OpenShift Container Platform Version less than 3.3 you will encounter a dockerschema version issue.

    Switch sourceStrategy ImageStreamTag(centos7-s2i-nodejs:6.3.1) to DockerImage (ryanj/centos7-s2i-nodejs:6.3.1):

    oc edit bc tmpy

    Database

    tmpy uses a mongodb to store the state

    51

    https://github.com/topaxi/tmpyhttps://github.com/sclorg/s2i-nodejs-containerhttps://github.com/openshift-s2i/s2i-nodejs-communityhttps://github.com/openshift-s2i/s2i-nodejs-community

  • APPUiO User Documentation Documentation, Release 1.0

    oc new-app mongodb-ephemeral -pDATABASE_SERVICE_NAME=mongodb -pMONGODB_USER=tmpy -pMONGODB_PASSWORD=tmpy -pMONGODB_DATABASE=tmpy

    Configuration

    You now need to configure your App via environment variables add the following configuration to your deployment-Config

    oc env dc tmpy -e TMPY_PORT=8080 -e TMPY_IP=0.0.0.0 -e TMPY_DB_HOST=mongodb -e TMPY_DB_NAME=tmpy -e TMPY_DB_USER=tmpy -e TMPY_DB_PASSWORD=tmpy -e TMPY_HOSTNAME=tmpy.appuio.ch

    52 Chapter 21. Node JS 6 Example

  • CHAPTER 22

    More OpenShift Sample Apps

    This is an overview of sample apps provided by OpenShift:

    CakePHP

    Dancer

    Golang

    Node.js

    Rails

    Ruby

    53

    https://github.com/openshift/cakephp-exhttps://github.com/openshift/dancer-exhttps://github.com/openshift/golang-exhttps://github.com/openshift/nodejs-exhttps://github.com/openshift/rails-exhttps://github.com/openshift/ruby-ex

  • APPUiO User Documentation Documentation, Release 1.0

    54 Chapter 22. More OpenShift Sample Apps

  • CHAPTER 23

    Central Logging

    Contents

    Central Logging

    Elasticsearch Security

    Elasticsearch Retention (Curator)

    Central logging monitoring

    Elasticsearch and Fluentd is used to collect logs from Pods and Syslogs. The official documentation is here: Aggre-gating Container Logs. Even more detailed documentation can be found in various READMEs on the correspondingGithub project.

    Elasticsearch Security

    For security measures the plugin Search Guard is used. It protects Elasticsearch access and does the authenticationand authorization.

    The configuration found in the Elasticsearch Pod under /etc/elasticsearch/elasticsearch.yml lookslike this:

    searchguard:config_index_name: ".searchguard.${HOSTNAME}"key_path: /elasticsearch/${CLUSTER_NAME}allow_all_from_loopback: falseauthentication:authentication_backend:

    impl: com.floragunn.searchguard.authentication.backend.simple.AlwaysSucceedAuthenticationBackend

    authorizer:impl: com.floragunn.searchguard.authorization.simple.SettingsBasedAuthorizator

    55

    https://docs.openshift.com/enterprise/latest/install_config/aggregate_logging.htmlhttps://docs.openshift.com/enterprise/latest/install_config/aggregate_logging.htmlhttps://github.com/openshift/origin-aggregated-logginghttps://github.com/floragunncom/search-guard

  • APPUiO User Documentation Documentation, Release 1.0

    http_authenticator:impl: io.fabric8.elasticsearch.plugin.HTTPSProxyClientCertAuthenticator

    proxy:header: X-Proxy-Remote-Usertrusted_ips: ["*"]

    authorization:settingsdb:

    roles:admin: ["admin"]fluentd: ["fluentd"]kibana: ["kibana"]

    ssl:transport:

    http:keystore_type: JKSkeystore_filepath: /etc/elasticsearch/keys/keykeystore_password: kspassenforce_clientauth: truetruststore_type: JKStruststore_filepath: /etc/elasticsearch/keys/truststoretruststore_password: tspass

    actionrequestfilter:names: ["readonly", "fluentd", "kibana", "admin"]readonly:

    allowed_actions: ["indices:data/read/*", "*monitor*"]forbidden_actions: ["cluster:*", "indices:admin*"]

    fluentd:allowed_actions: ["indices:data/write/*", "indices:admin/create"]

    kibana:allowed_actions: ["indices:data/read/*", "*monitor*", "indices:admin/read",

    "indices:admin/mappings/fields/get*"]

    openshift:acl:users:

    names: ["system.logging.fluentd", "system.logging.kibana", "system.logging.curator"]

    system.logging.fluentd:execute: ["actionrequestfilter.fluentd"]actionrequestfilter.fluentd.comment: "Fluentd can only write"

    system.logging.kibana:bypass: ["*"]execute: ["actionrequestfilter.kibana"]actionrequestfilter.kibana.comment: "Kibana can only read from every other

    index"system.logging.kibana.*.comment: "Kibana can do anything in the kibana index"system.logging.kibana.*.indices: [".kibana.*"]system.logging.curator:

    execute: ["actionrequestfilter.curator"]actionrequestfilter.curator.comment: "Curator can list all indices and delete

    them"system.admin:

    bypass: ["*"]system.admin.*.comment: "Admin user can do anything"

    56 Chapter 23. Central Logging

  • APPUiO User Documentation Documentation, Release 1.0

    Elasticsearch Retention (Curator)

    Detailed documentation is here: Curator.

    Default Curator configuration on APPUiO:

    .defaults:delete:days: 7

    runhour: 0runminute: 0

    Central logging monitoring

    For monitoring and testing the whole logging infrastructure, some scripts are available under origin-aggregated-logging/hack/testing.

    23.2. Elasticsearch Retention (Curator) 57

    https://github.com/openshift/origin-aggregated-logging#curatorhttps://github.com/openshift/origin-aggregated-logging/tree/master/hack/testinghttps://github.com/openshift/origin-aggregated-logging/tree/master/hack/testing

  • APPUiO User Documentation Documentation, Release 1.0

    58 Chapter 23. Central Logging

  • CHAPTER 24

    Node Maintenance

    All details are documented under Managing Nodes.

    Prepare for maintenance

    To get a node into maintenance mode:

    oadm manage-node --schedulable=falseoadm manage-node --evacuate

    To get a node out of maintenance mode:

    oadm manage-node --schedulable

    59

    https://docs.openshift.com/enterprise/latest/admin_guide/manage_nodes.html

  • APPUiO User Documentation Documentation, Release 1.0

    60 Chapter 24. Node Maintenance

  • CHAPTER 25

    Backup of Cluster Components

    etcd

    The following command creates a dump:

    ETCD_DIR=/var/lib/etcdETCD_BAK=${ETCD_DIR}.baketcdctl backup --data-dir $ETCD_DIR --backup-dir $ETCD_BAK

    To restore the data, follow this steps: Restoring etcd

    61

    https://docs.openshift.com/enterprise/latest/install_config/downgrade.html#downgrading-restoring-etcd

  • APPUiO User Documentation Documentation, Release 1.0

    62 Chapter 25. Backup of Cluster Components

  • CHAPTER 26

    Monitoring

    Read-only System Account

    For monitoring cluster resources its important to have a read-only system account.

    echo "{\"kind\":\"ServiceAccount\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"monitoring\"}}" | oc create -n default -f -oadm policy add-cluster-role-to-user view system:serviceaccount:default:monitoringoc get secrets | grep monitoringoc describe secret monitoring-token-XXXXX

    The token can be used to login with oc login --token=TOKEN

    63

  • APPUiO User Documentation Documentation, Release 1.0

    64 Chapter 26. Monitoring

  • CHAPTER 27

    OpenShift Cluster Troubleshooting

    Resources in OpenShift documentation

    OpenShift Network Access, includes required ports

    Troubleshooting OpenShift SDN

    Multi-master etcd

    Report cluster health:

    etcdctl -C https://master1.beta.puzzle.cust.vshn.net:2379,\https://master2.beta.puzzle.cust.vshn.net:2379,\https://master3.beta.puzzle.cust.vshn.net:2379 \--ca-file=/etc/origin/master/master.etcd-ca.crt \--cert-file=/etc/origin/master/master.etcd-client.crt \--key-file=/etc/origin/master/master.etcd-client.key cluster-health

    Issues and their solutions

    Issue: In a multi-master setup the service atomic-openshift-master-api starts successfully but startup takeslonger than usual and it logs the following errors:

    ensure.go:237] waiting for policy cache to initializeensure.go:237] waiting for policy cache to initializeensure.go:237] waiting for policy cache to initialize...ensure.go:243] error waiting for policy cache to initialize: timed out waitingfor the conditionensure.go:256] Could not auto reconcile roles: User "system:anonymous" cannot getclusterroles at the cluster scope

    65

    https://docs.openshift.com/enterprise/3.2/install_config/install/prerequisites.html#prereq-network-accesshttps://docs.openshift.com/enterprise/3.2/admin_guide/sdn_troubleshooting.html

  • APPUiO User Documentation Documentation, Release 1.0

    ensure.go:269] Could not auto reconcile role bindings: User "system:anonymous"cannot get clusterrolebindings at the cluster scopeensure.go:206] Unable to create default security context constraint privileged.Got error: User "system:anonymous" cannot create securitycontextconstraints atthe cluster scopeensure.go:206] Unable to create default security context constraint nonroot. Goterror: User "system:anonymous" cannot create securitycontextconstraints at thecluster scopeensure.go:206] Unable to create default security context constraint hostmount-anyuid. Got error: User "system:anonymous" cannot createsecuritycontextconstraints at the cluster scopeensure.go:206] Unable to create default security context constraint hostaccess.Got error: User "system:anonymous" cannot create securitycontextconstraints atthe cluster scopeensure.go:206] Unable to create default security context constraint restricted.Got error: User "system:anonymous" cannot create securitycontextconstraints atthe cluster scopeensure.go:206] Unable to create default security context constraint anyuid. Goterror: User "system:anonymous" cannot create securitycontextconstraints at thecluster scopeensure.go:206] Unable to create default security context constraint hostnetwork.Got error: User "system:anonymous" cannot create securitycontextconstraints atthe cluster scopeensure.go:107] Error adding service account roles to "default" namespace: User"system:anonymous" cannot get namespaces in project "default"ensure.go:54] Error creating namespace openshift-infra: User "system:anonymous"cannot create namespaces at the cluster scope

    Solution: The master needs to synchronize its cluster policy cache with other masters. In order to do so it needsa valid configuration to login to other masters with the system:openshift-master account in /etc/origin/master/openshift-master.kubeconfig.

    Issue: Docker 1.10 fails to create containers with the following error messages:

    oci-register-machine[5676]: 2016/07/28 15:55:28 Register machine: prestart6c5cd75f3295435df5705defe3ffa40e3e6e6624880df4776a2527e42c710249 5672 /var/lib/docker/devicemapper/mnt/2b4bcf3683c61dc8b9884459cceb6e1e8150d6d9d432118e2703cda66aeea3ac/rootfsforward-journal[4796]: time="2016-07-28T15:55:28.279749573+02:00" level=warningmsg="exit status 2"forward-journal[4796]: time="2016-07-28T15:55:28.438219006+02:00" level=error msg="error locating sandbox id5c13a081bb7f2143e67ef863f4125a3b85f9d15710a09484ac62a1f17ded3a88: sandbox5c13a081bb7f2143e67ef863f4125a3b85f9d15710a09484ac62a1f17ded3a88 not found"forward-journal[4796]: time="2016-07-28T15:55:28.438304065+02:00" level=warningmsg="failed to cleanup ipc mounts:\nfailed to umount /var/lib/docker/containers/6c5cd75f3295435df5705defe3ffa40e3e6e6624880df4776a2527e42c710249/shm: invalidargument"forward-journal[4796]: time="2016-07-28T15:55:28.438333805+02:00" level=error msg="Error unmounting container6c5cd75f3295435df5705defe3ffa40e3e6e6624880df4776a2527e42c710249: not mounted"forward-journal[4796]: time="2016-07-28T15:55:28.438624705+02:00" level=error msg="Handler for POST /containers/6c5cd75f3295435df5705defe3ffa40e3e6e6624880df4776a2527e42c710249/start returnederror: cantstart: Cannot start container6c5cd75f3295435df5705defe3ffa40e3e6e6624880df4776a2527e42c710249: [9] Systemerror: exit status 127"

    66 Chapter 27. OpenShift Cluster Troubleshooting

  • APPUiO User Documentation Documentation, Release 1.0

    forward-journal[4796]: time="2016-07-28T15:55:28.438666200+02:00" level=error msg="Handler for POST /containers/6c5cd75f3295435df5705defe3ffa40e3e6e6624880df4776a2527e42c710249/start returnederror: Cannot start container6c5cd75f3295435df5705defe3ffa40e3e6e6624880df4776a2527e42c710249: [9] Systemerror: exit status 127"

    Solution: The package yajl (Yet Another JSON Library), a dependency of oci-systemd-hook which is in turna dependency of docker, has not been installed because another package provides libyajl.so.2 in anotherlocation, e.g. icinga2-bin. Workaround: yum install yayl on all Docker hosts.

    27.3. Issues and their solutions 67

  • APPUiO User Documentation Documentation, Release 1.0

    68 Chapter 27. OpenShift Cluster Troubleshooting

  • CHAPTER 28

    OpenShift Patch Operations

    oc patch is currently not documented in the official OpenShift documentation. However since oc is an enhancedKubernetes client kubectl the following Kubernetes documentation applies:

    kubectl patch

    PATCH operations

    69

    http://kubernetes.io/docs/user-guide/kubectl/kubectl_patch/https://github.com/kubernetes/kubernetes/blob/master/docs/devel/api-conventions.md#patch-operations

  • APPUiO User Documentation Documentation, Release 1.0

    70 Chapter 28. OpenShift Patch Operations

  • CHAPTER 29

    Persistant Storage

    Resize Gluster Volumes

    The following commands must be executed on every node. To find out which volume is bound to the pod run:

    oc get pv

    Resize the underlying logical volume:

    lvextend /dev/vg_gluster/gluster_vol_16 -L+1G

    The filesystem is now smaller than the volume and must be resized. For xfs use the former command otherwise thelatter:

    xfs_growfs /dev/vg_gluster/gluster_vol_16

    resize2fs /dev/vg_gluster/gluster_vol_16

    Edit the storage capacity inside the persistant volume:

    oc edit pv gluster-pv16

    The persistant volume claim will still show the old size.

    71

  • APPUiO User Documentation Documentation, Release 1.0

    72 Chapter 29. Persistant Storage

  • CHAPTER 30

    Custom Builder

    Configuration

    OpenShift supports customizing the build process for images. APPUiO uses this mechanism to install its own builderfor Docker images.

    The image selection uses the imageConfig key in master-config.yaml (documentation). Default value:

    imageConfig:format: openshift/origin-${component}:${version}latest: false

    Example from a production cluster:

    imageConfig:format: 172.30.1.1:5000/cluster-infra/builder-${component}:${version}latest: false

    Individual build strategies can be [enabled or disabled globally, per user, group or project](https://docs.openshift.org/latest/admin_guide/securing_builds.html).

    73

    https://docs.openshift.org/latest/creating_images/custom.htmlhttps://docs.openshift.org/latest/install_config/master_node_configuration.html#master-config-image-confighttps://docs.openshift.org/latest/admin_guide/securing_builds.htmlhttps://docs.openshift.org/latest/admin_guide/securing_builds.html

  • APPUiO User Documentation Documentation, Release 1.0

    74 Chapter 30. Custom Builder

  • CHAPTER 31

    Introduction

    This documentation has been created with the intention of getting developers ready to automatically deploy their appsto the OpenShift container platform.

    We try to achieve this using an exemplary microservice application with basic functionalities of an online shop. Eachmicroservice is continuously integrated and deployed to APPUiO (our public OpenShift platform), which allows foran independent description of the necessary pipeline as well as the most relevant concepts for the respective use case.

    Before we describe the architecture of our application in more detail, let us shortly summarize what the followingchapters include (in order):

    General Concepts

    Motivation for Docker and OpenShift/APPUiO

    Motivation for Continuous Integration

    Overview of CI tooling (Gitlab CI and Jenkins)

    Overview of Source2Image principles

    Webserver

    Dockerizing a ReactJS application for OpenShift

    Testing and bundling a ReactJS application

    Continuous integration with Gitlab CI

    Deployment strategies for multiple environments

    Tracking of OpenShift configuration alongside the codebase

    Optimizing Gitlab CI configurations using variables and templates

    API

    75

    https://appuio.ch

  • APPUiO User Documentation Documentation, Release 1.0

    Dockerizing a Scala Play! application

    Testing and compiling a Scala Play! application

    Continuous integration with Gitlab CI

    Using OpenShift Source2Image for building a Docker container

    Creating a tailor-made Source2Image builder

    Users

    Dockerizing an Elixir application for OpenShift

    Testing and compiling an Elixir application

    Building a container using Alpine build and runtime containers

    Continuous integration with Gitlab CI

    Orders

    Testing a Python application

    Continuous integration with Jenkins 2 and the OpenShift plugin

    Creating a tailor-made Jenkins slave (runner)

    Using the OpenShift Python builder for S2I

    Architecture of our shop application

    76 Chapter 31. Introduction

  • APPUiO User Documentation Documentation, Release 1.0

    A first clear distinction in our applications architecture can be made between the frontend and the backend of theapplication. The frontend only contains a single service, which is the Webserver. The Webserver is an instance ofNginx that serves some static files (the compiled JS application).

    The backend consists of multiple microservices: the main endpoint (API) that is accessed from the frontend of theapplication, a service that handles user management and authentication (Users), a service that handles order manage-ment (Orders) and a service responsible for sending emails (Mailer). API, Users and Orders each manage their owndatabase to enforce separation of concerns. The API connects to the other services by using their respective RESTendpoints whenever it needs a timely response.

    Structure of this documentation

    This documentation is structured such that we first make sure that you know of the most relevant topics and prerequi-sites for following along later on. The chapter about General Concepts provides a short motivation for concepts likeDocker and OpenShift and guides you to useful resources if you need to deepen your knowledge about those topics.

    The following chapters will each describe one of our services more in depth. We go into how a continuous integrationpipeline might be built and how the respective service might be packaged for OpenShift, as well as several moreadvanced topics. We generally try to account for best practices like the 12-Factor App.

    Where you can find the sources

    The sources for all the parts of this documentation as well as for all the described examples can be found on APPUiOGitHub. The GitHub repositories are synchronized with our internal development repositories and represent the currentstate. The following lists contain all the public resources and repositories that have been created during the writing ofthis documentation:

    Documentation

    https://github.com/appuio/docs in subdirectory services

    Microservices

    Umbrella repository: https://github.com/appuio/shop-example

    API: https://github.com/appuio/shop-example-api

    Orders: https://github.com/appuio/shop-example-orders

    Users (builder): https://github.com/appuio/shop-example-users-builder

    Users (runtime): https://github.com/appuio/shop-example-users

    Webserver: https://github.com/appuio/shop-example-webserver

    Misc

    CI runner for SBT (hub): https://hub.docker.com/r/appuio/gitlab-runner-sbt

    CI runner for SBT (sources): https://github.com/appuio/gitlab-runner-sbt

    CI runner for OC (hub): https://hub.docker.com/r/appuio/gitlab-runner-oc

    CI runner for OC (sources): https://github.com/appuio/gitlab-runner-oc

    31.2. Structure of this documentation 77

    https://12factor.nethttps://github.com/appuiohttps://github.com/appuiohttps://github.com/appuio/docshttps://github.com/appuio/shop-examplehttps://github.com/appuio/shop-example-apihttps://github.com/appuio/shop-example-ordershttps://github.com/appuio/shop-example-users-builderhttps://github.com/appuio/shop-example-usershttps://github.com/appuio/shop-example-webserverhttps://hub.docker.com/r/appuio/gitlab-runner-sbthttps://github.com/appuio/gitlab-runner-sbthttps://hub.docker.com/r/appuio/gitlab-runner-ochttps://github.com/appuio/gitlab-runner-oc

  • APPUiO User Documentation Documentation, Release 1.0

    CI runner for Yarn (hub): https://hub.docker.com/r/appuio/gitlab-runner-yarn

    CI runner for Yarn (sources): https://github.com/appuio/gitlab-runner-yarn

    Vagrant box with necessary tools: https://github.com/appuio/shop-example-vagrant

    78 Chapter 31. Introduction

    https://hub.docker.com/r/appuio/gitlab-runner-yarnhttps://github.com/appuio/gitlab-runner-yarnhttps://github.com/appuio/shop-example-vagrant

  • CHAPTER 32

    General Concepts

    This chapter will introduce some of the most important concepts that you need to know about for the followingchapters. We will shortly motivate the concepts and provide you with the most relevant resources for getting started ordeepening your knowledge on your own.

    Containers

    Containers allow us to package everything we need to run our application right alongside the application. They aresimilar to virtual machines but dont package an entire operating system, which makes them very lightweight. Instead,they build on top of the underlying operating system (most often Linux) and only contain what is specific to theapplication.

    Docker allows us to define what a container should look like using simple configuration files (called Dockerfiles). Ifwe build said configuration files, we get an image that can be run on any machine with the docker binary. The DockerHub provides access to a vast amount of images that have been created by others and that are ready to be pulled andrun.

    The main advantage of containers is that they contain everything they need to run, which guarantees that they run thesame on any machine (in local development as well as in production). This confidence is crucial if one is consideringthe usage of fully automated deployment strategies like Continuous Deployment.

    Relevant Readings / Resources

    1. What is Docker? [Docker Docs]

    2. Official Documentation [Docker Docs]

    3. Dockerfile Reference [Docker Docs]

    4. Dockerfile Best Practices [Docker Docs]

    5. Docker Hub

    79

    https://www.docker.com/what-dockerhttps://docs.docker.comhttps://docs.docker.com/engine/reference/builderhttps://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practiceshttps://hub.docker.com

  • APPUiO User Documentation Documentation, Release 1.0

    Docker Compose

    Most of the time, an application will depend on other containers like databases, caches or other microservices. Tobe able to coordinate the application and its dependencies while developing locally, we can leverage Docker and theDocker Compose toolkit.

    Docker Compose allows us to set up an overall service definition that can contain many interdependent services. Theservice definition is saved in a docker-compose.yml file that can then be tracked alongside the source code.

    A service definition might look as follows:

    1 version: "2.1"2 services:3 # definition for the users service4 users:5 # build the Dockerfile in the current directory6 build: .7 # specify environment variables for the users service8 environment:9 SECRET_KEY: "abcd"

    10 # specify ports that the users service should publish11 ports:12 - "4000:4000"13

    14 # definition for the associated database15 users-db:16 # specify the image the users-db should run17 image: postgres:9.5-alpine18 # specify environment variables for the users-db service19 environment:20 POSTGRES_USER: users21 POSTGRES_PASSWORD: secret

    On running docker-compose up --build, this configuration will build the users service and pull the Post-greSQL database image. It will then start up both services and expose them with their hostname corresponding totheir name in the service definition. This means that the users service can connect to the database using the hostnameusers-db.

    We provide such docker-compose configuration files for every service independently as well as in the form ofan umbrella docker-compose file that allows to start-up the entire application. The umbrella can be found onhttps://github.com/appuio/shop-example. Please make sure also to include the submodules (i.e. using git clone--recursive -j8 https://github.com/appuio/shop-example).

    Note: A problem with such simple configurations is that the database usually performs an initialization processbefore starting up (creating indices etc.). If both services are started simultaneously, the users service will be unableto connect to the database.

    To circumvent this, we need to have the users service wait for the database to finish its initialization. This topic willbe addressed in later chapters, as it will not only matter in local development but also once the services are deployed.

    Relevant Readings / Resources

    1. Overview of Docker Compose [Docker Docs]

    80 Chapter 32. General Concepts

    https://github.com/appuio/shop-examplehttps://docs.docker.com/compose/overview

  • APPUiO User Documentation Documentation, Release 1.0

    Continuous Integration

    Modern continuous integration tools enable us to automate many tedious aspects of the software development lifecycle.We can configure these tools such that they automatically perform jobs like testing and compiling the application anddeploying a new release.

    These tools work especially well if we use them in conjunction with containers, as we can have the tool build acontainer from our sources, test the container and possibly directly deploy the new version of the container. As we areconfident that containers run the same on all environments, we can trust that the container built and tested in CI willalso run where we deployed it to.

    There are many CI tools around with all of them providing similar functionalities, which might make choosing betweenthem quite hard. To account for this diversity, we will use two very popular CI tools to continuously integrate ourmicroservices: Jenkins and Gitlab.

    Relevant Readings / Resources

    1. Continuous Integration [Wikipedia]

    2. Docker for CI/CD

    Jenkins

    Jenkins is the most popular open-source continuous integration solution. With a vast amount of plugins available, it isextendable to be able to fit almost any use case.

    To use Jenkins, you need to create a so-called Jenkinsfile that specifies all the jobs (the pipeline) that Jenkins shouldexecute. You also need to add a webhook to your source repository such that Jenkins gets notified on changes to thecodebase.

    A real example on using Jenkins for continuous integration will be presented in the chapter on the Orders microser-vice.

    Relevant Readings / Resources

    1. Getting Started [Jenkins Docs]

    2. Jenkinsfile [Jenkins Docs]

    Gitlab CI

    Gitlab CI is a continuous integration solution that is provided by the popular Git repository manager Gitlab. It isseamlessly integrated into the repository management functionality, which makes its usage very convenient. Thedownside is that it is only usable if Gitlab is used for repository management. If you use GitHub or similar, you willneed to find another solution (Jenkins, Travis CI, etc.).

    To use Gitlab CI, simply create a .gitlab-ci.yml with job definitions and store it in your source repository. Gitlab CIwill automatically execute your pipeline on any changes to the codebase.

    We will see examples for using Gitlab CI in the chapters about the Webserver, API and Users services.

    Relevant Readings / Resources

    1. Quick Start [Gitlab Docs]

    32.2. Continuous Integration 81

    https://en.wikipedia.org/wiki/Continuous_integrationhttps://www.docker.com/use-cases/cicdhttps://jenkins.io/doc/pipeline/tour/hello-worldhttps://jenkins.io/doc/book/pipeline/jenkinsfilehttps://docs.gitlab.com/ce/ci/quick_start

  • APPUiO User Documentation Documentation, Release 1.0

    2. Config with .gitlab-ci.yml [Gitlab Docs]

    Usage with Docker

    A feature that we find especially useful is that jobs can be run inside a Docker container. Instead of having to installdependencies for testing, building, etc. during execution of our job, we can simply specify a docker image that alreadyincludes all those dependencies and execute the job within this image. In many cases, this is as easy as using anofficially maintained docker image from the Hub.

    If we need a very specific configuration or dependencies while executing our job, we can build a tailor-made dockerimage just for running the job. We will describe how to create a custom runner later on in this documentation.

    Relevant Readings / Resources

    1. Using Docker Images [Gitlab Docs]

    OpenShift / Kubernetes

    Once you start using containers for more than small demo applications, you are bound to encounter challenges suchas scalability and reliability. Docker is an excellent tool in itself, but as soon as an application consists of severalcontainers that probably depend on each other, a need for orchestration arises.

    Orchestrators are pieces of software that have been built to handle exactly those types of problems. An orchestratororganizes multiple services such that they appear as a single service to the outside, allows scaling of those services,handles load-balancing and more. All of this can be done on a single machine as well as on a cluster of servers. Avery popular orchestration software is Kubernetes (K8S), which was originally developed by Google.

    Adding another layer on top, RedHat OpenShift provides a complete Platform-as-a-Service solution based on Ku-bernetes. It extends Kubernetes with features for application lifecycle management and DevOps and is easier to getstarted with. Our public cloud platform APPUiO runs on the OpenShift container platform, which is the enterpriseversion of OpenShift (with OpenShift Origin as an upstream).

    Relevant Readings / Resources

    1. User-Guide [Kubernetes Docs]

    2. What is K8S [Kubernetes Docs]

    3. Developer Guide [OpenShift Docs]

    4. APPUiO Documentation

    5. OpenShift Origin [GitHub]

    Source2Image

    Instead of writing a Dockerfile that extends some base image and building it with docker build, OpenShift in-troduces an alternative way of packaging applications into containers. The paradigm - which they call Source2Imageor short S2I - suggests that given your applications sources and a previously prepared builder image, you inject thesources into the builder container, run an assemble script inside the builder and commit the container. This will havecreated a runnable version of your application, which you can run using another command.

    82 Chapter 32. General Concepts

    https://docs.gitlab.com/ce/ci/yamlhttps://docs.gitlab.com/ce/ci/docker/using_docker_images.htmlhttps://kubernetes.io/docs/user-guidehttps://kubernetes.io/docs/whatisk8shttps://docs.openshift.com/container-platform/3.4/dev_guide/index.htmlhttp://docs.appuio.ch/en/latesthttps://github.com/openshift/origin

  • APPUiO User Documentation Documentation, Release 1.0

    This works very well for dynamic languages like Python where you dont need to compile the application beforehand.The OpenShift Container Platform already provides several such builder images (Python, PHP, Ruby, Node.js, etc.) soyou would only need to inject your sources and your application would be ready to run. We will use this strategy fordeployment of our Python microservice later on.

    For compiled languages like Java, this approach means that the compile-time dependencies would also be includedin the runtime image, which could heavily bloat that image and pose a security risk. S2I would allow us to providea runtime image for running the application after the builder image has assembled it. However, this is not yet fullyimplemented in OpenShift (it is still an experimental feature).

    There will also be cases where you cant find an S2I builder image that fits your use-case. A possible solution can beto create a custom builder that is tailor-made for the application. We will see how we can use such a custom builder inthe