diff --git a/_data/home-content.yml b/_data/home-content.yml index fce2a45e..4fdd3592 100644 --- a/_data/home-content.yml +++ b/_data/home-content.yml @@ -1,5 +1,21 @@ +- title: Example catalog + icon: images/home-icons/tutorial.svg + url: '' + links: + - title: CI/CD examples for pipelines + localurl: /docs/example-catalog/examples/ + - title: CI examples + localurl: /docs/example-catalog/ci-examples + - title: CD examples + localurl: /docs/example-catalog/cd-examples + - title: GitOps examples + localurl: /docs/example-catalog/gitops-examples + + + + - title: Deployments icon: images/home-icons/deployment.svg diff --git a/_data/nav.yml b/_data/nav.yml index eeb18f1c..681b2dce 100644 --- a/_data/nav.yml +++ b/_data/nav.yml @@ -1,4 +1,120 @@ + + + +- title: Example catalog + url: "/example-catalog" + pages: + - title: "CI/CD examples for pipelines" + url: "/examples" + - title: "CI examples" + url: "/ci-examples" + sub-pages: + - title: Check out Git repositories + url: "/git-checkout" + - title: Custom Git commmands + url: "/git-checkout-custom" + - title: Non-Git checkouts + url: "/non-git-checkout" + - title: Use Git Hash in CI + url: "/get-short-sha-id-and-use-it-in-a-ci-process" + - title: Build an Image with the Dockerfile in root directory + url: "/build-an-image-with-the-dockerfile-in-root-directory" + - title: Build an Images specifying Dockerfile Location + url: "/build-an-image-specify-dockerfile-location" + - title: Build an Image from a different Git repository + url: "/build-an-image-from-a-different-git-repository" + - title: Build and push an Image + url: "/build-and-push-an-image" + - title: Build an Image with build arguments + url: "/build-an-image-with-build-arguments" + - title: Share data between steps + url: "/shared-volumes-between-builds" + - title: Upload/download from Google Storage buckets + url: "/uploading-or-downloading-from-gs" + - title: Call other pipelines + url: "/call-child-pipelines" + - title: Run unit tests + url: "/run-unit-tests" + - title: Run integration tests + url: "/run-integration-tests" + - title: Fan-in/fan-out with unit tests + url: "/fan-in-fan-out" + - title: Codecov coverage reports + url: "/codecov-testing" + - title: Coveralls coverage reports + url: "/coveralls-testing" + - title: Codacy coverage reports + url: "/codacy-testing" + - title: Run integration tests with Mongo + url: "/integration-tests-with-mongo" + - title: Run integration tests with MySQL + url: "/integration-tests-with-mysql" + - title: Run integration tests with PostgreSQL + url: "/integration-tests-with-postgres" + - title: Run integration tests with Redis + url: "/integration-tests-with-redis" + - title: Populate a database with existing data + url: "/populate-a-database-with-existing-data" + - title: Share volumes in composition steps + url: "/shared-volumes-of-service-from-composition-step-for-other-yml-steps" + - title: Import data to MongoDB + url: "/import-data-to-mongodb" + - title: Vault Secrets in the Pipeline + url: "/vault-secrets-in-the-pipeline" + - title: Decrypt with Mozilla SOPS + url: "/decryption-with-mozilla-sops" + - title: GitOps secrets + url: "/gitops-secrets" + - title: Launch Composition + url: "/launch-composition" + - title: Use Docker compose + url: "/launching-a-composition-and-defining-a-service-environment-variables-using-a-file" + - title: Send notification to Slack + url: "/sending-the-notification-to-slack" + - title: Send notification to Jira + url: "/sending-the-notification-to-jira" + - title: "CD examples" + url: "/cd-examples" + sub-pages: + - title: Import data to MongoDB + url: "/import-data-to-mongodb" + - title: NodeJS + Angular2 + MongoDB + url: "/nodejs-angular2-mongodb" + - title: Secure a Docker Container Using HTTP Basic Auth + url: "/secure-a-docker-container-using-http-basic-auth" + - title: Spring Boot + Kafka + Zookeeper + url: "/spring-boot-kafka-zookeeper" + - title: Web terminal + url: "/web-terminal" + - title: Trigger a K8s Deployment from a DockerHub Push Event + url: "/trigger-a-k8s-deployment-from-docker-registry" + - title: Deploy to VM + url: "/packer-gcloud" + - title: Deploy to a VM via FTP + url: "/transferring-php-ftp" + - title: Deploy to Tomcat using SCP + url: "/deploy-to-tomcat-via-scp" + - title: Deploy with Helm + url: "/helm" + - title: Deploy with Terraform + url: "/terraform" + - title: Deploy with Pulumi + url: "/pulumi" + - title: Deploy to Nomad + url: "/nomad" + - title: Deploy to Heroku + url: "/deploy-to-heroku" + - title: Use kubectl as part of Freestyle step + url: "/use-kubectl-as-part-of-freestyle-step" + - title: Deploy with Kustomize + url: "/deploy-with-kustomize" + - title: Deploy to Docker Swarm + url: "/docker-swarm" + - title: Amazon ECS/Fargate + url: "/amazon-ecs" + - title: Elastic Beanstalk + url: "/elastic-beanstalk" - title: Deployments url: "/deployments" pages: @@ -179,6 +295,7 @@ url: "/administration" pages: - title: Account & user management + url: /account-user-management sub-pages: - title: Create a Codefresh account url: "/create-codefresh-account" @@ -204,6 +321,10 @@ - title: Single Sign-On url: /single-sign-on pages: + - title: SSO Overview + url: /sso-overview + - title: Common configuration + url: /team-sync - title: OpenID Connect url: /oidc sub-pages: @@ -230,8 +351,7 @@ url: /saml-pingid - title: LDAP url: /ldap - - title: Common configuration - url: /team-sync + - title: Reference diff --git a/_docs/administration/account-user-management/access-control.md b/_docs/administration/account-user-management/access-control.md index d65e29c7..854374cb 100644 --- a/_docs/administration/account-user-management/access-control.md +++ b/_docs/administration/account-user-management/access-control.md @@ -12,7 +12,7 @@ toc: true --- -Codefresh provides several complementary ways for access control within an organization: +Codefresh provides seral complementary ways for access control within an organization: * **Role-based access**: [Role-based access](#users-and-administrators), restricts access to parts of the Codefresh UI intended for account administrators. For example, only an account administrator should be able to change integrations with [git providers]({{site.baseurl}}/docs/integrations/git-providers/) and [cloud services]({{site.baseurl}}/docs/deployments/kubernetes/add-kubernetes-cluster/). @@ -51,10 +51,10 @@ The table below lists the functionality available for role-based access. |[External Helm repositories]({{site.baseurl}}/docs/new-helm/add-helm-repository/) | `Admin`| |[Cloud provider settings]({{site.baseurl}}/docs/deployments/kubernetes/add-kubernetes-cluster/) | `Admin`| |[Cloud storage settings]({{site.baseurl}}/docs/testing/test-reports/#connecting-your-storage-account) | `Admin`| -|[Shared configuration]({{site.baseurl}}/docs/configure-ci-cd-pipeline/shared-configuration/) | `Admin`| +|[Shared configuration]({{site.baseurl}}/docs/pipelines/shared-configuration/) | `Admin`| |[API token generation]({{site.baseurl}}/docs/integrations/codefresh-api/#authentication-instructions) | `Admin`| |[SSO Settings]({{site.baseurl}}/docs/administration/single-sign-on/) | `Admin`| -|[Runtime environment selection]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/#pipeline-settings) | `Admin`| +|[Runtime environment selection]({{site.baseurl}}/docs/pipelines/pipelines/#pipeline-settings) | `Admin`| |[Slack settings]({{site.baseurl}}/docs/integrations/notifications/slack-integration/) | `Admin`| |[Audit logs]({{site.baseurl}}/docs/administration/audit-logs/) | `Admin`| |ABAC for Kubernetes clusters | `Admin`| @@ -184,14 +184,14 @@ For pipelines: * `Update` - see and edit allowed pipelines only (including tagging them). * `Delete` - can delete allowed pipelines only. * `Run` - can run allowed pipelines only. -* `Approve` - resume pipelines that are waiting for manual [approval]({{site.baseurl}}/docs/codefresh-yaml/steps/approval/). -* `Debug` - allow the usage of the [pipeline debugger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/debugging-pipelines/). +* `Approve` - resume pipelines that are waiting for manual [approval]({{site.baseurl}}/docs/pipelines/steps/approval/). +* `Debug` - allow the usage of the [pipeline debugger]({{site.baseurl}}/docs/pipelines/debugging-pipelines/). ## Git-repository access restrictions -By default, users can load pipeline definitions when [creating a pipeline]({{site.baseurl}}/docs/configure-ci-cd-pipeline/pipelines/), from the inline editor, or any private or public Git repository. +By default, users can load pipeline definitions when [creating a pipeline]({{site.baseurl}}/docs/pipelines/pipelines/), from the inline editor, or any private or public Git repository. You can change the default behavior to restrict loading CI pipeline definitions from specific Git repositories or completely disable loading the definitions from all Git repositories. diff --git a/_docs/administration/user-self-management/user-settings.md b/_docs/administration/user-self-management/user-settings.md index ad969ff3..47743fb4 100644 --- a/_docs/administration/user-self-management/user-settings.md +++ b/_docs/administration/user-self-management/user-settings.md @@ -74,7 +74,7 @@ max-width="100%" When you connect your [Git provider]({{site.baseurl}}/docs/integrations/git-providers/) during sign-up, you may choose to let Codefresh access only your public Git repositories. -To allow Codefresh to also add [Git triggers]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/git-triggers/) on private repositories you need to explicitly enable it in this section. +To allow Codefresh to also add [Git triggers]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/) on private repositories you need to explicitly enable it in this section. Note that options available highly depend on what Git provider you are using with Codefresh. --> diff --git a/_docs/example-catalog/cd-examples/amazon-ecs.md b/_docs/example-catalog/cd-examples/amazon-ecs.md new file mode 100644 index 00000000..89905c22 --- /dev/null +++ b/_docs/example-catalog/cd-examples/amazon-ecs.md @@ -0,0 +1,155 @@ +--- +title: "Amazon ECS/Fargate" +description: "Use Codefresh to deploy Docker containers to ECS/Fargate" +group: example-catalog +sub_group: cd-examples +redirect_from: + - /docs/amazon-ecs/ + - /docs/deploy-your-containers/ + - /docs/deploy-your-containers/amazon-ecs/ +toc: true +--- +Codefresh can deploy to any ECS or Fargate cluster created in Amazon. + +{% include image.html +lightbox="true" +file="/images/examples/amazon-ecs/ecs-pipeline-deployment.png" +url="/images/examples/amazon-ecs/ecs-pipeline-deployment.png" +alt="Deploying to Amazon ECS" +caption="Deploying to Amazon ECS" +max-width="100%" +%} + +## Prerequisites + + +1. Configure an ECS (or Fargate) Cluster with at least one running instance. +1. Configure an ECS Service and Task Definition with a reference to **the image that you are going to build and push.** See [the official amazon docs](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html) for more details. +1. Connect your [ECR to Codefresh]({{site.baseurl}}/docs/docker-registries/external-docker-registries/amazon-ec2-container-registry/) so that it can be used by name in Codefresh pipelines. +1. Verify you have AWS Credentials (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`), with the following privileges: + + `JSON` +{% highlight json %} +{% raw %} +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Stmt1479146904000", + "Effect": "Allow", + "Action": [ + "ecs:DescribeServices", + "ecs:DescribeTaskDefinition", + "ecs:DescribeTasks", + "ecs:ListClusters", + "ecs:ListServices", + "ecs:ListTasks", + "ecs:RegisterTaskDefinition", + "ecs:UpdateService" + ], + "Resource": [ + "*" + ] + } + ] +} +{% endraw %} +{% endhighlight %} + + + +## Create a CI/CD pipeline for ECS/Fargate + +Here is the complete pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - "clone" + - "build" + - "deploy" +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}" + revision: "${{CF_BRANCH}}" + stage: "clone" + git: github + BuildingDockerImage: + stage: "build" + title: Building Docker Image + type: build + image_name: ${{IMAGE}} + tag: '${{CF_SHORT_REVISION}}' + dockerfile: Dockerfile.multistage + Push: + title: "Pushing image to ECR" + stage: "deploy" + type: "push" + tag: '${{CF_BRANCH_TAG_NORMALIZED}}-${{CF_SHORT_REVISION}}' + registry: "ecr" + candidate: "${{BuildingDockerImage}}" + DeployToFargate: + stage: "deploy" + image: codefreshplugins/cf-deploy-ecs + commands: + - cfecs-update ${{REGION}} ${{ECS_CLUSTER_NAME}} ${{ECS_SERVICE_NAME}} --image-name ${{IMAGE_PREFIX}}/${{IMAGE}} --image-tag '${{CF_BRANCH_TAG_NORMALIZED}}-${{CF_SHORT_REVISION}}' + environment: + - AWS_ACCESS_KEY_ID=${{AWS_ACCESS_KEY_ID}} + - AWS_SECRET_ACCESS_KEY=${{AWS_SECRET_ACCESS_KEY}} + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code with a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/) +1. Uses a [build step]({{site.baseurl}}/docs/pipelines/steps/build/) to create a Docker image +1. Uses a [push step]({{site.baseurl}}/docs/cpipelines/steps/push/) to push the docker image to ECR. The registry was previously [connected in Codefresh]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) with the `ecr` identifier. +1. Runs `codefreshplugins/cf-deploy-ecs` to perform the actual deployment + + +The pipeline needs [environment variables]({{site.baseurl}}/docs/pipelines/pipelines/#pipeline-settings) that hold all the required parameters. + +{% include image.html +lightbox="true" +file="/images/examples/amazon-ecs/ecs-variables.png" +url="/images/examples/amazon-ecs/ecs-variables.png" +alt="ECS environment variables" +caption="ECS environment variables" +max-width="80%" +%} + + + + +Note that the **`--image-name`** and **`--image-tag`** pair should comprise the **full name** of the image that was pushed to the registry (including the registry name) in order to be correctly referred by the corresponding Task Definition. + + + +## Deployment Flow + +The `codefreshplugins/cf-deploy-ecs` step performs the following: + + +1. Gets the ECS service by specified `aws-region`, `ecs-cluster`, and `service-names`. +1. Creates a new revision from the current task definition of the service. If `--image-name` and `--image-tag` are provided, it replaces the image tag. +1. Runs the `update-service` command with the new task definition revision. +1. Waits for the deployment to complete. + * Deployment is successfully completed if `runningCount == desiredCount` for PRIMARY deployment - see `aws ecs describe-services` + * The `cfecs-update` command exits with a timeout error if after --timeout (default = 900s) `runningCount` does not equal `desiredCount` + * The `cfecs-update` exits with an error if --max-failed (default = 2) or more ECS tasks were stopped with error for the task definition that you are deploying. ECS continuously retries failed tasks. + +You can also find the same step in the form of a [Codefresh plugin](https://codefresh.io/steps/step/ecs-deploy). + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[External Registries]({{site.baseurl}}/docs/integration/docker-registries/) + + diff --git a/_docs/example-catalog/cd-examples/deploy-to-heroku.md b/_docs/example-catalog/cd-examples/deploy-to-heroku.md new file mode 100644 index 00000000..100a56ec --- /dev/null +++ b/_docs/example-catalog/cd-examples/deploy-to-heroku.md @@ -0,0 +1,212 @@ +--- +title: "Deploy to Heroku" +description: "Deploy your application or image to Heroku" +group: example-catalog +sub_group: cd-examples +toc: true +--- + +Heroku is a container-based cloud PaaS (Platform as a Service) software that allows you to deploy, run, and manage your applications. Built on top of AWS, it supports Ruby, Node.js, Java, Python, Clojure, Scala, Go and PHP. + +This tutorial will cover two examples, depending on your use case. If you are not using containers, your use case is covered using the Codefresh heroku-deployer plugin ([Example #1](#pipeline-example-1-deploying-source-code-to-heroku-using-the-codefresh-heroku-plugin)). If you are using containers, you can achieve deployment by using a combination of build, push, and freestyle steps ([Example #2](#pipeline-example-2-deploy-a-docker-image-to-heroku)). + +## Example Django Application + +You can find the example project on [GitHub](https://github.com/codefresh-contrib/heroku-python-django-sample-app). + +The repository contains a Django starter project with the following commands: + +- `pip install -r requirements.txt` to install dependencies. +- `python -m unittest composeexample.utils` runs unit tests. +- `python manage.py runserver 0.0.0.0:8000` to start the application locally. + +Once launched the application presents the Django starter page at localhost:8000. + +## Pipeline Example #1: Deploying Source Code to Heroku Using the Codefresh Heroku Plugin + +### Prerequisites + +- A [free Codefresh account]({{site.baseurl}}/docs/administration/account-user-management/#create-a-codefresh-account/) +- A [free Heroku account](https://signup.heroku.com){:target="\_blank"} +- A Heroku API token (you can find this under **Account Settings** and then scrolling down, you will find the API Key) + +### Create the pipeline + +This pipeline has three stages: clone, test, and deploy. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/heroku-deployer-pipeline.png" +url="/images/examples/deployments/heroku-deployer-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor of the Codefresh UI. It will automatically clone the project for you. + +Note that you need to change the environment variables in the deploy stage to your respective values. You can do this directly [in the YAML itself]({{site.baseurl}}/docs/how-to-guides/migrating-from-travis-ci/#environment-variables), or through the Codefresh UI. Navigate to the in-line editor, and to the right you will find a tab lebeled **Variables**. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/heroku-deployer-variables2.png" +url="/images/examples/deployments/heroku-deployer-variables2.png" +alt="Codefresh UI Pipeline Variables View" +caption="Codefresh UI Pipeline Variables View" +max-width="100%" +%} + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - clone + - test + - deploy +steps: + clone: + title: "Cloning main repository..." + stage: "clone" + type: "git-clone" + arguments: + repo: "codefresh-contrib/heroku-python-django-sample-app" + revision: "master" + git: "github" + run_unit_tests: + title: "Running unit tests..." + stage: "test" + type: "freestyle" + working_directory: "${{clone}}" + arguments: + image: "python:3.6-slim" + commands: + - "pip install -r requirements.txt --cache-dir=/codefresh/volume/pip-cache" + - "python -m unittest composeexample.utils" + deploy_to_heroku: + title: "Deploying to Heroku..." + stage: "deploy" + type: "heroku-deployer" + arguments: + APP_NAME: $APP_NAME + EMAIL: $EMAIL + API_TOKEN: $API_TOKEN +{% endraw %} +{% endhighlight %} + +The above pipeline has the following steps: + +1. A [git-clone]({{site.baseurl}}/docs/pipelines/steps/git-clone/) step that clones the main repository +2. A [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) that installs dependencies and runs the unit tests +3. A freestyle step that deploys the application to Heroku using the heroku-deployer plugin from the [Step Marketplace](https://codefresh.io/steps/step/heroku-deployer) + +## Pipeline Example #2: Deploy a Docker Image to Heroku + +This example differs from the plugin usage, as it deploys a built Docker image to Heroku. + +Note that you need to change the environment variables to your respective values. You can do this directly [in the YAML itself]({{site.baseurl}}/docs/how-to-guides/migrating-from-travis-ci/#environment-variables), or through the Codefresh UI. Navigate to the in-line editor, and to the right you will find a tab lebeled **Variables**. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/heroku-deployer-variables.png" +url="/images/examples/deployments/heroku-deployer-variables.png" +alt="Codefresh UI Pipeline Variables View" +caption="Codefresh UI Pipeline Variables View" +max-width="100%" +%} + +## Prerequisites + +- A [free Codefresh account]({{site.baseurl}}/docs/administration/account-user-management/#create-a-codefresh-account/) +- A [free Heroku account](https://signup.heroku.com){:target="\_blank"} +- An empty repository already created in Heroku using the `heroku create ` command +- A Heroku registry [connected to Codefresh]({{site.baseurl}}/docs/docker-registries/external-docker-registries/other-registries/#heroku-registries) +- A Heroku API token (you can find this under **Account Settings** and then scrolling down, you will find the API Key) + +### Create the pipeline + +This pipeline has five stages: clone, build, test, push, and release. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/heroku-vanilla-push-pipeline.png" +url="/images/examples/deployments/heroku-vanilla-push-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor of the Codefresh UI. It will automatically clone the project for you. + +`codefresh-heroku-push-image.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +version: '1.0' +stages: + - clone + - build + - test + - push + - release +steps: + clone: + title: "Cloning main repository..." + stage: "clone" + type: "git-clone" + arguments: + repo: "codefresh-contrib/heroku-python-django-sample-app" + revision: "master" + git: "github" + build: + title: "Building Docker Image..." + stage: "build" + type: "build" + working_directory: "./heroku-python-django-sample-app" + arguments: + image_name: "${{IMAGE_NAME}}" + tag: "master" + dockerfile: "Dockerfile" + run_unit_tests: + title: "Running unit tests..." + stage: "test" + type: "freestyle" + working_directory: "./heroku-python-django-sample-app" + arguments: + image: '${{build}}' + commands: + - "python -m unittest composeexample.utils" + push_image: + title: "Pushing image to Heroku..." + stage: "push" + type: "push" + arguments: + candidate: '${{build}}' + image_name: "${{IMAGE_NAME}}/web" + registry: "heroku" + release_image: + title: "Releasing image..." + stage: "release" + type: "freestyle" + arguments: + image: "nazarcodefresh/heroku-cli:alpine" + commands: + - >- + printf "machine api.heroku.com\n login $EMAIL\n password + $API_TOKEN\nmachine git.heroku.com\n login $EMAIL\n password + $API_TOKEN\n" > ~/.netrc + - "heroku container:release --app $IMAGE_NAME web" +{% endraw %} +{% endhighlight %} + +The pipeline does the following: +1. Clones the main repository through the [git-clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Builds our Docker image through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). +1. Runs unit tests on our Docker image through another freestyle step. +1. Pushes to the Heroku registry through a [push step]({{site.baseurl}}/docs/pipelines/steps/push/). +1. Releases the Docker image through another freestyle step. + + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) diff --git a/_docs/example-catalog/cd-examples/deploy-to-tomcat-via-scp.md b/_docs/example-catalog/cd-examples/deploy-to-tomcat-via-scp.md new file mode 100644 index 00000000..fa66c1c2 --- /dev/null +++ b/_docs/example-catalog/cd-examples/deploy-to-tomcat-via-scp.md @@ -0,0 +1,122 @@ +--- +title: "Deploy to a VM via SCP" +description: "Deploy your application to Tomcat using SCP" +group: example-catalog +sub_group: cd-examples +toc: true +--- + +## Prerequisites + +- A [free Codefresh account]({{site.baseurl}}/docs/administration/account-user-management/create-codefresh-account) +- A distribution of [Tomcat](https://tomcat.apache.org/download-90.cgi){:target="\_blank"} setup on a remote server (running with port 8080 exposed) + +## The example Java Application + +You can find the example project on [GitHub](https://github.com/codefresh-contrib/scp-war-app){:target="\_blank"}. + +The example application is a simple Hello World Java application using the [Spark Java framework](http://sparkjava.com/){:target="\_blank"}: + +{% include image.html +lightbox="true" +file="/images/examples/deployments/scp-hello-world.png" +url="/images/examples/deployments/scp-hello-world.png" +alt="Hello World!" +caption="Hello World!" +max-width="100%" +%} + + +```java + @Override + public void init() { + get("/hello", (req, res) -> "Hello World"); + } +``` + +## Create the pipeline + +Our pipeline has three stages: clone, package, and transfer. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/scp-pipeline.png" +url="/images/examples/deployments/scp-pipeline.png" +alt="SCP pipeline" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor of the Codefresh UI. It will automatically clone the project for you. + +Note that you need to change the environment variables under the `transfer` step to your respective values. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +# More examples of Codefresh YAML can be found at +# https://codefresh.io/docs/docs/example-catalog/example + +version: "1.0" +# Stages can help you organize your steps in stages +stages: + - "clone" + - "package" + - "transfer" + +steps: + clone: + title: "Cloning repository..." + type: "git-clone" + stage: "clone" + arguments: + repo: "codefresh-contrib/scp-war-app" + + package: + title: "Packaging war..." + type: "freestyle" + stage: "package" + arguments: + image: "maven:3.5.2-jdk-8-alpine" + working_directory: "${{clone}}" + commands: + - "mvn -Dmaven.repo.local=/codefresh/volume/m2_repository clean package" + + transfer: + title: "Transferring war to Tomcat..." + type: "freestyle" + stage: "transfer" + arguments: + image: "ictu/sshpass:latest" + working_directory: "${{package}}/target" + environment: + - USER= + - HOST= + - PASSWORD= + - TOMCAT_DIR= + commands: + - "echo | ssh-keygen -P '' -t rsa" + - "sshpass -p $PASSWORD ssh-copy-id -i /root/.ssh/id_rsa.pub -o StrictHostKeyChecking=no $USER@$HOST" + - "scp sparkjava-hello-world-1.0.war $USER@$HOST:$TOMCAT_DIR" +{% endraw %} +{% endhighlight %} + +The above pipeline does the following: + +1. Clones the main repository through the [git-clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +2. Installs the dependencies via Maven and packages our `war` file through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). +3. Transfers our application via scp to a Tomcat server through another freestyle step. + +Note that you will need to change the listed environment variables accordingly, either through the YAML itself, or through your pipeline settings: + +{% include image.html +lightbox="true" +file="/images/examples/deployments/scp-variables.png" +url="/images/examples/deployments/scp-variables.png" +alt="Pipeline variables" +caption="Pipeline variables" +max-width="100%" +%} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) diff --git a/_docs/example-catalog/cd-examples/deploy-with-kustomize.md b/_docs/example-catalog/cd-examples/deploy-with-kustomize.md new file mode 100644 index 00000000..21b3089f --- /dev/null +++ b/_docs/example-catalog/cd-examples/deploy-with-kustomize.md @@ -0,0 +1,244 @@ +--- +title: "Deploy with Kustomize" +description: "Deploy your services to Kubernetes using Kustomize" +group: example-catalog +sub_group: cd-examples +toc: true +--- + +[Kustomize](https://kustomize.io) is a tool included with kubectl 1.14 that "lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML untouched and usable as is." + +Kustomize is more of an overlay engine, as opposed to a templating engine. You create a base configuration and overlays. Your overlays contain a *kustomization.yaml* file, and any variants/changes are applied over top of the base configuration. Kustomize does not use templates at all. + +While it is good for simple scenarios, we suggest that you use Helm for managing your Kubernetes applications. Helm is a full package manager for Kubernetes manifests that also provides templating capabilities. See [this example]({{site.baseurl}}/docs/example-catalog/cd-examples/helm/){:target="\_blank"} for more information. + +## The example application + +You can find the example project on [GitHub](https://github.com/codefresh-contrib/kustomize-sample-app){:target="\_blank"}. + +The sample application is a simple Spring Boot web app, that displays an environment variable, `MY_MYSQL_DB` on the page: + +```java +public class HelloController { + + String my_sql_db = System.getenv("MY_MYSQL_DB"); + + @RequestMapping("/") + public String index() { + return my_sql_db; + } +``` + +The project contains a [base](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/glossary.md#base){:target="\_blank"} and two [overlays](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/glossary.md#overlay){:target="\_blank"}, one for a staging environment and one for production. + +The base manifest holds a dummy variable for `MY_MYSQL_DB` which will be overlayed once we call the kustomize command in our pipeline. + +`base/deployment.yaml` +```yaml +... + env: + - name: MY_MYSQL_DB + valueFrom: + configMapKeyRef: + name: the-map + key: mysqlDB +``` + +We will overlay on top of the manifests a different value for `MY_MYSQL_DB` for the staging environment and production environment. + +`overlays/staging/config-map.yaml` +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: the-map +data: + mysqlDB: "staging-mysql.example.com:3306" +``` + +`overlays/production/config-map.yaml` +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: the-map +data: + mysqlDB: "prod-mysql.example.com:3306" +``` + +In addition, for the production environment, the number of replicas will be overlayed to 3 instead of 1 (as [defined in the base deployment](https://github.com/codefresh-contrib/kustomize-sample-app/blob/32e683f82940de0bf2de2da40fa6b150e2b24b23/base/deployment.yaml#L8)){:target="\_blank"}. + +`overlays/production/deployment.yaml` +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: the-deployment +spec: + replicas: 3 +``` + +## Prerequisites + +- A [free Codefresh account]({{site.baseurl}}/docs/administration/account-user-management/create-codefresh-account) + +- A Kubernetes cluster [connected to your Codefresh account](https://codefresh.io/docs/docs/integrations/kubernetes/#connect-a-kubernetes-cluster) + +## Create the staging environment pipeline + +This pipeline will have two stages: clone and deploy. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-kustomize-staging-pipeline.png" +url="/images/examples/deployments/k8s-kustomize-staging-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line pipeline editor of the Codefresh UI. However, make sure to replace cluster context for the kubectl command under the arguments section with your own that you integrated with Codefresh. It will automatically clone the project for you and deploy. + +`staging-codefresh.yml` +{% highlight yaml %} +{% raw %} +# More examples of Codefresh YAML can be found at +# https://codefresh.io/docs/docs/example-catalog/ + +version: "1.0" +# Stages can help you organize your steps in stages + +stages: + - clone + - deploy + +steps: + clone: + title: Cloning main repository... + type: git-clone + stage: clone + arguments: + repo: https://github.com/codefresh-contrib/kustomize-sample-app.git + git: github + revision: master + + deploy: + title: Deploying to Staging using Kustomize... + type: freestyle + stage: deploy + working_directory: ${{clone}} + arguments: + image: codefresh/kubectl:1.14.9 + commands: + - kubectl config use-context anna-sandbox@codefresh-support + - kubectl apply -k overlays/staging +{% endraw %} +{% endhighlight %} + +The above pipeline does the following: +1. Clones the main repository through a [git-clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +2. Connects to our Kubernetes cluster we have integrated with Codefresh using `kubectl`, and deploys the application as a staging environment with the appropriate value for `MY_MYSQL_DB` as defined in our configMap using Kustomize (the `-k` flag), through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). + +>If you are using `kubectl` prior to 1.14, you can use the following command to deploy with Kustomize: + `kustomize build overlays/production | kubectl apply -f` + +## Create the production environment pipeline + +Likewise, this pipeline will have two stages: clone and deploy. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-kustomize-prod-pipeline.png" +url="/images/examples/deployments/k8s-kustomize-prod-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor of the Codefresh UI and remember to replace cluster context for the kubectl command again with your own. Click Save and Run and it will automatically clone the project for you. + +`prod-codefresh.yml` +{% highlight yaml %} +{% raw %} +# More examples of Codefresh YAML can be found at +# https://codefresh.io/docs/docs/example-catalog/ + +version: "1.0" +# Stages can help you organize your steps in stages + +stages: + - clone + - deploy + +steps: + clone: + title: Cloning main repository... + type: git-clone + stage: clone + arguments: + repo: https://github.com/codefresh-contrib/kustomize-sample-app.git + git: github + revision: master + + deploy: + title: Deploying to Production using Kustomize... + type: freestyle + stage: deploy + working_directory: ${{clone}} + arguments: + image: codefresh/kubectl:1.14.9 + commands: + - kubectl config use-context anna-sandbox@codefresh-support + - kubectl apply -k overlays/production +{% endraw %} +{% endhighlight %} + +The above pipeline does the following: + +1. Clones the main repository through a [git-clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Connects to our Kubernetes cluster we have integrated with Codefresh using `kubectl`, and deploys the application as a staging environment with the appropriate value for `MY_MYSQL_DB` as defined in our configMap using Kustomize (the `-k` flag), through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). + + +>Note that if you are using kubectl prior to 1.14, you can use the following command to deploy with Kustomize: +>`kustomize build overlays/production | kubectl apply -f` + +## Verification + +After you run these pipelines, your deployments are displayed in the [Kubernetes dashboard]({{site.baseurl}}/docs/deployments/kubernetes/manage-kubernetes/#accessing-the-kubernetes-dashboard). + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-kustomize-dashboard.png" +url="/images/examples/deployments/k8s-kustomize-dashboard.png" +alt="Codefresh Kubernetes Deployments" +caption="Codefresh Kubernetes Deployments" +max-width="100%" +%} + +You can test that the application deployed correctly to both environments by accessing the endpoints: + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-kustomize-staging-endpoint.png" +url="/images/examples/deployments/k8s-kustomize-staging-endpoint.png" +alt="Staging endpoint" +caption="Staging endpoint" +max-width="100%" +%} + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-kustomize-prod-endpoint.png" +url="/images/examples/deployments/k8s-kustomize-prod-endpoint.png" +alt="Production endpoint" +caption="Production endpoint" +max-width="100%" +%} + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Deployment options to Kubernetes]({{site.baseurl}}/docs/deployments/kubernetes/deployment-options-to-kubernetes) +[Running custom kubectl commands]({{site.baseurl}}/docs/deployments/kubernetes/custom-kubectl-commands/) +[Deploy with Helm]({{site.baseurl}}/docs/example-catalog/cd-examples/helm/) + diff --git a/_docs/example-catalog/cd-examples/docker-swarm.md b/_docs/example-catalog/cd-examples/docker-swarm.md new file mode 100644 index 00000000..ad6dfbe1 --- /dev/null +++ b/_docs/example-catalog/cd-examples/docker-swarm.md @@ -0,0 +1,221 @@ +--- +title: "Deploy to Docker SWARM" +description: "Deploy to Docker Swarm with Codefresh" +group: example-catalog +sub_group: cd-examples +redirect_from: + - /docs/docker-swarm/ + - /docs/deploy-to-docker-swarm/ + - /docs/deploy-your-containers/docker-swarm/ +toc: true +--- + +Codefresh can easily deploy your application to [Docker Swarm](https://docs.docker.com/engine/swarm/){:target="\_blank"} using [Codefresh pipelines]({{site.baseurl}}/docs/pipelines/pipelines/). + +You will need to provide: + +1. The `docker-stack.yml` that contains the definition of the application +1. The host where your Docker Swarm is running +1. An SSH key that Codefresh can use to access remotely the Docker Swarm host +1. The stack name that will be used once the application is deployed + +All this information will be passed to the pipeline in the form of build parameters. + + +## Example application + +For an example Docker Swarm application, see [https://github.com/codefreshdemo/example-voting-app](https://github.com/codefreshdemo/example-voting-app){:target="\_blank"} + +To launch it locally you need to download [Docker](https://www.docker.com/products/overview){:target="\_blank"}. +If you are on Mac or Windows, [Docker Compose](https://docs.docker.com/compose){:target="\_blank"} is automatically installed. +On Linux, make sure you have the latest version of [Compose](https://docs.docker.com/compose/install/){:target="\_blank"}. + + +Run in this root directory: + +{% highlight bash %} +{% raw %} + +docker-compose up + +{% endraw %} +{% endhighlight %} + +The app runs at [http://localhost:5000](http://localhost:5000), and the results are at [http://localhost:5001](http://localhost:5001). + +Alternately, if you want to run it on a Docker Swarm, first make sure you have a Swarm. +If you don't, run: + +{% highlight bash %} +{% raw %} + +docker swarm init + +{% endraw %} +{% endhighlight %} + +Once you have your swarm, in this directory run: + +{% highlight bash %} +{% raw %} + +docker stack deploy --compose-file docker-stack.yml vote + +{% endraw %} +{% endhighlight %} + +{{site.data.callout.callout_warning}} +The swarm master must have Python installed. +{{site.data.callout.end}} + +## Deploy to Remote Swarm with Codefresh + +First you need to set up the following environment variables in your Codefresh pipeline: + +{: .table .table-bordered .table-hover} +| `RDOCKER_HOST` | remote Docker Swarm master machine, accessible over SSH (for example, ubuntu@ec2-public-ip) | +| `STACK_NAME` | is new Docker stack name (use \"vote\", for example) | +| `SSH_KEY` | private SSH key, used to access Docker Swarm master machine | +| `SPLIT_CHAR` | split character, you've used to replace `newline` in SSH key. Recommendation: use `,` (`comma` character). | + +The `SSH_KEY` variable has the contents of the [SSH key](https://www.ssh.com/ssh/public-key-authentication){:target="\_blank"} that can access the Docker Swarm host. Currently, in order to pass SSH key through Codefresh UI, you need to convert it to single line string (replacing `newline` with `comma`), like this: + +{% highlight bash %} +{% raw %} +SSH_KEY=$(cat ~/.ssh/my_ssh_key_file | tr '\n' ',') +{% endraw %} +{% endhighlight %} + +The `SPLIT_CHAR` variable should hold the replacement character that was used for the SSH key (in the example above it is the comma character) + +{% include image.html +lightbox="true" +file="/images/2f1884a-codefresh_env_vars.png" +url="/images/2f1884a-codefresh_env_vars.png" +alt="Docker Swarm build parameters" +caption="Docker Swarm build parameters" +max-width="70%" +%} + + +## Deploy to Docker Swarm with a YAML step + +Once you have defined all the variables, deploy to your cluster using the following [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). + + `codefresh.yml` +{% highlight yaml %} +{% raw %} + +deploy_to_swarm: + image: codefresh/remote-docker + working_directory: ${{main_clone}} + commands: + - rdocker ${{RDOCKER_HOST}} docker stack deploy --compose-file docker-stack.yml ${{STACK_NAME}} + environment: + - SSH_KEY=${{SSH_KEY}} + when: + branch: + only: + - master + +{% endraw %} +{% endhighlight %} + +You can also pass custom credentials like this: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} + +deploy_to_swarm: + image: codefresh/remote-docker + working_directory: ${{main_clone}} + commands: + - rdocker ${{RDOCKER_HOST}} docker login ${{MY_REGISTRY}} -u ${{MY_REGISTRY_USER}} -p ${{MY_REGISTRY_PASSWORD}} \&\& docker stack deploy --compose-file docker-compose.yml --with-registry-auth ${{STACK_NAME}} + environment: + - SSH_KEY=${{SSH_KEY}} + when: + branch: + only: + - master +{% endraw %} +{% endhighlight %} + + + +## Create a CI/CD pipeine for Docker Swarm + +Here is the complete pipeline: + +{% include +image.html +lightbox="true" +file="/images/examples/docker-swarm/docker-swarm-pipeline.png" +url="/images/examples/docker-swarm/docker-swarm-pipeline.png" +alt="Docker Swarm pipeline" +caption="Docker Swarm pipeline" +max-width="100%" +%} + +And here is the pipeline definition: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - deploy +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefreshdemo/example-voting-app' + revision: master + git: github-1 + MyResultDockerImage: + title: Building Result Docker Image + stage: build + type: build + image_name: resultApp + working_directory: ./result/ + tag: master + dockerfile: Dockerfile + MyVoteDockerImage: + title: Building Vote Docker Image + stage: build + type: build + image_name: voteApp + working_directory: ./vote/ + tag: master + dockerfile: Dockerfile + MyWorkerDockerImage: + title: Building Worker Docker Image + stage: build + type: build + image_name: workedApp + working_directory: ./worker/ + tag: master + dockerfile: Dockerfile + DeployToSwarmNow: + image: codefresh/remote-docker + working_directory: ${{main_clone}} + stage: deploy + commands: + - rdocker ${{RDOCKER_HOST}} docker login ${{MY_REGISTRY}} -u ${{MY_REGISTRY_USER}} -p ${{MY_REGISTRY_PASSWORD}} \&\& docker stack deploy --compose-file docker-compose.yml --with-registry-auth ${{STACK_NAME}} + environment: + - SSH_KEY=${{SSH_KEY}} +{% endraw %} +{% endhighlight %} + +The values of `MY_REGISTRY`, `MY_REGISTRY_USER` and `MY_REGISTRY_PASSWORD` depend upon the type of [your connected registry]({{site.baseurl}}/docs/integration/docker-registries/). + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) + diff --git a/_docs/example-catalog/cd-examples/elastic-beanstalk.md b/_docs/example-catalog/cd-examples/elastic-beanstalk.md new file mode 100644 index 00000000..cd0b6949 --- /dev/null +++ b/_docs/example-catalog/cd-examples/elastic-beanstalk.md @@ -0,0 +1,136 @@ +--- +title: "Deploy to Elastic Beanstalk" +description: "" +group: example-catalog +sub_group: cd-examples +redirect_from: + - /docs/elastic-beanstalk/ + - /docs/deploy-your-containers/elastic-beanstalk/ +toc: true +--- + + +## Prerequisites + +- Configured Application in Elastic Beanstalk service
+ See: [http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/GettingStarted.html](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/GettingStarted.html){:target="_blank"} + + +## Deployment with Codefresh +- Add encrypted environment variables for AWS credentials: + * `AWS_ACCESS_KEY_ID` + * `AWS_SECRET_ACCESS_KEY` + +- Provide the following environment variables: + * `AWS_REGION` + * `AWS_ENV_NAME` + * `AWS_VERSION` + * `AWS_BRANCH` + +{% include +image.html +lightbox="true" +file="/images/examples/elastic-beanstalk/codefresh_eb_env_vars.png" +url="/images/examples/elastic-beanstalk/codefresh_eb_env_vars.png" +alt="codefresh_eb_env_vars.png" +max-width="40%" +%} + +{{site.data.callout.callout_info}} +{% raw %} +The ``${{AWS_VERSION}}`` of application you can find in the Elastic Beanstalk service. +{% endraw %} +{{site.data.callout.end}} + +{% include +image.html +lightbox="true" +file="/images/examples/elastic-beanstalk/codefresh_eb_version_label.png" +url="/images/examples/elastic-beanstalk/codefresh_eb_version_label.png" +alt="codefresh_eb_version_label.png" +max-width="40%" +%} + +{{site.data.callout.callout_info}} +{% raw %} +The ``${{AWS_ENV_NAME}}`` of application you can find in the Elastic Beanstalk service. +{% endraw %} +{{site.data.callout.end}} + +{% include +image.html +lightbox="true" +file="/images/examples/elastic-beanstalk/codefresh_eb_environment.png" +url="/images/examples/elastic-beanstalk/codefresh_eb_environment.png" +alt="codefresh_eb_environment.png" +max-width="40%" +%} + +Add the following step to codefresh.yml: + + `deploy_step` +{% highlight yaml %} +{% raw %} +deploy-elastic-beanstalk: + fail-fast: false + image: garland/aws-cli-docker:latest + commands: + - sh -c "aws configure set region '${{AWS_REGION}}' && aws elasticbeanstalk update-environment --environment-name '${{AWS_ENV_NAME}}' --version-label '${{AWS_VERSION}}' " + when: + condition: + all: + masterBranch: "'${{CF_BRANCH}}' == '${{AWS_BRANCH}}'" +{% endraw %} +{% endhighlight %} + +{:.text-secondary} +## Deployment Flow +- Go to the Elastic Beanstalk service and create an application and environment. + + +{% include +image.html +lightbox="true" +file="/images/examples/elastic-beanstalk/codefresh_eb_environment-deploy.png" +url="/images/examples/elastic-beanstalk/codefresh_eb_environment-deploy.png" +alt="codefresh_eb_environment.png" +max-width="40%" +%} + +- Perform the following commands from root of your project: + * eb init + * eb create {% raw %}`${{AWS_ENV_NAME}}`{% endraw %} + + + +>Note: + If you don't have awsebcli - install EB CLI [http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html){:target="_blank"}. + + +{% include +image.html +lightbox="true" +file="/images/examples/elastic-beanstalk/codefresh_eb_health.png" +url="/images/examples/elastic-beanstalk/codefresh_eb_health.png" +alt="codefresh_eb_health.png" +max-width="40%" +%} + +- Add this repository to Codefresh, provide the necessary environments variables and build this service + +{% include +image.html +lightbox="true" +file="/images/examples/elastic-beanstalk/codefresh_eb_cf_step_deploy.png" +url="/images/examples/elastic-beanstalk/codefresh_eb_cf_step_deploy.png" +alt="codefresh_eb_cf_step_deploy.png" +max-width="40%" +%} + +## Example + +* [cf-example-deploy-elasticbeanstalk](https://github.com/codefreshdemo/cf-example-deploy-elasticbeanstalk){:target="_blank"} + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) diff --git a/_docs/example-catalog/cd-examples/helm.md b/_docs/example-catalog/cd-examples/helm.md new file mode 100644 index 00000000..1b104663 --- /dev/null +++ b/_docs/example-catalog/cd-examples/helm.md @@ -0,0 +1,225 @@ +--- +title: "Deploy with Helm" +description: "Use Helm in a Codefresh pipeline" +group: example-catalog +sub_group: cd-examples +toc: true +--- + +[Helm](https://helm.sh/){:target=\_blank"} is the package manager for Kubernetes. +Codefresh has comprehensive support for Helm: + +* Free [built-in Helm repository]({{site.baseurl}}/docs/deployments/helm/managed-helm-repository/) with each Codefresh account +* [Helm chart dashboard]({{site.baseurl}}/docs/docs/deployments/add-helm-repository/) to track your charts +* [Helm Release dashboard]({{site.baseurl}}/docs/docs/deployments/helm-releases-management/) to view your deployments +* [Environment dashsboard]({{site.baseurl}}/docs/deployments/kubernetes/environment-dashboard/) to view Helm releases +* [Helm promotion dashboard]({{site.baseurl}}/docs/deployments/helm-environment-promotion/) to promote Helm releases +* Add any external Helm repository on any other cloud provider + +Codefresh also provides a [pipeline step]({{site.baseurl}}/docs/new-helm/using-helm-in-codefresh-pipeline/) for deploying with Helm. + +For more insights on Helm charts see also our [Helm best practices]({{site.baseurl}}/docs/new-helm/helm-best-practices/) guide. + + +## The example Helm project + +You can see the example project at [https://github.com/codefresh-contrib/helm-sample-app](https://github.com/codefresh-contrib/helm-sample-app){:target=\_blank"}. The repository contains a simple Go application, a Dockerfile and an example chart. + + +## Prerequisites + +[At least one Kubernetes cluster]({{site.baseurl}}/docs/integrations/kubernetes/#connect-a-kubernetes-cluster/) in your Codefresh account. + +>Notice that if you still use Helm 2 you should also have installed the server side of Helm 2 (Tiller) using `helm init`. This command is best run from the cloud console of your cluster. The respective pipelines of this guide are in the [helm-2 branch](https://github.com/codefresh-contrib/helm-sample-app/tree/helm-2){:target=\_blank"}. + + + +## CI/CD pipeline with Helm deployment + +It is possible to deploy directly a Helm chart as it exists on the filesystem. This is not the recommended way to use Helm, because you are bypassing the Helm chart repository, but it is certainly the simplest Helm pipeline possible. + +{% include image.html +lightbox="true" +file="/images/examples/helm/helm-deploy-pipeline.png" +url="/images/examples/helm/helm-deploy-pipeline.png" +alt="Pipeline for Helm deployment" +caption="Pipeline for Helm deployment" +max-width="100%" +%} + +Here is the whole pipeline: + + `codefresh-do-not-store.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - deploy +steps: + clone: + title: Cloning main repository... + stage: prepare + type: git-clone + arguments: + repo: codefresh-contrib/helm-sample-app + revision: master + git: github + build: + title: Building Docker Image + stage: build + type: build + working_directory: ./helm-sample-app + arguments: + image_name: helm-sample-app-go + tag: multi-stage + dockerfile: Dockerfile + deploy: + title: Deploying Helm Chart + type: helm + stage: deploy + working_directory: ./helm-sample-app + arguments: + action: install + chart_name: charts/helm-example + release_name: my-go-chart-prod + helm_version: 3.0.2 + kube_context: my-demo-k8s-cluster + custom_values: + - 'buildID=${{CF_BUILD_ID}}' + - 'image_pullPolicy=Always' + - 'image_tag=multi-stage' + - 'replicaCount=3' + - 'image_pullSecret=codefresh-generated-r.cfcr.io-cfcr-default' +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/) +1. Builds a docker image through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/) +1. Deploys the Helm chart to a cluster named `my-demo-k8s-cluster` using the Helm step [from the Step Marketplace](https://codefresh.io/steps/step/helm){:target=\_blank"}. + +In this example, `charts/helm-example` refers to the [filesystem location in the code](https://github.com/codefresh-contrib/helm-sample-app/tree/master/charts/helm-example){:target=\_blank"} that was just checked out. + +The deployment will be visible in the [Helm releases dashboard]({{site.baseurl}}/docs/new-helm/helm-releases-management/). + +{% include image.html +lightbox="true" +file="/images/examples/helm/helm-release.png" +url="/images/examples/helm/helm-release.png" +alt="Helm release view" +caption="Helm release view" +max-width="100%" +%} + +If you want to run this example yourself, make sure to edit the chart and put your own values there for the Docker image. + +## CI/CD pipeline with Helm deployment that also stores the chart + +It is recommended to use a Helm repository to store your chart before deploying it. This way you know what is deployed in your clusters +and you can also reuse charts in other installations. + +First of all you need to import in your pipeline from the [shared configuration]({{site.baseurl}}/docs/pipelines/shared-configuration/) the settings for the internal Helm repository (or any other external repository that you have setup in Codefresh). + This will make available the internal Helm repository to your pipeline so that it can push/pull Helm charts from it. + + {% include image.html + lightbox="true" + file="/images/examples/helm/import-helm-configuration.png" + url="/images/examples/helm/import-helm-configuration.png" + alt="Using the default Helm repository in a Pipeline" + caption="Using the default Helm repository in a Pipeline" + max-width="40%" + %} + +Once that is done you can change your pipeline to also store the chart first and *then* deploy it. + + +{% include image.html +lightbox="true" +file="/images/examples/helm/helm-push-and-deploy-pipeline.png" +url="/images/examples/helm/helm-push-and-deploy-pipeline.png" +alt="Pipeline for Helm deployment that stores chart" +caption="Pipeline for Helm deployment that stores chart" +max-width="100%" +%} + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - store + - deploy +steps: + clone: + title: Cloning main repository... + stage: prepare + type: git-clone + arguments: + repo: codefresh-contrib/helm-sample-app + revision: master + git: github + build: + title: Building Docker Image + stage: build + type: build + working_directory: ./helm-sample-app + arguments: + image_name: helm-sample-app-go + tag: multi-stage + dockerfile: Dockerfile + store: + title: Storing Helm Chart + type: helm + stage: store + working_directory: ./helm-sample-app + arguments: + action: push + chart_name: charts/helm-example + kube_context: my-demo-k8s-cluster + deploy: + type: helm + stage: deploy + working_directory: ./helm-sample-app + arguments: + action: install + chart_name: charts/helm-example + release_name: my-go-chart-prod + helm_version: 3.0.2 + kube_context: my-demo-k8s-cluster + custom_values: + - 'buildID=${{CF_BUILD_ID}}' + - 'image_pullPolicy=Always' + - 'image_tag=multi-stage' + - 'replicaCount=3' + - 'image_pullSecret=codefresh-generated-r.cfcr.io-cfcr-default' +{% endraw %} +{% endhighlight %} + + +After you finish running your pipeline, not only the deployment will take place, but you will also see your chart in your [Helm Chart dashboard]({{site.baseurl}}/docs/new-helm/add-helm-repository/): + +{% include image.html +lightbox="true" +file="/images/examples/helm/helm-chart.png" +url="/images/examples/helm/helm-chart.png" +alt="Stored Helm chart" +caption="Stored Helm chart" +max-width="80%" +%} + +It is also possible to [run your own Helm commands]({{site.baseurl}}/docs/deployments/helm/using-helm-in-codefresh-pipeline/#example-custom-helm-commands) in a Codefresh pipeline. + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) diff --git a/_docs/example-catalog/cd-examples/import-data-to-mongodb.md b/_docs/example-catalog/cd-examples/import-data-to-mongodb.md new file mode 100644 index 00000000..68a6c79a --- /dev/null +++ b/_docs/example-catalog/cd-examples/import-data-to-mongodb.md @@ -0,0 +1,60 @@ +--- + +title: "Import data to MongoDB" +description: "" +group: example-catalog +sub_group: cd-examples +redirect_from: + - /docs/import-data-to-mongodb-in-composition/ + - /docs/on-demand-test-environment/example-compositions/import-data-to-mongodb/ +toc: true +--- + +If you want to import/restore or to do something else before using MongoDB in your application, you can look at the following example. + +You just need to create Dockerfile for mongo seed service and provide the command to prepare MongoDB. In this case it's command `mongoimport` + + `Dockerfile mongo_seed` +{% highlight docker %} +FROM mongo +COPY init.json /init.json +CMD mongoimport --host mongodb --db exampleDb --collection contacts --type json --file /init.json --jsonArray +{% endhighlight %} + +## Looking around +In the root of this repository you'll find a file named `docker-compose.yml`. +Let's quickly review the contents of this file: + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} +version: '3' +services: + mongodb: + image: mongo + command: mongod --smallfiles + ports: + - 27017 + + mongo_seed: + image: ${{mongo_seed}} + links: + - mongodb + + client: + image: ${{build_prj}} + links: + - mongodb + ports: + - 9000 + environment: + - MONGO_URI=mongodb:27017/exampleDb +{% endraw %} +{% endhighlight %} + +{{site.data.callout.callout_info}} +You can add the following example to your GitHub or Bitbucket account, and build the [example](https://github.com/codefreshdemo/cf-example-manage-mongodb){:target="_blank"}. +{{site.data.callout.end}} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) diff --git a/_docs/example-catalog/cd-examples/nodejs-angular2-mongodb.md b/_docs/example-catalog/cd-examples/nodejs-angular2-mongodb.md new file mode 100644 index 00000000..f4e69839 --- /dev/null +++ b/_docs/example-catalog/cd-examples/nodejs-angular2-mongodb.md @@ -0,0 +1,52 @@ +--- +title: "NodeJS + Angular2 + MongoDB" +description: "" +group: example-catalog +sub_group: cd-examples +redirect_from: + - /docs/nodejs-angular2-mongodb/ + - /docs/on-demand-test-environment/example-compositions/nodejs-angular2-mongodb/ +toc: true +--- +This tutorial will walk you through the process of adding the following: + +- Build client +- Build server +- Launch composition + +## Looking around +In the root of this repository you'll find a file named `docker-compose.yml`. +Let's quickly review the contents of this file: + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} +version: '3' +services: + mongodb: + image: mongo + ports: + - 28017 + server: + image: ${{build_server}} + environment: + - MONGO_URI=mongodb://mongodb/exampleDb + links: + - mongodb + ports: + - 9000 + client: + image: ${{build_client}} + ports: + - 3000 +{% endraw %} +{% endhighlight %} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/codefreshdemo/nodejs-angular2-mongo){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) diff --git a/_docs/example-catalog/cd-examples/nomad.md b/_docs/example-catalog/cd-examples/nomad.md new file mode 100644 index 00000000..a7e78d79 --- /dev/null +++ b/_docs/example-catalog/cd-examples/nomad.md @@ -0,0 +1,225 @@ +--- +title: "Deploy to Nomad" +description: "Deploy Docker images to a Nomad cluster with Codefresh" +group: example-catalog +sub_group: cd-examples +toc: true +--- + +Even though Codefresh has great support for Kubernetes and Helm deployments, there is no lock-in on using just Kubernetes. Codefresh can deploy on any infrastructure. + + +[Nomad](https://www.nomadproject.io/){:target=\_blank"} is an alternative scheduling platform from Hashicorp. It supports docker containers (like Kubernetes), but you can also use Nomad to schedule VMs, Java apps, Go apps or any other standalone executable. + +There are several public Docker Images with Nomad, so it is very easy to use Codefresh pipelines to deploy to a Nomad cluster. + + +{% include image.html +lightbox="true" +file="/images/examples/nomad/nomad-ci-pipeline.png" +url="/images/examples/nomad/nomad-ci-pipeline.png" +alt="Deploying to Nomad with Codefresh" +caption="Deploying to Nomad with Codefresh" +max-width="80%" +%} + +In this example, we will use the image at [https://hub.docker.com/r/djenriquez/nomad](https://hub.docker.com/r/djenriquez/nomad){:target=\_blank"}. + +## The example Nomad project + +You can see the example project at [https://github.com/codefresh-contrib/nomad-sample-app](https://github.com/codefresh-contrib/nomad-sample-app){:target=\_blank"}. The repository contains a simple job specification that deploys a docker container on nomad cluster. + + +Here is the whole job file: + + `docker-job.hcl` +{% highlight hcl %} +{% raw %} +job "example-job" { + # Specify this job should run in the region named "us". Regions + # are defined by the Nomad servers' configuration. + #region = "us" + + # Spread the tasks in this job between us-west-1 and us-east-1. + datacenters = ["dc1"] + + # Run this job as a "service" type. Each job type has different + # properties. See the documentation below for more examples. + type = "service" + + # Specify this job to have rolling updates, two-at-a-time, with + # 30 second intervals. + update { + stagger = "30s" + max_parallel = 1 + } + + # A group defines a series of tasks that should be co-located + # on the same client (host). All tasks within a group will be + # placed on the same host. + group "example-group" { + # Specify the number of these tasks we want. + count = 3 + + # Create an individual task (unit of work). This particular + # task utilizes a Docker container to front a web application. + task "example-task" { + # Specify the driver to be "docker". Nomad supports + # multiple drivers. + driver = "docker" + + # Configuration is specific to each driver. + config { + image = "r.cfcr.io/$CF_ACCOUNT/$CF_REPO_NAME:$CF_BRANCH_TAG_NORMALIZED" + + auth { + username = "$CF_ACCOUNT" + password = "$CFCR_LOGIN_TOKEN" + server_address = "r.cfcr.io" + } + + port_map { + http = 8080 + } + } + + # The service block tells Nomad how to register this service + # with Consul for service discovery and monitoring. + service { + # This tells Consul to monitor the service on the port + # labelled "http". Since Nomad allocates high dynamic port + # numbers, we use labels to refer to them. + port = "http" + + check { + type = "http" + path = "/" + interval = "10s" + timeout = "2s" + } + } + + # Specify the maximum resources required to run the task, + # include CPU, memory, and bandwidth. + resources { + cpu = 500 # MHz + memory = 128 # MB + + network { + mbits = 100 + + + port "http" {} + + + + } + } + } + } +} + +{% endraw %} +{% endhighlight %} + +Notice that the job specification has several [Codefresh variables]({{site.baseurl}}/docs/pipelines/variables/) embedded. We will use [envsubst](https://www.gnu.org/software/gettext/manual/html_node/envsubst-Invocation.html){:target=\_blank"} in our pipeline to replace +them with the correct values. + +## Prerequisites + +You need to create a Codefresh account and have a Nomad cluster running. You need to decide on how Codefresh will communicate +with the nomad cluster. In this simple example we just use the `NOMAD_ADDR` variable to point the nomad client to our cluster. In a production environment you should use proper [ACL](https://www.nomadproject.io/guides/security/acl.html){:target=\_blank"} and [certificate](https://www.nomadproject.io/guides/security/securing-nomad.html){:target=\_blank"} variables as well. + + +In this example the Nomad cluster is already setup on a VM at Google cloud. + +You also need to create a [token for the Docker registry]({{site.baseurl}}/docs/integrations/docker-registries/) so that Nomad can pull your private images on the cluster. + +## Create a CI/CD pipeline for Nomad deployments + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - "clone" + - "build" + - "deploy" +steps: + main_clone: + type: "git-clone" + title: "Clone main repository..." + repo: "codefresh-contrib/nomad-sample-app" + revision: "${{CF_BRANCH}}" + stage: "clone" + build: + title: "Building Docker Image" + type: "build" + image_name: "nomad-sample-app" + tag: "${{CF_BRANCH_TAG_NORMALIZED}}" + dockerfile: "Dockerfile" + stage: "build" + prepareJob: + title: "Preparing Nomad job" + image: bhgedigital/envsubst + stage: deploy + commands: + - envsubst < docker-job.hcl > docker-job-export.hcl + - cat docker-job-export.hcl + runJob: + title: "Deploying Nomad job" + image: djenriquez/nomad + stage: deploy + commands: + - nomad run docker-job-export.hcl +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Creates a Docker image for a simple Go application through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). The image is automatically pushed to the default Docker registry. +1. Replaces all variables in the job spec by running `envsubst`. These include: + * The Registry token so that Nomad can access the default Docker registry + * The docker image name and tag to be deployed +1. Runs the job to deploy the image to Nomad through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). + + +Run the pipeline and see your deployment succeed. + +Here are the environment variables defined for this pipeline. + +{% include image.html +lightbox="true" +file="/images/examples/nomad/nomad-variables.png" +url="/images/examples/nomad/nomad-variables.png" +alt="Pipeline variables for Nomad deployments" +caption="Pipeline variables for Nomad deployments" +max-width="50%" +%} + + +The `NOMAD_ADDR` variable is holding the URL of the cluster. The `CFCR_LOGIN_TOKEN` variable holds authentication for the Codefresh Docker registry. + +## Verify the deployment + +Nomad also comes with its own UI that can show you the result of a deployment. + +{% include image.html +lightbox="true" +file="/images/examples/nomad/nomad-ui-deployment.png" +url="/images/examples/nomad/nomad-ui-deployment.png" +alt="Nomad UI deployment" +caption="Nomad UI deployment" +max-width="80%" +%} + +You can also use [Terraform]({{site.baseurl}}/docs/example-catalog/cd-examples/terraform/) in Codefresh pipelines. + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/cd-examples/packer-gcloud.md b/_docs/example-catalog/cd-examples/packer-gcloud.md new file mode 100644 index 00000000..58d12ade --- /dev/null +++ b/_docs/example-catalog/cd-examples/packer-gcloud.md @@ -0,0 +1,132 @@ +--- +title: "Deploy to a Virtual Machine" +description: "Deploy to Google Cloud in a Codefresh pipeline with Packer" +group: example-catalog +sub_group: cd-examples +toc: true +--- + +Even though Codefresh is Kubernetes-native and designed for containers, it can still deploy traditional applications in the form of Virtual Machines to any Cloud provider. + +In this example, we will use [Packer](http://www.packer.io/){:target="\_blank"} to package an application into a VM disk image that will then be launched in Google Cloud. +Because Packer itself is already offered [in a Docker container](https://hub.docker.com/r/hashicorp/packer/){:target="\_blank"}, it is very easy to run Packer in a Codefresh pipeline. + +Google also offers a [Docker image for GCloud](https://hub.docker.com/r/google/cloud-sdk/){:target="\_blank"} making the launching of the VM straightforward in a Codefresh pipeline. + + +{% include image.html +lightbox="true" +file="/images/examples/packer-gcloud/packer-codefresh-pipeline.png" +url="/images/examples/packer-gcloud/packer-codefresh-pipeline.png" +alt="Running Packer inside Codefresh" +caption="Running Packer inside Codefresh" +max-width="80%" +%} + +This Codefresh pipeline creates a VM image and then uses it to launch a Google Compute instance. + + +## The example Packer/Gcloud project + +You can see the example project at [https://github.com/codefresh-contrib/vm-packer-sample-app](https://github.com/codefresh-contrib/vm-packer-sample-app){:target="\_blank"}. The repository contains a simple Go application as well as a packer template. + +You can play with it locally after installing the `packer` and `gcloud` executables. + +## Prerequisites + +You need to create a Codefresh account and a Google account first. Then you need to create a [Service account Key](https://cloud.google.com/iam/docs/creating-managing-service-account-keys){:target="\_blank"} which will allow `packer` and `gcloud` to communicate with Google cloud. + + +Add your service account json as a pipeline variable called `SERVICE_ACCOUNT`. The content of this variable will be used +in order to authenticate to Google cloud. + +{% include image.html +lightbox="true" +file="/images/examples/packer-gcloud/service-account-variable.png" +url="/images/examples/packer-gcloud/service-account-variable.png" +alt="Using a Service Account JSON in Codefresh" +caption="Using a Service Account JSON in Codefresh" +max-width="50%" +%} + +## Create a CI/CD pipeline for Packer/GCloud + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - deploy +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: 'codefresh-contrib/vm-packer-sample-app' + git: github + revision: 'master' + stage: prepare + SetupAuth: + title: 'Setup GCloud Auth' + image: 'alpine' + stage: prepare + commands: + - echo $SERVICE_ACCOUNT > account.json + BuildMyApp: + title: Compiling App code + stage: build + image: 'golang:1.12' + commands: + - go build -o sample src/sample/trivial-web-server.go + CreatePackerImage: + title: Baking VM image + stage: build + image: 'hashicorp/packer' + commands: + - packer validate my-google-cloud-example.json + - packer build -force my-google-cloud-example.json + DeployToVM: + title: Deploying to VM + stage: deploy + image: 'google/cloud-sdk' + commands: + - gcloud auth activate-service-account --key-file=account.json + - gcloud config set project firstkubernetes-176201 + - gcloud compute instances create packer-demo-codefresh --image codefresh-simple-ubuntu-vm --zone europe-west1-b --metadata-from-file startup-script=startup.sh --tags http-server --preemptible --quiet + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Saves the content of the variable that holds the Google account as a file called `account.json`. +1. Compiles the Go application through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). +1. Runs `packer` to create a VM image based on Ubuntu that also contains the simple Go application. +1. Runs `gcloud` to launch a VM with the image that was just created. + + +Run the pipeline and see your deployment succeed. You can customize the image by editing the [Packer template](https://github.com/codefresh-contrib/vm-packer-sample-app/blob/master/my-google-cloud-example.json){:target="\_blank"}. + +Once the VM has finished launching you can access it with your web browser. + +{% include image.html +lightbox="true" +file="/images/examples/packer-gcloud/web-app-url.png" +url="/images/examples/packer-gcloud/web-app-url.png" +alt="Accessing the VM application" +caption="Accessing the VM application" +max-width="70%" +%} + + +You can follow the same procedure for any other cloud that has an API/CLI (such as AWS, Azure, Digital Ocean etc). + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/cd-examples/pulumi.md b/_docs/example-catalog/cd-examples/pulumi.md new file mode 100644 index 00000000..74c1f3f7 --- /dev/null +++ b/_docs/example-catalog/cd-examples/pulumi.md @@ -0,0 +1,116 @@ +--- +title: "Deploy with Pulumi" +description: "Use Pulumi in a Codefresh pipeline with Docker" +group: example-catalog +sub_group: cd-examples +toc: true +--- + +[Pulumi](https://pulumi.io/){:target="\_blank"} is a platform for *Infrastructure as Code*. It works like Terraform but allows you to use a proper programming language (TypeScript, Python, Go) to describe your infrastructure (instead of a configuration language). + +You can use Pulumi to deploy to Kubernetes or any other supported cloud platform. Because Pulumi itself is already offered [in a Docker container](https://hub.docker.com/r/pulumi/pulumi), it is very easy to run Pulumi in a Codefresh pipeline. + + +{% include image.html +lightbox="true" +file="/images/examples/pulumi/pulumi-pipeline.png" +url="/images/examples/pulumi/pulumi-pipeline.png" +alt="Running Pulumi inside Codefresh" +caption="Running Pulumi inside Codefresh" +max-width="80%" +%} + +## The example Pulumi project + +You can see the example project at [https://github.com/codefresh-contrib/pulumi-sample-app](https://github.com/codefresh-contrib/pulumi-sample-app){:target="\_blank"}. The repository contains a simple Pulumi stack based on Kubernetes and TypeScript. + +You can play with it locally after installing the `pulumi` executable. + +## Prerequisites + +You need to create a Codefresh account and a Pulumi account first. Then you need to create a [Pulumi token](https://app.pulumi.com/account/tokens){:target="\_blank"} which will allows Codefresh to communicate with Pulumi. + +[Add a Kubernetes cluster]({{site.baseurl}}/docs/integrations/kubernetes/#connect-a-kubernetes-cluster/) in your Codefresh account from any cloud provider. + +Codefresh automatically creates a kubeconfig in any [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) with all your clusters. This is the same way that Pulumi communicated with Kubernetes, so the integration between Codefresh and Pulumi is ready out of the box. + +Create a [stack](https://pulumi.io/reference/stack.html){:target="\_blank"} in Pulumi or use the one provided in the example. + +Finally add you Pulumi token as a pipeline variable called `PULUMI_ACCESS_TOKEN`. All freestyle steps have automatic access to all pipeline variables, and Pulumi will search for a token by default with this name when logging in. + + +## Create a CI/CD pipeline for Pulumi + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - deploy +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: '${{CF_REVISION}}' + stage: prepare + git: github-1 + BuildProject: + title: Build project + stage: build + image: pulumi/pulumi + commands: + - yarn install + SelectMyCluster: + title: Select K8s cluster + stage: deploy + image: codefresh/kubectl:1.13.3 + commands: + - kubectl config get-contexts + - kubectl config use-context "kostis-demo@FirstKubernetes" + RunPulumi: + title: Deploying + stage: deploy + image: pulumi/pulumi + commands: + - pulumi stack select dev --non-interactive + - pulumi stack --non-interactive + - pulumi up --non-interactive +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/pipelines/git-clone/). +1. Runs `yarn install` to download dependencies. In this example we use TypeScript, but Go and Python would work as well (or any other language supported by Pulumi). +1. Chooses the cluster that will be used for deployments, if you have more than one. Use your own cluster name as seen in the [Kubernetes dashboard]({{site.baseurl}}/docs/deploy-to-kubernetes/manage-kubernetes/) of Codefresh. +1. Runs `pulumi up` with the same target cluster. + +The pipeline needs a [single environment variable]({{site.baseurl}}/docs/pipelines/pipelines/#pipeline-settings) that holds the content of your Pulumi Token. + + +{% include image.html +lightbox="true" +file="/images/examples/pulumi/pulumi-access-token.png" +url="/images/examples/pulumi/pulumi-access-token.png" +alt="Passing the Pulumi Token in the pipeline parameters" +caption="Passing the Pulumi Token in the pipeline parameters" +max-width="60%" +%} + +Run the pipeline and see your deployment succeed. + +## Handling Pull requests + +You can easily use the same pipeline or a different one for pull requests. In this case replace the `pulumi up` command with `pulumi preview`. Even better you can add an [approval step]({{site.baseurl}}/docs/pipelines/steps/approval/) to allows humans to inspect the pipeline first. + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) diff --git a/_docs/example-catalog/cd-examples/secure-a-docker-container-using-http-basic-auth.md b/_docs/example-catalog/cd-examples/secure-a-docker-container-using-http-basic-auth.md new file mode 100644 index 00000000..b7e2884c --- /dev/null +++ b/_docs/example-catalog/cd-examples/secure-a-docker-container-using-http-basic-auth.md @@ -0,0 +1,92 @@ +--- +title: "Secure a Docker Container using HTTP Basic Auth" +description: "" +group: example-catalog +sub_group: cd-examples +redirect_from: + - /docs/securing-docker-container-with-http-basic-auth/ + - /docs/on-demand-test-environment/examples-compositions/securing-docker-container-with-http-basic-auth/ + - /docs/on-demand-test-environment/example-compositions/secure-a-docker-container-using-http-basic-auth/ +toc: true +--- +Before making a product publicly available, you might want to restrict access to certain users. These are some options to accomplish this goal: + + - Implement custom authentication within the system + - Configure the server to act as a proxy between the user and the application + - Limit access to specific IP addresses + +This article explains how to secure a container by exposing public ports, using an extra NGINX container to act as a proxy. + +## Expose Web App Public Port + + `webapp` +{% highlight yaml %} +{% raw %} +version: '3' +services: + web: + image: codefreshio/webapp + ports: + - "3000" +{% endraw %} +{% endhighlight %} + +The architecture for this step is displayed in the diagram below. In this step example, Docker is forwarding an internal 3000 port to the host 80 port. + +{% include +image.html +lightbox="true" +file="/images/examples/docker-https/codefresh_webapp_container.png" +url="/images/examples/docker-https/codefresh_webapp_container.png" +alt="codefresh_webapp_container.png" +max-width="40%" +%} + +## Add NGINX Proxy +To secure the web-app we are going to specify these commands in the ```docker-compose.yml``` file. + +1. Remove the port that maps from the web-app (it won't be directly accessible) +2. Add an extra NGINX container with custom configuration (proxy all traffic) +3. Configure NGINX to communicate with the web-app + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} +version: '3' +services: + web: + image: ${{build-prj}} + auth: + image: ${{build-nginx}} + ports: + - 80 + links: + - web + environment: + USER: ${{USERNAME}} + PASS: ${{PASSWORD}} +{% endraw %} +{% endhighlight %} + +The architecture for the ```docker-compose.yml``` file is displayed in the diagram below. + +{% include +image.html +lightbox="true" +file="/images/examples/docker-https/codefresh_nginx_container.png" +url="/images/examples/docker-https/codefresh_nginx_container.png" +alt="codefresh_nginx_container.png" +max-width="40%" +%} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/codefreshdemo/cf-example-basic-auth-container){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/cd-examples/spring-boot-kafka-zookeeper.md b/_docs/example-catalog/cd-examples/spring-boot-kafka-zookeeper.md new file mode 100644 index 00000000..2134ff17 --- /dev/null +++ b/_docs/example-catalog/cd-examples/spring-boot-kafka-zookeeper.md @@ -0,0 +1,203 @@ +--- +title: "Spring Boot + Kafka + Zookeeper" +description: "" +group: example-catalog +sub_group: cd-examples +redirect_from: + - /docs/spring-boot-kafka-zookeeper/ + - /docs/on-demand-test-environment/example-compositions/spring-boot-kafka-zookeeper/ +toc: true +--- +This project uses `Java, Spring Boot, Kafka, Zookeeper` to show you how to integrate these services in the composition. + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/codefreshdemo/example-springboot-kafka){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} + +## Zookeeper Docker image + +Kafka uses ZooKeeper so you need to first start a ZooKeeper server if you don't already have one + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} + zookeeper: + image: wurstmeister/zookeeper + ports: + - "2181:2181" +{% endraw %} +{% endhighlight %} + +## Kafka Docker image +Now start the Kafka server. In the `docker-compose.yml` it can be something like this + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} + kafka: + build: + context: kafka + dockerfile: Dockerfile + links: + - zookeeper:zk + ports: + - "9092:9092" + environment: + KAFKA_ADVERTISED_HOST_NAME: $CF_HOST_IP + KAFKA_ZOOKEEPER_CONNECT: zk:2181 + KAFKA_MESSAGE_MAX_BYTES: 2000000 + KAFKA_CREATE_TOPICS: "Topic1:1:1" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + - zookeeper +{% endraw %} +{% endhighlight %} + +To start the Kafka server with the certain per-configuration, you need to use Environment variables. Below, you can see which Environment variables are available for this service. + +__Broker IDs__ + +You can configure the broker id in different ways: + +1. Explicitly, using ```KAFKA_BROKER_ID``` +2. Via a command, using ```BROKER_ID_COMMAND```, e.g. ```BROKER_ID_COMMAND: "hostname | awk -F'-' '{print $2}'"``` + +If you don't specify a broker id in your docker-compose file, it will automatically be generated (see [https://issues.apache.org/jira/browse/KAFKA-1070](https://issues.apache.org/jira/browse/KAFKA-1070){:target="_blank"}. This allows scaling up and down. In this case it is recommended to use the ```--no-recreate``` option of docker-compose to ensure that containers are not re-created and thus keep their names and ids. + + +__Automatically create topics__ + +If you want to have kafka-docker automatically create topics in Kafka during +creation, a ```KAFKA_CREATE_TOPICS``` environment variable can be +added in ```docker-compose.yml```. + +Here is an example snippet from ```docker-compose.yml```: + + environment: + KAFKA_CREATE_TOPICS: "Topic1:1:3,Topic2:1:1:compact" + +```Topic 1``` will have 1 partition and 3 replicas, ```Topic 2``` will have 1 partition, 1 replica and a `cleanup.policy` set to `compact`. + +__Advertised hostname__ + +You can configure the advertised hostname in different ways: + +1. Explicitly, using ```KAFKA_ADVERTISED_HOST_NAME``` +2. Via a command, using ```HOSTNAME_COMMAND```, e.g. ```HOSTNAME_COMMAND: "route -n | awk '/UG[ \t]/{print $$2}'"``` + +When using commands, make sure you review the "Variable Substitution" section in [https://docs.docker.com/compose/compose-file/](https://docs.docker.com/compose/compose-file/){:target="_blank"} + +If ```KAFKA_ADVERTISED_HOST_NAME``` is specified, it takes precedence over ```HOSTNAME_COMMAND``` + +For AWS deployment, you can use the Metadata service to get the container host's IP: +``` +HOSTNAME_COMMAND=wget -t3 -T2 -qO- http://169.254.169.254/latest/meta-data/local-ipv4 +``` +Reference: [http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html){:target="_blank"} + +__JMX__ + +For monitoring purposes, you may wish to configure JMX. Additional to the standard JMX parameters, problems could arise from the underlying RMI protocol used to connect + +* java.rmi.server.hostname - interface to bind listening port. +* com.sun.management.jmxremote.rmi.port - the port to service RMI requests. + +For example, to connect to a kafka running locally (assumes exposing port 1099) + + KAFKA_JMX_OPTS: "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.rmi.port=1099" + JMX_PORT: 1099 + +## Spring Boot + Kafka +Then grab the spring-kafka JAR and all of its dependencies - the easiest way to do that is to declare a dependency in your build tool, e.g. for Maven: + + `Text` +{% highlight xml %} +{% raw %} + + org.springframework.kafka + spring-kafka + ${spring-kafka.version} + + + org.springframework.kafka + spring-kafka-test + ${spring-kafka.version} + test + +{% endraw %} +{% endhighlight %} + +Using plain Java to send and receive a message: + + `Java` +{% highlight java %} +{% raw %} +private static String BOOT_TOPIC = "boot.t"; + +@Autowired +private Sender sender; + +@Autowired +private Receiver receiver; + +@ClassRule +public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, BOOT_TOPIC); + +@BeforeClass +public static void setUpBeforeClass() throws Exception { + System.setProperty("spring.kafka.bootstrap-servers", embeddedKafka.getBrokersAsString()); +} + +@Test +public void testReceive() throws Exception { + sender.send(BOOT_TOPIC, "Hello Boot!"); + + receiver.getLatch().await(10000, TimeUnit.MILLISECONDS); + assertThat(receiver.getLatch().getCount()).isEqualTo(0); +} +{% endraw %} +{% endhighlight %} + +Maven will download the needed dependencies, compile the code and run the unit test case. The result should be a successful build during which following logs are generated: + + `Java` +{% highlight java %} +{% raw %} +. ____ _ __ _ _ + /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ +( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ + \\/ ___)| |_)| | | | | || (_| | ) ) ) ) + ' |____| .__|_| |_|_| |_\__, | / / / / + =========|_|==============|___/=/_/_/_/ + :: Spring Boot :: (v1.5.2.RELEASE) + +08:36:56.175 [main] INFO c.c.kafka.SpringKafkaApplicationTest - Starting SpringKafkaApplicationTest on cnf-pc with PID 700 (started by CodeNotFound in c:\code\st\spring-kafka\spring-kafka-avro) +08:36:56.175 [main] INFO c.c.kafka.SpringKafkaApplicationTest - No active profile set, falling back to default profiles: default +08:36:56.889 [main] INFO c.c.kafka.SpringKafkaApplicationTest - Started SpringKafkaApplicationTest in 1.068 seconds (JVM running for 5.293) +08:36:58.223 [main] INFO c.codenotfound.kafka.producer.Sender - sending user='{"name": "John Doe", "favorite_number": null, "favorite_color": "green"}' +08:36:58.271 [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-L-1] INFO c.c.kafka.consumer.Receiver - received user='{"name": "John Doe", "favorite_number": null, "favorite_color": "green"}' +08:37:00.240 [main] ERROR o.a.zookeeper.server.ZooKeeperServer - ZKShutdownHandler is not registered, so ZooKeeper server won't take any action on ERROR or SHUTDOWN server state changes +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 8.871 sec - in com.codenotfound.kafka.SpringKafkaApplicationTest + +Results: + +Tests run: 3, Failures: 0, Errors: 0, Skipped: 0 + +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ +[INFO] Total time: 41.632 s +[INFO] Finished at: 2017-04-17T08:37:31+02:00 +[INFO] Final Memory: 18M/212M +[INFO] ------------------------------------------------------------------------ +{% endraw %} +{% endhighlight %} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/cd-examples/terraform.md b/_docs/example-catalog/cd-examples/terraform.md new file mode 100644 index 00000000..0dd05f46 --- /dev/null +++ b/_docs/example-catalog/cd-examples/terraform.md @@ -0,0 +1,113 @@ +--- +title: "Deploy with Terraform" +description: "Use Terraform in a Codefresh pipeline with Docker" +group: example-catalog +sub_group: cd-examples +toc: true +--- + +[Terraform](https://www.terraform.io/){:target="\_blank"} is a platform for *Infrastructure as Code*. It allows you to describe your cloud infrastructure in a declarative manner. + +You can use Terraform to deploy to Kubernetes or any other supported cloud platform. Because Terraform itself is already offered [in a Docker container](https://hub.docker.com/r/hashicorp/terraform/){:target="\_blank"}, it is very easy to run Terraform in a Codefresh pipeline. + + +{% include image.html +lightbox="true" +file="/images/examples/terraform/terraform-pipeline.png" +url="/images/examples/terraform/terraform-pipeline.png" +alt="Running Terraform inside Codefresh" +caption="Running Terraform inside Codefresh" +max-width="80%" +%} + +## The example Terraform project + +You can see the example project at [https://github.com/codefresh-contrib/terraform-sample-app](https://github.com/codefresh-contrib/terraform-sample-app){:target="\_blank"}. The repository contains a simple Terraform definition that creates a VM on Google cloud. + +You can play with it locally after installing the `terraform` executable. + +## Prerequisites + +You need to [create a Codefresh account]({{site.baseurl}}/docs/administration/create-a-codefresh-account/) and a Google account first. Then you need to create a [Service account Key](https://cloud.google.com/iam/docs/creating-managing-service-account-keys){:target="\_blank"} which will allow terraform to communicate with Google cloud. + + +Add your service account json as a pipeline variable called `ACCOUNT_JSON_CONTENT`. The content of this variable will be used +in order to authenticate to Google cloud. + +## Create a CI/CD pipeline for Terraform + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - prepare + - deploy +steps: + main_clone: + title: Cloning main repository... + stage: checkout + type: git-clone + repo: 'codefresh-contrib/terraform-sample-app' + revision: master + git: github + SetupAuth: + image: alpine:3.9 + title: Setting up Google cloud auth + stage: prepare + commands: + - echo $ACCOUNT_JSON_CONTENT > /codefresh/volume/account.json + - cf_export GOOGLE_CLOUD_KEYFILE_JSON=/codefresh/volume/account.json + DeployWithTerraform: + image: hashicorp/terraform:0.12.0 + title: Deploying Terraform plan + stage: deploy + commands: + - terraform init + - terraform apply -auto-approve + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Creates a pipeline variable with the path of the Google service account by running [cf_export]({{site.baseurl}}/docs/pipelines/variables/#exporting-environment-variables-from-a-freestyle-step). +1. Creates the VM on Google cloud by running `terraform init/apply`. + +>For simplicity, we auto-approve the Terraform plan in the example pipeline. In a production pipeline, you would instead use an [approval step]({{site.baseurl}}/docs/pipelines/steps/approval/) to inspect the plan before actually applying it. + +The pipeline needs a [single environment variable]({{site.baseurl}}/docs/pipelines/pipelines/#pipeline-settings) that holds the content of the service account. + + +{% include image.html +lightbox="true" +file="/images/examples/terraform/google_cloud_json.png" +url="/images/examples/terraform/google_cloud_json.png" +alt="Passing the Google account in the pipeline parameters" +caption="Passing the Google account in the pipeline parameters" +max-width="60%" +%} + + +Run the pipeline and see your deployment succeed. + + +Note that in a production pipeline you should also handle the [Terraform state](https://www.terraform.io/docs/state/){:target="\_blank"} in a proper manner. The example provided is using a file for [state storage](https://www.terraform.io/docs/backends/index.html){:target="\_blank"} which is not appropriate when using Terraform in a team environment. Instead you should use one of the [storage backends](https://www.terraform.io/docs/backends/types/index.html){:target="\_blank"} that support High Availability and Locking. + + + + +## Handling Pull requests + +You can easily use the same pipeline or a different one for pull requests. In this case replace the `terraform apply` command with `terraform plan`. Even better, you can add an [approval step]({{site.baseurl}}/docs/pipelines/steps/approval/) to allow humans to inspect the pipeline first. + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) diff --git a/_docs/example-catalog/cd-examples/transferring-php-ftp.md b/_docs/example-catalog/cd-examples/transferring-php-ftp.md new file mode 100644 index 00000000..56aa1d27 --- /dev/null +++ b/_docs/example-catalog/cd-examples/transferring-php-ftp.md @@ -0,0 +1,118 @@ +--- +title: "Deploy to VM via FTP" +description: "Deploying a PHP application to a VM using FTP" +group: example-catalog +sub_group: cd-examples +toc: true +redirect_from: + - /docs//learn-by-example/java/spring-mvc-jdbc-template/ +--- + +## Prerequisites + +- A [free Codefresh account]({{site.baseurl}}/docs/administration/account-management/create-a-codefresh-account/){:target="\_blank"} +- A remote machine with an FTP server and SSH setup (ensure that your FTP directory, I.e., `/srv/ftp/pub` has the proper write permissions for the FTP user). + +>Note that as you may already know, FTP is extremely insecure as it relies on plain-text passwords and usernames, making data very vulnerable to sniffing. A more secure solution would be to use SFTP or SCP. + +## Example PHP project + +The example project can be found on [GitHub](https://github.com/codefresh-contrib/ftp-php-app){:target="\_blank"}. The application is a simple PHP application that displays an example timer. + +{% include image.html +lightbox="true" +file="/images/examples/php-file-transfer/test-environment.png" +url="/images/examples/php-file-transfer/test-environment.png" +alt="Example PHP Application" +caption="Example PHP Application" +max-width="90%" +%} + +## Create the pipeline + +Our pipeline includes four stages: + +- A stage for cloning +- A stage for packaging +- A stage for transferring files + +{% include image.html +lightbox="true" +file="/images/examples/php-file-transfer/pipeline.png" +url="/images/examples/php-file-transfer/pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="90%" +%} + +Here is the entire pipeline: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +# More examples of Codefresh YAML can be found at +# https://codefresh.io/docs/docs/example-catalog/ + +version: "1.0" +# Stages can help you organize your steps in stages +stages: + - "clone" + - "install" + - "transfer" +steps: + clone: + title: "Cloning main repository..." + type: "git-clone" + arguments: + repo: "codefresh-contrib/ftp-php-app" + git: "github" + stage: "clone" + install_dependencies: + title: "Collecting Php dependencies..." + type: "freestyle" + working_directory: "./ftp-php-app" + arguments: + image: "composer:1.9.3" + commands: + - "composer install --ignore-platform-reqs --no-interaction --no-plugins --no-scripts --prefer-dist" + stage: "install" + steps: + ftp_transfer: + title: "Transferring application to VM via ftp..." + type: "freestyle" + working_directory: "./ftp-php-app" + arguments: + image: "dockito/lftp-client:latest" + environment: + - USER= + - PASSWORD= + - HOST= + - PUB_FTP_DIR= + commands: + - lftp -e "set ftp:use-site-utime2 false; mirror -x ^\.git/$ -X flat-logo.png -p -R ftp-php-ap $PUB_FTP_DIR/ftp-php-app; exit" -u $USER,$PASSWORD $HOST + stage: "transfer" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the main repository through a [Git-clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +2. Installs the necessary PHP dependencies for our application through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). +3. Transfers our application via FTP through another freestyle step. Note that you will need to change the environment variables to your respective values, either in the YAML itself (above), or through the pipeline settings: + +{% include image.html +lightbox="true" +file="/images/examples/php-file-transfer/variables.png" +url="/images/examples/php-file-transfer/variables.png" +alt="Codefresh Environment Variables" +caption="Codefresh Environment Variables" +max-width="90%" +%} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) + + diff --git a/_docs/example-catalog/cd-examples/trigger-a-k8s-deployment-from-docker-registry.md b/_docs/example-catalog/cd-examples/trigger-a-k8s-deployment-from-docker-registry.md new file mode 100644 index 00000000..c15084dd --- /dev/null +++ b/_docs/example-catalog/cd-examples/trigger-a-k8s-deployment-from-docker-registry.md @@ -0,0 +1,135 @@ +--- +title: "Trigger a Kubernetes Deployment from a Docker Hub Push Event" +description: "Learn how to trigger a Kubernetes deployment when an image is updated" +group: example-catalog +sub_group: cd-examples +toc: true +--- + +In this example, we will cover how to trigger a Kubernetes deployment from a Dockerhub Push event using a Dockerhub [registry trigger]({{site.baseurl}}/docs/pipelines/triggers/dockerhub-triggers/#create-a-new-dockerhub-trigger). + +Our example has two pipelines: one for packaging code (CI), and the second for deploying code (CD). + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A DockerHub registry [connected to your Codefresh account]({{site.baseurl}}/docs/integrations/docker-registries/#docker-hub) +- A Kubernetes cluster [connected to your Codefresh account]({{site.baseurl}}/docs/integrations/kubernetes/#connect-a-kubernetes-cluster) +- A service for your application [deployed to your cluster]({{site.baseurl}}/docs/deployments/kubernetes/manage-kubernetes/#viewing-your-kubernetes-services) + +## Example Project + +You can see the example project on [GitHub](https://github.com/codefresh-contrib/registry-trigger-sample-app/tree/master){:target=\_blank"}. The repository contains a simple Hello World NodeJs app as well as 2 pipelines. + +## Create the CI Pipeline + +As mentioned before, our first pipeline will handle the CI process. +The pipeline has three stages: + +- A stage for cloning +- A stage for building the image +- A stage for pushing the image to DockerHub + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-deployment-ci-pipeline.png" +url="/images/examples/deployments/k8s-deployment-ci-pipeline.png" +alt="Codefresh UI CI Pipeline View" +caption="Codefresh UI CI Pipeline View" +max-width="90%" +%} + + `codefresh-CI-pipeline.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' + +stages: +- checkout +- build +- push + +steps: + clone: + title: Cloning main repository... + type: git-clone + stage: checkout + arguments: + repo: 'codefresh-contrib/registry-trigger-sample-app' + revision: 'master' + git: github + build_my_app: + title: Building image... + type: build + stage: build + arguments: + image_name: registry-trigger-sample-app + working_directory: ${{clone}} + tag: 'master' + dockerfile: Dockerfile + push_to_my_registry: + stage: 'push' + type: push + title: Pushing to Dockerhub... + arguments: + candidate: ${{build_my_app}} + tag: 'latest' + registry: dockerhub + image_name: annabaker/registry-trigger-sample-app +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +2. Builds a docker image tagged with the Application version through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). +3. Pushes the Docker image through a [push step](https://codefresh.io/docs/docs/pipelines/steps/push/) to the Docker Hub registry you have integrated with Codefresh. + +## Create the CD Pipeline + +This pipeline contains one stage/step, for deploying. + +{% include image.html +lightbox="true" +file="/images/examples/deployments/k8s-deployment-CD-pipeline.png" +url="/images/examples/deployments/k8s-deployment-CD-pipeline.png" +alt="Codefresh UI CD Pipeline View" +caption="Codefresh UI CD Pipeline View" +max-width="90%" +%} + +Note that for the trigger mechanism to take place, you will need to [add a Docker Hub registry trigger]({{site.baseurl}}/docs/pipelines/triggers/dockerhub-triggers/#create-a-new-dockerhub-trigger) to the pipeline. + + `codefresh-CD-pipeline.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" + +stages: + - "deploy" + +steps: + deploy_to_k8s: + title: Running Deploy Script... + type: deploy + kind: kubernetes + arguments: + cluster: anna-demo@FirstKubernetes + namespace: default + service: registry-trigger-sample-app + candidate: + image: annabaker/registry-trigger-sample-app:latest + registry: 'dockerhub' +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Deploys the image to Kubernetes through a [deploy step]({{site.baseurl}}/docs/pipelines/steps/deploy/). The deploy step uses a [Registry trigger]({{site.baseurl}}/docs/pipelines/triggers/dockerhub-triggers/#create-a-new-dockerhub-trigger) to kick off the pipeline when the updated image is pushed to the registry. + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) +[Triggers in pipelines]({{site.baseurl}}/docs/pipelines/triggers/) diff --git a/_docs/example-catalog/cd-examples/use-kubectl-as-part-of-freestyle-step.md b/_docs/example-catalog/cd-examples/use-kubectl-as-part-of-freestyle-step.md new file mode 100644 index 00000000..b228a895 --- /dev/null +++ b/_docs/example-catalog/cd-examples/use-kubectl-as-part-of-freestyle-step.md @@ -0,0 +1,42 @@ +--- +title: "Use kubectl as part of freestyle step" +description: "How to run manually kubectl in a Codefresh pipeline" +group: example-catalog +sub_group: cd-examples +redirect_from: + - /docs/use-kubectl-as-part-of-freestyle-step/ +toc: true +--- + + +Running Kubernetes commands in Codefresh as part of the workflow is very easy. + + +Codefresh is adding all your clusters into the workflow ready to be used as part of your CI/CD pipeline. +The context remains the same as it appears in the [Codefresh Kubernetes dashboard]({{site.baseurl}}/docs/deploy-to-kubernetes/manage-kubernetes/). + +>If your cluster name includes spaces then make sure that you use quotes in the `kubectl` command. + +* Use image: `codefresh/kubectl` +* Add your commands: + * `kubectl config get-contexts`. Will print the cluster that we added to the workflow + * `kubectl config use-context "my-cluster-name"`. The name is the same as in `Account settings` → `Integrations` → `Kubernetes` + * `kubectl get po -owide` + * `kubectl get nodes` + + +## Follow the example + +* Add this [Git repo](https://github.com/Codefresh-Examples/kubectl-in-freestyle-step){:target="_blank"} to your account +* Change the pipeline configuration to use `codefresh.yml`. +* Build. + +## Running parallel steps with kubectl + +More complex examples can be found in the [custom kubectl commands]({{site.baseurl}}/docs/deploy-to-kubernetes/custom-kubectl-commands/) documentation page. + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/cd-examples/web-terminal.md b/_docs/example-catalog/cd-examples/web-terminal.md new file mode 100644 index 00000000..37151528 --- /dev/null +++ b/_docs/example-catalog/cd-examples/web-terminal.md @@ -0,0 +1,48 @@ +--- +title: "Web terminal" +description: "" +group: example-catalog +sub_group: cd-examples +redirect_from: + - /docs/web-terminal/ + - /docs/on-demand-test-environment/example-compositions/web-terminal/ +toc: true +--- +This example shows you how to access containers running in a Codefresh standup environment. + +## Looking around +In the root of this repository you'll find a file named `docker-compose.yml`. +Here are the contents of this file: + + `Composition.yml` +{% highlight yaml %} +version: '3' +services: + my-service: + image: 'containers101/whomi:master' + volumes: + - my-service:/app + ports: + - '1337' + terminal: + image: 'containers101/cfterminal:master' + ports: + - '8000' + volumes_from: + - my-service +volumes: + my-service: + driver: local +{% endhighlight %} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/codefreshdemo/cf-example-web-termial){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#cd-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/android.md b/_docs/example-catalog/ci-examples/android.md new file mode 100644 index 00000000..a02d66b1 --- /dev/null +++ b/_docs/example-catalog/ci-examples/android.md @@ -0,0 +1,80 @@ +--- +title: "Compile and package an Android application" +description: "Using Codefresh pipelines" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +Android applications use Java/Gradle for their build system. Because Codefresh already supports [Gradle]({{site.baseurl}}/docs/example-catalog/ci-examples/gradle/), it is also very easy to build Android projects. + +Any Gradle command can run inside a Docker image that contains the Android SDK. As an example, we will use a [Nextcloud](https://hub.docker.com/r/nextcloudci/android){:target="\_blank"} image from Dockerhub. + + +## The example project + +You can see the example project at [https://github.com/codefresh-contrib/android-sample-app](https://github.com/codefresh-contrib/android-sample-app){:target="\_blank"}. The repository contains a Hello World Android project with the following tasks: + +* `./gradlew test` runs unit tests +* `./gradlew build` builds the application + + +## Create a CI pipeline that compiles/releases Android + +In most cases you would create a similar pipeline to a Gradle project. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/mobile/android-ci-pipeline.png" +url="/images/learn-by-example/mobile/android-ci-pipeline.png" +alt="Building and Testing an Android app" +caption="Building and Testing an Android app" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/android-sample-app/blob/master/codefresh.yml){:target="\_blank"} that uses a Docker image with the Android SDK in order to run Gradle. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/android-sample-app' + revision: master + git: github + TestIt: + title: Running Tests + stage: test + image: nextcloudci/android:android-48 + commands: + - chmod +x ./gradlew + - ./gradlew test --no-daemon --gradle-user-home=/codefresh/volume/.gradle + BuildIt: + title: Packaging Android App + stage: build + image: nextcloudci/android:android-48 + commands: + - ./gradlew build --no-daemon --gradle-user-home=/codefresh/volume/.gradle +{% endraw %} +{% endhighlight %} + +This pipeline clones the source code, runs unit tests and finally builds the Android application. + +Codefresh is smart enough that [caches automatically]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#how-caching-works-in-codefresh) for us the workspace of a build (`/codefresh/volume`). This works great for build tools that keep their cache in the project folder, but not for Maven/Gradle which keep their cache externally. By changing the location of the Gradle cache we make sure that Codefresh will cache automatically the Gradle libraries resulting in much faster builds. + + + +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) + diff --git a/_docs/example-catalog/ci-examples/build-an-image-from-a-different-git-repository.md b/_docs/example-catalog/ci-examples/build-an-image-from-a-different-git-repository.md new file mode 100644 index 00000000..d81e5363 --- /dev/null +++ b/_docs/example-catalog/ci-examples/build-an-image-from-a-different-git-repository.md @@ -0,0 +1,94 @@ +--- +title: "Build an Image from a different Git repository" +description: "Build microservices from other repositories" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/build-an-image-from-a-different-git-repository/ +toc: true +--- + +In most cases, your Codefresh pipeline checks out a single Git repository. Codefresh has great support also for [monorepos]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/#using-the-modified-files-field-to-constrain-triggers-to-specific-folderfiles) if you have placed all your applications in a single repository. + +A Codefresh pipeline is not really tied to a specific Git repository, which means that by [checking out multiple Git repositories]({{site.baseurl}}/docs/example-catalog/ci-examples/git-checkout/#cloning-multiple-repositories) you can build Docker images from other unrelated repositories in a single pipeline if you wish to do so. + +## Building Docker images from other Git repositories + + +Here is a Codefresh pipeline that checks out two microservices from two different Git repositories. + +{% include image.html +lightbox="true" +file="/images/examples/docker-build/build-from-other-git-repo.png" +url="/images/examples/docker-build/build-from-other-git-repo.png" +alt="Checkout and build docker images" +caption="Checkout and build docker images" +max-width="100%" +%} + +And here is the [pipeline definition]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/). + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - 'clone phase' + - 'build phase' +steps: + checkoutApp1: + title: 'Cloning first repository...' + type: git-clone + repo: kostis-codefresh/example_nodejs_postgres + revision: experiment1 + git: github + stage: 'clone phase' + checkoutApp2: + title: 'Cloning second repository...' + type: git-clone + repo: kostis-codefresh/trivial-go-web + revision: master + git: github + stage: 'clone phase' + myFirstDockerImage: + title: 'Building Microservice A' + type: build + dockerfile: Dockerfile + image_name: my-nodejs-image + tag: from-develop-branch + working_directory: './example_nodejs_postgres' + stage: 'build phase' + mySecondDockerImage: + title: 'Building Microservice B' + type: build + dockerfile: Dockerfile + working_directory: './trivial-go-web' + image_name: my-app-image + tag: from-master-branch + stage: 'build phase' +{% endraw %} +{% endhighlight %} + +The pipeline first checks out two different Git repositories, which themselves contain Dockerfiles. Then it creates a Docker image for each one using the respective Dockerfile. + +You can see both images in the [Docker image dashboard]({{site.baseurl}}/docs/docker-registries/#viewing-docker-images) . + +{% include image.html +lightbox="true" +file="/images/examples/docker-build/two-docker-images.png" +url="/images/examples/docker-build/two-docker-images.png" +alt="Docker images from other Git repos" +caption="Docker images from other Git repos" +max-width="100%" +%} + + +Notice that there are no explicit push steps in the pipeline, as all successful Codefresh pipelines automatically push to the private Docker registry. + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/) +[Build step in pipelines in pipelines]({{site.baseurl}}/docs/pipelines/steps/build/) +[Build and Push an image]({{site.baseurl}}/docs/pipelines/examples/build-and-push-an-image/) +[Parallel pipelines]({{site.baseurl}}/docs/pipelines/advanced-workflows/) diff --git a/_docs/example-catalog/ci-examples/build-an-image-specify-dockerfile-location.md b/_docs/example-catalog/ci-examples/build-an-image-specify-dockerfile-location.md new file mode 100644 index 00000000..75d5b67f --- /dev/null +++ b/_docs/example-catalog/ci-examples/build-an-image-specify-dockerfile-location.md @@ -0,0 +1,74 @@ +--- +title: "Build an Image by specifying a Dockerfile location" +description: "How to choose a Dockerfile to build with Codefresh pipelines" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/build-an-image-specify-dockerfile-location/ +toc: true +--- + +You may have a project where the Dockerfile is **not** in the root folder of the project. Maybe the repository has multiple projects inside, each with its own Dockerfile, or you simply want to use a different folder for the Docker context. + +>The source code of the repository is at [https://github.com/codefreshdemo/cf-example-dockerfile-other-location](https://github.com/codefreshdemo/cf-example-dockerfile-other-location){:target="\_blank"}. Feel free to fork it if you want to follow along. + +If you don't have a Codefresh account already, you can easily create a free one from the [sign-up page]({{site.baseurl}}/docs/administration/create-a-codefresh-account/). + + +## Building a Dockerfile from a different folder + +By default, if you run a single command like the one below, Docker uses the Dockerfile of the current folder: + +``` +docker build . -t my-web-app +``` + +If your Dockerfile is in a different folder, specify it explicitly with: + +``` +docker build . -t my-web-app -f subfolder/Dockerfile +``` + +Codefresh supports a similar syntax as well. The `dockerfile` property of the [build step]({{site.baseurl}}/docs/pipelines/steps/build/) can accept a full path. + +Here is the full pipeline: + + `codefresh.yml` +{% highlight yaml %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/cf-example-dockerfile-other-location' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + image_name: my-app + working_directory: '.' + tag: 'master' + dockerfile: docker/Dockerfile +{% endhighlight %} + +This pipeline checks out the source code of the repository and then builds a Dockerfile found at the subfolder `docker` while still keeping as Docker context the root directory. + +{% include image.html +lightbox="true" +file="/images/examples/docker-build/build-spefify-dockerfile.png" +url="/images/examples/docker-build/build-spefify-dockerfile.png" +alt="Building a Docker image with specific Dockerfile" +caption="Building a Docker image with specific Dockerfile" +max-width="100%" +%} + +You could also change the Docker build context by editing the `working_directory` property. By default, it looks at the root folder of the project, but any subfolder path is also valid. + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Build step in pipelines]({{site.baseurl}}/docs/pipelines/steps/build/) +[Build an Image with the Dockerfile in root directory]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-dockerfile-in-root-directory/) +[Build an Image from a different Git repository]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-from-a-different-git-repository) +[Build and push an Image]({{site.baseurl}}/docs/yaml-examples/example-catalog/ci-examples/build-and-push-an-image) +[Build an Image With build arguments]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-with-build-arguments) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/build-an-image-with-build-arguments.md b/_docs/example-catalog/ci-examples/build-an-image-with-build-arguments.md new file mode 100644 index 00000000..a7a62356 --- /dev/null +++ b/_docs/example-catalog/ci-examples/build-an-image-with-build-arguments.md @@ -0,0 +1,133 @@ +--- +title: "Build an Image with build arguments" +description: "Use Docker arguments in Codefresh pipelines" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/build-an-image-with-build-arguments/ +toc: true +--- + +Building a Docker image that requires build arguments is very easy with Codefresh pipelines. + +The source code of the repository is at [https://github.com/codefreshdemo/cf-example-build-arguments](https://github.com/codefreshdemo/cf-example-build-arguments){:target="\_blank"}. Feel free to fork it if you want to follow along. + +If you don't have a Codefresh account already, you can easily create a free one from the [sign-up page]({{site.baseurl}}/docs/administration/create-a-codefresh-account/). + +## Using Docker build arguments + +The example application is a very simple NodeJS application with the following DYouockerfile: + +`Dockerfile` +{% highlight docker %} +{% raw %} +ARG NODE_VERSION +FROM node:$NODE_VERSION + +ARG APP_DIR + +RUN mkdir -p $APP_DIR + +WORKDIR $APP_DIR + +COPY package.json . +RUN npm install --silent +COPY . . +EXPOSE 3000 + +ENV PORT 3000 + +CMD [ "npm", "start" ] +{% endraw %} +{% endhighlight %} + +This Dockerfile expects two [build arguments](https://docs.docker.com/engine/reference/builder/#/arg){:target="\_blank"}: + +* `NODE_VERSION` is the version of Node image to use as base +* `APP_DIR` is the source directory to be used inside the container + +## Building a Dockerfile passing values for build arguments + +When you build an image locally on your workstation, you can define build arguments with the `--build-arg` syntax: + +``` +docker build . -t my-node-app --build-arg NODE_VERSION=8 --build-arg APP_DIR=/usr/src/app +``` + +You can get the same result within a Codefresh pipeline: + + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/cf-example-build-arguments' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + image_name: my-app + working_directory: '.' + tag: 'master' + dockerfile: Dockerfile + build_arguments: + - NODE_VERSION=8 + - APP_DIR=/usr/src/app +{% endraw %} +{% endhighlight %} + +This pipeline checks out the source code of the repository and then builds the Dockerfile by passing the values `8` and `/usr/src/app` to the two arguments. + +{% include image.html +lightbox="true" +file="/images/examples/docker-build/docker-build-arguments.png" +url="/images/examples/docker-build/docker-build-arguments.png" +alt="Using Docker build arguments in a pipeline" +caption="Using Docker build arguments in a pipeline" +max-width="100%" +%} + +## Using Codefresh variables as build arguments + +In the previous pipeline, the Docker build arguments are defined in the pipeline itself, but you can also use [pipeline variables]({{site.baseurl}}/docs/pipelines/pipelines/#creating-new-pipelines), [shared configuration]({{site.baseurl}}/docs/pipelines/shared-configuration/), or any other standard mechanism you already have in place. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/cf-example-build-arguments' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + image_name: my-app + working_directory: '.' + tag: 'master' + dockerfile: Dockerfile + build_arguments: + - NODE_VERSION=${{NODE_VERSION_FROM_SHARED_CONFIG}} + - APP_DIR=${{APP_DIR_PIPELINE_VARIABLE}} +{% endraw %} +{% endhighlight %} + +In this case, you can also use any of the built-in [Codefresh variables]({{site.baseurl}}/docs/pipelines/variables/). + + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Build step in pipelines]({{site.baseurl}}/docs/pipelines/steps/build/) +[Build an Image with the Dockerfile in root directory]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-dockerfile-in-root-directory/) +[Build an Image by specifying the Dockerfile location]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-specify-dockerfile-location) +[Build an Image from a different Git repository]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-from-a-different-git-repository) +[Build and push an Image]({{site.baseurl}}/docs/yaml-examples/example-catalog/ci-examples/build-and-push-an-image) diff --git a/_docs/example-catalog/ci-examples/build-an-image-with-the-dockerfile-in-root-directory.md b/_docs/example-catalog/ci-examples/build-an-image-with-the-dockerfile-in-root-directory.md new file mode 100644 index 00000000..a9c5cb2e --- /dev/null +++ b/_docs/example-catalog/ci-examples/build-an-image-with-the-dockerfile-in-root-directory.md @@ -0,0 +1,67 @@ +--- +title: "Build an Image with the Dockerfile in root directory" +description: "Get started quickly with building Docker images" +group: example-catalog +sub_group: ci-examples +toc: true +--- +Building a Docker image is one of the basic operations in Codefresh pipelines. + +>The source code of the repository is at [https://github.com/codefreshdemo/cf-yml-example-build-dockerfile-inroot](https://github.com/codefreshdemo/cf-yml-example-build-dockerfile-inroot){:target="\_blank"}. Feel free to fork it if you want to follow along. + +If you don't have a Codefresh account already, you can easily create a free one from the [sign-up page]({{site.baseurl}}/docs/administration/create-a-codefresh-account/). + + +## Building a Dockerfile from the root folder + +By default, if you run a single command like the one below, Docker uses the Dockerfile of the current folder: + +``` +docker build . -t my-web-app +``` + +You can get the same result within a Codefresh pipeline: + + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/cf-yml-example-build-dockerfile-inroot' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + image_name: my-app + working_directory: '${{main_clone}}' + tag: 'master' + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +This pipeline checks out the source code of the repository and then builds a dockerfile found at the root folder of the project. + +{% include image.html +lightbox="true" +file="/images/examples/docker-build/build-dockerfile-root.png" +url="/images/examples/docker-build/build-dockerfile-root.png" +alt="Building a Docker image with a default Dockerfile" +caption="Building a Docker image with a default Dockerfile" +max-width="100%" +%} + +You can also change the Docker build context by editing the `working_directory` property. By default, it looks at the root folder of the project, but any subfolder path is also valid. + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Build step in pipelines]({{site.baseurl}}/docs/pipelines/steps/build/) +[Build an Image by specifying the Dockerfile location]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-specify-dockerfile-location) +[Build an Image from a different Git repository]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-from-a-different-git-repository) +[Build and push an Image]({{site.baseurl}}/docs/yaml-examples/example-catalog/ci-examples/build-and-push-an-image) +[Build an Image With build arguments]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-with-build-arguments) diff --git a/_docs/example-catalog/ci-examples/build-and-push-an-image.md b/_docs/example-catalog/ci-examples/build-and-push-an-image.md new file mode 100644 index 00000000..33ebac63 --- /dev/null +++ b/_docs/example-catalog/ci-examples/build-and-push-an-image.md @@ -0,0 +1,137 @@ +--- +title: "Build and push an Image" +description: "Build Docker images and push them to registries with Codefresh" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/build-and-push-an-image/ + - /docs/docker-registries/push-image-to-a-docker-registry/ +toc: true +--- + +Building a Docker image and then pushing it to a registry is one of the most basic scenarios for creating a pipeline. +In this example we will use a demo Node.js application that will be packaged in a Docker image. + +The source code of the repository is at [https://github.com/codefreshdemo/cf-example-build-and-push](https://github.com/codefreshdemo/cf-example-build-and-push){:target="\_blank"}. Feel free to fork it if you want to follow along. + +If you don't have a Codefresh account already, you can easily create a free one from the [sign-up page]({{site.baseurl}}/docs/administration/create-a-codefresh-account/). + + +## Building and push Docker image to default registry + +Building a Docker image with Codefresh is easy, and only requires a simple step. In addition, all successful pipelines in Codefresh automatically push to [your default Docker registry]({{site.baseurl}}/docs/docker-registries/#the-default-registry), without additional configuration, if you have one. + +Here is the most basic pipeline that clones a repo and builds an image: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- checkout +- build +steps: + clone: + title: Cloning main repository... + type: git-clone + stage: checkout + repo: 'codefreshdemo/cf-example-build-and-push' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + stage: build + image_name: my-node-js-app + working_directory: {{clone}} + tag: 'master' + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +## Building and pushing Docker image to _any registry_. + +You can push your image to any [registry]({{site.baseurl}}/docs/docker-registries/). + +* First you need to connect your external registry in the integrations page. Here are the instructions for: + + * [Docker Hub]({{site.baseurl}}/docs/integrations/docker-registries/docker-hub/) + * [Google Container Registry]({{site.baseurl}}/docs/integrations/docker-registries/google-container-registry/) + * [Amazon EC2 Container Registry]({{site.baseurl}}/docs/integrations/docker-registries/amazon-ec2-container-registry/) + * [Bintray.io]({{site.baseurl}}/docs/integrations/docker-registries/bintray-io/) + * [Quay.io]({{site.baseurl}}/docs/integrations/docker-registries/quay-io/) + * [Other Registries]({{site.baseurl}}/docs/integrations/docker-registries/other-registries/) + +* Then add a [push step]({{site.baseurl}}/docs/pipelines/steps/push/) in your pipeline and use the registry name of your integration. + +Here is the full example: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: +- checkout +- build +- push +steps: + clone: + title: Cloning main repository... + type: git-clone + stage: checkout + repo: 'codefreshdemo/cf-example-build-and-push' + revision: 'master' + git: github + build_my_app: + title: Building Node.Js Docker Image + type: build + stage: build + image_name: my-node-js-app + working_directory: {{clone}} + tag: 'master' + dockerfile: Dockerfile + push_to_my_registry: + stage: 'push' + type: push + title: Pushing to a registry + candidate: ${{build_my_app}} + tag: 'v1.0.0' + registry: dockerhub + image_name: kkapelon/my-node-js-app +{% endraw %} +{% endhighlight %} + +Here we use a specific tag - `v1.0.0` but +Codefresh has several variables that you can use to tag images. Common examples are `CF_BRANCH_TAG_NORMALIZED`, `CF_SHORT_REVISION` or `CF_BUILD_ID`. Read more on [variables]({{site.baseurl}}/docs/pipelines/variables/). + +{% include image.html + lightbox="true" + file="/images/examples/docker-build/build-and-push-pipeline.png" + url="/images/examples/docker-build/build-and-push-pipeline.png" + alt="Pushing image to external registry" + caption="Pushing image to external registry" + max-width="100%" + %} + + +If you run the pipeline, the Docker image is pushed *both* to the private Docker regisry (by the build step) *and* the external docker registry (by the push step). + + +## More options for pushing images + +Codefresh has several options when it comes to pushing images: + +* You can specify multiple tags to be pushed +* You can use directly ECR registries +* You can embed credentials in the push steps + +Read more in [push steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/push/). + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Build step in pipelines]({{site.baseurl}}/docs/pipelines/steps/build/) +[Build an Image with the Dockerfile in root directory]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-dockerfile-in-root-directory/) +[Build an Image by specifying the Dockerfile location]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-specify-dockerfile-location) +[Build an Image from a different Git repository]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-from-a-different-git-repository) +[Build an Image With Build arguments]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-with-build-arguments) diff --git a/_docs/example-catalog/ci-examples/c-make.md b/_docs/example-catalog/ci-examples/c-make.md new file mode 100644 index 00000000..06b95d76 --- /dev/null +++ b/_docs/example-catalog/ci-examples/c-make.md @@ -0,0 +1,74 @@ +--- +title: "Compile and test a C application" +description: "Using Codefresh pipelines" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +Codefresh can work with any C/C++ application very easily as both `gcc` and `g++` are already offered in Dockerhub. There is also another example available with [C++ and cmake]({{site.baseurl}}/docs/example-catalog/ci-examples/cpp-cmake). + +## The example C project + +You can see the example project at [https://github.com/codefresh-contrib/c-sample-app](https://github.com/codefresh-contrib/c-sample-app){:target="\_blank"}. The repository contains a C starter project with a `Makefile` and several targets: + +* `make` compiles the code. +* `make test` runs unit tests +* `make clean` removes artifacts and binaries. + +There are also extra targets for `tags` and `etags`. + +## Create a CI pipeline for C applications + +Creating a CI/CD pipeline for C is very easy, because Codefresh can run any [gcc image](https://hub.docker.com/_/gcc/){:target="\_blank"} that you wish. Gcc docker images already contain the `make` utility. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/cc/c-make-pipeline.png" +url="/images/learn-by-example/cc/c-make-pipeline.png" +alt="Compiling a C application in a pipeline" +caption="Compiling a C application in a pipeline" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/c-sample-app/blob/master/codefresh.yml){:target="\_blank"} that compiles the application after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - build +steps: + main_clone: + title: Cloning main repository... + stage: checkout + type: git-clone + repo: 'codefresh-contrib/c-sample-app' + revision: master + git: github + compile_my_sources: + title: Compile + stage: build + image: gcc + commands: + - make + run_my_tests: + title: Test + stage: build + image: gcc + commands: + - make test +{% endraw %} +{% endhighlight %} + +This pipeline clones the source code, compiles the code and runs unit tests. In all cases we use the public Docker image of Gcc that also contains `make`. + + +## Related articles +[C++ example]({{site.baseurl}}/docs/example-catalog/ci-examples/cpp-cmake/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/call-child-pipelines.md b/_docs/example-catalog/ci-examples/call-child-pipelines.md new file mode 100644 index 00000000..fd83b5b7 --- /dev/null +++ b/_docs/example-catalog/ci-examples/call-child-pipelines.md @@ -0,0 +1,108 @@ +--- +title: "Call a CD pipeline from a CI pipeline" +description: "How to call child pipelines from a parent pipeline" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +In Codefresh you can easily create nested pipelines by calling other pipelines from within an existing pipeline. The [codefresh-run plugin](https://codefresh.io/steps/step/codefresh-run){:target="\_blank"} allows you to launch another pipeline, and optionally wait for its completion. + +{% include image.html +lightbox="true" +file="/images/examples/nested-pipelines/call-other-pipeline.png" +url="/images/examples/nested-pipelines/call-other-pipeline.png" +alt="Parent and child pipelines" +caption="Parent and child pipelines" +max-width="80%" +%} + +A very common pattern in Codefresh is to have a parent pipeline responsible for Continuous Integration (packaging code), that calls a child pipeline for Continuous Delivery (taking care of deployment). + +## Example project + +You can see the example project at [https://github.com/codefresh-contrib/call-child-pipeline-sample-app](https://github.com/codefresh-contrib/call-child-pipeline-sample-app){:target="\_blank"}. The repository contains a NodeJs app as well as three - one parent and two child pipelines. + +## Create a pipeline that calls other pipelines + +Here is the definition of the parent pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - package + - deploy +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: '${{CF_REVISION}}' + git: github + stage: prepare + read_my_app_version: + title: Reading Application version + stage: prepare + image: node:latest + commands: + - export PACKAGE_VERSION=$(node -p "require('./package.json').version") + - cf_export PACKAGE_VERSION + build_my_docker_image: + title: 'Building My Docker Image' + stage: package + type: build + dockerfile: Dockerfile + image_name: my-app-image + tag: ${{PACKAGE_VERSION}} + call_qa_pipeline: + title: Deploy to QA + stage: deploy + type: codefresh-run + arguments: + PIPELINE_ID: child-pipelines/qa-pipeline + VARIABLE: + - CF_BRANCH=${{CF_BRANCH}} + - CF_REVISION=${{CF_REVISION}} + - APP_VERSION=${{PACKAGE_VERSION}} + when: + branch: + only: + - develop + call_prod_pipeline: + title: Deploy to Prod + stage: deploy + type: codefresh-run + arguments: + PIPELINE_ID: child-pipelines/prod-pipeline + VARIABLE: + - CF_BRANCH=${{CF_BRANCH}} + - CF_REVISION=${{CF_REVISION}} + - APP_VERSION=${{PACKAGE_VERSION}} + when: + branch: + only: + - /^release.*/i + + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Creates a variable that contains the Application version as specified in `package.json` through [cf_export]({{site.baseurl}}/docs/pipelines/variables/#exporting-environment-variables-from-a-freestyle-step). +1. Builds a docker image tagged with the Application version through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). +1. Optionally runs the downstream QA pipeline if the branch is named `develop`. It also passes several environment variables to the child pipeline (including the Application version). +1. Optionally runs the downstream Prod pipeline if the branch name starts with `release`. It also passes several environment variables to the child pipeline (including the Application version). + +The last two steps use [conditions]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/) to decide if they will run or not. + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[Pipeline plugins](https://codefresh.io/steps/){:target="\_blank"} \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/cc.md b/_docs/example-catalog/ci-examples/cc.md new file mode 100644 index 00000000..c23c08fc --- /dev/null +++ b/_docs/example-catalog/ci-examples/cc.md @@ -0,0 +1,10 @@ +--- +title: "C/C++" +description: "How to build C/C++ applications with Codefresh CI/CD pipelines" +group: example-catalog +toc: true +--- +This section contains Codefresh examples based on C and C++. + +- [C Example with make]({{site.baseurl}}/docs/learn-by-example/cc/c-make) +- [C++ Example with cmake]({{site.baseurl}}/docs/learn-by-example/cc/cpp-cmake) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/codacy-testing.md b/_docs/example-catalog/ci-examples/codacy-testing.md new file mode 100644 index 00000000..bd2e437b --- /dev/null +++ b/_docs/example-catalog/ci-examples/codacy-testing.md @@ -0,0 +1,174 @@ +--- +title: "Codacy coverage reports" +description: "How to forward coverage reports to Codacy" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +[Codacy](https://www.codacy.com/){:target="\_blank"} is a code review tool that allows automatic analysis, code coverage tracking, and extensive reports, for you and your team to improve your code quality over time. + +Analysis reports displayed within Codacy dashboard: +{% include image.html +lightbox="true" +file="/images/testing/codacy/codacy-report.png" +url="/images/testing/codacy/codacy-report.png" +alt="Codacy UI with coverage reports" +max-width="100%" +%} + +## Prerequisites for using Codacy + +* A simple [Codefresh pipeline, up and running]({{site.baseurl}}/docs/getting-started/create-a-basic-pipeline/) +* A [Codacy account](https://www.codacy.com/){:target="\_blank"} (free, pro or enterprise) +* A testing tool added to your project that produces coverage reports + +Codacy supports over [30 different language integrations](https://docs.codacy.com/getting-started/supported-languages-and-tools/){:target="\_blank"}. Depending on the programming language used, it requires little to no set-up. + +You could try it out by cloning our [node example application](https://github.com/codefresh-contrib/codacy-sample-app){:target="\_blank"} that utilises [jest](https://jestjs.io/){:target="\_blank"}. + +## Create an account with Codacy +Codacy has a free version, a pro version, and an on-premises version. The latter two have a free trial, which allows you to test all features over the course of two weeks. You can sign-up via GitHub, Bitbucket, or GitLab. + +When you log into Codacy for the first time, it will ask you to provide access to a repository. At this stage, Codacy will not download any code from your repository but merely access its names. You can then either provide access to selective repositories or your entire git account. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/codacy-add-repo.png" +url="/images/testing/codacy/codacy-add-repo.png" +alt="Add repository to codacy" +max-width="80%" +%} + +## Generate Project API token +To use Codacy, we need a project API token. To generate the token, select your project => go to settings => integrations => add integration => select “Project API”. Make sure that you select the API token from here and not your general project settings. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/create-api-token.png" +url="/images/testing/codacy/create-api-token.png" +alt="Create Project API token" +max-width="80%" +%} + +## Codefresh pipeline + +In case the project that you want to use Codacy in does not have a pipeline, [create a new pipeline]({{site.baseurl}}/docs/getting-started/create-a-basic-pipeline/). + +{% include image.html +lightbox="true" +file="/images/testing/codacy/create-codacy-pipeline.png" +url="/images/testing/codacy/create-codacy-pipeline.png" +alt="Create Codacy Pipeline" +max-width="80%" +%} + +**Setting-up step** + +This step is based on our [TypeScript application](https://github.com/codefresh-contrib/codacy-sample-app){:target="\_blank"}. Before we set up our pipeline, we will add our Project API token as our environment variable. Note that we have specified our token in the variables section on the right, as displayed in the following screenshot. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/codacy-variable.png" +url="/images/testing/codacy/codacy-variable.png" +alt="Provide Codacy ENV variable" +max-width="80%" +%} + +Once the variable is called through the [Codefresh yml syntax]({{site.baseurl}}/docs/pipelines/variables/), it automatically uses the value provided within the variables section. If you are using this example as your pipeline, please delete anything in your pipeline. We can then add the following pipeline to our Inline YAML within the Workflow section in our UI: + +{% highlight yaml %} +{% raw %} +version: "1.0" +# Stages can help you organize your steps in stages +stages: + - "clone" + - "build" + - "test" + +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "anais-codefresh/codacy-sample-app" + # CF_BRANCH value is auto set when pipeline is triggered + # Learn more at codefresh.io/docs/docs/pipelines/variables/ + revision: "${{CF_BRANCH}}" + git: "github" + stage: "clone" + + build: + title: "Building Docker image" + type: "build" + image_name: "anaisurlichs/codacy-sample-app" + working_directory: "${{clone}}" + tag: "${{CF_BRANCH_TAG_NORMALIZED}}" + dockerfile: "Dockerfile" + stage: "build" + registry: "dockerhub" + + tests: + title: "Running test" + type: "freestyle" + working_directory: '${{clone}}' + arguments: + image: 'node:15.2' + commands: + - "npm install --save-dev jest" + - "npm run test" + stage: "test" + + codacy: + title: "Pushing reports to codacy" + type: "freestyle" + working_directory: '${{clone}}' + arguments: + image: 'alpine:3.8' + commands: + - "export CODACY_PROJECT_TOKEN=${{CODACY_PROJECT_TOKEN}}" + - "wget -qO - https://coverage.codacy.com/get.sh | sh" + stage: "test" +{% endraw %} +{% endhighlight %} + +The last two steps, ’tests’ and ’codacy’, are used to run our tests, create our coverage reports and forward those to Codacy. If you are using your own project and existing pipeline, add those two steps to your pipeline. In case you are using your own application, make sure to adapt the commands within the test step to run the tests of your application. Additionally, ensure that both the ’repo’ and the ’image_name’ point to your integrations. + +Once you run the pipeline, the steps will create the coverage report and forwards it to Codacy. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/codacy-pipeline.png" +url="/images/testing/codacy/codacy-pipeline.png" +alt="Pipeline with Codacy step" +max-width="80%" +%} + +## View reports + +You can view the updated coverage reports within Codacy's UI every time you make a commit and/or run the Codefresh pipeline directly. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/codacy-report.png" +url="/images/testing/codacy/codacy-report.png" +alt="Codacy UI Analysis Dashboard" +max-width="80%" +%} + +You can access further information on the coverage report by opening the file tab and accessing a specific file from your repository. + +{% include image.html +lightbox="true" +file="/images/testing/codacy/file-analysis.png" +url="/images/testing/codacy/file-analysis.png" +alt="Codacy report details" +max-width="90%" +%} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Unit tests]({{site.baseurl}}/docs/testing/unit-tests/) +[Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) +[Sonarqube Integration]({{site.baseurl}}/docs/testing/sonarqube-integration/) diff --git a/_docs/example-catalog/ci-examples/codecov-testing.md b/_docs/example-catalog/ci-examples/codecov-testing.md new file mode 100644 index 00000000..82e06f88 --- /dev/null +++ b/_docs/example-catalog/ci-examples/codecov-testing.md @@ -0,0 +1,128 @@ +--- +title: "Codecov coverage reports" +description: "How to forward coverage reports to Codecov" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +[Codecov account](https://codecov.io/){:target="\_blank"} is a code analysis tool with which users can group, merge, archive, and compare coverage reports. Code coverage describes which lines of code were executed by the test suite and which ones were not. However, this is not to be confused with a testing tool. + +Analysis reports displayed within the Codecov dashboard: +{% include image.html +lightbox="true" +file="/images/testing/codecov/analysis-report.png" +url="/images/testing/codecov/analysis-report.png" +alt="Codecov UI Analysis reports" +max-width="50%" +%} + +## Prerequisites for using Codecov + +* A simple [Codefresh pipeline up and running](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +* A [Codecov account](https://codecov.io/){:target="\_blank"} (free or enterprise) +* A testing tool added to your project that produces coverage reports + +Note that reports should ideally be written in .json, .xml, or txt. To be sure, please double check that your coverage [report format](https://docs.codecov.io/docs/supported-report-formats){:target="\_blank"} is supported. You can find a variety of examples for different programming languages and suggestions for respective testing tools in the [Codecov docs](https://docs.codecov.io/docs/supported-languages){:target="\_blank"}. + +To test Codecov and follow along with the next section, you can clone our [Codecov sample app](https://github.com/codefresh-contrib/codecov-sample-app){:target="\_blank"}. + +## Create a Codecov account + +Once you sign up to Codecov, you can add a new repository. The UI will then provide you with an access token to the repository. While it is recommended that you take note of the token, you will still be able to access it within the **Settings** tap. + +{% include image.html +lightbox="true" +file="/images/testing/codecov/codecov-interface.png" +url="/images/testing/codecov/codecov-interface.png" +alt="Codecov Project Repository UI" +max-width="50%" +%} + +## Codefresh pipeline + +In this case, we divided testing and connecting Codefresh to Codecov into two different steps. If they can be run within the same image, you could also connect them. + +**Testing step** +Runs the command(s) for our testing tool. This will generate the code coverage report upon running the pipeline. Please refer to the Codecov documentation for [supported testing frameworks](https://docs.codecov.io/docs/supported-report-formats){:target="\_blank"}. The [README of each example](https://docs.codecov.io/docs/supported-languages){:target="\_blank"} refers to possible frameworks that can be used. + +In general, ensure that the framework you use for testing and generating code coverage reports: +* Produce code coverage reports in the supported file format +* Is compatible with the programming language that your program is written in + +{% highlight yaml %} +{% raw %} + test: + title: "Running test" + type: "freestyle" # Run any command + image: "node:14.19.0" # The image in which command will be executed + working_directory: "${{clone}}" # Running command where code cloned + commands: + - "npm install --save-dev jest" + - "npx jest --coverage" + stage: "test" +{% endraw %} +{% endhighlight %} + +**Codecov step** + +{% highlight yaml %} +{% raw %} +upload: + title: "Running test" + type: "freestyle" # Run any command + image: "node:14.19.0" # The image in which command will be executed + working_directory: "${{clone}}" # Running command where code cloned + commands: + - "ci_env=`curl -s https://codecov.io/env`" + - "npm install codecov -g" + - "codecov -t ${{CODECOV_TOKEN}} -f ./coverage/clover.xml" + stage: "upload" +{% endraw %} +{% endhighlight %} + +The commands run inside of the node Docker image: +* `ci_env= curl -s https://codecov.io/env`: Sets the CI environment variable to take note that we are using Codefresh +* `npm install codecov -g`: Installs the odecov CLI +* `codecov -t ${{CODECOV_TOKEN}} -f ./coverage/clover.xml`: Sets the Codevoc access token provided in the UI when we connect to a new Git repository and point to the file that contains our coverage report. + +Once you run the pipeline, the steps will create the coverage report and forward it to Codecov. + +{% include image.html +lightbox="true" +file="/images/testing/codecov/codecov-pipeline.png" +url="/images/testing/codecov/codecov-pipeline.png" +alt="Pipeline with codecov step" +max-width="50%" +%} + +## View reports + +You can view the updated coverage reports within the Codecov UI every time you make a commit and/or run the Codefresh pipeline directly. + +{% include image.html +lightbox="true" +file="/images/testing/codecov/codecov-report.png" +url="/images/testing/codecov/codecov-report.png" +alt="Pipeline with codecov step" +max-width="50%" +%} + +You can access further information on the coverage report by opening the link to the file displayed in the table. + +{% include image.html +lightbox="true" +file="/images/testing/codecov/codecov-report-details.png" +url="/images/testing/codecov/codecov-report-details.png" +alt="Codecov report details" +max-width="50%" +%} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Unit tests]({{site.baseurl}}/docs/testing/unit-tests/) +[Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) +[Sonarqube Integration]({{site.baseurl}}/docs/testing/sonarqube-integration/) + diff --git a/_docs/example-catalog/ci-examples/coveralls-testing.md b/_docs/example-catalog/ci-examples/coveralls-testing.md new file mode 100644 index 00000000..dd060c20 --- /dev/null +++ b/_docs/example-catalog/ci-examples/coveralls-testing.md @@ -0,0 +1,221 @@ +--- +title: "Coveralls coverage reports" +description: "How to forward coverage reports to Coveralls" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +[Coveralls](https://coveralls.io/){:target="\_blank"} is a web service that allows users to track the code coverage of their application over time in order to optimize the effectiveness of their unit tests. This section details how coverage reports can be generated and forwarded to Coveralls with every Codefresh build. + +Analysis reports displayed within Coveralls dashboard: +{% include image.html +lightbox="true" +file="/images/testing/coveralls/coveralls-sample-app.png" +url="/images/testing/coveralls/coveralls-sample-app.png" +alt="Coveralls UI Analysis reports" +max-width="80%" +%} + +## Prerequisites for using Coveralls + +* A simple [Codefresh pipeline up and running](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +* A [Coveralls account](https://coveralls.io/) (free or enterprise) -- Note that all open-source projects are free on Coveralls +* A testing tool added to your project that produces coverage reports + +Coveralls supports [22 different language integrations](https://docs.coveralls.io/about-coveralls){:target="\_blank"}. Each example provided in the official documentation suggests several coverage report tools that can be used in combination with Coveralls. + +You could try it out by cloning our [node example application](https://github.com/codefresh-contrib/coveralls-sample-app){:target="\_blank"} that utilises [jest](https://jestjs.io/){:target="\_blank"}. + +## Prepare your repository + +If you are using your own application as an example, you have to make a few modifications to the repository. Please have a look at the Coveralls example section for other languages. + +First, install Coveralls in your project: +{% highlight yaml %} +{% raw %} +npm install coveralls --save-dev +{% endraw %} +{% endhighlight %} + +Coveralls requires a [script](https://github.com/nickmerwin/node-coveralls){:target="\_blank"} that takes standard input and sends it to coveralls.io to report your code coverage. Depending on the framework that you are using, you will have to add a different script to your application. + +Any coverage reports can be forwarded that are within a [lcov data format](http://ltp.sourceforge.net/coverage/lcov/geninfo.1.php){:target="\_blank"} (including [mocha's LCOV reporter](https://www.npmjs.com/package/mocha-lcov-reporter){:target="\_blank"}). For this, we are going to set-up a “bin” folder, and within the folder a coveralls.js file that contains the following content: + +{% highlight yaml %} +{% raw %} +#!/usr/bin/env node + +'use strict'; + +const { handleInput } = require('..'); + +process.stdin.resume(); +process.stdin.setEncoding('utf8'); + +let input = ''; + +process.stdin.on('data', chunk => { + input += chunk; +}); + +process.stdin.on('end', () => { + handleInput(input, err => { + if (err) { + throw err; + } + }); +}); +{% endraw %} +{% endhighlight %} + +## Create a Coveralls account + +Once you sign-up to Coveralls, you can add a new repository. The UI will then provide you with an access token to the repository. Take note of the token since it will be required in the next sections. + +{% include image.html +lightbox="true" +file="/images/testing/coveralls/add-repository.png" +url="/images/testing/coveralls/add-repository.png" +alt="Coveralls repository" +max-width="80%" +%} + +## Codefresh pipeline + + +In case the project that you want to use Coveralls in does not have a pipeline, [create a new pipeline]({{site.baseurl}}/docs/getting-started/create-a-basic-pipeline/). + +{% include image.html +lightbox="true" +file="/images/testing/coveralls/create-coveralls-pipeline.png" +url="/images/testing/coveralls/create-coveralls-pipeline.png" +alt="Create Coveralls Pipeline" +max-width="80%" +%} + +Once you ’create’ the pipeline, a standard codefresh.yml file is generated with three steps: +* The first step will clone your repository; +* The second step will both, build and push your repository to the container registry that you have connected with Codefresh; +* And the third step currently does not do much. +In the next section, we will modify the testing step. + +**Testing step** + +The testing step requires three different environment variables to connect to Coveralls: +* `export COVERALLS_SERVICE_NAME="codefresh"` +* `export COVERALLS_GIT_BRANCH="insert the branch that you will be using with your application"` +* `export COVERALLS_REPO_TOKEN="insert the secret repo token from coveralls.io"` + +{% highlight yaml %} +{% raw %} + test: + title: "Running test" + type: "freestyle" # Run any command + image: "node:15.2" # The image in which command will be executed + working_directory: "${{clone}}" # Running command where code cloned + commands: + - "export COVERALLS_SERVICE_NAME=${{COVERALLS_SERVICE_NAME}}" + - "export COVERALLS_GIT_BRANCH=${{CF_BRANCH}}" + - "export COVERALLS_REPO_TOKEN=${{COVERALLS_REPO_TOKEN}}" + - "npm install --save-dev jest" + - "npm run test" + stage: "test" +{% endraw %} +{% endhighlight %} + +We specify several variables within this step. Those, which start with ’CF’ are [Codefresh-specific steps]({{site.baseurl}}/docs/pipelines/variables/) and the value is automatically provided by Codefresh once you run the pipeline. Our entire codefresh.yml will look as such: + +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - "clone" + - "build" + - "test" + +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "anais-codefresh/coveralls-sample-app" + # CF_BRANCH value is auto set when pipeline is triggered + # Learn more at codefresh.io/docs/docs/pipelines/variables/ + revision: "${{CF_BRANCH}}" + git: "github" + stage: "clone" + + build: + title: "Building Docker image" + type: "build" + image_name: "anaisurlichs/coveralls-sample-app" + working_directory: "${{clone}}" + tag: "${{CF_BRANCH_TAG_NORMALIZED}}" + dockerfile: "Dockerfile" + stage: "build" + registry: "dockerhub" + + test: + title: "Running test" + type: "freestyle" # Run any command + image: "node:15.2" # The image in which command will be executed + working_directory: "${{clone}}" # Running command where code cloned + commands: + - "export COVERALLS_SERVICE_NAME=${{COVERALLS_SERVICE_NAME}}" + - "export COVERALLS_GIT_BRANCH=${{CF_BRANCH}}" + - "export COVERALLS_REPO_TOKEN=${{COVERALLS_REPO_TOKEN}}" + - "npm install --save-dev jest" + - "npm run test" + stage: "test" +{% endraw %} +{% endhighlight %} + +Once you run the pipeline the steps will create the coverage report and forward it to Coveralls. + +{% include image.html +lightbox="true" +file="/images/testing/coveralls/coveralls-pipeline.png" +url="/images/testing/coveralls/coveralls-pipeline.png" +alt="Pipeline with Coveralls step" +max-width="80%" +%} + +## View reports + +You can view the updated coverage reports within Coveralls UI every time you make a commit and/or run the Codefresh pipeline directly. + +{% include image.html +lightbox="true" +file="/images/testing/coveralls/coveralls-sample-app.png" +url="/images/testing/coveralls/coveralls-sample-app.png" +alt="Coveralls UI Analysis reports" +max-width="80%" +%} + +You can access further information on the coverage report by opening the link to the file displayed in the table. + +{% include image.html +lightbox="true" +file="/images/testing/coveralls/coveralls-specific-report.png" +url="/images/testing/coveralls/coveralls-specific-report.png" +alt="Coveralls report details" +max-width="80%" +%} + +And view a the code coverage of a specific file: +{% include image.html +lightbox="true" +file="/images/testing/coveralls/coveralls-coverage.png" +url="/images/testing/coveralls/coveralls-coverage.png" +alt="Coveralls report details" +max-width="80%" +%} + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Unit tests]({{site.baseurl}}/docs/testing/unit-tests/) +[Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) +[Sonarqube Integration]({{site.baseurl}}/docs/testing/sonarqube-integration/) diff --git a/_docs/example-catalog/ci-examples/cpp-cmake.md b/_docs/example-catalog/ci-examples/cpp-cmake.md new file mode 100644 index 00000000..11f8e963 --- /dev/null +++ b/_docs/example-catalog/ci-examples/cpp-cmake.md @@ -0,0 +1,125 @@ +--- +title: "Compile and test a C++ application" +description: "Using Codefresh pipelines" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +Codefresh can work with any C/C++ application very easily as both `gcc` and `g++` are already offered in Dockerhub. There is also another example available with [C and make]({{site.baseurl}}/docs/example-catalog/ci-examples/c-make). + +## The example C++ project + +You can see the example project at [https://github.com/codefresh-contrib/cpp-sample-app](https://github.com/codefresh-contrib/cpp-sample-app){:target="\_blank"}. The repository contains a C++ starter project with a `CMakeLists.txt` file: + +* `cmake .` creates the makefiles. +* `make test` runs unit tests +* `make` compiles the code + +The project is also using the [boost testing libraries](https://www.boost.org/){:target="\_blank"}. + +## Cmake, g++ and Docker + +Creating a CI/CD pipeline for C is very easy, because Codefresh can run any [gcc image](https://hub.docker.com/_/gcc/){:target="\_blank"} that you wish. Gcc docker images already contain the `make` utility but not the the `cmake` one. Therefore we will first create a Dockerfile that has `g++`, cmake and the boost libraries. You can follow the same pattern for other development tools that you use. + + +Here is the Dockerfile: + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM gcc:9.2 + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -y cmake libgtest-dev libboost-test-dev && rm -rf /var/lib/apt/lists/* + +CMD ["cmake"] + +{% endraw %} +{% endhighlight %} + +This docker build does the following: + +1. Starts from the GCC image +1. Installs cmake and boost +1. Sets cmake as the default command + +## Create a CI pipeline for C++ applications + +We can now use the custom Docker image in order to compile/test the C++ application: + +{% include image.html +lightbox="true" +file="/images/learn-by-example/cc/cpp-cmake-pipeline.png" +url="/images/learn-by-example/cc/cpp-cmake-pipeline.png" +alt="Compiling a C++ application in a pipeline" +caption="Compiling a C++ application in a pipeline" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/cpp-sample-app/blob/master/codefresh.yml){:target="\_blank"} that compiles the application after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - prepare + - build +steps: + main_clone: + title: Cloning main repository... + stage: checkout + type: git-clone + repo: 'codefresh-contrib/cpp-sample-app' + revision: master + git: github + build_dev_image: + title: Building Dev Image + stage: prepare + type: build + image_name: cmake + working_directory: ./dev/ + tag: 'latest' + dockerfile: Dockerfile + create_makefiles: + title: Create Makefiles + stage: prepare + image: ${{build_dev_image}} + commands: + - cmake . + compile_my_sources: + title: Compile + stage: build + image: ${{build_dev_image}} + commands: + - make + run_my_tests: + title: Test + stage: build + image: ${{build_dev_image}} + commands: + - make test +{% endraw %} +{% endhighlight %} + +This pipeline: + +1. clones the source code +1. Creates a development docker image that has g++, cmake and boost +1. Runs cmake on the source code to create the make files +1. Compiles the source code +1. Runs unit tests + +You can add additional tools in the pipeline by extending the Dockerfile mentioned in the previous section. You can also +change the version of Gcc/g++ by starting from a different public or private Docker image. + + +## Related articles +[C example]({{site.baseurl}}/docs/example-catalog/ci-examples/c-make/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/codefresh-yaml/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/decryption-with-mozilla-sops.md b/_docs/example-catalog/ci-examples/decryption-with-mozilla-sops.md new file mode 100644 index 00000000..d091ca24 --- /dev/null +++ b/_docs/example-catalog/ci-examples/decryption-with-mozilla-sops.md @@ -0,0 +1,177 @@ +--- +title: "Decrypt with Mozilla SOPS" +description: "Store secrets in your repository and decrypt them using Mozilla SOPS" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +## Prerequisites + +- A [free Codefresh account]({{site.baseurl}}/docs/administration/create-a-codefresh-account/) +- A public and private GnuGP key pair +- A credentials yaml, that is encrypted using Mozilla SOPS, and stored in your repository + +## Example Java application + +You can find the example project on [GitHub](https://github.com/codefresh-contrib/mozilla-sops-app){:target="\_blank"}. + +The example application retrieves the system variable "password," from the pipeline and uses it to authenticate to a Redis database, but you are free to use any type of database of your choosing. + +```java + String password = System.getenv("password"); + String host = System.getProperty("server.host"); + + RedisClient redisClient = new RedisClient( + RedisURI.create("redis://" + password + "@" + host + ":6379")); + RedisConnection connection = redisClient.connect(); +``` + +Also in the example application is a simple unit test that ensures we are able to read and write data to the database. + +An encrypted credentials file is stored in the repository (along with a public key): + +`credentials.yaml` +```yaml +password: ENC[AES256_GCM,data:Jsth2tY8GhLgj6Jct27l,iv:3vcKVoD5ms29R5SWHiFhDhSAvvJTRzjn9lA6woroUQ8=,tag:OjkLvcHxE4m5RSCV7ej+FA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + lastmodified: '2020-03-30T19:12:49Z' + mac: ENC[AES256_GCM,data:jGMTkFhXjgGMdWBpaSWjGZP6fta3UuYjEsnqziNELQZ2cLScT9v+GKg/c8iJYv1Gfiz3aw4ivYYrWzwmZehIbPHaw3/XBv/VRCQhzRWYKaf6pPFUXIS7XALSf9L9VbGOXL/CGPRae3t3HpaOor+knd6iQk2WR3K9kSeib4RBSCE=,iv:WSP8hBwaBv3ymTGltBOaVVC1sT08IG4hwqESlG8rN9w=,tag:3hZvCuql+ASWe/Mm5Bl7xg==,type:str] + pgp: + - created_at: '2020-03-30T19:12:49Z' + enc: | + -----BEGIN PGP MESSAGE----- + hQGMA9TqgBq6RQVRAQv/UouNaHfxkJ5PwXLvda97Fgj/2ew2VXPAlAnLvoGvTsb2 + U4GXcaE7c4mYf7wSKF9k/F0FZTUEnd3CRji/OqjrNyvj5zI/9KGRABCKvzjsx+ZG + JolVnDifHl78Mor1CUPQ4JXasHKbVSlNLMGgDHIsvpeC7f7pIi8YDUDIa3/zXhFK + jcKzz4nlrW1Ph8zukmQk49Xvv6+DFj2NTptOB3U6mh79RCdnyCSRHxA3f0X00Pi5 + g0p5x46S5E04uC2wXrZv8i/gyQbLHxwjmdbLq+P1Peu4/i9eSZZOpx0mc1KJ2mjr + oKRvgnUFz3xuYrSNzjC1vM01UbuSytlwx+S3J7VVLPSZRso1sbgv2+ylUOAHS+gZ + 64uL0j/BZrF4wZI8y8zr0nJ6cZLiiF3LeXhfcuWJJ7+5p1OBEvfO+sWorLahIZTw + pogYPDpz4rGnrJRKBkNsVlYuUG8aNerIfhEBr6n//VJtt7QXTEXraLCTt4a6z/Fl + R6YSeNCKWQlURrTfm4Kv0lwBzMTLUb+Fg3HO8ShhiE9/2dKTSJkRJMVXRDp22Fm1 + vO/wMFUjg6Dkrj1LVqQ9zcXc5QElgc4mF/V7SazacbQ7/g67tVtUrTit9LXgR9A0 + k7wU5iT5oWLJtWwpkA== + =Il2p + -----END PGP MESSAGE----- + fp: C70833A85193F72C2D72CB9DBC109AFC69E0185D + encrypted_regex: password + version: 3.5.0 +``` +You cannot run the application locally, as it needs to run in the pipeline in order to use our environment variables to connect. + +## Create pipeline + +The pipeline contains four stages: + +- A stage for cloning +- A stage for importing the private/public keypair +- A stage for decrypting the credentials file +- A stage for packaging our jar and running unit tests + +{% include image.html +lightbox="true" +file="/images/examples/secrets/mozilla-sops-pipeline.png" +url="/images/examples/secrets/mozilla-sops-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="90%" +%} + +First, you need to add a pipeline variable, `PRIV_KEY`, for your private key. You can do that in the UI by navigating to the in-line YAML editor and to the right-hand side, you will find the **Variables** tab: + +{% include image.html +lightbox="true" +file="/images/examples/secrets/mozilla-sops-pipeline-vars.png" +url="/images/examples/secrets/mozilla-sops-pipeline-vars.png" +alt="Mozilla SOPS Pipeline Variables" +caption="Pipeline Variables" +max-width="90%" +%} + +You can also add this [directly in the YAML itself]({{site.baseurl}}/docs/how-to-guides/migrating-from-travis-ci/#environment-variables). + +Here is the entire pipeline: + +`codefresh.yaml` +{% highlight yaml %} +{% raw %} +# More examples of Codefresh YAML can be found at +# https://codefresh.io/docs/docs/example-catalog/ci-examples/ + +version: "1.0" +# Stages can help you organize your steps in stages +stages: + - "clone" + - "import" + - "decrypt" + - "package" + +steps: + clone: + title: "Cloning repository..." + type: "git-clone" + stage: "clone" + arguments: + repo: "codefresh-contrib/mozilla-sops-app" + revision: "master" + + import_keys: + title: "Importing gpg keys..." + type: "freestyle" + stage: "import" + working_directory: '${{clone}}' + arguments: + image: "vladgh/gpg" + commands: + - gpg --import public.key + - echo -e "${{PRIV_KEY}}" > private.key + - gpg --allow-secret-key-import --import private.key + + decrypt_password: + title: "Decrypting password..." + type: "freestyle" + working_directory: "${{clone}}" + stage: "decrypt" + arguments: + image: "mozilla/sops" + commands: + - cp -r /codefresh/volume/.gnupg /root/.gnupg + - cf_export password=$(sops --decrypt --extract '["password"]' credentials.yaml) + + package_jar: + title: "Packaging jar and running unit tests..." + working_directory: ${{clone}} + stage: "package" + arguments: + image: "maven:3.5.2-jdk-8-alpine" + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dserver.host=my-redis-db-host clean package + services: + composition: + my-redis-db-host: + image: 'redis:4-alpine' + command: 'redis-server --requirepass $password' + ports: + - 6379 +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the main repository through a [git-clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +2. Uses a GPG image and imports the public and private key pair through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). +3. Decrypts the credentials file through a different freestyle step. At this step, SOPS looks for the .gnupg directory (where the keyring is stored) under /root. We need to copy it from the [Codefresh Volume]({{site.baseurl}}/docs/pipelines/steps/freestyle/#custom-volumes), as /root is not saved between containers. +4. The last step, `package_jar`, does a few special things to take note of: + - Spins up a [Service Container]({{site.baseurl}}/docs/pipelines/service-containers/) running Redis on port 6379 , and sets the password to the database using our exported environment variable + - Sets `maven.repo.local` to cache Maven dependencies into the local codefresh volume to [speed up builds]({{site.baseurl}}/docs/example-catalog/ci-examples/spring-boot-2/#caching-the-maven-dependencies) + - Runs unit tests and packages the jar. Note how you can directly refer to the service container's name (`my-redis-db-host`) when we set `server.host` + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Vault secrets in pipelines]({{site.baseurl}}/docs/example-catalog/ci-examples/vault-secrets-in-the-pipeline/) + diff --git a/_docs/example-catalog/ci-examples/django.md b/_docs/example-catalog/ci-examples/django.md new file mode 100644 index 00000000..fcc3e75d --- /dev/null +++ b/_docs/example-catalog/ci-examples/django.md @@ -0,0 +1,174 @@ +--- +title: "Python Django example" +description: "Create Docker images for Python applications" +excerpt: "" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/django/ + - /docs/python/django/ +toc: true +--- +Codefresh can work with Python projects using any of the popular frameworks. In this page we will see Django. For a Flask example see the [quick start guide]({{site.baseurl}}/docs/getting-started/create-a-basic-pipeline/). + +## The example Django project + +You can see the example project at [https://github.com/codefreshdemo/cf-example-python-django](https://github.com/codefreshdemo/cf-example-python-django){:target="\_blank"}. The repository contains a Django starter project with the following commands: + +* `pip install -r requirements.txt` install dependencies. +* `python -m unittest composeexample.utils` runs unit tests. +* `python manage.py runserver 0.0.0.0:8000` to start the application locally. + + +Once launched the application presents the Django starter page at localhost:8000. + +## Django and Docker + +The easiest way to build a Django application is with a Dockerfile that contains everything. This is very convenient as the Docker image can contain everything you need (i.e. app plus test frameworks) inside a pipeline. + + +Here is the Dockerfile: + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM python:3.6-slim + +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 +RUN mkdir /code +WORKDIR /code +RUN pip install --upgrade pip +COPY requirements.txt /code/ + +RUN pip install -r requirements.txt +COPY . /code/ + +EXPOSE 8000 + +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] +{% endraw %} +{% endhighlight %} + +This docker build does the following: + +1. Starts from the Python image +1. Sets some environment variables +1. Copies the dependencies file inside the container +1. Upgrades pip and installs all dependencies +1. Copies the rest of the source code +1. Starts the Django app + +You can build this image locally on your workstation and then launch it to test the application. + +### Create a CI pipeline for Python/Django + +Creating a CI/CD pipeline for Django is very easy if you already have the Dockerfile with all required dependencies. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/python/python-build-test.png" +url="/images/learn-by-example/python/python-build-test.png" +alt="Creating a Docker image for Python" +caption="Creating a Docker image for Python" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/gradle-sample-app/blob/master/codefresh.yml){:target="\_blank"} that creates the Docker image after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - test +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefreshdemo/cf-example-python-django' + revision: master + git: github + build_my_image: + title: Building Docker Image + stage: build + type: build + image_name: my-django-image + working_directory: ./ + tag: master + dockerfile: Dockerfile + test_my_image: + title: Running unit tests + stage: test + image: '${{build_my_image}}' + commands: + - python -m unittest composeexample.utils +{% endraw %} +{% endhighlight %} + +This pipeline clones the source code, creates a Docker image and then uses the same image to run unit tests. Codefresh is automatically caching +Docker layers (it uses the Docker image of a previous build as a cache for the next) and therefore builds will become +much faster after the first one finishes. + + +### Running tests before building the docker image + +Sometimes if you have a complex application you might want to run integration tests (or other Python commands), *before* building the Docker image. This scenario is also supported natively by Codefresh. + + +{% include image.html +lightbox="true" +file="/images/learn-by-example/python/python-test-build.png" +url="/images/learn-by-example/python/python-test-build.png" +alt="Building the image after tests have run" +caption="Building the image after tests have run" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefreshdemo/cf-example-python-django/blob/master/codefresh-build-after-test.yml){:target="\_blank"} builds the docker image after tests have already executed. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefreshdemo/cf-example-python-django' + revision: master + git: github + test_the_code: + title: Run unit tests + stage: test + image: python:3.6-slim + commands: + - pip install -r requirements.txt --cache-dir=/codefresh/volume/pip-cache + - python -m unittest composeexample.utils + build_my_image: + title: Building Docker Image + stage: build + type: build + image_name: my-django-image + working_directory: ./ + tag: full + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +Codefresh is smart enough that [caches automatically]({{site.baseurl}}/docs/pipelines/pipeline-caching/) for us the workspace of a build (`/codefresh/volume`). This works great for build tools that keep their cache in the project folder, but not for pip which keeps its cache externally (e.g. `~/.cache/pip`). By changing the location of the Pip cache on the project folder (the `pip-cache` name is arbitrary) we make sure that Codefresh will cache automatically the Pip libraries resulting in much faster builds. + +## Related articles +[Python examples]({{site.baseurl}}/docs/example-catalog/ci-examples/python/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/dotnet.md b/_docs/example-catalog/ci-examples/dotnet.md new file mode 100644 index 00000000..173a9569 --- /dev/null +++ b/_docs/example-catalog/ci-examples/dotnet.md @@ -0,0 +1,115 @@ +--- +title: "C# on .NET Core" +description: "How to build a C# project in Codefresh" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +Codefresh can work with any .NET core application very easily as there are official [Docker images from Microsoft](https://hub.docker.com/_/microsoft-dotnet-core){:target="\_blank"}. + +## The example C# project + +You can see the example project at [https://github.com/dotnet-architecture/eShopOnWeb](https://github.com/dotnet-architecture/eShopOnWeb){:target="\_blank"}. The repository contains a C# Web project with 3 kinds of tests. It has different tags for each version of .NET Core and has + +* a `docker-compose.yml` file for local development +* a `tests` directory with all types of tests +* a Dockerfile at `/src/Web` + +There are also previous releases at [https://github.com/dotnet-architecture/eShopOnWeb/releases](https://github.com/dotnet-architecture/eShopOnWeb/releases){:target="\_blank"}. + +### Create a CI pipeline for C# applications + +Creating a CI/CD pipeline for C# is very easy, because Codefresh can run any SDK image version that you wish. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/dotnet/dotnetcore-pipeline.png" +url="/images/learn-by-example/dotnet/dotnetcore-pipeline.png" +alt="Compiling a C# application in a pipeline" +caption="Compiling a C# application in a pipeline" +max-width="80%" +%} + +Here is the full pipeline that compiles the application after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - test + - build +steps: + main_clone: + title: Cloning main repository... + stage: checkout + type: git-clone + repo: 'dotnet-architecture/eShopOnWeb' + revision: 'netcore3.0' + git: github-1 + my_unit_tests: + title: Unit tests + stage: test + image: mcr.microsoft.com/dotnet/core/sdk:3.0 + working_directory: './tests/UnitTests/' + commands: + - dotnet test + my_integration_tests: + title: Integration tests + stage: test + image: mcr.microsoft.com/dotnet/core/sdk:3.0 + working_directory: './tests/IntegrationTests/' + commands: + - dotnet test + my_functional_tests: + title: Fuctional tests + stage: test + image: mcr.microsoft.com/dotnet/core/sdk:3.0 + working_directory: './tests/FunctionalTests/' + commands: + - dotnet test + my_app_docker_image: + title: Building Docker Image + type: build + stage: build + image_name: dotnetcore-eshop + working_directory: ./ + tag: latest + dockerfile: src/Web/Dockerfile +{% endraw %} +{% endhighlight %} + +This pipeline: + +1. clones the source code +1. Uses the official `mcr.microsoft.com/dotnet/core/sdk:3.0` image to run unit/integration/functional tests in 3 different folders +1. Builds the application docker image using the root folder as Docker context but with the Dockerfile located at `./src/Web` + + + + + +## Related articles +[C/C++ examples]({{site.baseurl}}/docs/learn-by-example/cc/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) + + + + + + diff --git a/_docs/example-catalog/ci-examples/fan-in-fan-out.md b/_docs/example-catalog/ci-examples/fan-in-fan-out.md new file mode 100644 index 00000000..a8c2b3d1 --- /dev/null +++ b/_docs/example-catalog/ci-examples/fan-in-fan-out.md @@ -0,0 +1,204 @@ +--- +title: "Fan-out-fan-in pipeline" +description: "Use parallel mode to fan-in and fan-out your step dependencies" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +In pipelines, the concept of fan-in/fan-out is depicted in the diagram below. This pipeline offers parallel sub-flows within the same pipeline. Fan-out refers to spreading a task to multiple destinations in parallel, and fan-in is the opposite, where we spread multiple tasks to the same destination. + +{% include image.html +lightbox="true" +file="/images/examples/unit-tests/parallel-pipeline-examples.png" +url="/images/examples/unit-tests/parallel-pipeline-examples.png" +alt="parallel pipeline diagraam" +caption="Parallel Mode Diagram" +max-width="100%" +%} + +As you can see in the diagram, Step1 fans out to Step2 and Step4 (which run in parallel), while Step3 and Step4 fan-in to Step5. + +You can achieve parallelism in your Codefresh pipelines by using the following: + +- Simple parallel jobs ([inserting parallel steps into a sequential pipeline]({{site.baseurl}}/docs/pipelines/advanced-workflows/#inserting-parallel-steps-in-a-sequential-pipeline)) +- [Full parallel mode]({{site.baseurl}}/docs/pipelines/advanced-workflows/#parallel-pipeline-mode) +- Fan-out/fan-in parallel pipelines, as described in this article + +## Prerequisites + +- A [free Codefresh account]({{site.baseurl}}/docs/getting-started/create-a-codefresh-account/) + +## Example project + +You can find the example Spring boot application on [GitHub](https://github.com/codefresh-contrib/fan-out-fan-in-sample-app.git){:target="\_blank"}. It is a simple Hello World application with several different types of tests we will use to run using Codefresh's parallel mode. + +## Create the pipeline + +Our pipeline will have five stages: setup, start, web-tests, smoke, and end: + +{% include image.html +lightbox="true" +file="/images/examples/unit-tests/fan-in-fan-out-pipeline.png" +url="/images/examples/unit-tests/fan-in-fan-out-pipeline.png" +alt="fan-in-fan-out UI pipeline view" +caption="Codefresh UI Pipeline View" +max-width="100%" +%} + +You should be able to copy and paste this YAML in the in-line editor in the Codefresh UI. It will automatically clone the project for you. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +mode: parallel +stages: +- setup +- start +- web-tests +- smoke +- end +steps: + Clone: + title: Cloning main repository... + stage: setup + type: git-clone + arguments: + repo: codefresh-contrib/fan-out-fan-in-sample-app + git: github + revision: master + Build_image: + title: Building Docker Image... + type: build + stage: setup + working_directory: ${{Clone}} + arguments: + image_name: spring-backend + tag: latest + dockerfile: Dockerfile + when: + steps: + - name: Clone + on: + - success + Step1: + title: Running unit tests... + stage: start + working_directory: ${{Clone}}/complete + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dgroups="unit" test + when: + steps: + - name: Build_image + on: + - success + services: + composition: + spring_backend: + image: ${{Build_image}} + ports: + - 8080 + Step2: + title: Running web mock test... + stage: web-tests + working_directory: ${{Clone}}/complete + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dgroups="web-mock" test + when: + steps: + - name: Step1 + on: + - success + services: + composition: + spring_backend: + image: ${{Build_image}} + ports: + - 8080 + Step3: + title: Running smoke test... + stage: smoke + working_directory: ${{Clone}}/complete + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dgroups="smoke" test + when: + steps: + - name: Step2 + on: + - success + services: + composition: + spring_backend: + image: ${{Build_image}} + ports: + - 8080 + Step4: + title: Running web layer tests... + stage: web-tests + working_directory: ${{Clone}}/complete + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dgroups="web-layer" test + when: + steps: + - name: Step1 + on: + - success + services: + composition: + spring_backend: + image: ${{Build_image}} + ports: + - 8080 + Step5: + title: Running integration tests... + stage: end + working_directory: ${{Clone}}/complete + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dgroups="integration" test + when: + steps: + - name: Step3 + on: + - success + - name: Step4 + on: + - success + services: + composition: + spring_backend: + image: ${{Build_image}} + ports: + - 8080 +{% endraw %} +{% endhighlight %} + +>Note the special use of `mode: parallel` declared at the root of our yaml. This syntax makes the pipeline use the full parallel mode. +The order of your build steps doesn't matter in this case, each step is executed according to its [condition]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/). + +- Step1 (unit tests) fans out to Step2 and Step4 (web tests), which run in parallel +- Step3 (smoke tests) does not execute until Step2 is completed +- Step3 and Step4 fan in to the final step, Step5 (integration tests) + +This pipeline consists of the following: + +1. Clones the main repository through a [Git-clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +2. Builds the cloned source code into a Docker image through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). +3. Runs [freestyle steps]({{site.baseurl}}/docs/pipelines/steps/freestyle/) that: + - Run unit tests according to their respective @Tags + - Use the image built in the second step as a [service container]({{site.baseurl}}/docs/pipelines/service-containers/) + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Parallel pipeline mode]({{site.baseurl}}/docs/pipelines/advanced-workflows/#parallel-pipeline-mode) + diff --git a/_docs/example-catalog/ci-examples/general.md b/_docs/example-catalog/ci-examples/general.md new file mode 100644 index 00000000..3cec98bc --- /dev/null +++ b/_docs/example-catalog/ci-examples/general.md @@ -0,0 +1,16 @@ +--- +title: "General" +description: "" +group: example-catalog +redirect_from: + - /docs/learn-by-example/general/ +toc: true +--- +This section contains Codefresh examples based on other technologies. +{% comment %} +links not available in base documentation +- [How to trigger the another pipeline using cf-cli](doc:how-to-trigger-another-pipeline-using-cf-cli) +- [How to run composition using cf-cli](doc:how-to-run-composition-using-cf-cli-1) +- [How to spin up image using cf-cli](doc:how-to-spin-up-image-using-cf-cli) +{% endcomment %} +- [Selenium test]({{site.baseurl}}/docs/learn-by-example/general/selenium-test/) diff --git a/_docs/example-catalog/ci-examples/get-short-sha-id-and-use-it-in-a-ci-process.md b/_docs/example-catalog/ci-examples/get-short-sha-id-and-use-it-in-a-ci-process.md new file mode 100644 index 00000000..b071c29b --- /dev/null +++ b/_docs/example-catalog/ci-examples/get-short-sha-id-and-use-it-in-a-ci-process.md @@ -0,0 +1,77 @@ +--- +title: "Use Git Hash in CI" +description: "Get short SHA ID and use it in a CI Process" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/how-to-guides/ + - /docs/how-get-first-8-digits-of-sha/ +toc: true +old_url: /docs/how-get-first-8-digits-of-sha +--- + +## Get the short SHA ID +Add the following variable to your script: + +{% highlight text %} +{% raw %} +${{CF_SHORT_REVISION}} +{% endraw %} +{% endhighlight %} + + +## Use the SHA ID in a tag + + +{% highlight text %} +{% raw %} +tag: ${{CF_SHORT_REVISION}} +{% endraw %} +{% endhighlight %} + + +## YAML example + +{% highlight yaml %} +{% raw %} +step-name: + type: build + description: Free text description + working-directory: ${{clone-step-name}} + dockerfile: path/to/Dockerfile + image-name: owner/new-image-name + tag: ${{CF_SHORT_REVISION}} + build-arguments: + - key=value + fail-fast: false +{% endraw %} +{% endhighlight %} + +## Result in [hub.docker](https://hub.docker.com){:target="_blank"} + +{% include image.html +lightbox="true" +file="/images/examples/git/sha-id-docker-hub.png" +url="/images/examples/git/sha-id-docker-hub.png" +alt="SHA ID in Docker Hub" +caption="SHA ID in Docker Hub" +max-width="60%" +%} + +## Result in Codefresh + +{% include image.html +lightbox="true" +file="/images/examples/git/sha-id-codefresh.png" +url="/images/examples/git/sha-id-codefresh.png" +caption="SHA ID in Codefresh" +alt="SHA ID in Codefresh" +max-width="60%" +%} + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/git-checkout-custom.md b/_docs/example-catalog/ci-examples/git-checkout-custom.md new file mode 100644 index 00000000..9a17e018 --- /dev/null +++ b/_docs/example-catalog/ci-examples/git-checkout-custom.md @@ -0,0 +1,106 @@ +--- +title: "Using custom Git commands" +description: "Manually clone Git repositories" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/git-clone-private-repository-using-freestyle-step/ + - /docs/example-catalog/ci-examples/git-clone-private-repository-using-freestyle-step/ +toc: true +--- + +>Manually running Git commands is an advanced technique. For most use cases you should use the [native Git checkout]({{site.baseurl}}/docs/example-catalog/ci-examples/git-checkout/) offered by Codefresh. + +For complex cloning, you can still use custom clone commands in a freestyle step. In this case, +you lose the native Codefresh integration such as Git authentication and automatic workdir setup. Use custom clone commands only as a last resort. + + +## Cloning with the Git executable + +It is very easy to run custom Git commands in a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). Pass any parameters to the Git clone step as you would pass them on your local workstation. + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myCustomClone: + title: Performing swallow clone + image: alpine/git:latest + commands: + - rm -rf ruby-on-rails-sample-app + - git clone --depth 1 https://github.com/codefresh-contrib/ruby-on-rails-sample-app.git + PrintFileList: + title: 'Listing files' + image: alpine:latest + working_directory: './ruby-on-rails-sample-app' + commands: + - 'ls -l' +{% endraw %} +{% endhighlight %} + +Notice the `rm` command before the clone step. This makes sure that every time the pipeline runs, the `git clone` step is implemented in an empty directory. Otherwise the `git clone` command will fail (Git will refuse to clone on an existing directory). + +You can enter your own Git username/password or [reuse the credentials]({{site.baseurl}}/docs/pipelines/steps/git-clone/#reuse-a-git-token-from-codefresh-integrations) from the Codefresh integration. + +## Manually running Git commands + +Once you understand that you can manually run Git commands in Codefresh pipelines, it is easy to see that any Git workflow is possible. +Here is an example where an application is packaged in a Docker container, after merging `master` to a specific branch. + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myCustomClone: + title: Performing swallow clone + image: alpine/git:latest + commands: + - rm -rf example_nodejs_postgres + - git clone https://github.com/kostis-codefresh/example_nodejs_postgres + - cd example_nodejs_postgres + - git checkout experiment1 + - git merge master + - git status + myDockerImage: + title: 'BuildingDockerImage' + type: build + dockerfile: Dockerfile + working_directory: './example_nodejs_postgres' + image_name: my-app-image + tag: from-master-branch +{% endraw %} +{% endhighlight %} + +If there are any errors with the merge, the pipeline fails automatically. Codefresh automatically stops any pipeline that shows an error in a step. + +## Other forms of cloning + +There is nothing special about running Git it in a freestyle step. In fact, you can check out code with any other command that you would run locally in your terminal. + +Here is an example with Golang. + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myCustomClone: + title: Download example + image: golang:1.11-alpine + commands: + - apk add --no-cache git + - go get github.com/golang/example/hello +{% endraw %} +{% endhighlight %} + +If you run this pipeline you will see git used as part of the `go get` mechanism. + +More examples such as using SSH keys and working with GIT submodules can be found in the [clone step documentation]({{site.baseurl}}/docs/pipelines/steps/git-clone/). + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Native Git checkout]({{site.baseurl}}/docs/example-catalog/ci-examples/git-checkout/) +[Native Git integration]({{site.baseurl}}/docs/integrations/git-providers/) +[Freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) +[Git Clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/) + diff --git a/_docs/example-catalog/ci-examples/git-checkout.md b/_docs/example-catalog/ci-examples/git-checkout.md new file mode 100644 index 00000000..81cc9b23 --- /dev/null +++ b/_docs/example-catalog/ci-examples/git-checkout.md @@ -0,0 +1,203 @@ +--- +title: "Check out Git repositories" +description: "Use the Codefresh native GIT integration" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +Codefresh has native support for Git repositories and Git triggers. First you need to set up a [Git integration]({{site.baseurl}}/docs/integrations/git-providers/) (your administrator might also have done this for you already). + +{% include image.html +lightbox="true" +file="/images/integrations/git/git-integrations.png" +url="/images/integrations/git/git-integrations.png" +alt="GIT integrations" +caption="GIT integrations" +max-width="70%" +%} + +You can add a new integration for any cloud provider or even [on-premises]({{site.baseurl}}/docs/reference/behind-the-firewall/) ones. By default you will also have a provider set up if you used one for Codefresh signup (GitHub, GitLab or Bitbucket). + +For each Git Integration, make sure that you note down its name, as you will use in your pipeline inside a [git-clone]({{site.baseurl}}/docs/pipelines/steps/git-clone/) step. + + +## Cloning a specific repository + +The simplest way to clone using your git provider is by specifying the exact repository details. +Here is a pipeline that clones a git repository and creates a Docker image from a Dockerfile: + + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: kostis-codefresh/example_nodejs_postgres + revision: master + git: github-1 + myDockerImage: + title: 'Building My Docker Image' + type: build + dockerfile: Dockerfile + image_name: my-app-image + tag: from-master-branch +{% endraw %} +{% endhighlight %} + +This syntax is very simple to use, but it has the disadvantage that ties your pipeline to a specific repository. This makes +the pipeline impossible to re-use among different micro-services (that are built in a similar manner). + +## Cloning the triggered repository (recommended) + +The proper way to use git-clone steps is to make them trigger specific. Instead of hard-coding the git repository that is checked-out, it is best to checkout the same one that [triggered the pipeline]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/). This is what you want in most scenarios anyway. + +This can be achieved by using Codefresh [variables]({{site.baseurl}}/docs/pipelines/variables/) to refer to the trigger. +Here is the same pipeline as before, written in a generic way: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: '${{CF_REVISION}}' + git: github-1 + myDockerImage: + title: 'Building My Docker Image' + type: build + dockerfile: Dockerfile + image_name: my-app-image + tag: ${{CF_BRANCH_TAG_NORMALIZED}} +{% endraw %} +{% endhighlight %} + +The big advantage of this pipeline is that it can be reused for *ALL* your projects that follow the same pattern of having a Dockerfile in the root of the git repository. + +{% include image.html +lightbox="true" +file="/images/examples/checkout/add-new-microservice.png" +url="/images/examples/checkout/add-new-microservice.png" +alt="Reusing a pipeline between microservices" +caption="Reusing a pipeline between microservices" +max-width="50%" +%} + +Thus you can have a single pipeline and when you want to enable it for a new micro-service you can simply add a new [git trigger]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/) for it. + +You still run the pipeline manually if you wish. In this case you will be asked which trigger you want to "simulate" so that the variable pipelines are correctly replaced by Codefresh. + +{% include image.html +lightbox="true" +file="/images/examples/checkout/simulate-trigger.png" +url="/images/examples/checkout/simulate-trigger.png" +alt="Simulating a GIT trigger" +caption="Simulating a GIT trigger" +max-width="50%" +%} + +This is the recommended way of creating re-usable pipelines in Codefresh. + +## Cloning a repository with Codefresh Runner +If you have the [Codefresh Runner]({{site.baseurl}}/docs/installation/codefresh-runner/) installed, you need to use +the fully qualified path of the Git repository: + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: https://github-internal.example.com/my-username/my-app + revision: '${{CF_REVISION}}' + git: my-internal-git-provider + PrintFileList: + title: 'Listing files' + image: alpine:latest + commands: + - 'ls -l' +{% endraw %} +{% endhighlight %} + +More details can be found in the [private Git instructions page]({{site.baseurl}}/docs/reference/behind-the-firewall/#checking-out-code-from-a-private-git-repository). + + +## Working inside the cloned directory + +Normally each [pipeline step]({{site.baseurl}}/docs/pipelines/steps/) in Codefresh can be named as you want. Specifically, for the Git-clone step however the name `main_clone` is special. + +If you name your clone step as `main_clone`, Codefresh automatically changes the working directory for all the next (non Git-clone) pipeline steps, to be the same as the project that was just checked out. This only applies to [built-in]({{site.baseurl}}/docs/pipelines/steps/#built-in-steps) Codefresh steps and not [custom plugins]({{site.baseurl}}/docs/pipelines/steps/#creating-a-typed-codefresh-plugin). + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/checkout.png" +url="/images/pipeline/introduction/checkout.png" +alt="Checkout structure" +caption="Checkout structure" +max-width="50%" +%} + +This is probably what you want anyway, so make sure that you name your Git-clone steps as `main_clone`. If you use any other name, then the working folder will be the parent of the checked-out project which is the [shared Codefresh volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) at `/codefresh/volume`. + +If you have more then one clone step in a pipeline, it is recommended to define the working directory explicitly (see next example), instead +of depending on the `main_clone` naming convention, which is best used in pipelines with a single clone step. + +## Cloning multiple repositories + +You can use as many clone steps as you want and at any position in the pipeline. + +Here is an example where two repositories are checked out and two docker images are then built. + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + checkoutApp1: + title: 'Cloning first repository...' + type: git-clone + repo: kostis-codefresh/example_nodejs_postgres + revision: experiment1 + git: github + myFirstDockerImage: + title: 'Building First Docker Image' + type: build + dockerfile: Dockerfile + image_name: my-nodejs-image + tag: from-develop-branch + working_directory: './example_nodejs_postgres' + checkoutApp2: + title: 'Cloning second repository...' + type: git-clone + repo: kostis-codefresh/trivial-go-web + revision: master + git: github + mySecondDockerImage: + title: 'Building Second Docker Image' + type: build + dockerfile: Dockerfile + working_directory: './trivial-go-web' + image_name: my-app-image + tag: from-master-branch +{% endraw %} +{% endhighlight %} + +Notice that in this case the git-clone steps are **not** named `main_clone` and therefore we specify exactly what is the working directory for each one. + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Git integrations]({{site.baseurl}}/docs/integrations/git-providers/) +[Git triggers in pipelines]({{site.baseurl}}/docs/pipelines/triggers/git-triggers/) +[Clone step in pipelines]({{site.baseurl}}/docs/pipelines/steps/git-clone/) +[Build step in pipelines]({{site.baseurl}}/docs/pipelines/steps/build/) +[Custom git commands]({{site.baseurl}}/docs/example-catalog/ci-examples/git-checkout-custom/) diff --git a/_docs/example-catalog/ci-examples/gitops-secrets.md b/_docs/example-catalog/ci-examples/gitops-secrets.md new file mode 100644 index 00000000..1db214dc --- /dev/null +++ b/_docs/example-catalog/ci-examples/gitops-secrets.md @@ -0,0 +1,229 @@ +--- +title: "Secrets with GitOps" +description: "Store secrets in Git with Bitnami sealed secrets" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +## Prerequisites + +- A [free Codefresh account]({{site.baseurl}}/docs/getting-started/create-a-codefresh-account/) +- A Kubernetes cluster +- The [Codefresh GitOps agent]({{site.baseurl}}/docs/integrations/argocd/) installed on the cluster + +## Using the Bitnami Sealed secrets controller + +If you follow [GitOps](https://codefresh.io/gitops/){:target="\_blank"}, then you should already know that everything should be placed under source control, and Git is to be used as the single source of truth. + +This presents a challenge with secrets that are needed by the application, as they must never be stored in Git in clear text under any circumstance. + +To solve this issue, we can use the [Bitnami Sealed secrets controller](https://github.com/bitnami-labs/sealed-secrets){:target="\_blank"}. This is a Kubernetes controller that can be used to encrypt/decrypt your application secrets in a secure way. + +The order of events is the following: + +1. You install the Bitnami Sealed secrets controller in the cluster. It generates a public and private key. The private key stays in the cluster and is never revealed. +1. You take a raw secret and use the `kubeseal` utility to encrypt it. Encryption happens with the public key of the cluster that you can give to anybody. +1. The encrypted secrets are stored in Git. There are safe to be committed and nobody can decrypt them without direct access to the cluster +1. During runtime you deploy the sealed secret like any other Kubernetes manifest. The controller converts them to [plain Kubernetes secrets](https://kubernetes.io/docs/concepts/configuration/secret/){:target="\_blank"} on the fly using the private key of the cluster +1. Your application reads the secrets like any other Kubernetes secret. Your application doesn't need to know anything about the sealed secrets controller or how the encryption decryption works. + + +To use the controller first install it in your cluster: + +``` +helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets +helm repo update +helm install sealed-secrets-controller sealed-secrets/sealed-secrets +``` + +By default, the controller is installed at the `kube-system` namespace. The namespace +and release names are important, since if you change the defaults, you need to set them up +with `kubeseal` as well, as you work with secrets. + +Download the `kubeseal` CLI: +``` +wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.16.0/kubeseal-linux-amd64 -O kubeseal +sudo install -m 755 kubeseal /usr/local/bin/kubeseal +``` + +## Example application + +You can find the example project at [https://github.com/codefresh-contrib/gitops-secrets-sample-app](https://github.com/codefresh-contrib/gitops-secrets-sample-app){:target="\_blank"}. + +It is a web application that prints out several secrets which are [read from the filesystem](https://github.com/codefresh-contrib/gitops-secrets-sample-app/blob/main/settings.ini){:target="\_blank"}: + +`settings.ini` +```ini +[security] +# Path to key pair +private_key = /secrets/sign/key.private +public_key= /secrets/sign/key.pub + +[paypal] +paypal_url = https://development.paypal.example.com +paypal_cert=/secrets/ssl/paypal.crt + +[mysql] +db_con= /secrets/mysql/connection +db_user = /secrets/mysql/username +db_password = /secrets/mysql/password +``` + +The application itself knows nothing about Kubernetes secrets, mounted volumes or any other cluster resource. It only reads its own filesystem at `/secrets` + +This folder is populated inside the pod with [secret mounting](https://github.com/codefresh-contrib/gitops-secrets-sample-app/blob/main/manifests/deployment.yml){:target="\_blank"}: + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gitops-secrets-deploy +spec: + replicas: 1 + selector: + matchLabels: + app: gitops-secrets-app + template: + metadata: + labels: + app: gitops-secrets-app + spec: + containers: + - name: gitops-secrets-app + image: docker.io/kostiscodefresh/gitops-secrets-sample-app:latest + imagePullPolicy: Always + ports: + - containerPort: 8080 + volumeMounts: + - name: mysql + mountPath: "/secrets/mysql" + readOnly: true + - name: paypal + mountPath: "/secrets/ssl" + readOnly: true + - name: sign-keys + mountPath: "/secrets/sign/" + readOnly: true + livenessProbe: + httpGet: + path: /health + port: 8080 + readinessProbe: + httpGet: + path: /health + port: 8080 + volumes: + - name: mysql + secret: + secretName: mysql-credentials + - name: paypal + secret: + secretName: paypal-cert + - name: sign-keys + projected: + sources: + - secret: + name: key-private + - secret: + name: key-public + +``` + +This way there is a clear separation of concerns. + + + +You can find the secrets themselves at [https://github.com/codefresh-contrib/gitops-secrets-sample-app/tree/main/never-commit-to-git/unsealed_secrets](https://github.com/codefresh-contrib/gitops-secrets-sample-app/tree/main/never-commit-to-git/unsealed_secrets){:target="\_blank"}. There are encoded with base64 so they are **NOT** safe to commit in Git. + +>Note that for demonstration purposes, the Git repository contains raw secrets so that you can encrypt them yourself. In a production application, the Git repository must only contain sealed/encrypted secrets. + +## Preparing the secrets + +The critical point of this application is to encrypt all the secrets and place them in Git. +By default, the sealed secrets controller encrypts a secret according to a specific namespace (this behavior is configurable), so you need to decide in advance which namespace wil host the application. + +Then encrypt all secrets as below: + +``` +kubectl create ns git-secrets +cd safe-to-commit/sealed_secrets +kubeseal -n git-secrets < ../../never-commit-to-git/unsealed_secrets/db-creds.yml > db-creds.json +kubeseal -n git-secrets < ../../never-commit-to-git/unsealed_secrets/key-private.yml > key-private.json +kubeseal -n git-secrets < ../../never-commit-to-git/unsealed_secrets/key-public.yml > key-public.json +kubeseal -n git-secrets < ../../never-commit-to-git/unsealed_secrets/paypal-cert.yml > paypal-cert.json +kubectl apply -f . -n git-secrets + +``` + +You now have encrypted your plain secrets. These files are safe to commit to Git. +You can see that they have been converted automatically to plain secrets with the command: + +``` +kubectl get secrets -n git-secrets +``` + +## Manually deploying the application + +Note that the application requires all secrets to be present: + +``` +cd safe-to-commit/manifests +kubectl apply -f . -n git-secrets +``` + +You can now visit the application url to see how it has access to all the secrets. + + +## Deploying the application with Codefresh GitOps + +Of course the big advantage of having everything committed into Git, is the ability to adopt GitOps +for the whole application (including secrets). + +This means that you can simply [point Codefresh GitOps to your repository]({{site.baseurl}}/docs/integrations/argocd/#creating-argocd-applications) and have the application +automatically deploy in the cluster. + +{% include image.html +lightbox="true" +file="/images/examples/sealed-secrets/add-app.png" +url="/images/examples/sealed-secrets/add-app.png" +alt="Creating a GitOps application" +caption="Creating a GitOps application" +max-width="50%" +%} + +You can then see the application in the GitOps dashboard: + +{% include image.html +lightbox="true" +file="/images/examples/sealed-secrets/current-state.png" +url="/images/examples/sealed-secrets/current-state.png" +alt="GitOps dashboard" +caption="GitOps dashboard" +max-width="90%" +%} + +If you visit its URL you will see the secrets being loaded: + +{% include image.html +lightbox="true" +file="/images/examples/sealed-secrets/app-secrets.png" +url="/images/examples/sealed-secrets/app-secrets.png" +alt="Application using secrets" +caption="Application using secrets" +max-width="90%" +%} + + +>Note that for simplicity reasons the same Git repository holds both the application source code and its +manifests. In an actual application, you should have two Git repositories (one of the source code only and one of the manifests). + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Codefresh GitOps]({{site.baseurl}}/docs/ci-cd-guides/gitops-deployments/) +[Using secrets]({{site.baseurl}}/docs/pipelines/secrets-store/) +[Secrets with Mozilla Sops]({{site.baseurl}}/docs/example-catalog/ci-examples/decryption-with-mozilla-sops/) +[Vault Secrets in the Pipeline]({{site.baseurl}}/docs/example-catalog/ci-examples/vault-secrets-in-the-pipeline/) + diff --git a/_docs/example-catalog/ci-examples/golang-hello-world.md b/_docs/example-catalog/ci-examples/golang-hello-world.md new file mode 100644 index 00000000..8c3e0c3f --- /dev/null +++ b/_docs/example-catalog/ci-examples/golang-hello-world.md @@ -0,0 +1,269 @@ +--- +title: "Create a Docker image for GO" +description: "Using Codefresh pipelines" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/go/cf-example-golang-hello-world/ +toc: true +--- + +Codefresh can work with Go projects of any version using built-in modules or any other dependency mechanism. + +## The example golang project + +You can see the example project at [https://github.com/codefresh-contrib/golang-sample-app](https://github.com/codefresh-contrib/golang-sample-app){:target="\_blank"}. The repository contains a simple Golang web application including unit tests. There are 3 Dockerfiles available: + +* [Simple Dockerfile](https://github.com/codefresh-contrib/golang-sample-app/blob/master/Dockerfile){:target="\_blank"} (with old Go version that requires `GOPATH` building) +* [Dockerfile with Go modules](https://github.com/codefresh-contrib/golang-sample-app/blob/master/Dockerfile.mod){:target="\_blank"} (optimized for Docker caching) +* [Multi-stage Dockerfile](https://github.com/codefresh-contrib/golang-sample-app/blob/master/Dockerfile.multistage){:target="\_blank"} (with Go modules and unit tests) + +Let's see these workflows in order. + +## Simple Docker image pipeline + +The most [simple pipeline](https://github.com/codefresh-contrib/golang-sample-app/blob/master/codefresh.yml){:target="\_blank"} that you can create is just two steps: +* A [clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/) to fetch the code +* A [build step]({{site.baseurl}}/docs/pipelines/steps/build/) to create a Docker image + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/golang-sample-app' + revision: master + git: github + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-golang-image + working_directory: ./ + tag: full + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +Once you run this pipeline Codefresh will create a Docker image for the Golang application: + +{% include image.html +lightbox="true" +file="/images/learn-by-example/golang/golang-simple-pipeline.png" +url="/images/learn-by-example/golang/golang-simple-pipeline.png" +alt="Simple pipeline for Golang" +caption="Simple pipeline for Golang" +max-width="80%" +%} + +The big advantage of this workflow is that the Dockerfile you use can define any Go version and dependency tool. As long as the Dockerfile is self-contained (i.e. it compiles GO on its own), the pipeline will work as expected. + +In the example application, the simple (unoptimized) Dockerfile has an old Go version that still requires `GOPATH` folders. + +`Dockerfile` +{% highlight docker %} +{% raw %} +FROM golang:1.10 + +# Set the Current Working Directory inside the container +WORKDIR $GOPATH/src/github.com/codefresh-contrib/go-sample-app + +# Copy everything from the current directory to the PWD (Present Working Directory) inside the container +COPY . . + +# Download all the dependencies +RUN go get -d -v ./... + +# Install the package +RUN go install -v ./... + +# This container exposes port 8080 to the outside world +EXPOSE 8080 + +# Run the executable +CMD ["go-sample-app"] +{% endraw %} +{% endhighlight %} + + +## Run unit tests as part of the pipeline + +If you want to run Go specific steps in your pipeline, you can use [freestyle]({{site.baseurl}}/docs/pipelines/steps/freestyle/) steps with any GO image that you want. If your GO application is using GO modules, this is even easier as you don't need to place the application into a specific GOPATH compliant directory first. + +This [pipeline](https://github.com/codefresh-contrib/golang-sample-app/blob/master/codefresh-gomod.yml){:target="\_blank"} is running unit tests as a separate step and then builds the docker image. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - checkout + - test + - build +steps: + main_clone: + title: Cloning main repository... + type: git-clone + stage: checkout + repo: 'codefresh-contrib/golang-sample-app' + revision: master + git: github + MyUnitTests: + title: Unit test + stage: test + image: 'golang:1.12' + commands: + - go test -v + MyAppDockerImage: + title: Building Docker Image + type: build + stage: build + image_name: my-golang-image + working_directory: ./ + tag: modules + dockerfile: Dockerfile.mod +{% endraw %} +{% endhighlight %} + +If the unit tests fail, then the docker image will never be created (Codefresh automatically stops a pipeline when there is an error). + +{% include image.html +lightbox="true" +file="/images/learn-by-example/golang/golang-ci-pipeline.png" +url="/images/learn-by-example/golang/golang-ci-pipeline.png" +alt="Golang pipeline with unit tests" +caption="Golang pipeline with unit tests" +max-width="80%" +%} + +Notice that in this case we have added module support in the Go application. The new Dockerfile is the following: + +`Dockerfile` +{% highlight docker %} +{% raw %} +FROM golang:1.12-alpine + +RUN apk add --no-cache git + +# Set the Current Working Directory inside the container +WORKDIR /app/go-sample-app + +# We want to populate the module cache based on the go.{mod,sum} files. +COPY go.mod . +COPY go.sum . + +RUN go mod download + +COPY . . + +# Build the Go app +RUN go build -o ./out/go-sample-app . + + +# This container exposes port 8080 to the outside world +EXPOSE 8080 + +# Run the binary program produced by `go install` +CMD ["./out/go-sample-app"] +{% endraw %} +{% endhighlight %} + +The Dockerfile will also automatically take advantage of the Codefresh distributed docker cache. + + + +## Create a multi-stage Docker image for GO + +Especially with Go applications, the recommended way to create Docker images is with [multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/){:target="\_blank"}. This makes the resulting Docker image as compact as possible. + +You can also embed unit tests in the Docker creation process, which guarantee the correctness of image (integration tests are best kept in the pipeline). + +Here is the new Dockerfile: + +`Dockerfile` +{% highlight docker %} +{% raw %} +FROM golang:1.12-alpine AS build_base + +RUN apk add --no-cache git + +# Set the Current Working Directory inside the container +WORKDIR /tmp/go-sample-app + +# We want to populate the module cache based on the go.{mod,sum} files. +COPY go.mod . +COPY go.sum . + +RUN go mod download + +COPY . . + +# Unit tests +RUN CGO_ENABLED=0 go test -v + +# Build the Go app +RUN go build -o ./out/go-sample-app . + +# Start fresh from a smaller image +FROM alpine:3.9 +RUN apk add ca-certificates + +COPY --from=build_base /tmp/go-sample-app/out/go-sample-app /app/go-sample-app + +# This container exposes port 8080 to the outside world +EXPOSE 8080 + +# Run the binary program produced by `go install` +CMD ["/app/go-sample-app"] +{% endraw %} +{% endhighlight %} + +Codefresh has native support for multi-stage builds. The [pipeline](https://github.com/codefresh-contrib/golang-sample-app/blob/master/codefresh-multi-stage.yml){:target="\_blank"} is the same as the first one with just two steps. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/golang-sample-app' + revision: master + git: github + MyAppDockerImage: + title: Building Docker Multi-stage Image + type: build + image_name: my-golang-image + working_directory: ./ + tag: multi-stage + dockerfile: Dockerfile.multistage +{% endraw %} +{% endhighlight %} + +You should see a much smaller Docker image at the end. + + +## Viewing Docker images + +If you look at your [Docker registry dashboard]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images) created the advantages of the multi-stage build are very clear: + +{% include image.html +lightbox="true" +file="/images/learn-by-example/golang/golang-image-size.png" +url="/images/learn-by-example/golang/golang-image-size.png" +alt="Creating different Docker images" +caption="Creating different Docker images" +max-width="80%" +%} + +We recommend using Go modules and multi-stage builds in your Go projects. + +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) + diff --git a/_docs/example-catalog/ci-examples/golang.md b/_docs/example-catalog/ci-examples/golang.md new file mode 100644 index 00000000..468e4eb8 --- /dev/null +++ b/_docs/example-catalog/ci-examples/golang.md @@ -0,0 +1,14 @@ +--- +title: "Go" +description: "How to build Golang applications with Codefresh CI/CD pipelines" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/go/ + - /docs/golang/ +toc: true +--- +This section contains Codefresh examples based on Go. + +- [Golang Docker Example]({{site.baseurl}}/docs/learn-by-example/golang/golang-hello-world/) +- [Golang with goreleaser]({{site.baseurl}}/docs/learn-by-example/golang/goreleaser/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/goreleaser.md b/_docs/example-catalog/ci-examples/goreleaser.md new file mode 100644 index 00000000..23cf3611 --- /dev/null +++ b/_docs/example-catalog/ci-examples/goreleaser.md @@ -0,0 +1,118 @@ +--- +title: "Compile and release a Go application" +description: "Using Codefresh pipelines" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +[Goreleaser](https://github.com/goreleaser/goreleaser){:target="\_blank"} is a helper utility that allows you to easily create the following for Go applications: + +* Binary packages for each OS/arch +* Archives +* GitHub releases +* Docker images +* Snap/RPM/deb/Homebrew + + +Codefresh can also create Docker images on its own, but Goreleaser is still useful for the binary artifact creation capability. + + +## Run Goreleaser with docker + +You can see the example project at [https://github.com/codefresh-contrib/goreleaser-sample-app](https://github.com/codefresh-contrib/goreleaser-sample-app){:target="\_blank"}. The repository contains a simple Golang web application with a [goreleaser configuration](https://github.com/codefresh-contrib/goreleaser-sample-app/blob/master/.goreleaser.yml){:target="\_blank"}. + + +There is already a [Docker image for Goreleaser](https://hub.docker.com/r/goreleaser/goreleaser/){:target="\_blank"} so it is very easy to use it in Codefresh pipeline. +In the most simple case you case run goreleaser in a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). + + `YAML` +{% highlight yaml %} +{% raw %} + ReleaseMyApp: + title: Creating packages + stage: release + image: 'goreleaser/goreleaser' + commands: + - goreleaser --snapshot --skip-publish --rm-dist +{% endraw %} +{% endhighlight %} + +More typically however you also need to provide a GitHub token so that GitHub releases are also available. There are two ways to do that. + + +## Create a CI pipeline that compiles/releases Go + +In most cases you want to just reuse the Git integration already defined in Codefresh. +This [pipeline](https://github.com/codefresh-contrib/goreleaser-sample-app/blob/master/codefresh.yml){:target="\_blank"} is using the GitHub token from [Git integration]({{site.baseurl}}/docs/integrations/git-providers/) in order to allow GitHub access. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build + - release +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: '${{CF_REVISION}}' + stage: prepare + BuildMyApp: + title: Compiling go code + stage: build + image: 'golang:1.12' + commands: + - go build + GetGitToken: + title: Reading GitHub token + stage: release + image: codefresh/cli + commands: + - cf_export GITHUB_TOKEN=$(codefresh get context github-1 --decrypt -o yaml | yq -y .spec.data.auth.password) + ReleaseMyApp: + title: Creating packages + stage: release + image: 'goreleaser/goreleaser' + commands: + - goreleaser --rm-dist +{% endraw %} +{% endhighlight %} + +Note that GoReleaser [requires a GitHub API token](https://goreleaser.com/environment/){:target="\_blank"} (`GITHUB_TOKEN`) with the `repo` scope to deploy artifacts to GitHub. +Here we use [cf_export]({{site.baseurl}}/docs/pipelines/variables/#exporting-environment-variables-from-a-freestyle-step) and the [codefresh CLI](https://codefresh-io.github.io/cli/){:target="\_blank"} in order to ask Codefresh about the existing token (that was used in git integrations). In your case you need to change `github-1` with the name of your [GitHub integration]({{site.baseurl}}/docs/integrations/git-providers/). + +It also possible to pass a GITHUB_TOKEN directly in the pipeline, if you don't want to re-use the existing one. This is an alternative way of allowing Goreleaser to create GitHub releases. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/golang/github-token.png" +url="/images/learn-by-example/golang/github-token.png" +alt="Passing a specific github token in the pipeline" +caption="Passing a specific github token in the pipeline" +max-width="70%" +%} + +You could also store the token in [shared configuration]({{site.baseurl}}/docs/pipelines/shared-configuration/). +Regardless of the way you choose to pass the GitHub token, the final step is to make sure that your pipeline is only executed for tag events. + + +{% include image.html +lightbox="true" +file="/images/learn-by-example/golang/tags-only-trigger.png" +url="/images/learn-by-example/golang/tags-only-trigger.png" +alt="Run pipeline only on tag creation" +caption="Run pipeline only on tag creation" +max-width="80%" +%} + +This means that this pipeline will not run on normal commits. It is also possible to use [step conditionals]({{site.baseurl}}/docs/pipelines/conditional-execution-of-steps/) for more complex cases. + +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/gradle.md b/_docs/example-catalog/ci-examples/gradle.md new file mode 100644 index 00000000..73bc26ee --- /dev/null +++ b/_docs/example-catalog/ci-examples/gradle.md @@ -0,0 +1,207 @@ +--- +title: "Java Example with Gradle and Docker" +description: "Create Docker images for Spring/Gradle" +excerpt: "" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/java/gradle/ +toc: true +--- + +Codefresh can work with Gradle builds in a similar manner as with [Maven builds]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/){:target="\_blank"}. + +## The example Gradle project + +You can see the example project at [https://github.com/codefresh-contrib/gradle-sample-app](https://github.com/codefresh-contrib/gradle-sample-app){:target="\_blank"}. The repository contains a Spring Boot 2 project built with Gradle with the following tasks: + +* `gradle test` runs unit tests. +* `gradle build` creates a self-contained jar file (using Spring boot). + +Once launched the application presents a simple message at localhost:8080 and also at the various `/actuator/health` endpoints. + +## Gradle and Docker (multi-stage builds) + +The easiest way to use Gradle is with [multi-stage builds](https://blog.docker.com/2017/07/multi-stage-builds/){:target="\_blank"}. With multi-stage builds a Docker build can use one base image for compilation/packaging/unit tests and a different one that will hold the runtime of the application. This makes the final image more secure and smaller in size (as it does not contain any development/debugging tools). + +In the case of Gradle, you can use a base image that has the full JDK and Gradle itself, while the final image has the JRE and nothing else. + +The example project is actually using multi-stage builds by default. + +Here is the multi-stage Dockerfile: + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM gradle:4.7.0-jdk8-alpine AS build +COPY --chown=gradle:gradle . /home/gradle/src +WORKDIR /home/gradle/src +RUN gradle build --no-daemon + +FROM openjdk:8-jre-slim + +EXPOSE 8080 + +RUN mkdir /app + +COPY --from=build /home/gradle/src/build/libs/*.jar /app/spring-boot-application.jar + +ENTRYPOINT ["java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-Djava.security.egd=file:/dev/./urandom","-jar","/app/spring-boot-application.jar"] +{% endraw %} +{% endhighlight %} + +This docker build does the following: + +1. Starts from the Gradle image +1. Copies the Java source code inside the container +1. Compiles the code and runs unit tests (with `Gradle build`) +1. Discards the Gradle image with all the compiled classes/unit test results etc. +1. Starts again from the JRE image and copies **only** the JAR file created before + +We start Gradle without the long-running daemon, as the deamon is best used during local development only and not in CI/CD pipelines. + +### Create a CI pipeline for Gradle (multi-stage Docker builds) + +Because in multi-stage builds Docker itself handles most of the build process, moving the project to Codefresh is straightforward. We just need [a single step](https://github.com/codefresh-contrib/gradle-sample-app/blob/master/codefresh.yml){:target="\_blank"} that creates the Docker image after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/gradle-sample-app' + revision: master + git: github + BuildingDockerImage: + title: Building Docker Image + stage: build + type: build + image_name: gradle-sample-app + working_directory: ./ + tag: 'multi-stage' + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +This will compile/test/package the Gradle application and create a Docker image. + + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/gradle-multistage.png" +url="/images/learn-by-example/java/gradle-multistage.png" +alt="Gradle Multi-stage Docker build" +caption="Gradle Multi-stage Docker build" +max-width="80%" +%} + +Codefresh is automatically caching +Docker layers (it uses the Docker image of a previous build as a cache for the next) and therefore builds will become +much faster after the first one finishes. + + +## Packaging an existing Jar in a Docker image + +It also possible to have a simpler Dockerfile that only packages the final jar which was already created in the CI/CD pipeline (i.e. outside of Docker). + +A [simpler Dockerfile](https://github.com/codefresh-contrib/gradle-sample-app/blob/master/Dockerfile.only-package){:target="\_blank"} is also provided at the same repository. It uses the base JRE image and just copies the JAR file inside the container. + + `Dockerfile.only-package` +{% highlight docker %} +{% raw %} +FROM openjdk:8-jre-slim + +EXPOSE 8080 + +RUN mkdir /app + +COPY build/libs/*.jar /app/spring-boot-application.jar + +ENTRYPOINT ["java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-Djava.security.egd=file:/dev/./urandom","-jar","/app/spring-boot-application.jar"] +{% endraw %} +{% endhighlight %} + +This means that _before_ building the Docker image, the compilation step (`gradle build`) is expected to be finished already. Therefore, in the `codefresh.yml` file we need at least two steps. The first one should prepare the JAR file and the second +one should create the Docker image. + +### Create a CI pipeline for a Gradle JAR + +The repository also contains a premade [Codefresh YAML file](https://github.com/codefresh-contrib/gradle-sample-app/blob/master/codefresh-package-only.yml){:target="\_blank"} that creates a JAR file first and then packages it in a Docker image. + +Here are the full contents of the file. + + `codefresh-package-only.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - package + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/gradle-sample-app' + revision: master + git: github + MyUnitTests: + title: Compile/Unit test + stage: test + image: gradle:4.7.0-jdk8-alpine + commands: + - gradle test --no-daemon --build-cache --gradle-user-home=/codefresh/volume/.gradle -Dmaven.repo.local=/codefresh/volume/m2 + BuildMyJar: + title: Packaging Jar file + stage: package + image: gradle:4.7.0-jdk8-alpine + commands: + - gradle build --no-daemon --build-cache --gradle-user-home=/codefresh/volume/.gradle -Dmaven.repo.local=/codefresh/volume/m2 + MyAppDockerImage: + title: Building Docker Image + type: build + stage: build + image_name: gradle-sample-app + working_directory: ./ + tag: 'non-multi-stage' + dockerfile: Dockerfile.only-package +{% endraw %} +{% endhighlight %} + +The pipeline starts by checking out the code using a [git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). The next two steps are [freestyle]({{site.baseurl}}/docs/pipelines/steps/freestyle/), while the last one is a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/gradle-ci-pipeline.png" +url="/images/learn-by-example/java/gradle-ci-pipeline.png" +alt="Gradle pipeline" +caption="Gradle pipeline" +max-width="80%" +%} + +After checking out the code we use the standard [Gradle Docker image](https://hub.docker.com/_/gradle/){:target="\_blank"} to run unit tests. We also pass parameters that disable the Gradle daemon, enable the build cache and also change the cache folder to reside in the Codefresh volume. + +### Using the Gradle cache in Codefresh + +Codefresh is smart enough that [caches automatically]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#how-caching-works-in-codefresh) for us the workspace of a build (`/codefresh/volume`). This works great for build tools that keep their cache in the project folder, but not for Maven/Gradle which keep their cache externally. By changing the location of the Gradle cache we make sure that Codefresh will cache automatically the Gradle libraries resulting in much faster builds. We also place in the shared volume the local maven repo so that all jars that are created by Gradle (i.e. with an `install` task) are also available to the next pipeline stage. + +The next step is similar to the previous one, but this time we actually build the JAR file. We define again a custom cache folder so when you run the build you will see that Gradle will automatically pick the cache from the previous step. All Codefresh steps in a pipeline [run on the same workspace]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps), so the build results from one step are visible to the next. + +The last step is a Docker build. We name our image **gradle-sample-app** and tag it with a string `non-multi-stage` but of course you can use any other tag name that you wish. +Once the pipeline is finished you will see the Spring Boot 2 Docker image your [Docker image dashboard]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images). + +## Related articles +[Spring Maven example]({{site.baseurl}}/docs/example-catalog/ci-examples/spring-boot-2/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) diff --git a/_docs/example-catalog/ci-examples/import-data-to-mongodb.md b/_docs/example-catalog/ci-examples/import-data-to-mongodb.md new file mode 100644 index 00000000..223ecc6c --- /dev/null +++ b/_docs/example-catalog/ci-examples/import-data-to-mongodb.md @@ -0,0 +1,60 @@ +--- + +title: "Import data to MongoDB" +description: "" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/import-data-to-mongodb-in-composition/ + - /docs/on-demand-test-environment/example-compositions/import-data-to-mongodb/ +toc: true +--- + +To import, restore, or for any operation before using MongoDB in your application, look at the following example. + +You just need to create Dockerfile for Mongo seed service and provide the command to prepare MongoDB. In this case, the command is `mongoimport`. + + `Dockerfile mongo_seed` +{% highlight docker %} +FROM mongo +COPY init.json /init.json +CMD mongoimport --host mongodb --db exampleDb --collection contacts --type json --file /init.json --jsonArray +{% endhighlight %} + +## Looking around +In the root of this repository you'll find a file named `docker-compose.yml`. +Let's quickly review the contents of this file: + + `docker-compose.yml` +{% highlight yaml %} +{% raw %} +version: '3' +services: + mongodb: + image: mongo + command: mongod --smallfiles + ports: + - 27017 + + mongo_seed: + image: ${{mongo_seed}} + links: + - mongodb + + client: + image: ${{build_prj}} + links: + - mongodb + ports: + - 9000 + environment: + - MONGO_URI=mongodb:27017/exampleDb +{% endraw %} +{% endhighlight %} + +{{site.data.callout.callout_info}} +You can add the following example to your GitHub or Bitbucket account, and build the [example](https://github.com/codefreshdemo/cf-example-manage-mongodb){:target="_blank"}. +{{site.data.callout.end}} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/integration-tests-with-mongo.md b/_docs/example-catalog/ci-examples/integration-tests-with-mongo.md new file mode 100644 index 00000000..1947496a --- /dev/null +++ b/_docs/example-catalog/ci-examples/integration-tests-with-mongo.md @@ -0,0 +1,101 @@ +--- +title: "Integration Tests with Mongo" +description: "Launching a MongoDB service container" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/nodejsmongo/ + - /docs/testing/unit-tests/unit-tests-with-mongo/ +toc: true +--- + +In this example, we will see a NodeJS project that uses MongoDB for data storage. For the integration test phase we will launch an instance of MongoDB in order to run a set of [Mocha tests](https://mochajs.org/){:target="\_blank"}. + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/mongodb-integration-tests.png" +url="/images/examples/integration-tests/mongodb-integration-tests.png" +alt="MongoDB integration tests with Codefresh" +caption="MongoDB integration tests with Codefresh" +max-width="90%" +%} + +The Mocha tests are looking for a MongoDB connection at `mongo:27017`. + +## The example NodeJS project + +You can see the example project at [https://github.com/codefreshdemo/example_nodejs_mongo](https://github.com/codefreshdemo/example_nodejs_mongo){:target="\_blank"}. The repository contains the NodeJS source code and the Mocha tests. + +You can play with it locally by using Docker compose to launch both the application and the MongoDB datastore. + +## Create a pipeline with MongoDB integration tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - prepare + - build + - test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefreshdemo/example_nodejs_mongo" + revision: "master" + git: github + stage: prepare + build_app_image: + title: "Building Docker Image" + type: "build" + image_name: "node-mongo-app" + tag: "master" + dockerfile: "Dockerfile" + stage: build + run_integration_tests: + title: "Running integration tests" + stage: test + image: '${{build_app_image}}' + environment: + - MONGO_PORT=27017 + commands: + # MongoDB is certainly up at this point + - cd /src + - npm test + services: + composition: + mongo: + image: mongo:latest + ports: + - 27017 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: '${{build_app_image}}' + commands: + - "nslookup mongo" + - "nc -z mongo 27017" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Builds a Docker image with the application source code as well as the Mocha tests through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). +1. Runs Mocha tests while launching a [service container]({{site.baseurl}}/docs/pipelines/service-containers/) for an active MongoDB instance + +Notice that we also use the `readiness` property in the testing phase so that we can verify MongoDB is ready and listening, before running the tests. + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Integration test example]({{site.baseurl}}/docs/example-catalog/ci-examples/run-integration-tests/) +[Integration Tests with Postgres]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-postgres/) +[Integration Tests with MySQL]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mysql/) +[Integration Tests with Redis]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-redis/) + + + + diff --git a/_docs/example-catalog/ci-examples/integration-tests-with-mysql.md b/_docs/example-catalog/ci-examples/integration-tests-with-mysql.md new file mode 100644 index 00000000..cccb9a43 --- /dev/null +++ b/_docs/example-catalog/ci-examples/integration-tests-with-mysql.md @@ -0,0 +1,110 @@ +--- +title: "Integration Tests with MySQL" +description: "Launching a MySQL service container" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/nodejsmysql/ + - /docs/testing/unit-tests/unit-tests-with-mysql/ + - /docs/setup-unit-tests/ + - /docs/testing/unit-tests/unit-tests-with-composition/ + - /docs/run-unit-tests-with-composition/ + - /docs/unit-tests-with-database/ + - /docs/testing/unit-tests/unit-tests-with-database/ + - /docs/example-catalog/ci-examples/integration-tests-with-database/ +toc: true +--- + +In this example, we will see a NodeJS project that is using MySQL for data storage. For the integration test phase we will launch an instance of MySQL in order to run a simple integration test. + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/mysql-integration-tests.png" +url="/images/examples/integration-tests/mysql-integration-tests.png" +alt="MySQL integration tests with Codefresh" +caption="MySQL integration tests with Codefresh" +max-width="90%" +%} + +The integration tests look for a MySQL connection at `test_mysql_db:3306`. + +## Example NodeJS project + +You can see the example project at [https://github.com/codefreshdemo/cf-example-unit-tests-with-composition](https://github.com/codefreshdemo/cf-example-unit-tests-with-composition){:target=\_blank"}. The repository contains the NodeJS source code and the simple integration test. + +You can play with it locally by using Docker compose to launch both the application and the MySQL Database. + +## Create a pipeline with MySQL integration tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - prepare + - build + - test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefreshdemo/cf-example-unit-tests-with-composition" + revision: "master" + git: github + stage: prepare + build_test_image: + title: "Building Test Docker Image" + type: "build" + image_name: "mysql-tests" + tag: "master" + dockerfile: "Dockerfile" + stage: build + run_integration_tests: + title: "Running integration tests" + stage: test + image: '${{build_test_image}}' + environment: &test_mysql_vars + - MYSQL_ROOT_PASSWORD=admin + - MYSQL_USER=my_user + - MYSQL_PASSWORD=admin + - MYSQL_DATABASE=nodejs + - MYSQL_HOST=test_mysql_db + commands: + # MySQL is certainly up at this point + - cd /usr/src/app + - npm test + services: + composition: + test_mysql_db: + image: mysql:5.7 + ports: + - 3306 + environment: *test_mysql_vars # Same MYSQL_HOST, MYSQL_USER etc. + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: '${{build_test_image}}' + commands: + - "nslookup test_mysql_db" + - "nc -z test_mysql_db 3306" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Builds a Docker image with the integration test through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). +1. Runs the tests while launching a [service container]({{site.baseurl}}/docs/pipelines/service-containers/) for an active MySQL instance passing the required environment variables (that match what the test is expecting). + +Notice that both the DB as well as the tests share a set of variables (`MYSQL_PASSWORD`, `MYSQL_USER` etc.) and thus we use [YAML anchors]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/#using-yaml-anchors-to-avoid-repetition) to avoid duplication. + +Notice that we also use the `readiness` property in the testing phase so that we can verify MySQL is ready and listening, before running the tests. + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Integration test example]({{site.baseurl}}/docs/example-catalog/ci-examples/run-integration-tests/) +[Integration Tests with Postgres]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-postgres/) +[Integration Tests with Redis]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-redis/) +[Integration Tests with Mongo]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mongo/) diff --git a/_docs/example-catalog/ci-examples/integration-tests-with-postgres.md b/_docs/example-catalog/ci-examples/integration-tests-with-postgres.md new file mode 100644 index 00000000..ee2a4110 --- /dev/null +++ b/_docs/example-catalog/ci-examples/integration-tests-with-postgres.md @@ -0,0 +1,99 @@ +--- +title: "Integration Tests with Postgres" +description: "Launching a PostgreSQL service container" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/unit-tests-with-postgres/ + - /docs/testing/unit-tests/unit-tests-with-postgres/ +toc: true +--- + +In this example, we will see a NodeJS project that is using PostgreSQL for data storage. For the integration test phase we will launch an instance of PostgreSQL in order to run a simple integration test. + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/postgresql-integration-tests.png" +url="/images/examples/integration-tests/postgresql-integration-tests.png" +alt="PostgreSQL integration tests with Codefresh" +caption="PostgreSQL integration tests with Codefresh" +max-width="90%" +%} + +The integration tests look for a PostgreSQL connection at `postgres:5432`. + +## Example NodeJS project + +You can see the example project at [https://github.com/codefreshdemo/example_nodejs_postgres](https://github.com/codefreshdemo/example_nodejs_postgres){:target="\_blank"}. The repository contains the NodeJS source code and the simple integration test. + +You can play with it locally by using Docker compose to launch both the application and the PostgreSQL Database. + +## Create a pipeline with PostgreSQL integration tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - prepare + - build + - test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefreshdemo/example_nodejs_postgres" + revision: "master" + git: github + stage: prepare + run_integration_tests: + title: "Running integration tests" + stage: test + image: node:6.9.1 + environment: &test_postgresql_vars + - POSTGRES_USER=user + - POSTGRES_PASSWORD=admin + - POSTGRES_DB=todo + commands: + # PostgreSQL is certainly up at this point + - npm install -g gulp + - npm install + - npm test + services: + composition: + postgres: + image: postgres:11.5 + ports: + - 5432 + environment: *test_postgresql_vars # Same POSTGRES_USER, POSTGRES_PASSWORD etc. + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: postgres:11.5 + commands: + - "pg_isready -h postgres" + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Runs the tests while launching a [service container]({{site.baseurl}}/docs/pipelines/service-containers/) for an active PostgreSQL instance passing the required environment variables (that match what the test is expecting). + +Notice that both the DB as well as the tests share a set of variables (`POSTGRES_USER`, `POSTGRES_PASSWORD` etc.) and thus we use [YAML anchors]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/#using-yaml-anchors-to-avoid-repetition) to avoid duplication. + +Notice that we also use the `readiness` property in the testing phase so that we can verify PostgreSQL is ready and listening, before running the tests. + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Integration test example]({{site.baseurl}}/docs/example-catalog/ci-examples/run-integration-tests/) +[Integration Tests with MySQL]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mysql/) +[Integration Tests with Redis]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-redis/) +[Integration Tests with Mongo]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mongo/) +[Preload a DB with tests data]({{site.baseurl}}/docs/example-catalog/ci-examples/populate-a-database-with-existing-data/) + + diff --git a/_docs/example-catalog/ci-examples/integration-tests-with-redis.md b/_docs/example-catalog/ci-examples/integration-tests-with-redis.md new file mode 100644 index 00000000..027a5710 --- /dev/null +++ b/_docs/example-catalog/ci-examples/integration-tests-with-redis.md @@ -0,0 +1,129 @@ +--- +title: "Integration Tests with Redis" +description: "Launching a Redis service container" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/python-redis/ + - /docs/testing/unit-tests/unit-tests-with-redis/ +toc: true +--- + +In this example, we will see a Python project that is using Redis for storing a web counter. For the integration test phase we will launch both the application and an instance of Redis in order to run a simple integration test. + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/redis-integration-tests.png" +url="/images/examples/integration-tests/redis-integration-tests.png" +alt="Redis integration tests with Codefresh" +caption="Redis integration tests with Codefresh" +max-width="90%" +%} + +The application will be launched with a hostname `web` while Redis will be at `redis:6379`. + +## Example Python project + +You can see the example project at [https://github.com/codefreshdemo/example_python_redis](https://github.com/codefreshdemo/example_python_redis){:target="\_blank"}. The repository contains the Python source code and a test script. + +You can play with it locally by using Docker compose to launch both the application and the Redis datastore. + +## Create a pipeline with Redis integration tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - prepare + - build + - test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefreshdemo/example_python_redis" + revision: "master" + git: github + stage: prepare + build_app_image: + title: "Building Docker Image" + type: "build" + image_name: "python-redis-app" + tag: "latest" + dockerfile: "Dockerfile" + stage: build + build_test_image: + title: "Building Docker Test Image" + type: "build" + image_name: "python-redis-app-tests" + tag: "latest" + dockerfile: "Dockerfile.test" + stage: test + run_integration_tests: + title: "Running integration tests" + stage: test + image: '${{build_test_image}}' + commands: + # Redis and app are certainly up at this point + - sh ./test.sh + services: + composition: + redis: + image: redis:latest + ports: + - 6379 + web: + image: '${{build_app_image}}' + ports: + - 80 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: '${{build_test_image}}' + commands: + - "nslookup redis" + - "nslookup web" + - "nc -z redis 6379" + - "nc -z web 80" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Builds a Docker image with the application itself through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). +1. Builds a helper image that contains `nc` and `curl` that will be used for the integration tests. +1. Runs the test script while launching two [service containers]({{site.baseurl}}/docs/pipelines/service-containers/) (one for the app and one for Redis). + +Notice that we also use the `readiness` property in the testing phase so that we can verify that both the application +as well as Redis are up, before running the tests. + +## Integration test script + +The integration test is very simple. It just uses `curl` to hit the Python endpoint and `grep` to check for a well known string. + + `test.sh` +{% highlight sh %} +#!bin/bash + +if curl web | grep -q 'Visits: '; then + echo "Tests passed!" + exit 0 +else + echo "Tests failed!" + exit 1 +fi +{% endhighlight %} + +Notice that we use the helper image both for running the test (because of `curl`) and for testing the readiness (because of `nc`). In a more complex application these could be two completely different images. + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Integration test example]({{site.baseurl}}/docs/example-catalog/ci-examples/run-integration-tests/) +[Integration Tests with Postgres]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-postgres/) +[Integration Tests with MySQL]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mysql/) +[Integration Tests with Mongo]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mongo/) diff --git a/_docs/example-catalog/ci-examples/java.md b/_docs/example-catalog/ci-examples/java.md new file mode 100644 index 00000000..c28cd55c --- /dev/null +++ b/_docs/example-catalog/ci-examples/java.md @@ -0,0 +1,15 @@ +--- +title: "Java" +description: "" +group: example-catalog +redirect_from: + - /docs/java/ +toc: true +--- +This section contains Codefresh examples based on Java: + +- [Spring Boot 2 with Maven]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/) +- [Gradle]({{site.baseurl}}/docs/learn-by-example/java/gradle/) +- [Publish a JAR]({{site.baseurl}}/docs/learn-by-example/java/publish-jar/) +- [Spring MVC JDBC Template]({{site.baseurl}}/docs/learn-by-example/java/spring-mvc-jdbc-template/) + diff --git a/_docs/example-catalog/ci-examples/launch-composition.md b/_docs/example-catalog/ci-examples/launch-composition.md new file mode 100644 index 00000000..4b010f39 --- /dev/null +++ b/_docs/example-catalog/ci-examples/launch-composition.md @@ -0,0 +1,85 @@ +--- +title: "Launch Compositions" +description: "Create a dynamic environment to preview your feature" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/launch-composition-1/ +toc: true +--- +Using this repository, we will help you get up to speed with basic functionality such as: building Docker images and launching compositions. +This project uses `Node JS` to build an application which will eventually become a distributable Docker image. + +## Looking around + +In the root of this repository you'll find a file named `codefresh.yml`. This is our [pipeline definition]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) and it describes the different steps that comprise our process. Let's quickly review the contents of this file: + + `codefresh.yml` +{% highlight yaml %} +version: '1.0' +stages: + - prepare + - package + - launch +steps: + main_clone: + title: 'Cloning main repository...' + type: git-clone + repo: codefreshdemo/cf-example-launch-composition + revision: 'master' + git: github + stage: prepare + build_image: + title: Building Image + type: build + #Important: rename this image to to a valid repository in your registry. For example: myUserName/vote + image_name: example-launch-compose + #Dockerfile location should be relative to the working directory + dockerfile: Dockerfile + tag: master + stage: package + launch_composition: + title: Launch Composition + type: launch-composition + composition: + version: '2' + services: + app: + image: example-launch-compose:master + ports: + - 3000 + environment_name: 'cf-example-launch-composition' + entry_point: app + fail_fast: false + stage: launch +{% endhighlight %} + +The pipeline clones the source code, builds a docker image and then + [creates a preview environment]({{site.baseurl}}/docs/pipelines/steps/launch-composition/) with that image. + + +>**Your environments are limited** + Be aware that the number of environments you can run is limited. When using the same environment, define that the old one would terminate before launching the new environment. That way you can control the number of environments running in your account. + + +### Example + +Just head over to the example [**repository**](https://github.com/codefreshdemo/cf-example-launch-composition){:target=\_blank"} in GitHub and follow the instructions there. + + +Here is the end result: + +{% include image.html +lightbox="true" +file="/images/examples/composition/launch-composition-example.png" +url="/images/examples/composition/launch-composition-example.png" +alt="Launch composition example" +caption="Launch composition example" +max-width="90%" +%} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Unit tests]({{site.baseurl}}/docs/examples/example-catalog/ci-examples/run-integration-tests/) +[Integration tests]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-database/) +[Preview environments]({{site.baseurl}}/docs/getting-started/on-demand-environments/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md b/_docs/example-catalog/ci-examples/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md new file mode 100644 index 00000000..47996ba4 --- /dev/null +++ b/_docs/example-catalog/ci-examples/launching-a-composition-and-defining-a-service-environment-variables-using-a-file.md @@ -0,0 +1,59 @@ +--- +title: "Use Docker compose" +description: "Launch a composition and define a service environment variable using a file" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/launching-a-composition-and-passing-a-service-environment-variable-using-a-file/ +toc: true +old_url: /docs/launching-a-composition-and-passing-a-service-environment-variable-using-a-file +--- +At times when launching a composition, you need to pass many environment variables to a specific service. +To do so, you can use `docker-compose 'env_file'` field on any service, and use files from the current working directory from which the composition is being launched. +This works for both `composition` and `launch-composition` step types. + +>**Note**: + When launching a composition directly from the Compositions view, using `env_file` does not work as it is being launched in an empty working directory. + Consider moving the composition launch as part of a usual pipeline which will give you ability to use files from your cloned repository. + + +## Examples +Compositions are launched within a working directory, which is the cloned repository by default. +This means that you can always reference an `env_file` just as would reference a `docker-compose` file. + + `Inline Composition` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + + inline_composition: + title: Launch inline composition + type: launch-composition + environment_name: 'environment name' + composition: + version: '3' + services: + service: + image: alpine + env_file: ./env-file +{% endraw %} +{% endhighlight %} + + + `Composition from file` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + + composition_from_file: + title: Launch composition from file + type: launch-composition + composition: './docker-compose.yml' + environment_name: 'environment name' +{% endraw %} +{% endhighlight %} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/lets-chat.md b/_docs/example-catalog/ci-examples/lets-chat.md new file mode 100644 index 00000000..b14e965b --- /dev/null +++ b/_docs/example-catalog/ci-examples/lets-chat.md @@ -0,0 +1,121 @@ +--- +title: "Let's Chat example" +description: "Create Docker images for Node/Express.js applications" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/lets-chat/ +toc: true +--- + +Let’s Chat is self-hosted chat app for small to big teams. + +## The example Node.JS project + +You can see the example project at [https://github.com/codefreshdemo/demochat](https://github.com/codefreshdemo/demochat){:target="\_blank"}. The repository contains the source code of the project along with two Dockerfiles (one for unit tests) and various docker-compose configurations + +The project requires a Mongo Database to work and by default it uses port 5000 for its web interface. + +## Create a CI pipeline for Node.js + +Creating a CI/CD pipeline for NodeJS is very easy, because Codefresh has built-in steps for creating Docker images and running commands with containers. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/nodejs/nodejs-pipeline.png" +url="/images/learn-by-example/nodejs/nodejs-pipeline.png" +alt="Building and testing a Node.js application" +caption="Building and testing a Node.js application" +max-width="100%" +%} + +Here is the [full pipeline](https://github.com/codefreshdemo/demochat/blob/master/codefresh.yml){:target="\_blank"} that creates the Docker image after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - "clone" + - "unit" + - "build" + - "integration" + +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "codefreshdemo/demochat" + revision: "master" + stage: "clone" + + build_dev_image: + title: "Building Dev image" + type: "build" + image_name: "codefreshdemo/demochat" + working_directory: "${{clone}}" + tag: "dev" + dockerfile: "Dockerfile.dev" + stage: "unit" + + test: + title: "Running test" + type: "freestyle" + image: ${{build_dev_image}} + working_directory: /root/demochat + commands: + - 'npm run test' + stage: "unit" + + build_image: + title: "Building App image" + type: "build" + image_name: "codefreshdemo/demochat" + working_directory: "${{clone}}" + tag: "dev" + dockerfile: "Dockerfile" + stage: "build" + + integration_step: + type: composition + stage: 'integration' + composition: + version: '2' + services: + app: + image: ${{build_image}} + links: + - mongo + ports: + - 5000 + mongo: + image: mongo + composition-candidates: + main: + image: nhoag/curl + command: bash -c "sleep 30 && curl http://app:5000/" | echo 'works' + +{% endraw %} +{% endhighlight %} + +> Note that you should change `codefreshdemo` in the clone step with your own Github account if you fork the repository. Also in both build steps you should change `codefreshdemo/demochat` with your own image name that is compliant to your Dockerhub account or other connected registry. + +This pipeline has 4 [stages]({{site.baseurl}}/docs/pipelines/stages/) and performs the following: + + 1. Clones the source code using the [git-clone]({{site.baseurl}}/docs/pipelines/steps/git-clone/) step + 1. Builds a Docker image for unit tests with the [build step]({{site.baseurl}}/docs/pipelines/steps/build/) + 1. Runs [unit tests]({{site.baseurl}}/docs/testing/unit-tests/) in the Docker image that was just created with a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) + 1. Building a Docker image for the final application + 1. Runs [integration tests]({{site.baseurl}}/docs/testing/integration-tests/) using a [composition step]({{site.baseurl}}/docs/pipelines/steps/composition/) + +If you run the pipeline multiple times, you will also see the [Codefresh caching mechanisms]({{site.baseurl}}/docs/pipelines/pipeline-caching/) in action for faster build times. + +## Related articles +[Voting app example]({{site.baseurl}}/docs/example-catalog/ci-examples/voting-app/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) + + + diff --git a/_docs/example-catalog/ci-examples/mobile.md b/_docs/example-catalog/ci-examples/mobile.md new file mode 100644 index 00000000..e0c6f991 --- /dev/null +++ b/_docs/example-catalog/ci-examples/mobile.md @@ -0,0 +1,10 @@ +--- +title: "Mobile Apps" +description: "How to build Mobile applications with Codefresh CI/CD pipelines" +group: example-catalog +sub_group: ci-examples +toc: true +--- +This section contains Codefresh examples for Mobile application. + +- [Android]({{site.baseurl}}/docs/learn-by-example/mobile/android/) diff --git a/_docs/example-catalog/ci-examples/nodejs.md b/_docs/example-catalog/ci-examples/nodejs.md new file mode 100644 index 00000000..4ed04ccd --- /dev/null +++ b/_docs/example-catalog/ci-examples/nodejs.md @@ -0,0 +1,15 @@ +--- +title: "Node.js" +description: "" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/nodejs/ +toc: true +--- + +This section contains Codefresh examples based on Node.js: + +- [Let's Chat]({{site.baseurl}}/docs/learn-by-example/nodejs/lets-chat/) - Express.js + Mongo Example +- [Voting app]({{site.baseurl}}/docs/learn-by-example/nodejs/voting-app/) - Microservices app with multiple programming languages +- [React JS app]({{site.baseurl}}/docs/learn-by-example/nodejs/react/) - React.JS + multi stage Docker build example \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/non-git-checkout.md b/_docs/example-catalog/ci-examples/non-git-checkout.md new file mode 100644 index 00000000..5f32d93b --- /dev/null +++ b/_docs/example-catalog/ci-examples/non-git-checkout.md @@ -0,0 +1,100 @@ +--- +title: "Checking out from other source control systems" +description: "Work with non-git repositories" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +Codefresh has [native Git support]({{site.baseurl}}/docs/example-catalog/ci-examples/git-checkout/), but you can still use any other version control system such as SVN, CVS, hg, etc. + +The only requirement is that you find or create a Docker image that contains the client for that source control system and then use a +[freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) to run it. + +## Checking out Subversion code + +There is already a public [Docker image with the svn client](https://hub.docker.com/r/jgsqware/svn-client/){:target="\_blank"}, so it is very easy to run it in a Codefresh pipeline. + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myCustomCheckout: + title: Performing SVN checkout + image: jgsqware/svn-client + commands: + - pwd + - rm -rf audacity-svn + - svn checkout https://svn.code.sf.net/p/audacity/svn/ audacity-svn + PrintFileList: + title: 'Listing files' + image: alpine:latest + commands: + - 'ls -l /codefresh/volume/' +{% endraw %} +{% endhighlight %} + +Notice the `rm` command before the clone step. This makes sure that every time the pipeline runs, the `svn checkout` step is implemented in an empty directory. + + + +## Checking out Mercurial or CVS Code + +It is very simple to use any other source control system in a Codefresh pipeline. The easiest way is to just call the respective executable. Here are two examples: + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myHgStep: + title: Using HG + image: alpine:latest + commands: + - apk add --no-cache mercurial + - hg --version + - hg clone https://www.mercurial-scm.org/repo/hg mercurial-repo + myCvsStep: + title: Using CVS + image: alpine:latest + commands: + - apk add --no-cache cvs + - cvs --version + - cvs -d :pserver:anonymous@cvs.project-open.net:/home/cvsroot checkout -c +{% endraw %} +{% endhighlight %} + +A much faster way is to create your own Dockerfile that includes the client you need and then define that image directly in the freestyle step. + + +## Checking out Perforce code + +Codefresh has created a [Perforce plugin](https://hub.docker.com/r/codefresh/cf-p4-plugin/tags){:target="\_blank"} which packs the p4 client into a Docker image to be used from Codefresh pipelines: + +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + myCustomCheckout: + title: Performing Perforce checkout + image: codefresh/cf-p4-plugin:latest + commands: + - mkdir -p /codefresh/volume/p4repo/ + - p4 client -o | grep -v '#' | sed '/Root:/c\Root:/codefresh/volume/p4repo/' | p4 client -i + - cd /codefresh/volume/p4repo/ && p4 rec + - 'ls -la' + environment: + - P4PORT=serveradress:serverport + - P4CLIENT=clientname + - P4USER=username + - P4PASSWD=password +{% endraw %} +{% endhighlight %} + +Define the environment variables in [Codefresh shared configuration]({{site.baseurl}}/docs/pipelines/shared-configuration/). + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Native Git checkout]({{site.baseurl}}/docs/example-catalog/ci-examples/git-checkout/) +[Running custom git commands]({{site.baseurl}}/docs/example-catalog/ci-examples/git-checkout-custom/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) diff --git a/_docs/example-catalog/ci-examples/php.md b/_docs/example-catalog/ci-examples/php.md new file mode 100644 index 00000000..b447f0d5 --- /dev/null +++ b/_docs/example-catalog/ci-examples/php.md @@ -0,0 +1,135 @@ +--- +title: "Create a Docker image for Php" +description: "Using Codefresh pipelines" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +Codefresh can work with Php projects using any of the popular frameworks (Laravel, Symphony, CakePHp etc.) + +## The example php project + +You can see the example project at [https://github.com/codefresh-contrib/php-composer-sample-app](https://github.com/codefresh-contrib/php-composer-sample-app){:target="\_blank"}. The repository contains a simple Php project that uses [composer](https://getcomposer.org/) as a package manager. + +The dockerfile uses [multi-stage builds](https://docs.docker.com/develop/develop-images/multistage-build/){:target="\_blank"} to minimize the size of the docker image. + +`Dockerfile` +{% highlight docker %} +{% raw %} +FROM composer:1.9.3 as vendor + +WORKDIR /tmp/ + +COPY composer.json composer.json +COPY composer.lock composer.lock + +RUN composer install \ + --ignore-platform-reqs \ + --no-interaction \ + --no-plugins \ + --no-scripts \ + --prefer-dist + + +FROM php:7.2-apache-stretch + +COPY . /var/www/html +COPY --from=vendor /tmp/vendor/ /var/www/html/vendor/ +{% endraw %} +{% endhighlight %} + + +## Create a Docker image for Php project + +An [example pipeline](https://github.com/codefresh-contrib/php-composer-sample-app/blob/master/codefresh.yml){:target="\_blank"} is also offered in the git repository. +It contains just two [steps]({{site.baseurl}}/docs/pipelines/steps/): + +* A [clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/) to fetch the code +* A [build step]({{site.baseurl}}/docs/pipelines/steps/build/) to create a Docker image + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/php-composer-sample-app' + revision: master + git: github + MyAppDockerImage: + title: Building Docker Image + type: build + image_name: my-php-image + working_directory: ./ + tag: master + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +Once you run this pipeline Codefresh will create a Docker image for the Php application: + +{% include image.html +lightbox="true" +file="/images/learn-by-example/php/php-cicd-pipeline.png" +url="/images/learn-by-example/php/php-cicd-pipeline.png" +alt="Creating a docker image for php" +caption="Creating a docker image for php" +max-width="80%" +%} + +Notice that all dependencies are downloaded when the dockerfile is created. + + + + +## Launch Docker images + +Codefresh can also launch Docker images (using Docker swarm behind the scenes). With each Codefresh account you get access to a limited number of Docker environments that can host any Docker image or Docker compose file. + +First find your images in the [Docker image dashboard]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images). + +{% include image.html +lightbox="true" +file="/images/learn-by-example/php/launch-docker-image.png" +url="/images/learn-by-example/php/launch-docker-image.png" +alt="Launching a Docker image" +caption="Launching a Docker image" +max-width="80%" +%} + +Click on the launch button and a new pipeline will run for deployment: + +{% include image.html +lightbox="true" +file="/images/learn-by-example/php/test-environment-url.png" +url="/images/learn-by-example/php/test-environment-url.png" +alt="Getting the environment url" +caption="Getting the environment url" +max-width="80%" +%} + +Notice that the pipeline logs show the dynamic URL of the application. Simply visit it with your browser +and you will see the result. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/php/test-environment.png" +url="/images/learn-by-example/php/test-environment.png" +alt="Application preview" +caption="Application preview" +max-width="80%" +%} + +Notice that these environments are only for testing and previewing your application as it is developed. They are **NOT** for production purposes. + + + +## Related articles + +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) diff --git a/_docs/example-catalog/ci-examples/populate-a-database-with-existing-data.md b/_docs/example-catalog/ci-examples/populate-a-database-with-existing-data.md new file mode 100644 index 00000000..14f27b14 --- /dev/null +++ b/_docs/example-catalog/ci-examples/populate-a-database-with-existing-data.md @@ -0,0 +1,153 @@ +--- +title: "Populate database with existing data" +description: "Preload test data before integration tests" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/populate-a-database-with-existing-data-copied/ +toc: true +old_url: /docs/populate-a-database-with-existing-data-copied +was_hidden: true +--- +In another example we saw how to run [integration tests with a database]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-postgres/) such as PostgreSQL. Sometimes however, the integration tests require the database to already have some test data beforehand. With Codefresh you can use the [setup block]({{site.baseurl}}/docs/pipelines/service-containers/#preloading-data-to-databases) in service containers to preload data to a database. + + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/preload-data-to-db.png" +url="/images/examples/integration-tests/preload-data-to-db.png" +alt="Preloading test data to a DB" +caption="Preloading test data to a DB" +max-width="90%" +%} + +In this pipeline the database is populated with data from an SQL file. + +## Example PostgreSQL project + +You can see the example project at [https://github.com/codefresh-contrib/preload-db-integration-tests](https://github.com/codefresh-contrib/preload-db-integration-tests){:target="\_blank"}. The repository contains a simple integration test and an SQL file that inserts test data. + +The SQL file creates a single table in the database: + + `preload.sql` +{% highlight sql %} +{% raw %} +CREATE TABLE link ( + ID serial PRIMARY KEY, + url VARCHAR (255) NOT NULL, + name VARCHAR (255) NOT NULL, + description VARCHAR (255), + rel VARCHAR (50) +); + +INSERT INTO link (url, name) +VALUES + ('http://www.google.com','Google'), + ('http://www.azure.microsoft.com','Azure'), + ('http://www.codefresh.io','Codefresh'); +{% endraw %} +{% endhighlight %} + + +To work with the project locally, you need to have `docker`, `golang` and `postgres-client` installed on your workstation first. + +``` +$ docker run -p 5432:5432 postgres:11.5 +``` + +Then open another terminal and load the test data: + +``` +$ psql -h localhost -U postgres < testdata/preload.sql +``` + +A Postgres instance is now running at `localhost:5432` and you can run the tests with: + +``` +$ go test -v +``` + + +## Create a pipeline the preloads test data to PostgreSQL + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: +- prepare +- package +- test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefresh-contrib/preload-db-integration-tests" + revision: "master" + title: "Checking out source code" + git: github + stage: prepare + package_my_app: + stage: package + image: 'golang:1.13' + title: "Compile code" + commands: + - 'go build' + run_my_db_tests: + stage: test + image: 'golang:1.13' + title: "Running integration tests" + commands: + - 'go test -v' + environment: + - POSTGRES_HOST=my_postgresql_db + services: + composition: + my_postgresql_db: + image: postgres:11.5 + ports: + - 5432 + readiness: + timeoutSeconds: 30 + initialDelaySeconds: 10 + periodSeconds: 15 + image: 'postgres:11.5' + commands: + - "pg_isready -h my_postgresql_db -U postgres" + setup: + image: 'postgres:11.5' + commands: + - "psql -h my_postgresql_db -U postgres < /codefresh/volume/preload-db-integration-tests/testdata/preload.sql" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Compiles the code that runs `go build` through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). +1. Runs the tests while launching a [service container]({{site.baseurl}}/docs/pipelines/service-containers/) for an active PostgreSQL instance. Before tests are run, we launch another container with the `psql` executable to load database data. + + +> In this simple example, we use `psql` to preload the database. In a production application you might also use dedicated db tools such as [liquibase](https://hub.docker.com/r/liquibase/liquibase){:target="\_blank"} or [flyway](https://hub.docker.com/r/flyway/flyway){:target="\_blank"} or other command line tools that communicate with your database. + +Notice that we also use the `readiness` property in the testing phase so that we can verify PostgreSQL is ready and listening, before running the tests. The exact order of events is: + +1. Codefresh launches `postgres:11.5` at port 5432. +1. It then launches another container in the same network with `pg_isready` in order to wait for the DB to be up. +1. Then it launches a third container with `psql` to preload data. +1. Finally, it launches a container with `golang:1.13` to run the actual tests. + +All containers are discarded after the pipeline has finished. + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Integration test example]({{site.baseurl}}/docs/example-catalog/ci-examples/run-integration-tests/) +[Integration Tests with Postgres]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-postgres/) +[Integration Tests with MySQL]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mysql/) +[Integration Tests with Mongo]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mongo/) +[Integration Tests with Redis]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-redis/) + + + diff --git a/_docs/example-catalog/ci-examples/publish-jar.md b/_docs/example-catalog/ci-examples/publish-jar.md new file mode 100644 index 00000000..47add369 --- /dev/null +++ b/_docs/example-catalog/ci-examples/publish-jar.md @@ -0,0 +1,116 @@ +--- +title: "Publish Jar" +description: "How to upload a JAR file to Nexus or artifactory" +excerpt: "" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +Even though Codefresh has great support for containers, it can still be used for traditional JAR uploads of libraries or applications that are not dockerized yet. In this example we will compile a JAR and upload it to Nexus. The process is the same for Artifactory or any other package manager. + +For a Java application with Docker, see the [Gradle]({{site.baseurl}}/docs/learn-by-example/java/gradle/){} or + [Maven example]({{site.baseurl}}/docs/learn-by-example/java/spring-boot-2/). + +## The example Java library project + +You can see the example project at [https://github.com/codefresh-contrib/plain-jar-sample-lib](https://github.com/codefresh-contrib/plain-jar-sample-lib). The repository contains a simple Java library built with Maven with the following goals: + +* `mvn package` creates a jar file of the library. It also runs unit tests. +* `mvn upload` uploads the jar to a package manager such as Nexus or Artifactory. + +We use Nexus for this example. To upload the Jar manually first edit the `pom.xml` with the URL of the package manager. The project also includes a [settings.xml](https://github.com/codefresh-contrib/plain-jar-sample-lib/blob/master/settings.xml) with parameterized credential. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/nexus-browser.png" +url="/images/learn-by-example/java/nexus-browser.png" +alt="The Nexus package manager" +caption="The Nexus package manager" +max-width="80%" +%} + +From your workstation you can upload the jar manually with: + + +``` +mvn -s settings.xml -Dserver.password=my-nexus-user -Dserver.username=my-nexus-pass deploy +``` +If you then visit Nexus you should see your JAR file in the snapshots repository. + +## Create a CI pipeline for publishing a JAR file + +[Create a new pipeline]({{site.baseurl}}/docs/pipelines/pipelines/) in Codefresh and define as parameters your Nexus credentials. You could also use [shared configuration]({{site.baseurl}}/docs/pipelines/shared-configuration/) or any other credential mechanism you already use in your other pipelines. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/nexus-credentials.png" +url="/images/learn-by-example/java/nexus-credentials.png" +alt="Parameters for Nexus" +caption="Parameters for Nexus" +max-width="50%" +%} + +Then copy/paste the [Codefresh YAML file](https://github.com/codefresh-contrib/plain-jar-sample-lib/blob/master/codefresh.yml) in the pipeline editor. +Here are the full contents of the file: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/plain-jar-sample-lib' + revision: master + git: github + publish_jar: + title: Upload to nexus + image: 'maven:3.5.2-jdk-8-alpine' + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -s settings.xml -Dserver.password=${{NEXUS_PASS}} -Dserver.username=${{NEXUS_USER}} deploy +{% endraw %} +{% endhighlight %} + +The pipeline starts by checking out the code using a [git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). The next step is a [freestyle]({{site.baseurl}}/docs/pipelines/steps/freestyle/) one and packages the jar file. We also use the [Codefresh volume for caching]({{site.baseurl}}/docs/pipelines/pipeline-caching/#traditional-build-caching). + +You can define the version of Maven/JDK you want to use by picking the appropriate image from Dockerhub, or using any of your own images (even from [external registries]({{site.baseurl}}/docs/docker-registries/external-docker-registries/)). + +Note the use of the two user-defined environment variables passed to `server.password` and `server.username`. You will need to define those yourself. See the documentation on [User Procided Variables]({{site.baseurl}}/docs/pipelines/variables/#user-provided-variables). +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/publish-jar-pipeline.png" +url="/images/learn-by-example/java/publish-jar-pipeline.png" +alt="Publish JAR pipeline" +caption="Publish JAR pipeline" +max-width="100%" +%} + +Once the pipeline has finished you should see the JAR file in the Nexus browser UI. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/nexus-upload.png" +url="/images/learn-by-example/java/nexus-upload.png" +alt="Upload finished" +caption="Upload finished" +max-width="70%" +%} + +You can use the same pipeline for Artifactory or any other compliant Java package registry. + + +## Related articles +[Gradle example]({{site.baseurl}}/docs/example-catalog/ci-examples/java/gradle/) +[Spring boot example]({{site.baseurl}}/docs//example-catalog/ci-examples/spring-boot-2/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) + + + + + + diff --git a/_docs/example-catalog/ci-examples/python.md b/_docs/example-catalog/ci-examples/python.md new file mode 100644 index 00000000..d80cb991 --- /dev/null +++ b/_docs/example-catalog/ci-examples/python.md @@ -0,0 +1,11 @@ +--- +title: "Python" +description: "" +group: example-catalog +redirect_from: + - /docs/python/ +toc: true +--- +This section contains Codefresh examples based on Python. +- [Voting app]({{ site.baseurl }}/docs/learn-by-example/python/voting-app/) +- [Django]({{ site.baseurl }}/docs/learn-by-example/python/django/) diff --git a/_docs/example-catalog/ci-examples/react.md b/_docs/example-catalog/ci-examples/react.md new file mode 100644 index 00000000..0cb0466e --- /dev/null +++ b/_docs/example-catalog/ci-examples/react.md @@ -0,0 +1,172 @@ +--- +title: "React example with Yarn" +description: "Create Docker images for React applications" +group: example-catalog +sub_group: nodejs +toc: true +--- + +Codefresh can work with React projects as with any [Node.js project]({{site.baseurl}}/docs/learn-by-example/nodejs/). + +## The example React project + +You can see the example project at [https://github.com/codefresh-contrib/react-sample-app](https://github.com/codefresh-contrib/react-sample-app){:target:"\_blank"}. The repository contains a React starter project with the following tasks: + +* `yarn test` runs unit tests. +* `yarn start` to start the application locally. +* `yarn build` to create a production deployment. + +Once launched the application presents a simple page at localhost:3000. + +## React and Docker (multi-stage builds) + +The easiest way to build a React.JS application is with [multi-stage builds](https://blog.docker.com/2017/07/multi-stage-builds/){:target:"\_blank"}. With multi-stage builds a Docker build can use one base image for packaging/unit tests and a different one that will hold the runtime of the application. This makes the final image more secure and smaller in size (as it does not contain any development/debugging tools). + +In the case of React, you can use a base image that has Node and all testing utilities, while the final image has your server (e.g. nginx) with the static content and nothing else. + +The example project is actually using multi-stage builds by default. + +Here is the multi-stage Dockerfile: + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM node:8.16 as build-deps +WORKDIR /usr/src/app +COPY package.json yarn.lock ./ +RUN yarn +COPY . ./ +RUN yarn build + +FROM nginx:1.12-alpine +COPY --from=build-deps /usr/src/app/build /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] +{% endraw %} +{% endhighlight %} + +This docker build does the following: + +1. Starts from the Node/Yarn image +1. Copies the dependencies inside the container +1. Copies the source code and creates all static files +1. Discards the Node.js image with all the JavaScript libraries +1. Starts again from the nginx image and copies **static build result** created before + +The resulting is very small, as it contains only packaged/minified files. + +## Create a CI pipeline for React.js (Docker build) + +Creating a CI/CD pipeline for React is very easy, because Codefresh can run any [node image](https://hub.docker.com/_/node/){:target:"\_blank"} that you wish. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/nodejs/react-pipeline-docker.png" +url="/images/learn-by-example/nodejs/react-pipeline-docker.png" +alt="Creating a Docker image for react.js" +caption="Creating a Docker image for react.js" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/gradle-sample-app/blob/master/codefresh.yml){:target:"\_blank"} that creates the Docker image after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/react-sample-app' + revision: master + git: github + MyUnitTests: + title: Unit test + stage: test + image: node:8.16 + commands: + - yarn install + - yarn test + environment: + - CI=true + MyAppDockerImage: + title: Building Docker Image + type: build + stage: build + image_name: react-sample-app + working_directory: ./ + tag: 'with-nginx' + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +This pipeline clones the source code, runs unit tests and finally creates a Docker image. Codefresh is automatically caching +Docker layers (it uses the Docker image of a previous build as a cache for the next) and therefore builds will become +much faster after the first one finishes. + + +## Building a React.Js application without Docker + +If your application is not dockerized yet, you can still create a pipeline that runs any command that you would run locally. You can also choose which Node version is used for each step of the pipeline by defining a different docker image for each step. + + +{% include image.html +lightbox="true" +file="/images/learn-by-example/nodejs/react-pipeline-build.png" +url="/images/learn-by-example/nodejs/react-pipeline-build.png" +alt="Building a Reach.js application" +caption="Building a Reach.js application" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/react-sample-app/blob/master/codefresh-only-build.yml){:target:"\_blank"} that creates a production deployment of all files. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/react-sample-app' + revision: master + git: github + MyUnitTests: + title: Unit test + stage: test + image: node:11.0 + commands: + - yarn install + - yarn test + environment: + - CI=true + MyReactBuild: + title: Packaging application + stage: build + image: node:8.16 + commands: + - yarn build +{% endraw %} +{% endhighlight %} + +Notice that for demonstration purposes we uses node 11 for the tests, and node 8 for the packaging. Normally you should use the same version of node/Yarn for all your steps, but Codefresh pipelines are flexible on version of tools. + +Even when you don't create a Docker image, Codefresh still caches your workspace volume. This means that `node_modules` are downloaded only once. All subsequent builds will be much faster. + +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/ruby.md b/_docs/example-catalog/ci-examples/ruby.md new file mode 100644 index 00000000..0758068e --- /dev/null +++ b/_docs/example-catalog/ci-examples/ruby.md @@ -0,0 +1,183 @@ +--- +title: "Ruby" +description: "How to build a Ruby On Rails project in Codefresh" +group: example-catalog +sub_group: ci-examples +toc: true +--- +Ruby on Rails is a very popular development framework that combines ease of use and a great amount of programming languages. In Codefresh, ROR projects behave like any other web application. You can easily build them, run [integration tests]({{site.baseurl}}/docs/testing/integration-tests/) and launch them on [demo environments]({{site.baseurl}}/docs/getting-started/on-demand-environments/). + +The example application is located at [https://github.com/codefresh-contrib/ruby-on-rails-sample-app](https://github.com/codefresh-contrib/ruby-on-rails-sample-app){:target:"\_blank"}. + + + +## Dockerize your Ruby on Rails project + +The first step should be to write a [Dockerfile](https://github.com/codefresh-contrib/ruby-on-rails-sample-app/blob/master/Dockerfile){:target:"\_blank"} for your Rails project. As an example we will use the following: + + + +`Dockerfile` +{% highlight docker %} +FROM ruby:2.3.1-slim + +RUN apt-get update && \ + apt-get install -y build-essential libcurl4-openssl-dev libxml2-dev libsqlite3-dev libpq-dev nodejs postgresql-client sqlite3 --no-install-recommends && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# throw errors if Gemfile has been modified since Gemfile.lock +RUN bundle config --global frozen 1 + +ENV APP_PATH /usr/src/app + +RUN mkdir -p $APP_PATH + +COPY Gemfile $APP_PATH +COPY Gemfile.lock $APP_PATH + +WORKDIR $APP_PATH + +RUN bundle install + +COPY . $APP_PATH + +ENV RAILS_ENV development + +RUN bin/rake db:migrate + +RUN bin/rake assets:precompile + +EXPOSE 3000 + +CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"] + +{% endhighlight %} + +Notice the order of commands and especially the fact that we copy the `Gemfile` on its own first, so that we take advantage of the Docker layer caching. + +>Codefresh also supports multi-stage docker builds. You can use one parent docker image for preparing your gem modules and another one for actually deployment the application. + +Once you have a Dockerfile, [creating a pipeline in Codefresh]({{site.baseurl}}/docs/pipelines/pipelines/) is very easy either from the GUI or with the yaml syntax. + +## Simple pipeline with Docker image and unit tests + +A very simple pipeline is one that has only two steps: + +1. Build the docker image +1. Run the tests inside the docker image that was just build + +Here is the example [codefresh.yml](https://github.com/codefresh-contrib/ruby-on-rails-sample-app/blob/master/codefresh.yml){:target:"\_blank"} file. + + +`codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefresh-contrib/ruby-on-rails-sample-app' + revision: master + git: github + BuildingDockerImage: + title: Building Docker Image + type: build + image_name: ruby-on-rails-sample-app + working_directory: ./ + tag: '${{CF_BRANCH_TAG_NORMALIZED}}' + dockerfile: Dockerfile + RunningUnitTests: + title: Running Unit Tests + image: '${{BuildingDockerImage}}' + commands: + - rails db:migrate + - rails test +{% endraw %} +{% endhighlight %} + +The first step is a [build step]({{site.baseurl}}/docs/pipelines/steps/build/) named `BuildingDockerImage`. It reads the Dockerfile and creates a Docker image out of it. The second step is a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) called `RunningUnitTests`. It uses the image mentioned in the first step and executes custom commands inside it. + + +## Inspecting your Docker image + +You can see all your latest [Docker artifacts]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images) by selecting *Images* from the left sidebar. + + +{% include image.html +lightbox="true" +file="/images/learn-by-example/ruby/images.png" +url="/images/learn-by-example/ruby/images.png" +alt="Codefresh built-in Registry" +caption="Codefresh built-in Registry" +max-width="80%" +%} + +You can click on the image and get extra details. One of the tabs contains a visual explanation of the layers contained in the image. This view can be helpful when you are trying to make your Docker images smaller (which is a recommended practice) + +{% include image.html +lightbox="true" +file="/images/learn-by-example/ruby/layers.png" +url="/images/learn-by-example/ruby/layers.png" +alt="Ruby On Rails image filesystem layers" +caption="Ruby On Rails Image filesystem layers" +max-width="70%" +%} + +In Codefresh you can also use any other [external registry]({{site.baseurl}}/docs/docker-registries/external-docker-registries/) such as Dockerhub, Azure, Google etc. + + +## Previewing the Ruby on Rails application in a Demo environment + +Codefresh has the unique capability of launching Docker images within its infrastructure for a quick demonstration (e.g. to customers and colleagues). + +In the example Rails repository, the default development "environment" is self-contained (it uses sqlite for a database). This makes it very easy to preview. + +Launch the environment by clicking at the rocket icon in the images view. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/ruby/launch.png" +url="/images/learn-by-example/ruby/launch.png" +alt="Launching a demo environment" +caption="Launching a demo environment" +max-width="50%" +%} + +A new build will start. Once it is complete your new environment will be created. You can inspect it by clicking in the *Compositions* menu on the left sidebar and then clicking *Running Compositions*. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/ruby/environment.png" +url="/images/learn-by-example/ruby/environment.png" +alt="Inspecting a demo environment" +caption="Inspecting a demo environment" +max-width="70%" +%} + +Click the *Open App* icon on the right and your browser will open a new tab with the environment. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/ruby/preview.png" +url="/images/learn-by-example/ruby/preview.png" +alt="Previewing a demo environment" +caption="Previewing a demo environment" +max-width="50%" +%} + + +You can share this link with other people in your team. + +>Demo environments are not intended for production purposes. Use them only for quick feedback. They also shutdown automatically after a period of inactivity. + + + +## Related articles +[Introduction to Pipelines]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[On demand environments]({{site.baseurl}}/docs/getting-started/on-demand-environments/) +[Integration tests]({{site.baseurl}}/docs/testing/integration-tests/) + + + diff --git a/_docs/example-catalog/ci-examples/run-integration-tests.md b/_docs/example-catalog/ci-examples/run-integration-tests.md new file mode 100644 index 00000000..9bbbbdc0 --- /dev/null +++ b/_docs/example-catalog/ci-examples/run-integration-tests.md @@ -0,0 +1,102 @@ +--- +title: "Run integration tests" +description: "Launch separate App and test containers" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/run-integration-tests/ +toc: true +--- +In this example, we will see a Java/Tomcat project using JUnit for unit tests and Spock for integration tests. For the integration test phase, we will launch both the application and the tests in order to run the integration tests against a real web instance (without mocking). + +{% include image.html +lightbox="true" +file="/images/examples/integration-tests/integration-tests.png" +url="/images/examples/integration-tests/integration-tests.png" +alt="Integration tests with Codefresh" +caption="Integration tests with Codefresh" +max-width="90%" +%} + +The integration tests will look at the application instance at `app:8080`. + +## Example Java/Tomcat/Spring project + +You can see the example project at [https://github.com/codefreshdemo/cf-example-integration-tests](https://github.com/codefreshdemo/cf-example-integration-tests){:target:"\_blank"}. The repository contains the Java source code and some integration tests. + +You can play with it locally by using Docker compose to launch both the application and the tests. + +## Create a pipeline with separate integration tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - prepare + - build + - test +steps: + main_clone: + type: "git-clone" + description: "Cloning main repository..." + repo: "codefreshdemo/cf-example-integration-tests" + revision: "master" + git: github + stage: prepare + build_app_image: + title: "Building Docker Image" + type: "build" + image_name: "my-spring-app" + tag: "master" + dockerfile: "Dockerfile" + stage: build + build_test_image: + title: "Building Docker Test Image" + type: "build" + image_name: "my-junit-spock-tests" + tag: "master" + dockerfile: "Dockerfile.testing" + stage: test + run_integration_tests: + title: "Running integration tests" + stage: test + image: '${{build_test_image}}' + commands: + # Tomcat is certainly up at this point + - mvn verify -Dserver.host=app + services: + composition: + app: + image: '${{build_app_image}}' + ports: + - 8080 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: byrnedo/alpine-curl + commands: + - "curl http://app:8080/wizard/" + +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Builds a Docker image with only Tomcat and the application WAR through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). +1. Builds a helper image that contains the source code and Maven to run integration tests. +1. Runs the `mvn verify` command in the helper image while launching a [service container]({{site.baseurl}}/docs/pipelines/service-containers/) with the Tomcat/Java image. + +Notice that we also use the `readiness` property in the testing phase to verify that the application +is actually up, before running the tests. + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Service Containers]({{site.baseurl}}/docs/pipelines/service-containers/) +[Integration Tests with Postgres]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-postgres/) +[Integration Tests with MySQL]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mysql/) +[Integration Tests with Mongo]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mongo/) +[Integration Tests with Redis]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-redis/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/run-unit-tests.md b/_docs/example-catalog/ci-examples/run-unit-tests.md new file mode 100644 index 00000000..360da67e --- /dev/null +++ b/_docs/example-catalog/ci-examples/run-unit-tests.md @@ -0,0 +1,106 @@ +--- +title: "Run unit tests" +description: "Running unit tests in Codefresh pipelines" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/run-unit-tests/ +toc: true +--- + +As explained in [unit tests]({{site.baseurl}}/docs/testing/unit-tests/), Codefresh supports several ways of running unit tests. The most common scenarios use an existing Docker Hub image (common with compiled languages such as Java and Go), or the application image itself (common with languages such as JavaScript/Python/Ruby/PHP). + +In this example, we will see both ways using two different applications in a single pipeline. + +{% include image.html +lightbox="true" +file="/images/examples/unit-tests/unit-tests-pipeline.png" +url="/images/examples/unit-tests/unit-tests-pipeline.png" +alt="Unit tests with Codefresh" +caption="Unit tests with Codefresh" +max-width="90%" +%} + +In the first case, we run unit tests *before* creating the application docker image. In the second case, we run the unit tests +*inside* the application Docker image. + +## Example Python/Go project + +You can see the example project at [https://github.com/codefreshdemo/cf-example-unit-test](https://github.com/codefreshdemo/cf-example-unit-test){:target="\_blank"}. The repository contains two applications (Python and Go) with their respective unit tests. + +You can play with it locally by using Docker commands to package the applications. + +## Create a pipeline with unit tests + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - 'Microservice A' + - 'Microservice B' +steps: + main_clone: + title: Cloning main repository... + type: git-clone + repo: 'codefreshdemo/cf-example-unit-test' + revision: 'master' + git: github + stage: prepare + run_my_tests_before_build: + title: Running Unit tests directly + stage: 'Microservice A' + image: golang:1.12 + working_directory: './golang-app-A' + commands: + - go test -v + build_after_my_tests: + title: Building Go Docker Image + type: build + stage: 'Microservice A' + image_name: my-go-image + working_directory: './golang-app-A' + tag: 'master' + dockerfile: Dockerfile + build_before_my_tests: + title: Building Python Docker Image + type: build + stage: 'Microservice B' + image_name: my-python-image + working_directory: './python-app-B' + tag: 'master' + dockerfile: Dockerfile + run_my_tests_inside_image: + title: Running Unit tests inside App image + stage: 'Microservice B' + image: ${{build_before_my_tests}} + working_directory: '/app' + commands: + - python setup.py test +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Runs unit test for the GO application using the Dockerhub image `golang:1.12`. +1. Builds the Docker image for the Go application through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). +1. Builds the Docker image for the Python application. +1. Runs unit tests for the Python application using as runtime context the application image that was just created. + + +In the second case, the tests run in the context of `build_before_my_tests` which is the name of the step that creates the Docker image for Python. Read more about [context variables]({{site.baseurl}}/docs/pipelines/variables/#context-related-variables). + +We generally recommend the first approach, so that your production Docker image does not contain any unit testing libraries or frameworks, but there is no right or wrong choice regarding the way you run unit tests. + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Unit tests]({{site.baseurl}}/docs/testing/unit-tests/) +[Integration test example]({{site.baseurl}}/docs/example-catalog/ci-examples/run-integration-tests/) +[Service Containers]({{site.baseurl}}/docs/pipelines/service-containers/) +[Freestyle step]({{site.baseurl}}/docs/pipelines/steps/) + + diff --git a/_docs/example-catalog/ci-examples/rust.md b/_docs/example-catalog/ci-examples/rust.md new file mode 100644 index 00000000..1efd443b --- /dev/null +++ b/_docs/example-catalog/ci-examples/rust.md @@ -0,0 +1,84 @@ +--- +title: "Compile and test a Rust application" +description: "Using Codefresh pipelines" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +Codefresh can work with any Rust application very easily as both `rustc` and `cargo` are already offered in Dockerhub. + +## The example Rust project + +You can see the example project at [https://github.com/codefresh-contrib/rust-sample-app](https://github.com/codefresh-contrib/rust-sample-app){:target="\_blank"}. The repository contains a Rust starter project with a dummy unit test. + +* `cargo build` compiles the code. +* `cargo test` runs unit tests +* `cargo clean` removes artifacts and binaries. + + +## Create a CI pipeline for Rust applications + +Creating a CI/CD pipeline for Rust is very easy, because Codefresh can run any [Rust image](https://hub.docker.com/_/rust){:target="\_blank"} that you wish. Rust docker images already contain the `cargo` package manager. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/rust/rust-pipeline.png" +url="/images/learn-by-example/rust/rust-pipeline.png" +alt="Compiling a Rust application in a pipeline" +caption="Compiling a Rust application in a pipeline" +max-width="80%" +%} + +Here is the [full pipeline](https://github.com/codefresh-contrib/rust-sample-app/blob/master/codefresh.yml){:target="\_blank"} that compiles the application after checking out the code. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - "clone" + - "build" + - "test" +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "codefresh-contrib/rust-sample-app" + revision: "master" + stage: "clone" + compile: + title: "Building Code" + type: "freestyle" + image: "rust:1.44-stretch" + working_directory: "${{clone}}" + environment: + - CARGO_HOME=/codefresh/volume/cargo + commands: + - "cargo build" + stage: "build" + test: + title: "Running tests" + type: "freestyle" + image: "rust:1.44-stretch" + working_directory: "${{clone}}" + environment: + - CARGO_HOME=/codefresh/volume/cargo + commands: + - "cargo test" + stage: "test" + +{% endraw %} +{% endhighlight %} + +This pipeline clones the source code, compiles the code and runs unit tests. In all cases we use the public Docker image of Rust that also contains `cargo`. + +We also pass the `CARGO_HOME` environment variable to place the Cargo cache on the [shared Codefresh volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps). See the [Caching documentation]({{site.baseurl}}/docs/pipelines/pipeline-caching/#traditional-build-caching) for more details. + + + +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) \ No newline at end of file diff --git a/_docs/example-catalog/ci-examples/scala-hello-world.md b/_docs/example-catalog/ci-examples/scala-hello-world.md new file mode 100644 index 00000000..66681d4a --- /dev/null +++ b/_docs/example-catalog/ci-examples/scala-hello-world.md @@ -0,0 +1,184 @@ +--- +title: "Scala: Hello World" +description: "Use Scala and Codefresh to clone, package, and build a Docker image" +excerpt: "" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/scala-hello-world/ +toc: true +--- + +So, you’ve decided to try Codefresh? Welcome on board! + +We’ll help you get up to speed with basic functionality such as: compiling, building Docker images and launching. + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) + +## The Example Scala Application + +This project uses `Scala` to build an application which will eventually become a distributable Docker image. + +You can find the example application on [GitHub](https://github.com/codefresh-contrib/scala-hello-world-app){:target="\_blank"}. + +There are two pipeline examples provided in this tutorial: + +- Multi-stage Docker build +- Single stage Docker Build + +## Example Pipeline #1: Single stage Docker Build + +This example uses a single stage Docker build. The pipeline will have three stages: + +- A stage for cloning +- A stage for packaging +- A stage for building + +{% include image.html +lightbox="true" +file="/images/examples/scala/single-stage-pipeline.png" +url="/images/examples/scala/single-stage-pipeline.png" +alt="Codefresh UI pipeline view" +caption="Codefresh UI pipeline view" +max-width="100%" +%} + +Here is the Dockerfile used for this example: + +`Dockerfile-single-stage` +```shell +FROM openjdk:8-jre-alpine3.9 + +COPY . . + +CMD ["java", "-cp", "target/scala-2.12/*.jar:scala-library-2.12.2.jar", "HelloWorld"] +``` + +And here is the pipeline. You can copy and paste it in the inline YAML editor in the UI: + + `codefresh-single-stage.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" + +stages: + - clone + - package + - build + +steps: + clone: + title: Cloning repository... + type: git-clone + stage: clone + arguments: + repo: codefresh-contrib/scala-hello-world-app + revision: master + package: + title: Packaging application... + type: freestyle + stage: package + working_directory: ./scala-hello-world-app + arguments: + image: hseeberger/scala-sbt:11.0.6_1.3.9_2.13.1 + commands: + - sbt -Dsbt.ivy.home=/codefresh/volume/ivy_cache clean compile package + - cp /codefresh/volume/ivy_cache/cache/org.scala-lang/scala-library/jars/scala-library-2.12.2.jar . + build_image: + title: Building Docker image... + type: build + working_directory: ${{clone}} + stage: build + arguments: + image_name: codefresh/scala-sample-app + tag: 1.0.0 + dockerfile: Dockerfile-single-stage +{% endraw %} +{% endhighlight %} + +The above pipeline does the following: + +1. A [git-clone]({{site.baseurl}}/docs/pipelines/steps/git-clone/) step that clones the main repository +2. A [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) that uses an SBT image that packages the application (note how `sbt.ivy.home` is set to an arbitrarily named directory that is part of the codefresh volume). This ensures we cache dependencies to [speed up builds]({{site.baseurl}}/docs/example-catalog/ci-examples/spring-boot-2/#caching-the-maven-dependencies), similar to Maven. +3. The last step, `build_image`, is a [build step]({{site.baseurl}}/docs/pipelines/steps/build/) that builds a Docker image using the Dockerfile provided in the repository. + +## Example Pipeline #2: Multi-stage Docker Build + +This example uses a multi stage Docker build. The pipeline will have only two stages this time, as packaging of the app is handled in the Dockerfile itself: + +- A stage for cloning +- A stage for building + +{% include image.html +lightbox="true" +file="/images/examples/scala/multi-stage-pipeline.png" +url="/images/examples/scala/multi-stage-pipeline.png" +alt="Codefresh UI pipeline view" +caption="Codefresh UI pipeline view" +max-width="100%" +%} + +Here, you will find the multi-stage Dockerfile, copying over only the jars we need: + +`Dockerfile-multi-stage` + +```shell +# first stage + +FROM hseeberger/scala-sbt:11.0.6_1.3.9_2.13.1 AS build + +COPY ./ ./ + +RUN sbt compile clean package + +# second stage + +FROM openjdk:8-jre-alpine3.9 + +COPY --from=build /root/target/scala-2.12/*.jar /scala-hello-world-sample-app.jar +COPY --from=build /root/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.2.jar /scala-library-2.12.2.jar + +CMD ["java", "-cp", "scala-hello-world-sample-app.jar:scala-library-2.12.2.jar", "HelloWorld"] +``` +Here is the pipeline, you can copy and paste it into the inline YAML editor: + +`codefresh-multi-stage.yml` + +{% highlight yaml %} +{% raw %} +version: "1.0" + +stages: + - clone + - build + +steps: + clone: + title: Cloning repository... + type: git-clone + stage: clone + arguments: + repo: codefresh-contrib/scala-hello-world-app + revision: master + build_image: + title: Building Docker image... + type: build + working_directory: ${{clone}} + stage: build + arguments: + image_name: codefresh/scala-hello-world-app + tag: 1.0.0 + dockerfile: Dockerfile +{% endraw %} +{% endhighlight %} + +1. A [git-clone]({{site.baseurl}}/docs/pipelines/steps/git-clone/) step that clones the main repository +2. A [build step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) that builds our code into a Docker image using the Dockerfile present in the repository + + +## Related articles +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Freestyle Step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) + diff --git a/_docs/example-catalog/ci-examples/scala.md b/_docs/example-catalog/ci-examples/scala.md new file mode 100644 index 00000000..7415259d --- /dev/null +++ b/_docs/example-catalog/ci-examples/scala.md @@ -0,0 +1,10 @@ +--- +title: "Scala" +description: "" +group: example-catalog +redirect_from: + - /docs/scala/ +toc: true +--- +This section contains Codefresh examples based on Scala. +- [Scala: Hello World]({{site.baseurl}}/docs/learn-by-example/scala/scala-hello-world/) diff --git a/_docs/example-catalog/ci-examples/sending-the-notification-to-jira.md b/_docs/example-catalog/ci-examples/sending-the-notification-to-jira.md new file mode 100644 index 00000000..2d024509 --- /dev/null +++ b/_docs/example-catalog/ci-examples/sending-the-notification-to-jira.md @@ -0,0 +1,88 @@ +--- +title: "Send notification to Jira" +description: "" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +The plugin marketplace offers several freestyle steps for your Codefresh pipeline. + +One of those steps is the [Jira Issue Manager](https://codefresh.io/steps/step/jira-issue-manager){:target:"\_blank"}. + +## Prerequisites +* [Codefresh pipeline]({{site.baseurl}}/docs/getting-started/create-a-basic-pipeline/) +* [Jira account](https://www.atlassian.com/software/jira){:target:"\_blank"} + +## Example +This documentation uses the following [example](https://github.com/codefresh-contrib/jira-demo-app){:target:"\_blank"}. You can either use the example provided to try out the Jira integration or follow along with your own application. + +1. You need an issue in your Jira account that you want to link to your Codefresh pipeline. If you do not have one yet, please create an issue. (Note that the project type and who is creating the issue etc. does not matter.) Alternatively, you can also create an issue first with the Jira step. However, this is not explained in this example. + +2. Next, add the following step to your Codefresh pipeline. In case you are using the example, the [codefresh.yml](https://github.com/codefresh-contrib/jira-demo-app/blob/master/codefresh.yml){:target:"\_blank"} file is already added. + +{% highlight yaml %} + JiraCommentCreate: + title: "Add Jira Comment" + type: "jira-issue-manager" + stage: "deploy" + arguments: + JIRA_BASE_URL: '${{JIRA_BASE_URL}}' + JIRA_USERNAME: '${{JIRA_USERNAME}}' + JIRA_API_KEY: '${{JIRA_API_KEY}}' + JIRA_ISSUE_SOURCE_FIELD: '${{JIRA_ISSUE_SOURCE_FIELD}}' + ACTION: "comment_create" + COMMENT_BODY: "Build number ${{CF_BUILD_URL}} finished in Codefresh" +{% endhighlight yaml %} + +Let's look in detail at this step. +- Everything up to the arguments is similar to other Codefresh steps. + +These arguments are required to use the step: +- `JIRA_BASE_URL`: This is the url of your organisation e.g. 'https://company-name.atlassian.net' +- `JIRA_USERNAME`: This is usually the e-mail that you are logged in with at Jira +- `JIRA_API_KEY`: Note that you will have to create this key. The official [Atlassian documentation](https://confluence.atlassian.com/cloud/api-tokens-938839638.html){:target:"\_blank"} details how it can be created. + +Then we added these arguments for our specific step: +- `JIRA_ISSUE_SOURCE_FIELD`: This is the tag that identifies your issue, for example, `MKTG-102` +- Within the comment, we use a [Codefresh native variable]({{site.baseurl}}/docs/docs/pipelines/variables/) `CF_BUILD_URL`, which references your pipeline build and allows you to search for your pipeline. + +All variables use the Codefresh-specific variable notation ${% raw %}`{{MY_VARIABLE_EXAMPLE}}`{% endraw %}`. + +Since it is a new stage in your Codefresh pipeline, you want to add it at the top to your stages, e.g.: + +{% highlight yaml %} + stages: + - "clone" + - "build" + - "JiraCommentCreate" +{% endhighlight yaml %} + +Note that you can [provide the variables]({{site.baseurl}}/docs/pipelines/shared-configuration/) needed for the Jira step directly in the shared configuration. The benefits are: +* You do not have to post sensitive information, such as the API key, directly in the codefresh.yml. +* If you use the same step across multiple pipelines, you don't have to copy-paste the same variables. + +Once you run the pipeline, you should be able to see the following output or similar: + +{% include image.html +lightbox="true" +file="/images/integrations/jira/codefreshpipeline.png" +url="/images/integrations/jira/codefreshpipeline.png" +alt="Pipeline with Jira integration" +max-width="80%" +%} + +And the comment, including the URL to the pipeline, should be added to your Jira issue: + +{% include image.html +lightbox="true" +file="/images/integrations/jira/jira-comment.png" +url="/images/integrations/jira/jira-comment.png" +alt="Comment in Jira" +max-width="80%" +%} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/ci-examples/) +[Sending notifications to Slack]({{site.baseurl}}/docs/example-catalog/ci-examples/sending-the-notification-to-slack/) +[Create a pipeline]({{site.baseurl}}/docs/pipelines/pipelines/) diff --git a/_docs/example-catalog/ci-examples/sending-the-notification-to-slack.md b/_docs/example-catalog/ci-examples/sending-the-notification-to-slack.md new file mode 100644 index 00000000..1af32946 --- /dev/null +++ b/_docs/example-catalog/ci-examples/sending-the-notification-to-slack.md @@ -0,0 +1,44 @@ +--- +title: "Send notification to Slack" +description: "Connect your Codefresh pipelines to Slack" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/sending-the-notification-to-slack/ +toc: true +--- + +There are many ways to integrate Slack with Codefresh: + +1. Use the [global slack integration]({{site.baseurl}}/docs/integrations/notifications/slack-integration/) +1. Use individual pipeline plugins such [slack-message-sender](https://codefresh.io/steps/step/slack-message-sender){:target:"\_blank"} and [slack-notifier](https://codefresh.io/steps/step/slack-notifier){:target:"\_blank"} +1. Use simple POST requests with Curl, as explained in this article + +## Custom webhook to Slack + +Use a container image with a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/) such as `byrnedo/alpine-curl` to send a notification to a Slack channel. + +{:start="1"} +1. Get the {% raw %}```${{SLACK_WEB_URL}}```{% endraw %} and put it in the Environment Variables or use [shared configuration]({{site.baseurl}}/docs/pipelines/shared-configuration/). + + > To integrate with Slack, see [https://api.slack.com/incoming-webhooks](https://api.slack.com/incoming-webhooks){:target="_blank"}. + +{:start="2"} +2. Add the following step to your `codefresh.yml`: + + `slack step` +{% highlight yaml %} +slack_notify: + image: byrnedo/alpine-curl # curlimages/curl, or any other curl image + commands: + - curl -X POST --data-urlencode 'payload={"text":"Test slack integration via yaml"}' {% raw %}${{SLACK_WEB_URL}}{% endraw %} +{% endhighlight %} + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[Global Slack Integration]({{site.baseurl}}/docs/integrations/notifications/slack-integration/) +[Advanced Workflows]({{site.baseurl}}/docs/pipelines/advanced-workflows/) +[Hooks in pipelines]({{site.baseurl}}/docs/pipelines/hooks/) +[Shared Configuration]({{site.baseurl}}/docs/pipelines/shared-configuration/) + diff --git a/_docs/example-catalog/ci-examples/shared-volumes-between-builds.md b/_docs/example-catalog/ci-examples/shared-volumes-between-builds.md new file mode 100644 index 00000000..99db466d --- /dev/null +++ b/_docs/example-catalog/ci-examples/shared-volumes-between-builds.md @@ -0,0 +1,115 @@ +--- +title: "Share data between pipeline steps" +description: "How to cache folders between steps and builds" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/shared-volumes-between-builds/ +toc: true +--- + +Codefresh creates a [shared volume]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) in each pipeline that is automatically shared with all freestyle steps. + +{% include +image.html +lightbox="true" +file="/images/pipeline/introduction/codefresh-volume.png" +url="/images/pipeline/introduction/codefresh-volume.png" +alt="Codefresh volume" +caption="All steps share the same volume" +max-width="90%" +%} + +This volume exists at `/codefresh/volume` by default. Simply copy files there to have them available to all Codefresh steps (as well as subsequent builds of the same pipeline). + +>The [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/) deletes any files **not** specified in `.gitignore`. To cache a folder that exists in your project directory (such as `node_modules`), you must also add it to `.gitignore` + +## Using the shared volume + +You can see the example project at [https://github.com/codefreshdemo/cf-example-shared-volumes-between-builds](https://github.com/codefreshdemo/cf-example-shared-volumes-between-builds){:target="\_blank"}. The repository contains a simple application, a Dockerfile, and an example pipeline that saves/reads a dummy file to the Codefresh volume. + + +Here is the whole pipeline: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" +stages: + - "clone" + - "build" + - "shared-volume" + +steps: + clone: + title: "Cloning repository" + type: "git-clone" + repo: "codefreshdemo/cf-example-shared-volumes-between-builds" + revision: "master" + stage: "clone" + + build_image: + title: "Building image" + type: "build" + image_name: "sample-app" + working_directory: "${{clone}}" + tag: "demo" + dockerfile: "Dockerfile" + stage: "build" + + copy_to_shared_volume: + title: "Copy file to shared volume" + type: "freestyle" + image: alpine:3.9 + working_directory: "${{clone}}" + commands: + - ls -l /codefresh/volume/ + - cp ./artifact/artifact.example /codefresh/volume/artifact.example + stage: "shared-volume" + + list_shared_volume: + title: "List shared volume files" + type: "freestyle" + image: alpine:3.9 + working_directory: "${{clone}}" + commands: + - pwd + - ls -l /codefresh/volume + stage: "shared-volume" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +1. Builds a docker image through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). +1. Copies the file `artifact.example` to the volume through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). +1. Reads the contents of the volume through a different freestyle step. + +If you run the pipeline, you will see the file contents in the fourth step: + +{% include +image.html +lightbox="true" +file="/images/examples/shared-workspace/volume-list.png" +url="/images/examples/shared-workspace/volume-list.png" +alt="Listing volume contents" +caption="Listing volume contents" +max-width="80%" +%} + + +If you run the pipeline a second time, you will see the dummy file in all steps, as the volume is automatically cached for subsequent builds as well. + + +## Caching build dependencies and Docker layers + +Read more about caching build dependencies in [caching in pipelines]({{site.baseurl}}/docs/pipelines/pipeline-caching/), and in this [blog post](https://codefresh.io/blog/caching-build-dependencies-codefresh-volumes/){:target:"\_blank"}. + + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/examples/#ci-examples) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Freestyle steps]({{site.baseurl}}/docs/pipelines/steps/freestyle) diff --git a/_docs/example-catalog/ci-examples/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md b/_docs/example-catalog/ci-examples/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md new file mode 100644 index 00000000..d99b74cf --- /dev/null +++ b/_docs/example-catalog/ci-examples/shared-volumes-of-service-from-composition-step-for-other-yml-steps.md @@ -0,0 +1,45 @@ +--- +title: "Share service volumes in composition steps" +description: "How to share data in compositions" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/shared-volumes-of-service-from-composition-step-for-other-yml-steps/ +toc: true +--- +Using this repository, we'll help you get up to speed with basic functionality such as building Docker images and using the shared volumes. + +This project uses Node Js to build an application which will eventually become a distributable Docker image. +To share volumes of service in composition step for other yml steps you can use the variable {% raw %}```${{CF_VOLUME_NAME}}```{% endraw %}. It will refer to the volume that was generated for the specific flow. Can be used in conjunction with a composition to provide access to your cloned repository. + +>Read more about caching build dependencies our [blog](https://codefresh.io/blog/caching-build-dependencies-codefresh-volumes/){:target="_blank"}. + +## Looking around +In the root of this repository you'll find a file named `codefresh.yml`, this is our build descriptor that describes the different steps that comprise our process. Let's quickly review the contents of this file: + + `codefresh.yml` +{% highlight yaml %} +step_file_generation: + type: composition + composition: + version: '2' + services: + service1: + volumes: + - {% raw %}${{CF_VOLUME_NAME}}{% endraw %}:/codefresh/volume + image: {% raw %}${{build_step}}{% endraw %} + command: bash -c "echo hello > /codefresh/volume/myfile.txt" + composition_candidates: + test: + image: {% raw %}${{build_step}}{% endraw %} + command: echo hello +{% endhighlight %} + +>Example + Just head over to the example [**repository**](https://github.com/codefreshdemo/cf-example-shared-volumes-composition-step){:target="_blank"} in GitHub, and follow the instructions there. + +The way the volume is shared between builds is that upon build completion we create an image of the volume state to be used in the next builds. If you run 2 builds in parallel from the same pipeline and at the same time, each will use the same last volume image, but it’ll run separately on both. The volume image you’ll get upon completion is the state of the build that finished last. + + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/ci-examples/) diff --git a/_docs/example-catalog/ci-examples/spring-boot-2.md b/_docs/example-catalog/ci-examples/spring-boot-2.md new file mode 100644 index 00000000..37230e51 --- /dev/null +++ b/_docs/example-catalog/ci-examples/spring-boot-2.md @@ -0,0 +1,252 @@ +--- +title: "Spring Boot 2/Maven" +description: "Create Docker images for Spring/Maven" +excerpt: "" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/spring-boot-2/ + - /docs/java/spring-boot-2/ +toc: true +--- + +Spring Boot is quickly becoming a very popular choice for building Java back-end applications. Compared to traditional application servers,it is a bit different since it includes a servlet container in the final JAR file allowing +for self-contained Java Archives (JAR files). + +Codefresh can easily handle Spring Boot applications that are dockerized either in the traditional way or using multi-stage builds. + +## The example Java project + +You can see the example project at [https://github.com/codefresh-contrib/spring-boot-2-sample-app](https://github.com/codefresh-contrib/spring-boot-2-sample-app){:target="\_blank"}. The repository contains a Spring Boot 2 project built with Maven with the following goals: + +* `mvn package` creates a jar file that can be run on its own (exposes port 8080). It also runs unit tests. +* `mvn verify` runs integration tests as well. The application is launched locally as part of the Maven lifecycle. + +Once launched the application presents a simple message at localhost:8080 and also at the various `/actuator/health` endpoints. You can use the standard `spring-boot:run` command to run it locally (without Docker). + +## Spring Boot 2 and Docker (package only) + +A Dockerfile is also provided at the same repository. It uses the base JRE image and just copies the JAR file inside the container. + + `Dockerfile.only-package` +{% highlight docker %} +{% raw %} +FROM java:8-jre-alpine + +EXPOSE 8080 + +RUN mkdir /app +COPY target/*.jar /app/spring-boot-application.jar + +ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/spring-boot-application.jar"] + +HEALTHCHECK --interval=1m --timeout=3s CMD wget -q -T 3 -s http://localhost:8080/actuator/health/ || exit 1 + +{% endraw %} +{% endhighlight %} + +This means that _before_ building the Docker image, the compilation step (`mvn package`) is expected to be finished already. Therefore, in the `codefresh.yml` file we need at least two steps. The first one should prepare the JAR file and the second +one should create the Docker image. + +### Create a CI pipeline for Spring + +The repository also contains a premade [Codefresh YAML file]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) that you can use as a starting point in your own Spring Boot 2 projects. + +Here are the full contents of the file. + + `codefresh-package-only.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build + - 'integration test' +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/spring-boot-2-sample-app' + revision: master + git: github + run_unit_tests: + title: Compile/Unit test + stage: test + image: 'maven:3.5.2-jdk-8-alpine' + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository package + build_app_image: + title: Building Docker Image + type: build + stage: build + image_name: spring-boot-2-sample-app + working_directory: ./ + tag: 'non-multi-stage' + dockerfile: Dockerfile.only-package + run_integration_tests: + title: Integration test + stage: 'integration test' + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository verify -Dserver.host=http://my-spring-app + services: + composition: + my-spring-app: + image: '${{build_app_image}}' + ports: + - 8080 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: byrnedo/alpine-curl + commands: + - "curl http://my-spring-app:8080/" +{% endraw %} +{% endhighlight %} + +The pipeline starts by checking out the code using a [git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). The next step is a [freestyle]({{site.baseurl}}/docs/pipelines/steps/freestyle/) one and packages the jar file. Next we have a [build step]({{site.baseurl}}/docs/pipelines/steps/build/) that creates the docker image. Finally we have another freestyle +step that uses [service containers]({{site.baseurl}}/docs/pipelines/service-containers/) to run integration tests. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/spring-boot-steps.png" +url="/images/learn-by-example/java/spring-boot-steps.png" +alt="Spring boot pipeline" +caption="Spring boot pipeline" +max-width="80%" +%} + +After checking out the code we use the standard [Maven Docker image](https://hub.docker.com/_/maven/){:target="\_blank"} to compile the Spring Boot source code and create a JAR file. We also pass a parameter that changes the Maven cache location folder. The reason for this parameter is that the default Maven location is `/root/.m2` which is defined as a volume (and thus discarded after each build). + +### Caching the Maven dependencies + +Codefresh is smart enough that [caches automatically]({{site.baseurl}}/docs/pipelines/pipeline-caching/) for us the workspace of a build (`/codefresh/volume`). This works great for build tools that keep their cache in the project folder, but not for Maven/Gradle which keep their cache externally. By changing the location of the Maven repo on the project folder (the `m2_repository` name is arbitrary) we make sure that Codefresh will cache automatically the Maven libraries resulting in much faster builds. + +The next step is a Docker build. We name our image **spring-boot-2-sample-app** and tag it with a string `non-multi-stage` but of course you can use any other tag name that you wish. + +{% include image.html +lightbox="true" +file="/images/learn-by-example/java/spring-boot-docker-image.png" +url="/images/learn-by-example/java/spring-boot-docker-image.png" +alt="Spring Boot Docker image" +caption="Spring Boot Docker image" +max-width="80%" +%} + +Once the pipeline is finished you will see the Spring Boot 2 Docker image your [Docker image dashboard]({{site.baseurl}}/docs/docker-registries/working-with-docker-registries/#viewing-docker-images). + +The last step is similar to the unit tests, but this time we run integration tests. We define again a custom cache folder so when you run the build you will see that Maven will automatically pick the cache from the previous step. All Codefresh steps in a pipeline [run on the same workspace]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps), so the build results from one step are visible to the next. + +>Notice that because the [Maven lifecycle](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html){:target="\_blank"} also executes the previous steps in a build, the `mvn verify` command essentially will run `mvn package` as well. In theory we could just have the _Integration_ step in this pipeline on its own. That step would build the code, run unit and integration tests all in one stage. For demonstration purposes however, we include two steps so that you can see the correct usage of Maven cache. + + +## Spring Boot 2 and Docker (multi-stage builds) + +Docker added [multi-stage builds](https://blog.docker.com/2017/07/multi-stage-builds/){:target="\_blank"} at version 17.05. With multi-stage builds a Docker build can use one base image for compilation/packaging/unit tests and a different one that will hold the runtime of the application. This makes the final image more secure and smaller in size (as it does not contain any development/debugging tools). + +In the case of Java, multistage builds allow for the compilation itself to happen during the build process, even though the final Docker image will not contain a full JDK. + + +Here is the multi-stage build definition: + + `Dockerfile` +{% highlight docker %} +{% raw %} +FROM maven:3.5.2-jdk-8-alpine AS MAVEN_TOOL_CHAIN +COPY pom.xml /tmp/ +RUN mvn -B dependency:go-offline -f /tmp/pom.xml -s /usr/share/maven/ref/settings-docker.xml +COPY src /tmp/src/ +WORKDIR /tmp/ +RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml package + +FROM java:8-jre-alpine + +EXPOSE 8080 + +RUN mkdir /app +COPY --from=MAVEN_TOOL_CHAIN /tmp/target/*.jar /app/spring-boot-application.jar + +ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/spring-boot-application.jar"] + +{% endraw %} +{% endhighlight %} + +This docker build does the following: + +1. Starts from the standard Maven Docker image +1. Copies only the `pom.xml` file inside the container +1. Runs a mvn command to download all dependencies found in the `pom.xml` +1. Copies the rest of the source code in the container +1. Compiles the code and runs unit tests (with `mvn package`) +1. Discards the Maven image with all the compiled classes/unit test results etc +1. Starts again from the JRE image and copies **only** the JAR file created before + +The order of the steps is tuned so that it takes advantage of the layer caching built-in to Docker. +If you change something in the source code Docker already has a layer with Maven dependencies so they +will not be re-downloaded again. Only if you change the `pom.xml` file itself, Docker will start again from the lowest layer. + +Again, we define a custom location for the Maven cache (using the `settings-docker.xml` file). This way the Maven dependencies are placed inside the container and they will be cached automatically with the respective layer (Read more about this technique [at the official documentation](https://github.com/carlossg/docker-maven#packaging-a-local-repository-with-the-image){:target="\_blank"}. + +### Create a CI pipeline for Spring (multi-stage Docker builds) + +Because in multi-stage builds Docker itself handles most of the build process, moving the project to Codefresh is straightforward. We just need [a single step](https://github.com/codefresh-contrib/spring-boot-2-sample-app/blob/master/codefresh.yml){:target="\_blank"} that creates the Docker image after checking out the code. The integration test step is the same as before. + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +stages: + - prepare + - test + - build + - 'integration test' +steps: + main_clone: + title: Cloning main repository... + stage: prepare + type: git-clone + repo: 'codefresh-contrib/spring-boot-2-sample-app' + revision: master + git: github + build_app_image: + title: Building Docker Image + type: build + stage: build + image_name: spring-boot-2-sample-app + working_directory: ./ + tag: 'multi-stage' + dockerfile: Dockerfile + run_integration_tests: + title: Integration test + stage: 'integration test' + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository verify -Dserver.host=http://my-spring-app + services: + composition: + my-spring-app: + image: '${{build_app_image}}' + ports: + - 8080 + readiness: + timeoutSeconds: 30 + periodSeconds: 15 + image: byrnedo/alpine-curl + commands: + - "curl http://my-spring-app:8080/" +{% endraw %} +{% endhighlight %} + +This will compile/test/package the Spring Boot application and create a Docker image. Codefresh is automatically caching +Docker layers (it uses the Docker image of a previous build as a cache for the next) and therefore builds will become +much faster after the first one finishes. + + +## Related articles +[Gradle example]({{site.baseurl}}/docs/example-catalog/ci-examples/gradle/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) +[Creating pipelines]({{site.baseurl}}/docs/pipelines/pipelines/) +[How Codefresh pipelines work]({{site.baseurl}}/docs/pipelines/introduction-to-codefresh-pipelines/) diff --git a/_docs/example-catalog/ci-examples/uploading-or-downloading-from-gs.md b/_docs/example-catalog/ci-examples/uploading-or-downloading-from-gs.md new file mode 100644 index 00000000..1bfcf82d --- /dev/null +++ b/_docs/example-catalog/ci-examples/uploading-or-downloading-from-gs.md @@ -0,0 +1,152 @@ +--- +title: "Upload/Download files to/from Google Storage" +description: "Upload and download a JAR from Google Storage from within a pipeline" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- A [Google Storage Bucket](https://cloud.google.com/storage/docs/creating-buckets){:target="\_blank"} with public read access +- A private key [downloaded](https://cloud.google.com/storage/docs/authentication#gsutilauth){:target="\_blank"} for the existing service account associated with your bucket (for this example, we base64 encoded the key for ease of use in a pipeline variable using `base64 key_file.json > key_file.b64`) + +## Example Project + +The example project is at [GitHub](https://github.com/codefresh-contrib/gcloud-storage-sample-app.git){:target="\_blank"}. The application is a simple Scala Hello World application contained in a jar, with a dependency on a scala-library jar which we will download from the bucket and package into a Docker image. + +Our project contains two pipelines, one to upload the dependency JAR _to_ our bucket, and the other to download the JAR _from_ the bucket. + +## Create the first pipeline + +The first pipeline contains one stage/step, to upload the JAR to the Google Storage Bucket. + +{% include image.html +lightbox="true" +file="/images/examples/gs/gs-upload-pipeline.png" +url="/images/examples/gs/gs-upload-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="90%" +%} + +You need to define a pipeline variable, KEY_FILE, in the pipeline settings: + +{% include image.html +lightbox="true" +file="/images/examples/gs/gs-pipeline-vars.png" +url="/images/examples/gs/gs-pipeline-vars.png" +alt="Codefresh UI Pipeline Variables" +caption="Codefresh UI Pipeline Variables" +max-width="70%" +%} + +Here is the first pipeline: + +`codefresh-upload.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" + +stages: + - "upload" + +steps: + upload: + title: "Uploading library jar to GS..." + type: "freestyle" + stage: "upload" + arguments: + image: "google/cloud-sdk:slim" + commands: + - echo $KEY_FILE | base64 --decode > key_file.json + - gcloud auth activate-service-account --key-file=key_file.json + - curl https://repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.2/scala-library-2.12.2.jar | gsutil cp - gs://anna-demo-bucket/scala-library-2.12.2.jar +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Uploads a JAR from Maven into our Google Storage bucket through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). + +## Create the second pipeline + +Our second pipeline has four stages: + +- A stage for cloning the repository +- A stage for downloading the jar from the bucket +- A stage for building the image +- A stage for pushing the image to the repository + +{% include image.html +lightbox="true" +file="/images/examples/gs/gs-download-pipeline.png" +url="/images/examples/gs/gs-download-pipeline.png" +alt="Codefresh UI Pipeline View" +caption="Codefresh UI Pipeline View" +max-width="90%" +%} + +Here is the YAML for the second pipeline: + +`codefresh-download.yml` +{% highlight yaml %} +{% raw %} +version: "1.0" + +stages: + - "clone" + - "download" + - "build" + - "push" + +steps: + clone: + title: "Cloning main repository..." + type: "git-clone" + stage: "clone" + arguments: + repo: "codefresh-contrib/gcloud-storage-sample-app" + git: "github" + revision: "master" + download: + title: "Downloading dependency lib from GS..." + type: "freestyle" + stage: "download" + working_directory: ${{clone}} + arguments: + image: "google/cloud-sdk:slim" + commands: + - gsutil cp gs://anna-demo-bucket/scala-library-2.12.2.jar . + build: + title: "Building docker image..." + type: "build" + stage: "build" + working_directory: ${{clone}} + arguments: + image_name: "annabaker/gcloud-storage-sample-app" + tag: "master" + push_to_my_registry: + stage: "push" + type: "push" + title: "Pushing to external registry..." + arguments: + candidate: ${{build}} + tag: '1.0.0' + registry: "dockerhub" +{% endraw %} +{% endhighlight %} + +This pipeline does the following: + +1. Clones the source code through a [Git clone step]({{site.baseurl}}/docs/pipelines/steps/git-clone/). +2. Downloads the dependency JAR from our publicly-accessible Google Storage bucket through a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). +3. Builds a docker image through a [build step]({{site.baseurl}}/docs/pipelines/steps/build/). +4. Pushes the Docker image to the DockerHub registry you have integrated with Codefresh through a [push step](https://codefresh.io/docs/docs/pipelines/steps/push/). + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/ci-examples/) +[Codefresh YAML]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) + + diff --git a/_docs/example-catalog/ci-examples/vault-secrets-in-the-pipeline.md b/_docs/example-catalog/ci-examples/vault-secrets-in-the-pipeline.md new file mode 100644 index 00000000..d02cee77 --- /dev/null +++ b/_docs/example-catalog/ci-examples/vault-secrets-in-the-pipeline.md @@ -0,0 +1,116 @@ +--- +title: "Vault secrets in pipelines" +description: "Access and refer to Vault secrets in pipelines" +group: example-catalog +sub_group: ci-examples +toc: true +--- + +Codefresh offers a Vault plugin you may use from the [Step Marketplace](https://codefresh.io/steps/step/vault){:target="\_blank"}. The plugin imports key-value pairs from the Vault server, and exports them into the pipeline. + +## Prerequisites + +- A [free Codefresh account](https://codefresh.io/docs/docs/getting-started/create-a-codefresh-account/) +- An existing Vault server [already setup](https://learn.hashicorp.com/vault/getting-started/install){:target="\_blank"} +- A secret stored in said Vault server with a key of `password` +- A Vault [authorization token](https://learn.hashicorp.com/vault/getting-started/authentication#tokens){:target="\_blank"} + +## Example Java application + +You can find the example project on [GitHub](https://github.com/codefresh-contrib/vault-sample-app){:target="\_blank"}. + +The example application retrieves the system variable `password` from the pipeline, and uses it to authenticate to a Redis database, but you are free to use any type of database of your choosing. + +```java + String password = System.getenv("password"); + String host = System.getProperty("server.host"); + + RedisClient redisClient = new RedisClient( + RedisURI.create("redis://" + password + "@" + host + ":6379")); + RedisConnection connection = redisClient.connect(); +``` + +Also in the example application is a simple unit test that ensures we are able to read and write data to the database. + +You cannot run the application locally, as it needs to run in the pipeline in order to use our environment variables to connect. + +## Create the pipeline + +The following pipeline contains three steps: a vault step, a [git-clone]({{site.baseurl}}/docs/pipelines/steps/git-clone/) step, and a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). + +{% include image.html +lightbox="true" +file="/images/examples/secrets/vault-pipeline.png" +url="/images/examples/secrets/vault-pipeline.png" +alt="Vault pipeline" +caption="Vault Pipeline" +max-width="100%" +%} + +You should be able to copy and paste this YAML into the in-line editor in the Codefresh UI. It will automatically clone the project for you. + +Note that you need to change the `VAULT_ADDR`, `VAULT_AUTH`, and `VAULT_AUTH_TOKEN` arguments within the first step to your respective values. + +`codefresh.yml` +```yaml +version: "1.0" +stages: + - "vault" + - "clone" + - "package" +steps: + vault: + title: Importing vault values... + stage: "vault" + type: vault + arguments: + VAULT_ADDR: 'http://:' + VAULT_PATH: 'path/to/secret' + VAULT_AUTH_TOKEN: '' + clone: + title: Cloning main repository... + type: git-clone + arguments: + repo: 'codefresh-contrib/vault-sample-app' + git: github + stage: clone + package_jar: + title: Packaging jar and running unit tests... + stage: package + working_directory: ${{clone}} + arguments: + image: maven:3.5.2-jdk-8-alpine + commands: + - mvn -Dmaven.repo.local=/codefresh/volume/m2_repository -Dserver.host=my-redis-db-host clean package + services: + composition: + my-redis-db-host: + image: 'redis:4-alpine' + command: 'redis-server --requirepass $password' + ports: + - 6379 +``` + +The pipeline does the following: + +1. Imports the key-value pairs from the Vault server and exports them into the pipeline under `/meta/env_vars_to_export`. +2. Clones the main repository (note the special use of naming the step `main_clone`). This ensures that all subsequent commands are run [inside the project that was checked out]({{site.baseurl}}/docs/pipelines/steps/git-clone/#basic-clone-step-project-based-pipeline). +3. The `package_jar`, does a few special things to take note of: + - Spins up a [Service Container]({{site.baseurl}}/docs/pipelines/service-containers/) running Redis on port 6379 , and sets the password to the database using our exported environment variable + - Sets `maven.repo.local` to cache Maven dependencies into the local codefresh volume to [speed up builds]({{site.baseurl}}/docs/example-catalog/ci-examples/spring-boot-2/#caching-the-maven-dependencies) + - Runs unit tests and packages the jar. Note how you can directly refer to the service container's name (`my-redis-db-host`) when we set `server.host` + +You will see that the variable was correctly exported to the pipeline by running a simple `echo` command: + {% include image.html + lightbox="true" + file="/images/examples/secrets/vault-pipeline2.png" + url="/images/examples/secrets/vault-pipeline2.png" + alt="Vault pipeline variable" + caption="Vault pipeline variable" + max-width="100%" + %} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/ci-examples/) +[Steps in pipelines]({{site.baseurl}}/docs/pipelines/steps/) + diff --git a/_docs/example-catalog/ci-examples/voting-app.md b/_docs/example-catalog/ci-examples/voting-app.md new file mode 100644 index 00000000..08cb4a5c --- /dev/null +++ b/_docs/example-catalog/ci-examples/voting-app.md @@ -0,0 +1,93 @@ +--- +title: "Voting app" +description: "" +excerpt: "" +group: example-catalog +sub_group: ci-examples +redirect_from: + - /docs/voting-app-1/ + - /docs/python/voting-app/ +toc: true +--- +This voting application is a demo with which you can build an advanced composition that uses `Python, Redis, Postgres, Node.js, and .Net`. + +## Looking around +In the root of this repository you'll find a file named codefresh.yml, this is our build descriptor and it describes the different steps that comprise our process. Let's quickly review the contents of this file: + + `codefresh.yml` +{% highlight yaml %} +{% raw %} +version: '1.0' +steps: + unit-tests: + image: codefresh/buildpacks:nodejs-5 + working-directory : ${{initial-clone}} + commands: + - echo Installing npm modules silent + - npm install + - gulp test + - echo $(date) + + build-step: + #title: Build My Image #Display name for the step + type: build + image-name: containers101/cf-example-result + tag: ${{CF_BRANCH}} + build_arguments: + - OPTION_A=${{OPTION_A}} + - OPTION_B=${{OPTION_B}} + + push-to-registry: + type: push + #candidate: the image from the build step + candidate: ${{build-step}} + tag: ${{CF_BRANCH}} + + integration-tests-step: + type: composition + #location of the compostion on the filesystem of the cloned image + composition: './cf-compositions/voting-app-full.yml' + #run integration only when pushing to master + when: + branch: + only: + - master #can also be regex + composition-candidates: + #this will be the image that we will test + integ-test: + image: containers101/cf-example-tests:master + command: ./tests.sh + composition-variables: + - VOTING_OPTION_A=${{OPTION_A}} + - VOTING_OPTION_B=${{OPTION_B}} + + launch-composition: + type: launch-composition + environment-name: 'Test composition after build' + composition: './cf-compositions/voting-app-full.yml' + composition-variables: + - VOTING_OPTION_A=${{OPTION_A}} + - VOTING_OPTION_B=${{OPTION_B}} + + deploy to ecs: + image: codefresh/cf-deploy-ecs + commands: + - cfecs-update --image-name containers101/cf-example-result --image-tag ${{CF_BRANCH}} eu-west-1 vote-app result + environment: + - AWS_ACCESS_KEY_ID=${{AWS_ACCESS_KEY_ID}} + - AWS_SECRET_ACCESS_KEY=${{AWS_SECRET_ACCESS_KEY}} + when: + condition: + all: + pushCommit: 'includes(lower("${{CF_COMMIT_MESSAGE}}"), "[deploy]") == true' +{% endraw %} +{% endhighlight %} + +{{site.data.callout.callout_info}} +##### Example + +Just head over to the example [__repository__](https://github.com/containers101/cf-example-result){:target="_blank"} in GitHub and follow the instructions there. +{{site.data.callout.end}} + +## Related articles +[CI/CD pipeline examples]({{site.baseurl}}/docs/example-catalog/ci-examples/) diff --git a/_docs/example-catalog/examples.md b/_docs/example-catalog/examples.md new file mode 100644 index 00000000..9dee4525 --- /dev/null +++ b/_docs/example-catalog/examples.md @@ -0,0 +1,127 @@ +--- +title: "CI/CD pipeline examples" +description: "A collection of examples for Codefresh pipelines" +group: example-catalog +redirect_from: + - /docs/examples-v01/ + - examples.html + - /docs/catalog-examples/ + - /docs/examples/ + - /docs/pipelines-examples/ + - /docs/pipelines/pipelines-examples/ +toc: true +--- +Codefresh enables you to define the steps of your pipeline in a [YAML file]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/). By default, the file is named `codefresh.yml`, and is located in the root directory of the repository. + +## CI examples + +### Programming-language specific examples + +Codefresh is agnostic as far as programming languages are concerned. All major programming languages are supported: + +- [Go Web App]({{site.baseurl}}/docs/example-catalog/ci-examples/golang-hello-world/) or [Go CLI]({{site.baseurl}}/docs/example-catalog/golang/goreleaser) +- [Spring Java app with Maven]({{site.baseurl}}/docs/example-catalog/ci-examples/spring-boot-2/) or [Gradle]({{site.baseurl}}/docs/example-catalog/ci-examples/gradle/). Also how to [upload JAR to Nexus/Artifactory]({{site.baseurl}}/docs/example-catalog/ci-examples/publish-jar/) +- Node [Express.js App]({{site.baseurl}}/docs/example-catalog/ci-examples/lets-chat/) or [React.js App]({{site.baseurl}}/docs/example-catalog/ci-examples/react/) +- [Php App]({{site.baseurl}}/docs/example-catalog/ci-examples/php) +- [Python Django App]({{site.baseurl}}/docs/example-catalog/ci-examples/django/) +- [Ruby On Rails App]({{site.baseurl}}/docs/example-catalog/ci-examples/ruby) +- [C]({{site.baseurl}}/docs/example-catalog/ci-examples/c-make/) or [C++]({{site.baseurl}}/docs/example-catalog/ci-examples/cpp-cmake) +- [Rust]({{site.baseurl}}/docs/example-catalog/ci-examples/rust/) +- [C# .NET core]({{site.baseurl}}/docs/example-catalog/ci-examples/dotnet/) +- [Scala App]({{site.baseurl}}/docs/example-catalog/ci-examples/scala-hello-world/) +- [Android (Mobile)]({{site.baseurl}}/docs/example-catalog/ci-examples/android/) + +### Source code checkout examples + +You can check out code from one or more repositories in any pipeline phase. Codefresh includes [built-in GIT integration]({{site.baseurl}}/docs/integrations/git-providers/) with all the popular GIT providers and can be used with [git-clone]({{site.baseurl}}/docs/pipelines/steps/git-clone/) steps. + +- [Cloning Git repositories using the built-in integration]({{site.baseurl}}/docs/example-catalog/ci-examples/git-checkout/) +- [Cloning Git repositories using manual Git commands]({{site.baseurl}}/docs/example-catalog/ci-examples/git-checkout-custom/) +- [Checking out from Subversion, Perforce, Mercurial, etc ]({{site.baseurl}}/docs/example-catalog/ci-examples/non-git-checkout/) + +### Build/push examples + +Codefresh has native support for [building]({{site.baseurl}}/docs/pipelines/steps/build/) and [pushing]({{site.baseurl}}/docs/pipelines/steps/push/) Docker containers. +You can also compile traditional applications that are not Dockerized yet. + +- [Build an Image with the Dockerfile in root directory]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-dockerfile-in-root-directory/) +- [Build an Image by specifying the Dockerfile location]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-specify-dockerfile-location) +- [Build an Image from a different Git repository]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-from-a-different-git-repository) +- [Build and Push an Image]({{site.baseurl}}/docs/example-catalog/ci-examples/build-and-push-an-image) +- [Build an Image with build arguments]({{site.baseurl}}/docs/example-catalog/ci-examples/build-an-image-with-build-arguments) +- [Share data between steps]({{site.baseurl}}/docs/example-catalog/ci-examples/shared-volumes-between-builds) +- [Upload or download from a Google Storage Bucket]({{site.baseurl}}/docs/example-catalog/ci-examples/uploading-or-downloading-from-gs/) +- [Get Short SHA ID and use it in a CI process]({{site.baseurl}}/docs/example-catalog/ci-examples/get-short-sha-id-and-use-it-in-a-ci-process) +- [Call a CD pipeline from a CI pipeline]({{site.baseurl}}/docs/example-catalog/ci-examples/call-child-pipelines) +- [Trigger a Kubernetes Deployment from a Dockerhub Push Event]({{site.baseurl}}/docs/example-catalog/ci-examples/trigger-a-k8s-deployment-from-docker-registry/) + + +### Unit and integration test examples + +Codefresh has support for both [unit]({{site.baseurl}}/docs/testing/unit-tests/) and [integration tests]({{site.baseurl}}/docs/testing/integration-tests/) as well as [test reporting]({{site.baseurl}}/docs/testing/test-reports/). + +- [Run unit tests]({{site.baseurl}}/docs/example-catalog/ci-examples/run-unit-tests) +- [Run integration tests]({{site.baseurl}}/docs/example-catalog/ci-examples/run-integration-tests/) +- [Run integration tests with MongoDB]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mongo/) +- [Run integration tests with MySQL]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-mysql/) +- [Run integration tests with PostgreSQL]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-postgres/) +- [Run integration tests with Redis]({{site.baseurl}}/docs/example-catalog/ci-examples/integration-tests-with-redis/) +- [Populate a database with existing data]({{site.baseurl}}/docs/example-catalog/populate-a-database-with-existing-data) + +- [Shared volumes of service from composition step for other yml steps]({{site.baseurl}}/docs/example-catalog/shared-volumes-of-service-from-composition-step-for-other-yml-steps) +- [Launch Composition]({{site.baseurl}}/docs/example-catalog/ci-examples/launch-composition) +- [Launch Composition and define Service Environment variables using a file]({{site.baseurl}}/docs/example-catalog/ci-examples/launching-a-composition-and-defining-a-service-environment-variables-using-a-file) +- [Run multiple kinds of unit tests using fan-in-fan-out parallel pipeline]({{site.baseurl}}/docs/example-catalog/fan-in-fan-out) + +### Code coverage examples + +- [Run coverage reports with Codecov]({{site.baseurl}}/docs/example-catalog/ci-examples/codecov-testing) +- [Run coverage reports with Coveralls]({{site.baseurl}}/docs/example-catalog/ci-examples/coveralls-testing) +- [Run coverage reports with Codacy]({{site.baseurl}}/docs/example-catalog/ci-examples/codacy-testing) + +### Secrets examples + +Codefresh can automatically export secret key-value pairs using the Vault plugin from the [Step Marketplace](https://codefresh.io/steps/step/vault). + +- [Vault secrets in the Pipeline]({{site.baseurl}}/docs/example-catalog/ci-examples/vault-secrets-in-the-pipeline) +- [Decryption with Mozilla SOPS]({{site.baseurl}}/docs/example-catalog/ci-examples/ci-examples/decryption-with-mozilla-sops) +- [GitOps with Bitnami sealed secrets]({{site.baseurl}}/docs/example-catalog/ci-examples/gitops-secrets) + +### Notification examples + +- [Send notification to Slack]({{site.baseurl}}/docs/example-catalog/ci-examples/sending-the-notification-to-slack) +- [Send notification to Jira]({{site.baseurl}}/docs/example-catalog/ci-examples/sending-the-notification-to-jira) + + +## CD examples + +### Preview environment examples + +Codefresh can automatically launch environments (powered by Docker swarm) to [preview a Pull Reqest or feature]({{site.baseurl}}/docs/getting-started/on-demand-environments/). The definition of the environment can come from an [existing composition]({{site.baseurl}}/docs/testing/create-composition/), a docker-compose file or an inline YAML. Preview environments can be launched manually or [automatically from pipelines]({{site.baseurl}}/docs/pipelines/steps/launch-composition/). + +- [MongoDB preload data]({{site.baseurl}}/docs/example-catalog/cd-examples/import-data-to-mongodb/) +- [NodeJS + Angular2 + MongoDB]({{site.baseurl}}/docs/example-catalog/cd-examples/nodejs-angular2-mongodb/) +- [NGINX Basic Auth]({{site.baseurl}}/docs/example-catalog/cd-examples/secure-a-docker-container-using-http-basic-auth/) +- [Spring Boot + Kafka + Zookeeper]({{site.baseurl}}/docs/example-catalog/cd-examples/spring-boot-kafka-zookeeper/) +- [Web terminal]({{site.baseurl}}/docs/example-catalog/cd-examples/web-terminal/) + +### Deployment examples + +Codefresh can deploy to any platform such as VMs, FTP/SSH/S3 sites, app servers, but of course it has great support for [Kubernetes clusters]({{site.baseurl}}/docs/deploy-to-kubernetes/deployment-options-to-kubernetes/) and [Helm releases]({{site.baseurl}}/docs/new-helm/helm-releases-management/): + +- [Deploy to a VM with packer]({{site.baseurl}}/docs/example-catalog/cd-examples/packer-gcloud/) +- [Deploy to a VM with FTP]({{site.baseurl}}/docs/example-catalog/cd-examples/transferring-php-ftp) +- [Deploy to Tomcat using SCP]({{site.baseurl}}/docs/example-catalog/cd-examples/deploy-to-tomcat-via-scp) +- [Deploy Demochat to a Kubernetes cluster]({{site.baseurl}}/docs/cd-examples/deploy-to-kubernetes/codefresh-kubernetes-integration-demochat-example/) +- [Use kubectl as part of freestyle step]({{site.baseurl}}/docs/example-catalog/cd-examples/use-kubectl-as-part-of-freestyle-step) +- [Deploy with Kustomize]({{site.baseurl}}/docs/example-catalog/cd-examples/deploy-with-kustomize) +- [Deploy with Helm]({{site.baseurl}}/docs/example-catalog/cd-examples/helm) +- [Deploy with Terraform]({{site.baseurl}}/docs/example-catalog/cd-examples/terraform) +- [Deploy with Pulumi]({{site.baseurl}}/docs/example-catalog/cd-examples/pulumi) +- [Deploy to Nomad]({{site.baseurl}}/docs/example-catalog/cd-examples/nomad) +- [Deploy to Heroku]({{site.baseurl}}/docs/example-catalog/cd-examples/deploy-to-heroku/) +- [Deploy to Docker swarm]({{site.baseurl}}/docs/example-catalog/cd-examples/docker-swarm/) +- [Deploy to Elastic Beanstalk]({{site.baseurl}}/docs/example-catalog/cd-examples/elastic-beanstalk/) +- [Deploy to Amazon ECS/Fargate]({{site.baseurl}}/docs/example-catalog/cd-examples/amazon-ecs/) + + diff --git a/_docs/example-catalog/gitops-example.md b/_docs/example-catalog/gitops-example.md new file mode 100644 index 00000000..ba1c727d --- /dev/null +++ b/_docs/example-catalog/gitops-example.md @@ -0,0 +1,9 @@ +--- +title: "GitOps examples" +description: "A collection of examples for GitOps deployments" +group: example-catalog +sub_group: gitops-examples +toc: true +--- + +TBD \ No newline at end of file diff --git a/_docs/integrations/ci-integrations/codefresh-classic.md b/_docs/integrations/ci-integrations/codefresh-classic.md new file mode 100644 index 00000000..ce01417e --- /dev/null +++ b/_docs/integrations/ci-integrations/codefresh-classic.md @@ -0,0 +1,247 @@ +--- +title: "Codefresh Classic" +description: "" +group: integrations +sub_group: ci-integrations +toc: true +--- + + + Use Hosted GitOps with any popular Continuous Integration (CI) solution, not just with Codefresh CI. Codefresh Classic is one of the third-party CI platform/tools that you can connect to Codefresh for deployment with image enrichment and reporting. + + + Connecting Codefresh Classic, adds the CI information to images which are displayed in the Images dashboard, as in the example below. + + {% include + image.html + lightbox="true" + file="/images/integrations/images-dashboard.png" + url="/images/integrations/images-dashboard.png" + alt="Images dashboard with enriched image information" + caption="Images dashboard with enriched image information" + max-width="70%" + %} + + + +For information on how to use the image reporting action in your Codefresh Classic pipeline and how to configure the integration, see [CI Integrations]({{site.baseurl}}/docs/integrations/ci-integrations/). + + +### Example of Codefresh Classic pipeline with report image step + +{% highlight yaml %} +{% raw %} + +reportImage: + title: Report image to Codefresh CD + type: codefresh-report-image + working_directory: /code + arguments: + # The URL to the cluster with the Codefresh runtime to integrate with. + CF_HOST: '[runtime-host-url]' + + # Codefresh API key !! Committing a plain text token is a security risk. We highly recommend using encrypted secrets !! + # Documentation - https://codefresh.io/docs/docs/pipelines/secrets-store/ + CF_API_KEY: ${{API_KEY}} + + # Image path to enrich + CF_IMAGE: '[full image path here, including tag]' + + # Name of Container registry integration + CF_CONTAINER_REGISTRY_INTEGRATION: 'v2' + + # The git branch which is related for the commit + CF_GIT_BRANCH: '[name-of-your-git-branch]' + + # Name of Jira integration + CF_JIRA_INTEGRATION: 'jira' + + # Jira project filter + CF_JIRA_PROJECT_PREFIX: '[jira-project-prefix]' + + # String starting with the issue ID to associate with image + CF_JIRA_MESSAGE: '[issue-id]' + +{% endraw %} +{% endhighlight yaml %} + +### Codefresh Classic-Codefresh integration arguments +The table describes the arguments required to connect Codefresh Classic to Codefresh. + +>Except for Git branch and Git repo which are required, you can omit other Git provider arguments. Codefresh retrieves the required values from the runtime context selected for the integration. + +For the complete argument reference, see [CI integration argument reference]({{site.baseurl}}/docs/integrations/ci-integrations/#ci-integration-argument-reference). + + +{: .table .table-bordered .table-hover} +| Argument | Description | Required/Optional/Default | +| ---------- | -------- | ------------------------- | +| `CF_RUNTIME_NAME` | The runtime to use for the integration. If you have more than one runtime, select the runtime from the list. | Required | +| `CF_PLATFORM_URL` | The root URL of the Codefresh application. The default value is `https://g.codefresh.io`. | Optional | +| `CF_API_KEY` | The API key to authenticate the Codefresh Classic user to Codefresh. Generate the key for the integration. | Required | +| `CF_CONTAINER_REGISTRY_INTEGRATION` | The name of the container registry integration created in Codefresh where the image is stored. To create a container registry integration if you don't have one, click **Create Container Registry Integration**, and then configure the settings. See [Container registry integrations]({{site.baseurl}}/docs/integrations/container-registries/). | Optional | +| `CF_JIRA_INTEGRATION` | Deprecated from version 0.0.565. Replaced by `CF_ISSUE_TRACKING_INTEGRATION`. | _Deprecated_ +| `CF_ISSUE_TRACKING_INTEGRATION` | The name of the issue tracking integration created in Codefresh to use to enrich the image. Relevant only if Jira enrichment is required for the image. If you don't have a Jira integration, click **Create Atlassian Jira Integration** and configure settings. See [Jira integration]({{site.baseurl}}/docs/integrations/issue-tracking/jira/). | Optional | +| `CF_IMAGE` | The image to be enriched and reported in Codefresh. Pass the `[account-name]/[image-name]:[tag]` built in your CI. | Required | +| `CF_WORKFLOW_NAME` | The name assigned to the workflow that builds the image. When defined, the name is displayed in the Codefresh platform. Example, `Staging step` | Optional | +| `CF_GIT_BRANCH` | The Git branch with the commit and PR (pull request) data to add to the image. Pass the Branch from the event payload used to trigger your action. | Required | +| `CF_GIT_REPO` | The Git repository with the configuration and code used to build the image. | Required | +| `CF_GIT_PROVIDER` | The Git provider for the integration, and can be either `github`, `gitlab`, or `bitbucket`. {::nomarkdown}
  • Optional when you don't define other related Git provider arguments. When not defined, Codefresh retrieves the required information from the runtime selected for the integration.
  • Required when you define at least one of the Git provider arguments. For example, when you define CF_GITLAB_TOKEN, then you must define all Git provider arguments, in this case, CF_GIT_PROVIDER as gitlab, and CF_GITLAB_HOST_URL.
    • {:/}| Optional | +| `CF_GITLAB_TOKEN` | The token to authenticate the GitLab account. {::nomarkdown}
      • Optional when you don't define any GitLab-specific arguments. When not defined, Codefresh retrieves the required information from the runtime selected for the integration.
      • Required when you define at least one of the GitLab-specific arguments, such as CF_GIT_PROVIDER as gitlab, or CF_GITLAB_HOST_URL.
        • {:/} | Optional | +| `CF_GITLAB_HOST_URL` | The URL address of your GitLab Cloud/Server instance. {::nomarkdown}
          • Optional when you don't define other related GitLab-specific arguments. When not defined, Codefresh retrieves the required information from the runtime selected for the integration.
          • Required when you define at least one of the GitLab-specific arguments, such as CF_GIT_PROVIDER as gitlab, or CF_GITLAB_TOKEN.
            • {:/} | Optional | +| `CF_BITBUCKET_USERNAME` | The username for the Bitbucket or the Bitbucket Server (on-prem) account. {::nomarkdown}
              • Optional when you don't define other related Bitbucket-specific arguments. When not defined, Codefresh retrieves the required information from the runtime selected for the integration.
              • Required when you define at least one of the Bitbucket-specific arguments, such as CF_GIT_PROVIDER as bitbucket, CF_BITBUCKET_PASSWORD or CF_BITBUCKET_HOST_URL.
                • {:/}| Optional | +| `CF_BITBUCKET_PASSWORD` | The password for the Bitbucket or the Bitbucket Server (on-prem) account. {::nomarkdown}
                  • Optional when you don't define other related Bitbucket-specific arguments. When not defined, Codefresh retrieves the required information from the runtime selected for the integration.
                  • Required when you define at least one of the Bitbucket-specific arguments, such as CF_GIT_PROVIDER as bitbucket, CF_BITBUCKET_USERNAME, or CF_BITBUCKET_HOST_URL.
                    • {:/}| Optional | +| `CF_BITBUCKET_HOST_URL` | Relevant for Bitbucket Server accounts only. The URL address of your Bitbucket Server instance. Example, `https://bitbucket-server:7990`. {::nomarkdown}
                      • Optional when you don't define other related Bitbucket Server-specific arguments. When not defined, Codefresh retrieves the required information from the runtime selected for the integration.
                      • Required when you define at least one of the Bitbucket Server-specific arguments, such as CF_GIT_PROVIDER as bitbucket, CF_BITBUCKET_USERNAME or CF_BITBUCKET_PASSWORD.
                      {:/} | Optional | +|`CF_JIRA_PROJECT_PREFIX` | Relevant only when `CF_ISSUE_TRACKING_INTEGRATION` is defined. The Jira project prefix that identifies the ticket number to use.| Required| +| `CF_JIRA_MESSAGE` | Relevant only when `CF_ISSUE_TRACKING_INTEGRATION` is defined. The Jira issue IDs matching the string to associate with the image. | Required | +| `CF_JIRA_FAIL_ON_NOT_FOUND` | Relevant only when `CF_ISSUE_TRACKING_INTEGRATION` is defined. The report image action when the `CF_JIRA_MESSAGE` is not found. When set to `true`, the report image action is failed. | Required | + +For how-to instructions, see [Connect a third-party CI platform/tool to Codefresh]({{site.baseurl}}/docs/integrations/ci-integrations/#connect-a-third-party-ci-platformtool-to-codefresh/). + +### Templatization examples for CF arguments + +Arguments such as `CF_IMAGE`, `CF_GIT_BRANCH`, and `CF_JIRA_MESSAGE` are populated dynamically when the Codefresh Classic integration pipeline is triggered. You can templatize the values of these arguments to ensure that the required information is included in the reported image. + +Codefresh Classic offers [system variables](https://codefresh.io/docs/docs/pipelines/variables/#system-provided-variables) you can use to templatize argument values. + +{::nomarkdown} +
                      +{:/} + +#### CF_IMAGE examples +**Example: Report full repo and branch information** +This example illustrates how to define the value for `CF_IMAGE` to report the repo owner, name, and branch, with the Git hash. + + Value: + {% raw %}`${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}:${{CF_BRANCH_TAG_NORMALIZED}}-${{CF_SHORT_REVISION}}`{% endraw %} + + where: + * {% raw %}`${{CF_REPO_OWNER}}`{% endraw %} reports the owner of the repository. For example, `nr-codefresh`. + * {% raw %}`${{CF_REPO_NAME}}`{% endraw %} reports the name of the repository. For example, `codefresh-production`. + * {% raw %}`${{CF_BRANCH_TAG_NORMALIZED}}`{% endraw %} reports the normalized version of the branch name, without invalid characters in case the branch name is the Docker image tag name. For example, `pr-2345`, `new-auth-strategy` (branch names without normalization required), and `gcr.io/codefresh-inc/codefresh-io/argo-platform-audit.1.1909.0` (normalized version of original branch name `gcr.io/codefresh-inc/codefresh-io/argo-platform-audit:1.1909.0`). + * {% raw %}`${{CF_SHORT_REVISION}}`{% endraw %} reports the abbreviated 7-character revision hash, as used in Git. For example, `40659e7`. + +**Example: Report a specific image tag** +This example illustrates how to define the value for `CF_IMAGE` value when you know the specific image version you want to report. + + Value: + {% raw %}`{{CF_REPO_OWNER}}/${{CF_REPO_NAME}}:` {% endraw %} + + where: + * {% raw %}`${{CF_REPO_OWNER}}`{% endraw %} and {% raw %}`${{CF_REPO_NAME}}`{% endraw %} report the names of the repository owner and the repository, respectively. For example, `nr-codefresh` and `codefresh-production`, respectively. + * {% raw %}``{% endraw %} reports the hard-coded tag `v1.0`. + +**Example: Report the latest Git tag available on repository** +This example illustrates how to define the value for `CF_IMAGE` value to report the latest Git tag on the repository. + +Value: +{% raw %}`codefresh/${{CF_REPO_NAME}}:latest`{% endraw %} + +where: +* {% raw %}`codefresh`{% endraw %} is the hard-coded owner of the image. +* {% raw %}`${{CF_REPO_NAME}}`{% endraw %} reports the name of the repository that triggered the pipeline. For example, `codefresh-production`. +* {% raw %}`latest`{% endraw %} reports the latest Git tag available for the repository defined by {% raw %}`${{CF_REPO_NAME}}`{% endraw %}. For example, `v1.0.4-14-g2414721`. + +{::nomarkdown} +
                      +{:/} + +#### CF_GIT_BRANCH examples + +**Example: Report Git branch or tag with committer and commit message** + +This example illustrates how to report the name or tag of the Git branch with committer and commit message. + + Value: + {% raw %}`${{CF_REPO_NAME}}/${{CF_BRANCH}}:${{CF_COMMIT_AUTHOR}}/${{CF_COMMIT_MESSAGE}}`{% endraw %} + + where: + * {% raw %}`${{CF_REPO_NAME}}`{% endraw %} reports the name of the repository. For example, `codefresh-production`. + * {% raw %}`${{CF_BRANCH}}`{% endraw %} reports the branch name or tag based on the JSON payload of the Git repository that triggered the pipeline. For example, `new-auth-strategy`. + * {% raw %}`${{CF_COMMIT_AUTHOR}}`{% endraw %} reports the name of the user who made the commit. For example, `cf-support`. + * {% raw %}`${{CF_COMMIT_MESSAGE}}`{% endraw %} reports the commit message of the repository. For example, `support oauth authentication for ci integrations`. + + +**Example: Report normalized Git branch or tag with committer and commit message** + +This example illustrates how to report the normalized name or tag of the Git branch with committer and commit message. +Normalizing the branch name removes any invalid characters in the name if the branch name is also used as the Docker image tag name. + + Value: + + {% raw %}`${{CF_REPO_NAME}}/${{CF_BRANCH_TAG_NORMALIZED}}:${{CF_COMMIT_AUTHOR}}/${{CF_COMMIT_MESSAGE}}`{% endraw %} + + where: + * {% raw %}`${{CF_REPO_NAME}}`{% endraw %} reports the name of the repository. For example, `codefresh-production`. + * {% raw %}`${{CF_BRANCH_TAG_NORMALIZED}}`{% endraw %} reports the normalized version of the branch name or tag based on the JSON payload of the Git repository that triggered the pipeline. + * {% raw %}`${{CF_COMMIT_AUTHOR}}`{% endraw %} reports the name of the user who made the commit. For example, `nr-codefresh`. + * {% raw %}`${{CF_COMMIT_MESSAGE}}`{% endraw %}reports the commit message of the repository. For example, `support oauth authentication for ci integrations`. + +**Example: Report normalized Git branch or tag in lowercase with PR information** + +This example illustrates how to report the normalized name or tag of the Git branch in lowercase, with PR (pull request) information. +Normalizing the branch name removes any invalid characters in the name if the branch name is also used as the Docker image tag name. + +Value: + {% raw %}`${{CF_REPO_NAME}}/${{CF_BRANCH_TAG_NORMALIZED}}:${{CF_PULL_REQUEST_TARGET}}/${{CF_PULL_REQUEST_NUMBER}}`{% endraw %} + + where: + * {% raw %}`${{CF_REPO_NAME}}`{% endraw %} reports the name of the repository. For example, `production`. + * {% raw %}`${{CF_BRANCH_TAG_NORMALIZED}}`{% endraw %} reports the normalized version of the branch name or tag based on the JSON payload of the Git repository that triggered the pipeline. For example, `pr-2345`, `new-auth-strategy` (branch names without normalization required), and `gcr.io/codefresh-inc/codefresh-io/argo-platform-audit.1.1909.0` (normalized version of original branch name `gcr.io/codefresh-inc/codefresh-io/argo-platform-audit:1.1909.0`). + * {% raw %}`${{CF_PULL_REQUEST_TARGET}}`{% endraw %} reports the target branch of the PR. For example, `new-auth-strategy`. + * {% raw %}`${{CF_PULL_REQUEST_NUMBER}}`{% endraw %} reports the number of the PR. For example, `#323`. + +{::nomarkdown} +
                      +{:/} + +#### CF_JIRA_MESSAGE examples +The Jira message represents an existing Jira issue, and must be a literal string. + + Value: + `CR-1246` + +### Codefresh Classic integration logs +View and analyze logs for Codefresh Classic workflows through the Logs tab. When a Codefresh Classic pipeline is run, it is added to the Logs tab. +You can: +* Filter by status or by date range to view a subset of actions +* Navigate to the build file in Codefresh Classic, and view the Codefresh report image step + +{% include image.html +lightbox="true" +file="/images/integrations/classic/classic-logs-tab.png" +url="/images/integrations/classic/classic-logs-tab.png" +alt="Codefresh Classic: Logs tab" +caption="Codefresh Classic: Logs tab" +max-width="50%" +%} + +**Build in Codefresh Classic** + +The Run column includes the link to the pipeline in Codefresh Classic. + +Here is an example of the pipeline build in Codefresh Classic with the Enrich image for CSDP step (top) and the log (down). + +{% include image.html +lightbox="true" +file="/images/integrations/classic/classic-pipeline-enrich-step.png" +url="/images/integrations/classic/classic-pipeline-enrich-step.png" +alt="Codefresh Classic pipeline with Codefresh enrich image step" +caption="Codefresh Classic pipeline with Codefresh enrich image step" +max-width="50%" +%} + +{% include image.html +lightbox="true" +file="/images/integrations/classic/classic-logs.png" +url="/images/integrations/classic/classic-logs.png" +alt="Logs for Codefresh report image step in Codefresh Classic build" +caption="Logs for Codefresh report image step in Codefresh Classic build" +max-width="50%" +%} + +### Related articles +[Shared configuration repo]({{site.baseurl}}/docs/reference/shared-configuration/) +[Image enrichment with integrations]({{site.baseurl}}/docs/integrations/image-enrichment-overview/) +[Container registry integrations]({{site.baseurl}}/docs/integrations/container-registries/) +[Issue-tracking integrations]({{site.baseurl}}/docs/integrations/issue-tracking/) \ No newline at end of file diff --git a/_docs/single-sign-on/team-sync.md b/_docs/single-sign-on/team-sync.md index d5a7d6c9..87eb0700 100644 --- a/_docs/single-sign-on/team-sync.md +++ b/_docs/single-sign-on/team-sync.md @@ -44,9 +44,9 @@ max-width="40%" Though you can run this command manually it makes more sense to run it periodically as a job. And the obvious -way to perform this is with a Codefresh CI pipeline. The CLI can be used as a [freestyle step]({{site.baseurl}}/docs/codefresh-yaml/steps/freestyle/). +way to perform this is with a Codefresh CI pipeline. The CLI can be used as a [freestyle step]({{site.baseurl}}/docs/pipelines/steps/freestyle/). -You can create a git repository with a [codefresh.yml]({{site.baseurl}}/docs/codefresh-yaml/what-is-the-codefresh-yaml/) file with the following content: +You can create a git repository with a [codefresh.yml]({{site.baseurl}}/docs/pipelines/what-is-the-codefresh-yaml/) file with the following content: ```yaml version: '1.0' @@ -58,7 +58,7 @@ steps: - 'codefresh synchronize teams my-client-name -t azure' ``` -To fully automate this pipeline you should set a [cron trigger]({{site.baseurl}}/docs/configure-ci-cd-pipeline/triggers/cron-triggers/) for it. The cron-trigger will run this pipeline (and therefore synchronize the teams) in a fully automated manner. +To fully automate this pipeline you should set a [cron trigger]({{site.baseurl}}/docs/pipelines/triggers/cron-triggers/) for it. The cron-trigger will run this pipeline (and therefore synchronize the teams) in a fully automated manner. This way you can synchronize your teams every day/week/hour depending on you Cron trigger setup. diff --git a/images/examples/amazon-ecs/ecs-pipeline-deployment.png b/images/examples/amazon-ecs/ecs-pipeline-deployment.png new file mode 100644 index 00000000..cc4d3347 Binary files /dev/null and b/images/examples/amazon-ecs/ecs-pipeline-deployment.png differ diff --git a/images/examples/amazon-ecs/ecs-variables.png b/images/examples/amazon-ecs/ecs-variables.png new file mode 100644 index 00000000..f9bc5fa1 Binary files /dev/null and b/images/examples/amazon-ecs/ecs-variables.png differ diff --git a/images/examples/checkout/add-new-microservice.png b/images/examples/checkout/add-new-microservice.png new file mode 100644 index 00000000..58b965bc Binary files /dev/null and b/images/examples/checkout/add-new-microservice.png differ diff --git a/images/examples/checkout/add-new-microservice.svg b/images/examples/checkout/add-new-microservice.svg new file mode 100644 index 00000000..fd393f6b --- /dev/null +++ b/images/examples/checkout/add-new-microservice.svg @@ -0,0 +1,1348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + +   + step + + +   + + + Pipeline + + +   + step + + + +   + step + + + + Trigger 1 + + + + + Trigger 2 + + + + Trigger 3 + + + + Trigger 4 + + + + + + + Microservice N + + Trigger N + + + + diff --git a/images/examples/checkout/simulate-trigger.png b/images/examples/checkout/simulate-trigger.png new file mode 100644 index 00000000..2c4da4ff Binary files /dev/null and b/images/examples/checkout/simulate-trigger.png differ diff --git a/images/examples/composition/launch-composition-example.png b/images/examples/composition/launch-composition-example.png new file mode 100644 index 00000000..ff5068a1 Binary files /dev/null and b/images/examples/composition/launch-composition-example.png differ diff --git a/images/examples/deployments/heroku-deployer-pipeline.png b/images/examples/deployments/heroku-deployer-pipeline.png new file mode 100644 index 00000000..3189634c Binary files /dev/null and b/images/examples/deployments/heroku-deployer-pipeline.png differ diff --git a/images/examples/deployments/heroku-deployer-variables.png b/images/examples/deployments/heroku-deployer-variables.png new file mode 100644 index 00000000..7fff37fb Binary files /dev/null and b/images/examples/deployments/heroku-deployer-variables.png differ diff --git a/images/examples/deployments/heroku-deployer-variables2.png b/images/examples/deployments/heroku-deployer-variables2.png new file mode 100644 index 00000000..a8a944c5 Binary files /dev/null and b/images/examples/deployments/heroku-deployer-variables2.png differ diff --git a/images/examples/deployments/heroku-vanilla-push-pipeline.png b/images/examples/deployments/heroku-vanilla-push-pipeline.png new file mode 100644 index 00000000..d3ef1209 Binary files /dev/null and b/images/examples/deployments/heroku-vanilla-push-pipeline.png differ diff --git a/images/examples/deployments/k8s-deployment-CD-pipeline.png b/images/examples/deployments/k8s-deployment-CD-pipeline.png new file mode 100644 index 00000000..551ff840 Binary files /dev/null and b/images/examples/deployments/k8s-deployment-CD-pipeline.png differ diff --git a/images/examples/deployments/k8s-deployment-ci-pipeline.png b/images/examples/deployments/k8s-deployment-ci-pipeline.png new file mode 100644 index 00000000..0e51832c Binary files /dev/null and b/images/examples/deployments/k8s-deployment-ci-pipeline.png differ diff --git a/images/examples/deployments/k8s-kustomize-dashboard.png b/images/examples/deployments/k8s-kustomize-dashboard.png new file mode 100644 index 00000000..2117ca0e Binary files /dev/null and b/images/examples/deployments/k8s-kustomize-dashboard.png differ diff --git a/images/examples/deployments/k8s-kustomize-pipeline.png b/images/examples/deployments/k8s-kustomize-pipeline.png new file mode 100644 index 00000000..59ab7270 Binary files /dev/null and b/images/examples/deployments/k8s-kustomize-pipeline.png differ diff --git a/images/examples/deployments/k8s-kustomize-prod-endpoint.png b/images/examples/deployments/k8s-kustomize-prod-endpoint.png new file mode 100644 index 00000000..1dc4639b Binary files /dev/null and b/images/examples/deployments/k8s-kustomize-prod-endpoint.png differ diff --git a/images/examples/deployments/k8s-kustomize-prod-pipeline.png b/images/examples/deployments/k8s-kustomize-prod-pipeline.png new file mode 100644 index 00000000..91ee13d0 Binary files /dev/null and b/images/examples/deployments/k8s-kustomize-prod-pipeline.png differ diff --git a/images/examples/deployments/k8s-kustomize-staging-endpoint.png b/images/examples/deployments/k8s-kustomize-staging-endpoint.png new file mode 100644 index 00000000..fb9d016b Binary files /dev/null and b/images/examples/deployments/k8s-kustomize-staging-endpoint.png differ diff --git a/images/examples/deployments/k8s-kustomize-staging-pipeline.png b/images/examples/deployments/k8s-kustomize-staging-pipeline.png new file mode 100644 index 00000000..4984c624 Binary files /dev/null and b/images/examples/deployments/k8s-kustomize-staging-pipeline.png differ diff --git a/images/examples/deployments/scp-hello-world.png b/images/examples/deployments/scp-hello-world.png new file mode 100644 index 00000000..d375443d Binary files /dev/null and b/images/examples/deployments/scp-hello-world.png differ diff --git a/images/examples/deployments/scp-pipeline.png b/images/examples/deployments/scp-pipeline.png new file mode 100644 index 00000000..de281fb7 Binary files /dev/null and b/images/examples/deployments/scp-pipeline.png differ diff --git a/images/examples/deployments/scp-variables.png b/images/examples/deployments/scp-variables.png new file mode 100644 index 00000000..5d884180 Binary files /dev/null and b/images/examples/deployments/scp-variables.png differ diff --git a/images/examples/docker-build/auto-push-to-cfcr.png b/images/examples/docker-build/auto-push-to-cfcr.png new file mode 100644 index 00000000..6f0b1013 Binary files /dev/null and b/images/examples/docker-build/auto-push-to-cfcr.png differ diff --git a/images/examples/docker-build/build-and-push-pipeline.png b/images/examples/docker-build/build-and-push-pipeline.png new file mode 100644 index 00000000..9e4a943d Binary files /dev/null and b/images/examples/docker-build/build-and-push-pipeline.png differ diff --git a/images/examples/docker-build/build-dockerfile-root.png b/images/examples/docker-build/build-dockerfile-root.png new file mode 100644 index 00000000..d08ca037 Binary files /dev/null and b/images/examples/docker-build/build-dockerfile-root.png differ diff --git a/images/examples/docker-build/build-from-other-git-repo.png b/images/examples/docker-build/build-from-other-git-repo.png new file mode 100644 index 00000000..5c61a1e3 Binary files /dev/null and b/images/examples/docker-build/build-from-other-git-repo.png differ diff --git a/images/examples/docker-build/build-spefify-dockerfile.png b/images/examples/docker-build/build-spefify-dockerfile.png new file mode 100644 index 00000000..23e71e29 Binary files /dev/null and b/images/examples/docker-build/build-spefify-dockerfile.png differ diff --git a/images/examples/docker-build/cfcr-layers.png b/images/examples/docker-build/cfcr-layers.png new file mode 100644 index 00000000..ca67be1f Binary files /dev/null and b/images/examples/docker-build/cfcr-layers.png differ diff --git a/images/examples/docker-build/docker-build-arguments.png b/images/examples/docker-build/docker-build-arguments.png new file mode 100644 index 00000000..5907584a Binary files /dev/null and b/images/examples/docker-build/docker-build-arguments.png differ diff --git a/images/examples/docker-build/two-docker-images.png b/images/examples/docker-build/two-docker-images.png new file mode 100644 index 00000000..c7974d0d Binary files /dev/null and b/images/examples/docker-build/two-docker-images.png differ diff --git a/images/examples/docker-https/codefresh_nginx_container.png b/images/examples/docker-https/codefresh_nginx_container.png new file mode 100644 index 00000000..f2aea39d Binary files /dev/null and b/images/examples/docker-https/codefresh_nginx_container.png differ diff --git a/images/examples/docker-https/codefresh_webapp_container.png b/images/examples/docker-https/codefresh_webapp_container.png new file mode 100644 index 00000000..b56e30ae Binary files /dev/null and b/images/examples/docker-https/codefresh_webapp_container.png differ diff --git a/images/examples/docker-swarm/docker-swarm-pipeline.png b/images/examples/docker-swarm/docker-swarm-pipeline.png new file mode 100644 index 00000000..2fe7ed3c Binary files /dev/null and b/images/examples/docker-swarm/docker-swarm-pipeline.png differ diff --git a/images/examples/elastic-beanstalk/60d70d4-codefresh_eb_env_vars.png b/images/examples/elastic-beanstalk/60d70d4-codefresh_eb_env_vars.png new file mode 100644 index 00000000..2d481ef8 Binary files /dev/null and b/images/examples/elastic-beanstalk/60d70d4-codefresh_eb_env_vars.png differ diff --git a/images/examples/elastic-beanstalk/codefresh_eb_cf_step_deploy.png b/images/examples/elastic-beanstalk/codefresh_eb_cf_step_deploy.png new file mode 100644 index 00000000..631cc70b Binary files /dev/null and b/images/examples/elastic-beanstalk/codefresh_eb_cf_step_deploy.png differ diff --git a/images/examples/elastic-beanstalk/codefresh_eb_env_vars.png b/images/examples/elastic-beanstalk/codefresh_eb_env_vars.png new file mode 100644 index 00000000..2d481ef8 Binary files /dev/null and b/images/examples/elastic-beanstalk/codefresh_eb_env_vars.png differ diff --git a/images/examples/elastic-beanstalk/codefresh_eb_environment-deploy.png b/images/examples/elastic-beanstalk/codefresh_eb_environment-deploy.png new file mode 100644 index 00000000..f1f462b5 Binary files /dev/null and b/images/examples/elastic-beanstalk/codefresh_eb_environment-deploy.png differ diff --git a/images/examples/elastic-beanstalk/codefresh_eb_environment.png b/images/examples/elastic-beanstalk/codefresh_eb_environment.png new file mode 100644 index 00000000..3b7f6fce Binary files /dev/null and b/images/examples/elastic-beanstalk/codefresh_eb_environment.png differ diff --git a/images/examples/elastic-beanstalk/codefresh_eb_health.png b/images/examples/elastic-beanstalk/codefresh_eb_health.png new file mode 100644 index 00000000..90e083b5 Binary files /dev/null and b/images/examples/elastic-beanstalk/codefresh_eb_health.png differ diff --git a/images/examples/elastic-beanstalk/codefresh_eb_version_label.png b/images/examples/elastic-beanstalk/codefresh_eb_version_label.png new file mode 100644 index 00000000..62e33942 Binary files /dev/null and b/images/examples/elastic-beanstalk/codefresh_eb_version_label.png differ diff --git a/images/examples/git/sha-id-codefresh.png b/images/examples/git/sha-id-codefresh.png new file mode 100644 index 00000000..1b8b758d Binary files /dev/null and b/images/examples/git/sha-id-codefresh.png differ diff --git a/images/examples/git/sha-id-docker-hub.png b/images/examples/git/sha-id-docker-hub.png new file mode 100644 index 00000000..15bb4499 Binary files /dev/null and b/images/examples/git/sha-id-docker-hub.png differ diff --git a/images/examples/gs/gs-download-pipeline.png b/images/examples/gs/gs-download-pipeline.png new file mode 100644 index 00000000..cd704ccf Binary files /dev/null and b/images/examples/gs/gs-download-pipeline.png differ diff --git a/images/examples/gs/gs-pipeline-vars.png b/images/examples/gs/gs-pipeline-vars.png new file mode 100644 index 00000000..c356bc58 Binary files /dev/null and b/images/examples/gs/gs-pipeline-vars.png differ diff --git a/images/examples/gs/gs-upload-pipeline.png b/images/examples/gs/gs-upload-pipeline.png new file mode 100644 index 00000000..e6154ca4 Binary files /dev/null and b/images/examples/gs/gs-upload-pipeline.png differ diff --git a/images/examples/helm/helm-chart.png b/images/examples/helm/helm-chart.png new file mode 100644 index 00000000..54bfff9c Binary files /dev/null and b/images/examples/helm/helm-chart.png differ diff --git a/images/examples/helm/helm-deploy-pipeline.png b/images/examples/helm/helm-deploy-pipeline.png new file mode 100644 index 00000000..3cf18fa3 Binary files /dev/null and b/images/examples/helm/helm-deploy-pipeline.png differ diff --git a/images/examples/helm/helm-push-and-deploy-pipeline.png b/images/examples/helm/helm-push-and-deploy-pipeline.png new file mode 100644 index 00000000..284b6aa8 Binary files /dev/null and b/images/examples/helm/helm-push-and-deploy-pipeline.png differ diff --git a/images/examples/helm/helm-release.png b/images/examples/helm/helm-release.png new file mode 100644 index 00000000..aa25f473 Binary files /dev/null and b/images/examples/helm/helm-release.png differ diff --git a/images/examples/helm/import-helm-configuration.png b/images/examples/helm/import-helm-configuration.png new file mode 100644 index 00000000..538e04ab Binary files /dev/null and b/images/examples/helm/import-helm-configuration.png differ diff --git a/images/examples/integration-tests/integration-tests.png b/images/examples/integration-tests/integration-tests.png new file mode 100644 index 00000000..d1483324 Binary files /dev/null and b/images/examples/integration-tests/integration-tests.png differ diff --git a/images/examples/integration-tests/mongodb-integration-tests.png b/images/examples/integration-tests/mongodb-integration-tests.png new file mode 100644 index 00000000..78604436 Binary files /dev/null and b/images/examples/integration-tests/mongodb-integration-tests.png differ diff --git a/images/examples/integration-tests/mysql-integration-tests.png b/images/examples/integration-tests/mysql-integration-tests.png new file mode 100644 index 00000000..de46fed8 Binary files /dev/null and b/images/examples/integration-tests/mysql-integration-tests.png differ diff --git a/images/examples/integration-tests/postgresql-integration-tests.png b/images/examples/integration-tests/postgresql-integration-tests.png new file mode 100644 index 00000000..b661aecb Binary files /dev/null and b/images/examples/integration-tests/postgresql-integration-tests.png differ diff --git a/images/examples/integration-tests/preload-data-to-db.png b/images/examples/integration-tests/preload-data-to-db.png new file mode 100644 index 00000000..bc7762e3 Binary files /dev/null and b/images/examples/integration-tests/preload-data-to-db.png differ diff --git a/images/examples/integration-tests/redis-integration-tests.png b/images/examples/integration-tests/redis-integration-tests.png new file mode 100644 index 00000000..67b04e6e Binary files /dev/null and b/images/examples/integration-tests/redis-integration-tests.png differ diff --git a/images/examples/nested-pipelines/call-other-pipeline.png b/images/examples/nested-pipelines/call-other-pipeline.png new file mode 100644 index 00000000..dc170913 Binary files /dev/null and b/images/examples/nested-pipelines/call-other-pipeline.png differ diff --git a/images/examples/nomad/.keep b/images/examples/nomad/.keep new file mode 100644 index 00000000..e69de29b diff --git a/images/examples/nomad/nomad-ci-pipeline.png b/images/examples/nomad/nomad-ci-pipeline.png new file mode 100644 index 00000000..45f9c676 Binary files /dev/null and b/images/examples/nomad/nomad-ci-pipeline.png differ diff --git a/images/examples/nomad/nomad-ui-deployment.png b/images/examples/nomad/nomad-ui-deployment.png new file mode 100644 index 00000000..bf1b9736 Binary files /dev/null and b/images/examples/nomad/nomad-ui-deployment.png differ diff --git a/images/examples/nomad/nomad-variables.png b/images/examples/nomad/nomad-variables.png new file mode 100644 index 00000000..98de8aaa Binary files /dev/null and b/images/examples/nomad/nomad-variables.png differ diff --git a/images/examples/packer-gcloud/.keep b/images/examples/packer-gcloud/.keep new file mode 100644 index 00000000..e69de29b diff --git a/images/examples/packer-gcloud/packer-codefresh-pipeline.png b/images/examples/packer-gcloud/packer-codefresh-pipeline.png new file mode 100644 index 00000000..831361ea Binary files /dev/null and b/images/examples/packer-gcloud/packer-codefresh-pipeline.png differ diff --git a/images/examples/packer-gcloud/service-account-variable.png b/images/examples/packer-gcloud/service-account-variable.png new file mode 100644 index 00000000..6da5c0c3 Binary files /dev/null and b/images/examples/packer-gcloud/service-account-variable.png differ diff --git a/images/examples/packer-gcloud/web-app-url.png b/images/examples/packer-gcloud/web-app-url.png new file mode 100644 index 00000000..b5e35624 Binary files /dev/null and b/images/examples/packer-gcloud/web-app-url.png differ diff --git a/images/examples/php-file-transfer/pipeline.png b/images/examples/php-file-transfer/pipeline.png new file mode 100644 index 00000000..bc8e1d54 Binary files /dev/null and b/images/examples/php-file-transfer/pipeline.png differ diff --git a/images/examples/php-file-transfer/test-environment.png b/images/examples/php-file-transfer/test-environment.png new file mode 100644 index 00000000..53f6fe80 Binary files /dev/null and b/images/examples/php-file-transfer/test-environment.png differ diff --git a/images/examples/php-file-transfer/variables.png b/images/examples/php-file-transfer/variables.png new file mode 100644 index 00000000..12e59682 Binary files /dev/null and b/images/examples/php-file-transfer/variables.png differ diff --git a/images/examples/pulumi/pulumi-access-token.png b/images/examples/pulumi/pulumi-access-token.png new file mode 100644 index 00000000..b060c710 Binary files /dev/null and b/images/examples/pulumi/pulumi-access-token.png differ diff --git a/images/examples/pulumi/pulumi-pipeline.png b/images/examples/pulumi/pulumi-pipeline.png new file mode 100644 index 00000000..c685ecae Binary files /dev/null and b/images/examples/pulumi/pulumi-pipeline.png differ diff --git a/images/examples/scala/multi-stage-pipeline.png b/images/examples/scala/multi-stage-pipeline.png new file mode 100644 index 00000000..fccce93c Binary files /dev/null and b/images/examples/scala/multi-stage-pipeline.png differ diff --git a/images/examples/scala/pipeline.png b/images/examples/scala/pipeline.png new file mode 100644 index 00000000..0ad5f393 Binary files /dev/null and b/images/examples/scala/pipeline.png differ diff --git a/images/examples/scala/single-stage-pipeline.png b/images/examples/scala/single-stage-pipeline.png new file mode 100644 index 00000000..a6c34e5c Binary files /dev/null and b/images/examples/scala/single-stage-pipeline.png differ diff --git a/images/examples/sealed-secrets/add-app.png b/images/examples/sealed-secrets/add-app.png new file mode 100644 index 00000000..e90655be Binary files /dev/null and b/images/examples/sealed-secrets/add-app.png differ diff --git a/images/examples/sealed-secrets/app-secrets.png b/images/examples/sealed-secrets/app-secrets.png new file mode 100644 index 00000000..71f7c905 Binary files /dev/null and b/images/examples/sealed-secrets/app-secrets.png differ diff --git a/images/examples/sealed-secrets/current-state.png b/images/examples/sealed-secrets/current-state.png new file mode 100644 index 00000000..afab1258 Binary files /dev/null and b/images/examples/sealed-secrets/current-state.png differ diff --git a/images/examples/secrets/mozilla-sops-pipeline-vars.png b/images/examples/secrets/mozilla-sops-pipeline-vars.png new file mode 100644 index 00000000..fdbef99c Binary files /dev/null and b/images/examples/secrets/mozilla-sops-pipeline-vars.png differ diff --git a/images/examples/secrets/mozilla-sops-pipeline.png b/images/examples/secrets/mozilla-sops-pipeline.png new file mode 100644 index 00000000..977e6ac0 Binary files /dev/null and b/images/examples/secrets/mozilla-sops-pipeline.png differ diff --git a/images/examples/secrets/vault-pipeline.png b/images/examples/secrets/vault-pipeline.png new file mode 100644 index 00000000..ce4245ab Binary files /dev/null and b/images/examples/secrets/vault-pipeline.png differ diff --git a/images/examples/secrets/vault-pipeline2.png b/images/examples/secrets/vault-pipeline2.png new file mode 100644 index 00000000..3b53a97c Binary files /dev/null and b/images/examples/secrets/vault-pipeline2.png differ diff --git a/images/examples/shared-workspace/volume-list.png b/images/examples/shared-workspace/volume-list.png new file mode 100644 index 00000000..dd81b2c7 Binary files /dev/null and b/images/examples/shared-workspace/volume-list.png differ diff --git a/images/examples/terraform/google_cloud_json.png b/images/examples/terraform/google_cloud_json.png new file mode 100644 index 00000000..489c0da2 Binary files /dev/null and b/images/examples/terraform/google_cloud_json.png differ diff --git a/images/examples/terraform/terraform-pipeline.png b/images/examples/terraform/terraform-pipeline.png new file mode 100644 index 00000000..7fa28781 Binary files /dev/null and b/images/examples/terraform/terraform-pipeline.png differ diff --git a/images/examples/unit-tests/fan-in-fan-out-pipeline.png b/images/examples/unit-tests/fan-in-fan-out-pipeline.png new file mode 100644 index 00000000..f4e24eb6 Binary files /dev/null and b/images/examples/unit-tests/fan-in-fan-out-pipeline.png differ diff --git a/images/examples/unit-tests/parallel-pipeline-examples.png b/images/examples/unit-tests/parallel-pipeline-examples.png new file mode 100644 index 00000000..8b171545 Binary files /dev/null and b/images/examples/unit-tests/parallel-pipeline-examples.png differ diff --git a/images/examples/unit-tests/unit-tests-pipeline.png b/images/examples/unit-tests/unit-tests-pipeline.png new file mode 100644 index 00000000..8f21d296 Binary files /dev/null and b/images/examples/unit-tests/unit-tests-pipeline.png differ