diff --git a/community/annual_reports/README.md b/community/annual_reports/README.md deleted file mode 100644 index 4c1040733..000000000 --- a/community/annual_reports/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Welcome to the Knative Annual Reports page. Feedback and comments are welcome at [knative-steering@googlegroups.com](mailto:knative-steering@googlegroups.com). - -| Annual Reports | -| -------------- | -| [2019](https://github.com/knative/community/tree/main/annual_reports/Knative%202019%20Annual%20Report.pdf) | -| [2020](https://github.com/knative/community/tree/main/annual_reports/Knative%202020%20Annual%20Report.pdf) | diff --git a/community/annual_reports/_index.md b/community/annual_reports/_index.md index 06883d2dc..3bdfa2f59 100644 --- a/community/annual_reports/_index.md +++ b/community/annual_reports/_index.md @@ -5,4 +5,10 @@ weight: 40 type: "docs" --- -{{% readfile file="README.md" %}} +Welcome to the Knative Annual Reports page. Feedback and comments are welcome at [knative-steering@googlegroups.com](mailto:knative-steering@googlegroups.com). + +| Annual Reports | +| -------------- | +| [2019](https://github.com/knative/community/tree/main/annual_reports/Knative%202019%20Annual%20Report.pdf) | +| [2020](https://github.com/knative/community/tree/main/annual_reports/Knative%202020%20Annual%20Report.pdf) | + diff --git a/community/meetup/README.md b/community/meetup/README.md deleted file mode 100644 index 8299632a9..000000000 --- a/community/meetup/README.md +++ /dev/null @@ -1,74 +0,0 @@ -Welcome to the Knative Community Meetup page! - -The virtual event is designed for end users, a space for our community to meet, get to know each other, and learn about uses and applications of Knative. - -Catch up with past community meetups on our [YouTube channel](https://www.youtube.com/playlist?list=PLQjzPfIiEQLLyCyLBKLlwDLfE_A-P7nyg). - -Here we will list all the information related to past and future events. - -Stay tuned for new events by subscribing to our [calendar](https://calendar.google.com/calendar/embed?src=knative.team_9q83bg07qs5b9rrslp5jor4l6s%40group.calendar.google.com&ctz=America%2FLos_Angeles) ([iCal export file](https://calendar.google.com/calendar/ical/knative.team_9q83bg07qs5b9rrslp5jor4l6s%40group.calendar.google.com/public/basic.ics)) and following us on [Twitter](https://twitter.com/KnativeProject). - ---- - -### 2020-05-14 – Knative Community Meetup #2 - -Video: https://youtu.be/24owwOKj86E - -## Agenda -- Welcome! (5’) - - Announce recording of meeting. -- Update from the Steering Committee (15’) - - TOC election results (Tomas Isdal) -- Working groups updates (5’) -- Demo - "Automating service delivery with bindings" by Evan Anderson, software engineer at VMware (30’) -- Demo discussion / conversation (15’-20’) -- Close (5’) -- Take the [survey](https://docs.google.com/forms/d/e/1FAIpQLSebw2IOjmnStiUhPpnndpjyuBUoziZOw9PK9fnJeFBQX0QxWw/viewform)! (it’s good karma) - -## TOC Election results -- Nghia Tran (Google) - new member -- Markus Thömmes (Red Hat) - new member -- Grant Rodgers (Google) - new member -- Matt Moore (VMWare) - existing member -- Evan Anderson (VMWare) - existing member -Congratulations to the newly elected members! ✨ - -## Working group updates -- Autoscaling WG - - Big improvements to the autoscaling documentation, both internally and user-facing. Go check them out! - - User facing docs: https://knative.dev/docs/serving/configuring-autoscaling/ - - Technical docs: https://github.com/knative/serving/blob/main/docs/scaling/SYSTEM.md -- A lot of improvements to the loadbalancing in Knative has landed, vastly improving latency for concurrency-limited revisions. Give HEAD a whirl if you’re seeing issues there. -- Speaking of issues: We need your input! - - We’re preparing a questionnaire to gather structured feedback regarding the types of workloads you’re running and which settings you find yourself tweaking to make autoscaling work in your favor. - - While we’re preparing that (will likely be sent out via the knative-users list), please feel free to give us free-form feedback on anything autoscaling. That can either be Github issues if you’re having issues, a thread on knative-users or send it to me privately if you can’t share publicly. - -## Eventing -- Update on Brokers - - https://github.com/knative/eventing/issues/3139 - ---- - -### 2020-04-16 – Knative Community Meetup #1 -Video: https://www.youtube.com/watch?v=k0QJEyV4U-4 - -Agenda: -- Welcome! (5’) - - Announce recording of meeting. -- Update from the Steering Committee (5’) - - TOC election announcement (Brenda Chan) -- Working groups updates (15’-20’) - - Eventing (Aleksander Slominski and Davy Odom) - - Networking (Nghia Tran) - - Operation (Vincent Hou) - - Client (Roland Huss) -- [Demo - "Tracking the Bitcoin ledger" - by Johana Saladas (IBM) (30’)](https://www.youtube.com/watch?v=sGi_LuAaaT0) -- Demo discussion / conversation (15’-20’) -- Close (5’) - - Take the [survey](https://docs.google.com/forms/d/e/1FAIpQLSebw2IOjmnStiUhPpnndpjyuBUoziZOw9PK9fnJeFBQX0QxWw/viewform)! (it’s good karma) - -The demo for this first community meetup is "Tracking the Bitcoin ledger", designed and carried out by @josiemundi, software engineer at IBM. Thank you for volunteering, Johana! - -Here are the resources from the demo: -- https://github.com/josiemundi/knative-eventing-blockchain-demo -- https://github.com/josiemundi/knative-bitcoin-websocket-eventsource diff --git a/community/meetup/_index.md b/community/meetup/_index.md index 51cd7f3f7..39e4e3bd4 100644 --- a/community/meetup/_index.md +++ b/community/meetup/_index.md @@ -5,4 +5,78 @@ weight: 30 type: "docs" --- -{{% readfile file="README.md" %}} +Welcome to the Knative Community Meetup page! + +The virtual event is designed for end users, a space for our community to meet, get to know each other, and learn about uses and applications of Knative. + +Catch up with past community meetups on our [YouTube channel](https://www.youtube.com/playlist?list=PLQjzPfIiEQLLyCyLBKLlwDLfE_A-P7nyg). + +Here we will list all the information related to past and future events. + +Stay tuned for new events by subscribing to our [calendar](https://calendar.google.com/calendar/embed?src=knative.team_9q83bg07qs5b9rrslp5jor4l6s%40group.calendar.google.com&ctz=America%2FLos_Angeles) ([iCal export file](https://calendar.google.com/calendar/ical/knative.team_9q83bg07qs5b9rrslp5jor4l6s%40group.calendar.google.com/public/basic.ics)) and following us on [Twitter](https://twitter.com/KnativeProject). + +--- + +### 2020-05-14 – Knative Community Meetup #2 + +Video: https://youtu.be/24owwOKj86E + +## Agenda +- Welcome! (5’) + - Announce recording of meeting. +- Update from the Steering Committee (15’) + - TOC election results (Tomas Isdal) +- Working groups updates (5’) +- Demo - "Automating service delivery with bindings" by Evan Anderson, software engineer at VMware (30’) +- Demo discussion / conversation (15’-20’) +- Close (5’) +- Take the [survey](https://docs.google.com/forms/d/e/1FAIpQLSebw2IOjmnStiUhPpnndpjyuBUoziZOw9PK9fnJeFBQX0QxWw/viewform)! (it’s good karma) + +## TOC Election results +- Nghia Tran (Google) - new member +- Markus Thömmes (Red Hat) - new member +- Grant Rodgers (Google) - new member +- Matt Moore (VMWare) - existing member +- Evan Anderson (VMWare) - existing member +Congratulations to the newly elected members! ✨ + +## Working group updates +- Autoscaling WG + - Big improvements to the autoscaling documentation, both internally and user-facing. Go check them out! + - User facing docs: https://knative.dev/docs/serving/configuring-autoscaling/ + - Technical docs: https://github.com/knative/serving/blob/main/docs/scaling/SYSTEM.md +- A lot of improvements to the loadbalancing in Knative has landed, vastly improving latency for concurrency-limited revisions. Give HEAD a whirl if you’re seeing issues there. +- Speaking of issues: We need your input! + - We’re preparing a questionnaire to gather structured feedback regarding the types of workloads you’re running and which settings you find yourself tweaking to make autoscaling work in your favor. + - While we’re preparing that (will likely be sent out via the knative-users list), please feel free to give us free-form feedback on anything autoscaling. That can either be Github issues if you’re having issues, a thread on knative-users or send it to me privately if you can’t share publicly. + +## Eventing +- Update on Brokers + - https://github.com/knative/eventing/issues/3139 + +--- + +### 2020-04-16 – Knative Community Meetup #1 +Video: https://www.youtube.com/watch?v=k0QJEyV4U-4 + +Agenda: +- Welcome! (5’) + - Announce recording of meeting. +- Update from the Steering Committee (5’) + - TOC election announcement (Brenda Chan) +- Working groups updates (15’-20’) + - Eventing (Aleksander Slominski and Davy Odom) + - Networking (Nghia Tran) + - Operation (Vincent Hou) + - Client (Roland Huss) +- [Demo - "Tracking the Bitcoin ledger" - by Johana Saladas (IBM) (30’)](https://www.youtube.com/watch?v=sGi_LuAaaT0) +- Demo discussion / conversation (15’-20’) +- Close (5’) + - Take the [survey](https://docs.google.com/forms/d/e/1FAIpQLSebw2IOjmnStiUhPpnndpjyuBUoziZOw9PK9fnJeFBQX0QxWw/viewform)! (it’s good karma) + +The demo for this first community meetup is "Tracking the Bitcoin ledger", designed and carried out by @josiemundi, software engineer at IBM. Thank you for volunteering, Johana! + +Here are the resources from the demo: +- https://github.com/josiemundi/knative-eventing-blockchain-demo +- https://github.com/josiemundi/knative-bitcoin-websocket-eventsource + diff --git a/community/samples/README.md b/community/samples/README.md deleted file mode 100644 index 78dbaafb8..000000000 --- a/community/samples/README.md +++ /dev/null @@ -1,40 +0,0 @@ -Get up and running with one of the community code samples. These samples are -contributed and maintained by members of the Knative community. - -Note: It is possible that one or more samples might become outdated or the -original author is unable to maintain their contribution. If you find that -something isn't working, lend a helping hand and fix it in a PR. - -[Learn more about the lifespan of samples](https://github.com/knative/docs/tree/main/CONTRIBUTING.md#user-focused-content) - -[**See all Knative code samples**](../../docs/samples.md) - -### Interactive serving sample - -Check out [this Katacoda -tutorial](https://www.katacoda.com/swapb/scenarios/knative-intro) which will -walk you through installing Knative and the `kn` command line tool, deploying a -sample container, updating your deployment, and performing a traffic split -between the two versions. - -### Serving samples - -Knative Serving sample apps. - -| Sample Name | Description | Language(s) | -| ----------- | ----------- | ----------- | -| Hello World | A quick introduction to Knative Serving that highlights how to deploy an app. | [Clojure](./serving/helloworld-clojure/README.md), [Dart](./serving/helloworld-dart/README.md), [Elixir](./serving/helloworld-elixir/README.md), [Haskell](./serving/helloworld-haskell/README.md), [Java - Micronaut](./serving/helloworld-java-micronaut/README.md), [Java - Quarkus](./serving/helloworld-java-quarkus/README.md), [R - Go Server](./serving/helloworld-r/README.md), [Rust](./serving/helloworld-rust/README.md), [Swift](./serving/helloworld-swift/README.md), [Vertx](./serving/helloworld-vertx/README.md) | -| Machine Learning | A quick introduction to using Knative Serving to serve machine learning models | [Python - BentoML](./serving/machinelearning-python-bentoml) - -#### Eventing and Eventing Resources samples - -- _Be the first to contribute an Eventing or Eventing Sources code sample to the - community collection._ - -### Client samples - -Knative `kn` Client sample workflows and apps. - -| Sample Name | Description | -| ----------- | ----------- | -| [knfun](https://github.com/maximilien/knfun) | Knative micro-functions (Twitter and Watson APIs) demo using the `kn` client. | diff --git a/community/samples/_index.md b/community/samples/_index.md index e4d5a7c09..72187cda7 100644 --- a/community/samples/_index.md +++ b/community/samples/_index.md @@ -5,4 +5,44 @@ weight: 40 type: "docs" --- -{{% readfile file="README.md" %}} +Get up and running with one of the community code samples. These samples are +contributed and maintained by members of the Knative community. + +Note: It is possible that one or more samples might become outdated or the +original author is unable to maintain their contribution. If you find that +something isn't working, lend a helping hand and fix it in a PR. + +[Learn more about the lifespan of samples](https://github.com/knative/docs/tree/main/CONTRIBUTING.md#user-focused-content) + +[**See all Knative code samples**](../../docs/samples.md) + +### Interactive serving sample + +Check out [this Katacoda +tutorial](https://www.katacoda.com/swapb/scenarios/knative-intro) which will +walk you through installing Knative and the `kn` command line tool, deploying a +sample container, updating your deployment, and performing a traffic split +between the two versions. + +### Serving samples + +Knative Serving sample apps. + +| Sample Name | Description | Language(s) | +| ----------- | ----------- | ----------- | +| Hello World | A quick introduction to Knative Serving that highlights how to deploy an app. | [Clojure](./serving/helloworld-clojure/README.md), [Dart](./serving/helloworld-dart/README.md), [Elixir](./serving/helloworld-elixir/README.md), [Haskell](./serving/helloworld-haskell/README.md), [Java - Micronaut](./serving/helloworld-java-micronaut/README.md), [Java - Quarkus](./serving/helloworld-java-quarkus/README.md), [R - Go Server](./serving/helloworld-r/README.md), [Rust](./serving/helloworld-rust/README.md), [Swift](./serving/helloworld-swift/README.md), [Vertx](./serving/helloworld-vertx/README.md) | +| Machine Learning | A quick introduction to using Knative Serving to serve machine learning models | [Python - BentoML](./serving/machinelearning-python-bentoml) + +#### Eventing and Eventing Resources samples + +- _Be the first to contribute an Eventing or Eventing Sources code sample to the + community collection._ + +### Client samples + +Knative `kn` Client sample workflows and apps. + +| Sample Name | Description | +| ----------- | ----------- | +| [knfun](https://github.com/maximilien/knfun) | Knative micro-functions (Twitter and Watson APIs) demo using the `kn` client. | + diff --git a/community/samples/serving/helloworld-clojure/README.md b/community/samples/serving/helloworld-clojure/README.md deleted file mode 100644 index d4c1960db..000000000 --- a/community/samples/serving/helloworld-clojure/README.md +++ /dev/null @@ -1,155 +0,0 @@ -A simple web app written in Clojure that you can use for testing. It reads in an -env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not -specified, it will use "World" as the TARGET. - -## Prerequisites - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../docs/install/README.md) if you need to create - one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Recreating the sample code - -While you can clone all of the code from this directory, hello world apps are -generally more useful if you build them step-by-step. The following instructions -recreate the source files from this folder. - -1. Create a new file named `src/helloworld/core.clj` and paste the following - code. This code creates a basic web server which listens on port 8080: - - ```clojure - (ns helloworld.core - (:use ring.adapter.jetty) - (:gen-class)) - - (defn handler [request] - {:status 200 - :headers {"Content-Type" "text/html"} - :body (str "Hello " - (if-let [target (System/getenv "TARGET")] - target - "World") - "!\n")}) - - (defn -main [& args] - (run-jetty handler {:port (if-let [port (System/getenv "PORT")] - (Integer/parseInt port) - 8080)})) - ``` - -1. In your project directory, create a file named `project.clj` and copy the - code below into it. This code defines the project's dependencies and - entrypoint. - - ```clojure - (defproject helloworld "1.0.0-SNAPSHOT" - :description "Hello World - Clojure sample" - :dependencies [[org.clojure/clojure "1.9.0"] - [ring/ring-core "1.6.3"] - [ring/ring-jetty-adapter "1.6.3"]] - :main helloworld.core) - ``` - -1. In your project directory, create a file named `Dockerfile` and copy the code - block below into it. For detailed instructions on dockerizing a Clojure app, - see - [the clojure image documentation](https://github.com/docker-library/docs/tree/master/clojure). - - ```docker - # Use the official Clojure image. - # https://hub.docker.com/_/clojure - FROM clojure - - # Create the project and download dependencies. - WORKDIR /usr/src/app - COPY project.clj . - RUN lein deps - - # Copy local code to the container image. - COPY . . - - # Build an uberjar release artifact. - RUN mv "$(lein uberjar | sed -n 's/^Created \(.*standalone\.jar\)/\1/p')" app-standalone.jar - - # Run the web service on container startup. - CMD ["java", "-jar", "app-standalone.jar"] - ``` - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-clojure - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-clojure - env: - - name: TARGET - value: "Clojure Sample v1" - ``` - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-clojure . - - # Push the container to docker registry - docker push {username}/helloworld-clojure - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. To find the URL for your service, use - - ``` - kubectl get ksvc helloworld-clojure --output=custom-columns=NAME:.metadata.name,URL:.status.url - NAME URL - helloworld-clojure http://helloworld-clojure.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-clojure.default.1.2.3.4.xip.io - Hello World! - ``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-clojure/index.md b/community/samples/serving/helloworld-clojure/index.md index 8704c38ed..f9dabb47e 100644 --- a/community/samples/serving/helloworld-clojure/index.md +++ b/community/samples/serving/helloworld-clojure/index.md @@ -5,4 +5,159 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in Clojure that you can use for testing. It reads in an +env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not +specified, it will use "World" as the TARGET. + +## Prerequisites + +- A Kubernetes cluster with Knative installed and DNS configured. Follow the + [installation instructions](../../../../docs/install/README.md) if you need to create + one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). + +## Recreating the sample code + +While you can clone all of the code from this directory, hello world apps are +generally more useful if you build them step-by-step. The following instructions +recreate the source files from this folder. + +1. Create a new file named `src/helloworld/core.clj` and paste the following + code. This code creates a basic web server which listens on port 8080: + + ```clojure + (ns helloworld.core + (:use ring.adapter.jetty) + (:gen-class)) + + (defn handler [request] + {:status 200 + :headers {"Content-Type" "text/html"} + :body (str "Hello " + (if-let [target (System/getenv "TARGET")] + target + "World") + "!\n")}) + + (defn -main [& args] + (run-jetty handler {:port (if-let [port (System/getenv "PORT")] + (Integer/parseInt port) + 8080)})) + ``` + +1. In your project directory, create a file named `project.clj` and copy the + code below into it. This code defines the project's dependencies and + entrypoint. + + ```clojure + (defproject helloworld "1.0.0-SNAPSHOT" + :description "Hello World - Clojure sample" + :dependencies [[org.clojure/clojure "1.9.0"] + [ring/ring-core "1.6.3"] + [ring/ring-jetty-adapter "1.6.3"]] + :main helloworld.core) + ``` + +1. In your project directory, create a file named `Dockerfile` and copy the code + block below into it. For detailed instructions on dockerizing a Clojure app, + see + [the clojure image documentation](https://github.com/docker-library/docs/tree/master/clojure). + + ```docker + # Use the official Clojure image. + # https://hub.docker.com/_/clojure + FROM clojure + + # Create the project and download dependencies. + WORKDIR /usr/src/app + COPY project.clj . + RUN lein deps + + # Copy local code to the container image. + COPY . . + + # Build an uberjar release artifact. + RUN mv "$(lein uberjar | sed -n 's/^Created \(.*standalone\.jar\)/\1/p')" app-standalone.jar + + # Run the web service on container startup. + CMD ["java", "-jar", "app-standalone.jar"] + ``` + +1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-clojure + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-clojure + env: + - name: TARGET + value: "Clojure Sample v1" + ``` + +## Building and deploying the sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-clojure . + + # Push the container to docker registry + docker push {username}/helloworld-clojure + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. To find the URL for your service, use + + ``` + kubectl get ksvc helloworld-clojure --output=custom-columns=NAME:.metadata.name,URL:.status.url + NAME URL + helloworld-clojure http://helloworld-clojure.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-clojure.default.1.2.3.4.xip.io + Hello World! + ``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` + diff --git a/community/samples/serving/helloworld-dart/README.md b/community/samples/serving/helloworld-dart/README.md deleted file mode 100644 index 2311c1c03..000000000 --- a/community/samples/serving/helloworld-dart/README.md +++ /dev/null @@ -1,153 +0,0 @@ -A simple web app written in the [Dart](https://www.dart.dev) programming language -that you can use for testing. It reads in the env variable `TARGET` and prints -`"Hello $TARGET"`. If `TARGET` is not specified, it will use `"World"` as -`TARGET`. - -## Prerequisites - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../docs/install/README.md) if you need to create - one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). -- [dart-sdk](https://www.dart.dev/tools/sdk#install) installed and - configured if you want to run the program locally. - -## Recreating the sample code - -While you can clone all of the code from this directory, it is useful to know -how to build a hello world Dart application step-by-step. This application can -be created using the following instructions. - -1. Create a new directory and write `pubspec.yaml` as follows: - - ```yaml - name: hello_world_dart - publish_to: none # let's not accidentally publish this to pub.dartlang.org - - environment: - sdk: ">=2.12.0 <3.0.0" - - dependencies: - shelf: ^1.0.0 - ``` - -2. If you want to run locally, install dependencies. If you only want to run in - Docker or Knative, you can skip this step. - - ```shell - > pub get - ``` - -3. Create a new file `bin/server.dart` and write the following code: - - ```dart - import 'dart:io'; - - import 'package:shelf/shelf.dart'; - import 'package:shelf/shelf_io.dart'; - - Future main() async { - // Find port to listen on from environment variable. - final port = int.parse(Platform.environment['PORT'] ?? '8080'); - - // Read $TARGET from environment variable. - final target = Platform.environment['TARGET'] ?? 'World'; - - Response handler(Request request) => Response.ok('Hello $target'); - - // Serve handler on given port. - final server = await serve( - const Pipeline().addMiddleware(logRequests()).addHandler(handler), - InternetAddress.anyIPv4, - port, - ); - print('Serving at http://${server.address.host}:${server.port}'); - } - ``` - -4. Create a new file named `Dockerfile`, this file defines instructions for - dockerizing your applications, for dart apps this can be done as follows: - - ```Dockerfile - # Use Google's official Dart image. - # https://hub.docker.com/r/google/dart-runtime/ - FROM google/dart-runtime - ``` - -5. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-dart - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-dart - env: - - name: TARGET - value: "Dart Sample v1" - ``` - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-dart . - - # Push the container to docker registry - docker push {username}/helloworld-dart - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. To find the URL for your service, use - - ``` - kubectl get ksvc helloworld-dart --output=custom-columns=NAME:.metadata.name,URL:.status.url - NAME URL - helloworld-dart http://helloworld-dart.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-dart.default.1.2.3.4.xip.io - Hello Dart Sample v1 - ``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-dart/index.md b/community/samples/serving/helloworld-dart/index.md index c576dfc69..c87ca8e35 100644 --- a/community/samples/serving/helloworld-dart/index.md +++ b/community/samples/serving/helloworld-dart/index.md @@ -5,4 +5,156 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in the [Dart](https://www.dart.dev) programming language +that you can use for testing. It reads in the env variable `TARGET` and prints +`"Hello $TARGET"`. If `TARGET` is not specified, it will use `"World"` as +`TARGET`. + +## Prerequisites + +- A Kubernetes cluster with Knative installed and DNS configured. Follow the + [installation instructions](../../../../docs/install/README.md) if you need to create + one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). +- [dart-sdk](https://www.dart.dev/tools/sdk#install) installed and + configured if you want to run the program locally. + +## Recreating the sample code + +While you can clone all of the code from this directory, it is useful to know +how to build a hello world Dart application step-by-step. This application can +be created using the following instructions. + +1. Create a new directory and write `pubspec.yaml` as follows: + + ```yaml + name: hello_world_dart + publish_to: none # let's not accidentally publish this to pub.dartlang.org + + environment: + sdk: ">=2.12.0 <3.0.0" + + dependencies: + shelf: ^1.0.0 + ``` + +2. If you want to run locally, install dependencies. If you only want to run in + Docker or Knative, you can skip this step. + + ```shell + > pub get + ``` + +3. Create a new file `bin/server.dart` and write the following code: + + ```dart + import 'dart:io'; + + import 'package:shelf/shelf.dart'; + import 'package:shelf/shelf_io.dart'; + + Future main() async { + // Find port to listen on from environment variable. + final port = int.parse(Platform.environment['PORT'] ?? '8080'); + + // Read $TARGET from environment variable. + final target = Platform.environment['TARGET'] ?? 'World'; + + Response handler(Request request) => Response.ok('Hello $target'); + + // Serve handler on given port. + final server = await serve( + const Pipeline().addMiddleware(logRequests()).addHandler(handler), + InternetAddress.anyIPv4, + port, + ); + print('Serving at http://${server.address.host}:${server.port}'); + } + ``` + +4. Create a new file named `Dockerfile`, this file defines instructions for + dockerizing your applications, for dart apps this can be done as follows: + + ```Dockerfile + # Use Google's official Dart image. + # https://hub.docker.com/r/google/dart-runtime/ + FROM google/dart-runtime + ``` + +5. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-dart + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-dart + env: + - name: TARGET + value: "Dart Sample v1" + ``` + +## Building and deploying the sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-dart . + + # Push the container to docker registry + docker push {username}/helloworld-dart + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. To find the URL for your service, use + + ``` + kubectl get ksvc helloworld-dart --output=custom-columns=NAME:.metadata.name,URL:.status.url + NAME URL + helloworld-dart http://helloworld-dart.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-dart.default.1.2.3.4.xip.io + Hello Dart Sample v1 + ``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/community/samples/serving/helloworld-deno/README.md b/community/samples/serving/helloworld-deno/README.md deleted file mode 100644 index 8a1ac729a..000000000 --- a/community/samples/serving/helloworld-deno/README.md +++ /dev/null @@ -1,142 +0,0 @@ -A simple web app written in Deno. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/hello-world/helloworld-deno -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed. Follow the - [installation instructions](../../../../docs/install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Recreating the sample code - -1. Create a new file named `deps.ts` and paste the following script: - - ```ts - export { serve } from "https://deno.land/std@std@0.50.0/http/server.ts"; - ``` - -1. Create a new file named `main.ts` and paste the following script: - - ```ts - import { serve } from "./deps.ts"; - import "https://deno.land/x/dotenv/mod.ts"; - - const PORT = Deno.env.get('PORT') || 8080; - const s = serve(`0.0.0.0:${PORT}`); - const body = new TextEncoder().encode("Hello Deno\n"); - - console.log(`Server started on port ${PORT}`); - for await (const req of s) { - req.respond({ body }); - } - ``` - -1. Create a new file named `Dockerfile` and copy the code block below into it. - - ```docker - FROM hayd/alpine-deno:1.0.0-rc2 - WORKDIR /app - - # These steps will be re-run upon each file change in your working directory: - COPY . ./ - - # Added to ENTRYPOINT of base image. - CMD ["run", "--allow-env", "--allow-net", "main.ts"] - ``` - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-deno - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-deno - ``` - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-deno . - - # Push the container to docker registry - docker push {username}/helloworld-deno - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative performs the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. Run the following command to find the domain URL for your service: - - ```shell - kubectl get ksvc helloworld-deno --output=custom-columns=NAME:.metadata.name,URL:.status.url - ``` - - Example: - - ```shell - NAME URL - helloworld-deno http://helloworld-deno.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-deno.default.1.2.3.4.xip.io - ``` - - Example: - - ```shell - curl http://helloworld-deno.default.1.2.3.4.xip.io - [1] "Hello R Sample v1!" - ``` - - > Note: Add `-v` option to get more detail if the `curl` command failed. - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-deno/index.md b/community/samples/serving/helloworld-deno/index.md index 8ccc08c90..d58fe6840 100644 --- a/community/samples/serving/helloworld-deno/index.md +++ b/community/samples/serving/helloworld-deno/index.md @@ -5,4 +5,146 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in Deno. + +Follow the steps below to create the sample code and then deploy the app to your +cluster. You can also download a working copy of the sample, by running the +following commands: + +```shell +git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs +cd knative-docs/docs/serving/samples/hello-world/helloworld-deno +``` + +## Before you begin + +- A Kubernetes cluster with Knative installed. Follow the + [installation instructions](../../../../docs/install/README.md) if you need to + create one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). + +## Recreating the sample code + +1. Create a new file named `deps.ts` and paste the following script: + + ```ts + export { serve } from "https://deno.land/std@std@0.50.0/http/server.ts"; + ``` + +1. Create a new file named `main.ts` and paste the following script: + + ```ts + import { serve } from "./deps.ts"; + import "https://deno.land/x/dotenv/mod.ts"; + + const PORT = Deno.env.get('PORT') || 8080; + const s = serve(`0.0.0.0:${PORT}`); + const body = new TextEncoder().encode("Hello Deno\n"); + + console.log(`Server started on port ${PORT}`); + for await (const req of s) { + req.respond({ body }); + } + ``` + +1. Create a new file named `Dockerfile` and copy the code block below into it. + + ```docker + FROM hayd/alpine-deno:1.0.0-rc2 + WORKDIR /app + + # These steps will be re-run upon each file change in your working directory: + COPY . ./ + + # Added to ENTRYPOINT of base image. + CMD ["run", "--allow-env", "--allow-net", "main.ts"] + ``` + +1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-deno + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-deno + ``` + +## Building and deploying the sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-deno . + + # Push the container to docker registry + docker push {username}/helloworld-deno + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative performs the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. Run the following command to find the domain URL for your service: + + ```shell + kubectl get ksvc helloworld-deno --output=custom-columns=NAME:.metadata.name,URL:.status.url + ``` + + Example: + + ```shell + NAME URL + helloworld-deno http://helloworld-deno.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-deno.default.1.2.3.4.xip.io + ``` + + Example: + + ```shell + curl http://helloworld-deno.default.1.2.3.4.xip.io + [1] "Hello R Sample v1!" + ``` + + > Note: Add `-v` option to get more detail if the `curl` command failed. + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` + diff --git a/community/samples/serving/helloworld-elixir/README.md b/community/samples/serving/helloworld-elixir/README.md deleted file mode 100644 index a191fb7ac..000000000 --- a/community/samples/serving/helloworld-elixir/README.md +++ /dev/null @@ -1,292 +0,0 @@ -A simple web application written in [Elixir](https://elixir-lang.org/) using the -[Phoenix Framework](https://phoenixframework.org/). The application prints all -environment variables to the main page. - -# Set up Elixir and Phoenix Locally - -Following the -[Phoenix Installation Guide](https://hexdocs.pm/phoenix/installation.html) is -the best way to get your computer set up for developing, building, running, and -packaging Elixir Web applications. - -# Running Locally - -To start your Phoenix server: - -- Install dependencies with `mix deps.get` -- Install Node.js dependencies with `cd assets && npm install` -- Start Phoenix endpoint with `mix phx.server` - -Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. - -# Recreating the sample code - -1. Generate a new project. - -```shell -mix phoenix.new helloelixir -``` - -When asked, if you want to `Fetch and install dependencies? [Yn]` select `y` - -1. Follow the direction in the output to change directories into start your - local server with `mix phoenix.server` - -1. In the new directory, create a new Dockerfile for packaging your application - for deployment - - ```docker - # Start from a base image for elixir - # Phoenix works best on pre 1.7 at the moment. - FROM elixir:1.6.6-alpine - - # Set up Elixir and Phoenix - ARG APP_NAME=hello - ARG PHOENIX_SUBDIR=. - ENV MIX_ENV=prod REPLACE_OS_VARS=true TERM=xterm - WORKDIR /opt/app - - # Update nodejs, rebar, and hex. - RUN apk update \ - && apk --no-cache --update add nodejs nodejs-npm \ - && mix local.rebar --force \ - && mix local.hex --force - COPY . . - - # Download and compile dependencies, then compile Web app. - RUN mix do deps.get, deps.compile, compile - RUN cd ${PHOENIX_SUBDIR}/assets \ - && npm install \ - && ./node_modules/brunch/bin/brunch build -p \ - && cd .. \ - && mix phx.digest - - # Create a release version of the application - RUN mix release --env=prod --verbose \ - && mv _build/prod/rel/${APP_NAME} /opt/release \ - && mv /opt/release/bin/${APP_NAME} /opt/release/bin/start_server - - # Prepare final layer - FROM alpine:latest - RUN apk update && apk --no-cache --update add bash openssl-dev ca-certificates - - # Add a user so the server will run as a non-root user. - RUN addgroup -g 1000 appuser && \ - adduser -S -u 1000 -G appuser appuser - # Pre-create necessary temp directory for erlang and set permissions. - RUN mkdir -p /opt/app/var - RUN chown appuser /opt/app/var - # Run everything else as 'appuser' - USER appuser - - ENV MIX_ENV=prod REPLACE_OS_VARS=true - WORKDIR /opt/app - COPY --from=0 /opt/release . - ENV RUNNER_LOG_DIR /var/log - - # Command to execute the application. - CMD ["/opt/app/bin/start_server", "foreground", "boot_var=/tmp"] - ``` - -1. Create a new file, `service.yaml` and copy the following Service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-elixir - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-elixir - env: - - name: TARGET - value: "elixir Sample v1" - ``` - -# Building and deploying the sample - -The sample in this directory is ready to build and deploy without changes. You -can deploy the sample as is, or use you created version following the directions -above. - -1. Generate a new `secret_key_base` in the `config/prod.secret.exs` file. - Phoenix applications use a secrets file on production deployments and, by - default, that file is not checked into source control. We have provides - shell of an example on `config/prod.secret.exs.sample` and you can use the - following command to generate a new prod secrets file. - - ```shell - SECRET_KEY_BASE=$(elixir -e ":crypto.strong_rand_bytes(48) |> Base.encode64 |> IO.puts") - sed "s|SECRET+KEY+BASE|$SECRET_KEY_BASE|" config/prod.secret.exs.sample >config/prod.secret.exs - ``` - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-elixir . - - # Push the container to docker registry - docker push {username}/helloworld-elixir - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. - Apply the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. To find the URL for your service, use - - ``` - kubectl get ksvc helloworld-elixir --output=custom-columns=NAME:.metadata.name,URL:.status.url - - NAME URL - helloworld-elixir http://helloworld-elixir.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app to see the results. Replace - `{IP_ADDRESS}` with the address you see returned in the previous step. - - ```shell - curl http://helloworld-elixir.default.1.2.3.4.xip.io - - ... - # HTML from your application is returned. - ``` - - Here is the HTML returned from our deployed sample application: - - ```HTML - - - - - - - - - - Hello Knative - - - ``` - - -
-
- -
- - - - -
- -
-

Welcome to Knative and Elixir

- -

$TARGET = elixir Sample v1

-
- -

Environment

- -
- -
- - - - - ``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-elixir/index.md b/community/samples/serving/helloworld-elixir/index.md index fadaab7af..df9d95f7f 100644 --- a/community/samples/serving/helloworld-elixir/index.md +++ b/community/samples/serving/helloworld-elixir/index.md @@ -5,4 +5,295 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web application written in [Elixir](https://elixir-lang.org/) using the +[Phoenix Framework](https://phoenixframework.org/). The application prints all +environment variables to the main page. + +# Set up Elixir and Phoenix Locally + +Following the +[Phoenix Installation Guide](https://hexdocs.pm/phoenix/installation.html) is +the best way to get your computer set up for developing, building, running, and +packaging Elixir Web applications. + +# Running Locally + +To start your Phoenix server: + +- Install dependencies with `mix deps.get` +- Install Node.js dependencies with `cd assets && npm install` +- Start Phoenix endpoint with `mix phx.server` + +Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. + +# Recreating the sample code + +1. Generate a new project. + +```shell +mix phoenix.new helloelixir +``` + +When asked, if you want to `Fetch and install dependencies? [Yn]` select `y` + +1. Follow the direction in the output to change directories into start your + local server with `mix phoenix.server` + +1. In the new directory, create a new Dockerfile for packaging your application + for deployment + + ```docker + # Start from a base image for elixir + # Phoenix works best on pre 1.7 at the moment. + FROM elixir:1.6.6-alpine + + # Set up Elixir and Phoenix + ARG APP_NAME=hello + ARG PHOENIX_SUBDIR=. + ENV MIX_ENV=prod REPLACE_OS_VARS=true TERM=xterm + WORKDIR /opt/app + + # Update nodejs, rebar, and hex. + RUN apk update \ + && apk --no-cache --update add nodejs nodejs-npm \ + && mix local.rebar --force \ + && mix local.hex --force + COPY . . + + # Download and compile dependencies, then compile Web app. + RUN mix do deps.get, deps.compile, compile + RUN cd ${PHOENIX_SUBDIR}/assets \ + && npm install \ + && ./node_modules/brunch/bin/brunch build -p \ + && cd .. \ + && mix phx.digest + + # Create a release version of the application + RUN mix release --env=prod --verbose \ + && mv _build/prod/rel/${APP_NAME} /opt/release \ + && mv /opt/release/bin/${APP_NAME} /opt/release/bin/start_server + + # Prepare final layer + FROM alpine:latest + RUN apk update && apk --no-cache --update add bash openssl-dev ca-certificates + + # Add a user so the server will run as a non-root user. + RUN addgroup -g 1000 appuser && \ + adduser -S -u 1000 -G appuser appuser + # Pre-create necessary temp directory for erlang and set permissions. + RUN mkdir -p /opt/app/var + RUN chown appuser /opt/app/var + # Run everything else as 'appuser' + USER appuser + + ENV MIX_ENV=prod REPLACE_OS_VARS=true + WORKDIR /opt/app + COPY --from=0 /opt/release . + ENV RUNNER_LOG_DIR /var/log + + # Command to execute the application. + CMD ["/opt/app/bin/start_server", "foreground", "boot_var=/tmp"] + ``` + +1. Create a new file, `service.yaml` and copy the following Service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-elixir + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-elixir + env: + - name: TARGET + value: "elixir Sample v1" + ``` + +# Building and deploying the sample + +The sample in this directory is ready to build and deploy without changes. You +can deploy the sample as is, or use you created version following the directions +above. + +1. Generate a new `secret_key_base` in the `config/prod.secret.exs` file. + Phoenix applications use a secrets file on production deployments and, by + default, that file is not checked into source control. We have provides + shell of an example on `config/prod.secret.exs.sample` and you can use the + following command to generate a new prod secrets file. + + ```shell + SECRET_KEY_BASE=$(elixir -e ":crypto.strong_rand_bytes(48) |> Base.encode64 |> IO.puts") + sed "s|SECRET+KEY+BASE|$SECRET_KEY_BASE|" config/prod.secret.exs.sample >config/prod.secret.exs + ``` + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-elixir . + + # Push the container to docker registry + docker push {username}/helloworld-elixir + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. + Apply the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. To find the URL for your service, use + + ``` + kubectl get ksvc helloworld-elixir --output=custom-columns=NAME:.metadata.name,URL:.status.url + + NAME URL + helloworld-elixir http://helloworld-elixir.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app to see the results. Replace + `{IP_ADDRESS}` with the address you see returned in the previous step. + + ```shell + curl http://helloworld-elixir.default.1.2.3.4.xip.io + + ... + # HTML from your application is returned. + ``` + + Here is the HTML returned from our deployed sample application: + + ```HTML + + + + + + + + + + Hello Knative + + + ``` + + +
+
+ +
+ + + + +
+ +
+

Welcome to Knative and Elixir

+ +

$TARGET = elixir Sample v1

+
+ +

Environment

+ +
+ +
+ + + + + ``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/community/samples/serving/helloworld-haskell/README.md b/community/samples/serving/helloworld-haskell/README.md deleted file mode 100644 index 0eba47edc..000000000 --- a/community/samples/serving/helloworld-haskell/README.md +++ /dev/null @@ -1,181 +0,0 @@ -A simple web app written in Haskell that you can use for testing. It reads in an -env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not -specified, it will use "World" as the TARGET. - -## Prerequisites - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../docs/install/README.md) if you need to create - one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Recreating the sample code - -While you can clone all of the code from this directory, hello world apps are -generally more useful if you build them step-by-step. The following instructions -recreate the source files from this folder. - -1. Create a new file named `stack.yaml` and paste the following code: - - ```yaml - flags: {} - packages: - - . - extra-deps: [] - resolver: lts-10.7 - ``` - -1. Create a new file named `package.yaml` and paste the following code - - ```yaml - name: helloworld-haskell - version: 0.1.0.0 - dependencies: - - base >= 4.7 && < 5 - - scotty - - text - - executables: - helloworld-haskell-exe: - main: Main.hs - source-dirs: app - ghc-options: - - -threaded - - -rtsopts - - -with-rtsopts=-N - ``` - -1. Create a `app` folder, then create a new file named `Main.hs` in that folder - and paste the following code. This code creates a basic web server which - listens on port 8080: - - ```haskell - {-# LANGUAGE OverloadedStrings #-} - - import Data.Maybe - import Data.Monoid ((<>)) - import Data.Text.Lazy (Text) - import Data.Text.Lazy - import System.Environment (lookupEnv) - import Web.Scotty (ActionM, ScottyM, scotty) - import Web.Scotty.Trans - - main :: IO () - main = do - t <- fromMaybe "World" <$> lookupEnv "TARGET" - pStr <- fromMaybe "8080" <$> lookupEnv "PORT" - let p = read pStr :: Int - scotty p (route t) - - route :: String -> ScottyM() - route t = get "/" $ hello t - - hello :: String -> ActionM() - hello t = text $ pack ("Hello " ++ t) - ``` - -1. In your project directory, create a file named `Dockerfile` and copy the code - block below into it. - - ```docker - # Use the official Haskell image to create a build artifact. - # https://hub.docker.com/_/haskell/ - FROM haskell:8.2.2 as builder - - # Copy local code to the container image. - WORKDIR /app - COPY . . - - # Build and test our code, then build the “helloworld-haskell-exe” executable. - RUN stack setup - RUN stack build --copy-bins - - # Use a Docker multi-stage build to create a lean production image. - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM fpco/haskell-scratch:integer-gmp - - # Copy the "helloworld-haskell-exe" executable from the builder stage to the production image. - WORKDIR /root/ - COPY --from=builder /root/.local/bin/helloworld-haskell-exe . - - # Run the web service on container startup. - CMD ["./helloworld-haskell-exe"] - ``` - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-haskell - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-haskell - env: - - name: TARGET - value: "Haskell Sample v1" - ``` - -## Build and deploy this sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, enter these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-haskell . - - # Push the container to docker registry - docker push {username}/helloworld-haskell - ``` - -1. After the build has completed and the container is pushed to Docker Hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. To find the URL for your service, enter: - - ``` - kubectl get ksvc helloworld-haskell --output=custom-columns=NAME:.metadata.name,URL:.status.url - NAME URL - helloworld-haskell http://helloworld-haskell.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-haskell.default.1.2.3.4.xip.io - Hello world: Haskell Sample v1 - ``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-haskell/index.md b/community/samples/serving/helloworld-haskell/index.md index f96be3be2..aabfd2de7 100644 --- a/community/samples/serving/helloworld-haskell/index.md +++ b/community/samples/serving/helloworld-haskell/index.md @@ -5,4 +5,185 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in Haskell that you can use for testing. It reads in an +env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not +specified, it will use "World" as the TARGET. + +## Prerequisites + +- A Kubernetes cluster with Knative installed and DNS configured. Follow the + [installation instructions](../../../../docs/install/README.md) if you need to create + one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). + +## Recreating the sample code + +While you can clone all of the code from this directory, hello world apps are +generally more useful if you build them step-by-step. The following instructions +recreate the source files from this folder. + +1. Create a new file named `stack.yaml` and paste the following code: + + ```yaml + flags: {} + packages: + - . + extra-deps: [] + resolver: lts-10.7 + ``` + +1. Create a new file named `package.yaml` and paste the following code + + ```yaml + name: helloworld-haskell + version: 0.1.0.0 + dependencies: + - base >= 4.7 && < 5 + - scotty + - text + + executables: + helloworld-haskell-exe: + main: Main.hs + source-dirs: app + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + ``` + +1. Create a `app` folder, then create a new file named `Main.hs` in that folder + and paste the following code. This code creates a basic web server which + listens on port 8080: + + ```haskell + {-# LANGUAGE OverloadedStrings #-} + + import Data.Maybe + import Data.Monoid ((<>)) + import Data.Text.Lazy (Text) + import Data.Text.Lazy + import System.Environment (lookupEnv) + import Web.Scotty (ActionM, ScottyM, scotty) + import Web.Scotty.Trans + + main :: IO () + main = do + t <- fromMaybe "World" <$> lookupEnv "TARGET" + pStr <- fromMaybe "8080" <$> lookupEnv "PORT" + let p = read pStr :: Int + scotty p (route t) + + route :: String -> ScottyM() + route t = get "/" $ hello t + + hello :: String -> ActionM() + hello t = text $ pack ("Hello " ++ t) + ``` + +1. In your project directory, create a file named `Dockerfile` and copy the code + block below into it. + + ```docker + # Use the official Haskell image to create a build artifact. + # https://hub.docker.com/_/haskell/ + FROM haskell:8.2.2 as builder + + # Copy local code to the container image. + WORKDIR /app + COPY . . + + # Build and test our code, then build the “helloworld-haskell-exe” executable. + RUN stack setup + RUN stack build --copy-bins + + # Use a Docker multi-stage build to create a lean production image. + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM fpco/haskell-scratch:integer-gmp + + # Copy the "helloworld-haskell-exe" executable from the builder stage to the production image. + WORKDIR /root/ + COPY --from=builder /root/.local/bin/helloworld-haskell-exe . + + # Run the web service on container startup. + CMD ["./helloworld-haskell-exe"] + ``` + +1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-haskell + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-haskell + env: + - name: TARGET + value: "Haskell Sample v1" + ``` + +## Build and deploy this sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, enter these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-haskell . + + # Push the container to docker registry + docker push {username}/helloworld-haskell + ``` + +1. After the build has completed and the container is pushed to Docker Hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. To find the URL for your service, enter: + + ``` + kubectl get ksvc helloworld-haskell --output=custom-columns=NAME:.metadata.name,URL:.status.url + NAME URL + helloworld-haskell http://helloworld-haskell.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-haskell.default.1.2.3.4.xip.io + Hello world: Haskell Sample v1 + ``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` + diff --git a/community/samples/serving/helloworld-java-micronaut/README.md b/community/samples/serving/helloworld-java-micronaut/README.md deleted file mode 100644 index 5086b85a0..000000000 --- a/community/samples/serving/helloworld-java-micronaut/README.md +++ /dev/null @@ -1,282 +0,0 @@ -Learn how to deploy a simple web app that is written in Java and uses Micronaut. - -This samples uses Docker to build locally. The app reads in a `TARGET` env -variable and then prints "Hello World: \${TARGET}!". If a value for `TARGET` is -not specified, the "NOT SPECIFIED" default value is used. - -Use this sample to walk you through the steps of creating and modifying the -sample app, building and pushing your container image to a registry, and then -deploying your app to your Knative cluster. - -## Before you begin - -You must meet the following requirements to complete this sample: - -- A version of the Knative Serving component installed and DNS configured. Follow the - [Knative installation instructions](../../../../docs/install/README.md) if you need - to create a Knative cluster. -- The following software downloaded and install on your loacal machine: - - [Java SE 8 or later JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html). - - [Micronaut 1.1](https://micronaut.io/). - - [Docker](https://www.docker.com) for building and pushing your container - image. - - [curl](https://curl.haxx.se/) to test the sample app after deployment. -- A [Docker Hub](https://hub.docker.com/) account where you can push your - container image. - -**Tip**: You can clone the [Knatve/docs repo](https://github.com/knative/docs) -and then modify the source files. Alternatively, learn more by manually creating -the files yourself. - -## Creating and configuring the sample code - -To create and configure the source files in the root of your working directory: - -1. Create the `pom.xml` file: - - ```xml - 4.0.0 - com.example.micronaut - helloworld - 1.0.0-SNAPSHOT - - 1.1.0 - 1.8 - UTF-8 - com.example.helloworld.Application - - - - - io.micronaut - micronaut-bom - ${micronaut.version} - pom - import - - - - - - io.micronaut - micronaut-inject - compile - - - io.micronaut - micronaut-validation - compile - - - io.micronaut - micronaut-runtime - compile - - - io.micronaut - micronaut-http-client - compile - - - io.micronaut - micronaut-http-server-netty - compile - - - ch.qos.logback - logback-classic - 1.2.3 - runtime - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.1.0 - - - package - - shade - - - - - ${exec.mainClass} - - - - - - - - - - - ``` - -1. Create the `HelloWorldController.java` file in the - `src/main/java/com/example/helloworld` directory. The - `[ROOT]/src/main/java/com/example/helloworld/HelloWorldController.java` file - handles requests to the root URI `/`. - - ```java - package com.example.helloworld; - - import io.micronaut.http.MediaType; - import io.micronaut.http.annotation.Controller; - import io.micronaut.http.annotation.Get; - - @Controller("/") - public class HelloWorldController { - - @Get(value = "/", produces = MediaType.TEXT_PLAIN) - public String index() { - String target = System.getenv("TARGET"); - if (target == null) { - target = "NOT SPECIFIED"; - } - return "Hello World: " + target; - } - } - ``` - -1. The Micronaut application is configured via - `src/main/resources/application.yml`: - - ```yaml - micronaut: - application: - name: helloworld-java-micronaut - server: - port: ${PORT:8080} - ``` - -1. Create the `Dockerfile` file: - - ```docker - # Use the official maven/Java 8 image to create a build artifact. - # https://hub.docker.com/_/maven - FROM maven:3.5-jdk-8-alpine as builder - - # Copy local code to the container image. - WORKDIR /app - COPY pom.xml . - COPY src ./src - - # Build a release artifact. - RUN mvn package -DskipTests - - # Use AdoptOpenJDK for base image. - # It's important to use OpenJDK 8u191 or above that has container support enabled. - # https://hub.docker.com/r/adoptopenjdk/openjdk8 - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM adoptopenjdk/openjdk8:jdk8u202-b08-alpine-slim - - # Copy the jar to the production image from the builder stage. - COPY --from=builder /app/target/helloworld-1.0.0-SNAPSHOT.jar /helloworld.jar - - # Run the web service on container startup. - CMD ["java","-jar","/helloworld.jar"] - ``` - -1. Create the `service.yaml` file. You must specify your Docker Hub username in - `{username}`. You can also configure the `TARGET`, for example you can modify - the `Micronaut Sample v1` value. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-java-micronaut - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-java-micronaut - env: - - name: TARGET - value: "Micronaut Sample v1" - ``` - -## Building and deploying the sample - -To build a container image, push your image to the registry, and then deploy -your sample app to your cluster: - -1. Use Docker to build your container image and then push that image to your - Docker Hub registry. You must replace the `{username}` variables in the - following commands with your Docker Hub username. - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-java-micronaut . - - # Push the container to docker registry - docker push {username}/helloworld-java-micronaut - ``` - -1. Now that your container image is in the registry, you can deploy it to your - Knative cluster by running the `kubectl apply` command: - - ```shell - kubectl apply --filename service.yaml - ``` - - Result: A service name `helloworld-java-micronaut` is created in your cluster - along with the following resources: - - - A new immutable revision for the version of the app that you just deployed. - - The following networking resources are created for your app: - - route - - ingress - - service - - load balancer - - Auto scaling is enable to allow your pods to scale up to meet traffic, and - also back down to zero when there is no traffic. - -## Testing the sample app - -To verify that your sample app has been successfully deployed: - -1. Retrieve the URL for your service, by running the following `kubectl get` - command: - - ```shell - kubectl get ksvc helloworld-java-micronaut --output=custom-columns=NAME:.metadata.name,URL:.status.url - ``` - - Example result: - - ```shell - NAME URL - helloworld-java-micronaut http://helloworld-java-micronaut.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-java-micronaut.default.1.2.3.4.xip.io - ``` - - Example result: - - ```shell - Hello World: Micronaut Sample v1 - ``` - -Congratulations on deploying your sample Java app to Knative! - -## Removing the sample app deployment - -To remove the sample app from your cluster, run the following `kubectl delete` -command: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-java-micronaut/index.md b/community/samples/serving/helloworld-java-micronaut/index.md index 32b6e63cd..b02c18233 100644 --- a/community/samples/serving/helloworld-java-micronaut/index.md +++ b/community/samples/serving/helloworld-java-micronaut/index.md @@ -5,4 +5,285 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +Learn how to deploy a simple web app that is written in Java and uses Micronaut. + +This samples uses Docker to build locally. The app reads in a `TARGET` env +variable and then prints "Hello World: \${TARGET}!". If a value for `TARGET` is +not specified, the "NOT SPECIFIED" default value is used. + +Use this sample to walk you through the steps of creating and modifying the +sample app, building and pushing your container image to a registry, and then +deploying your app to your Knative cluster. + +## Before you begin + +You must meet the following requirements to complete this sample: + +- A version of the Knative Serving component installed and DNS configured. Follow the + [Knative installation instructions](../../../../docs/install/README.md) if you need + to create a Knative cluster. +- The following software downloaded and install on your loacal machine: + - [Java SE 8 or later JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html). + - [Micronaut 1.1](https://micronaut.io/). + - [Docker](https://www.docker.com) for building and pushing your container + image. + - [curl](https://curl.haxx.se/) to test the sample app after deployment. +- A [Docker Hub](https://hub.docker.com/) account where you can push your + container image. + +**Tip**: You can clone the [Knatve/docs repo](https://github.com/knative/docs) +and then modify the source files. Alternatively, learn more by manually creating +the files yourself. + +## Creating and configuring the sample code + +To create and configure the source files in the root of your working directory: + +1. Create the `pom.xml` file: + + ```xml + 4.0.0 + com.example.micronaut + helloworld + 1.0.0-SNAPSHOT + + 1.1.0 + 1.8 + UTF-8 + com.example.helloworld.Application + + + + + io.micronaut + micronaut-bom + ${micronaut.version} + pom + import + + + + + + io.micronaut + micronaut-inject + compile + + + io.micronaut + micronaut-validation + compile + + + io.micronaut + micronaut-runtime + compile + + + io.micronaut + micronaut-http-client + compile + + + io.micronaut + micronaut-http-server-netty + compile + + + ch.qos.logback + logback-classic + 1.2.3 + runtime + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + + package + + shade + + + + + ${exec.mainClass} + + + + + + + + + + + ``` + +1. Create the `HelloWorldController.java` file in the + `src/main/java/com/example/helloworld` directory. The + `[ROOT]/src/main/java/com/example/helloworld/HelloWorldController.java` file + handles requests to the root URI `/`. + + ```java + package com.example.helloworld; + + import io.micronaut.http.MediaType; + import io.micronaut.http.annotation.Controller; + import io.micronaut.http.annotation.Get; + + @Controller("/") + public class HelloWorldController { + + @Get(value = "/", produces = MediaType.TEXT_PLAIN) + public String index() { + String target = System.getenv("TARGET"); + if (target == null) { + target = "NOT SPECIFIED"; + } + return "Hello World: " + target; + } + } + ``` + +1. The Micronaut application is configured via + `src/main/resources/application.yml`: + + ```yaml + micronaut: + application: + name: helloworld-java-micronaut + server: + port: ${PORT:8080} + ``` + +1. Create the `Dockerfile` file: + + ```docker + # Use the official maven/Java 8 image to create a build artifact. + # https://hub.docker.com/_/maven + FROM maven:3.5-jdk-8-alpine as builder + + # Copy local code to the container image. + WORKDIR /app + COPY pom.xml . + COPY src ./src + + # Build a release artifact. + RUN mvn package -DskipTests + + # Use AdoptOpenJDK for base image. + # It's important to use OpenJDK 8u191 or above that has container support enabled. + # https://hub.docker.com/r/adoptopenjdk/openjdk8 + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM adoptopenjdk/openjdk8:jdk8u202-b08-alpine-slim + + # Copy the jar to the production image from the builder stage. + COPY --from=builder /app/target/helloworld-1.0.0-SNAPSHOT.jar /helloworld.jar + + # Run the web service on container startup. + CMD ["java","-jar","/helloworld.jar"] + ``` + +1. Create the `service.yaml` file. You must specify your Docker Hub username in + `{username}`. You can also configure the `TARGET`, for example you can modify + the `Micronaut Sample v1` value. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-java-micronaut + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-java-micronaut + env: + - name: TARGET + value: "Micronaut Sample v1" + ``` + +## Building and deploying the sample + +To build a container image, push your image to the registry, and then deploy +your sample app to your cluster: + +1. Use Docker to build your container image and then push that image to your + Docker Hub registry. You must replace the `{username}` variables in the + following commands with your Docker Hub username. + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-java-micronaut . + + # Push the container to docker registry + docker push {username}/helloworld-java-micronaut + ``` + +1. Now that your container image is in the registry, you can deploy it to your + Knative cluster by running the `kubectl apply` command: + + ```shell + kubectl apply --filename service.yaml + ``` + + Result: A service name `helloworld-java-micronaut` is created in your cluster + along with the following resources: + + - A new immutable revision for the version of the app that you just deployed. + - The following networking resources are created for your app: + - route + - ingress + - service + - load balancer + - Auto scaling is enable to allow your pods to scale up to meet traffic, and + also back down to zero when there is no traffic. + +## Testing the sample app + +To verify that your sample app has been successfully deployed: + +1. Retrieve the URL for your service, by running the following `kubectl get` + command: + + ```shell + kubectl get ksvc helloworld-java-micronaut --output=custom-columns=NAME:.metadata.name,URL:.status.url + ``` + + Example result: + + ```shell + NAME URL + helloworld-java-micronaut http://helloworld-java-micronaut.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-java-micronaut.default.1.2.3.4.xip.io + ``` + + Example result: + + ```shell + Hello World: Micronaut Sample v1 + ``` + +Congratulations on deploying your sample Java app to Knative! + +## Removing the sample app deployment + +To remove the sample app from your cluster, run the following `kubectl delete` +command: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/community/samples/serving/helloworld-java-quarkus/README.md b/community/samples/serving/helloworld-java-quarkus/README.md deleted file mode 100644 index 3de4f12d8..000000000 --- a/community/samples/serving/helloworld-java-quarkus/README.md +++ /dev/null @@ -1,269 +0,0 @@ -A simple [JAX-RS REST API](https://github.com/jax-rs) application that is -written in Java and uses [Quarkus](https://quarkus.io/). - -This samples uses Docker to build locally. The app reads in a `TARGET` env -variable and then prints "Hello World: \${TARGET}!". If a value for `TARGET` is -not specified, the "NOT SPECIFIED" default value is used. - -## Before you begin - -You must meet the following requirements to run this sample: - -- Have a Kubernetes cluster running with the Knative Serving component - installed. For more information, see the - [Knative instruction guides](https://github.com/knative/docs/blob/main/docs/install/README.md). -- An installed version of the following tools: - - [Docker](https://www.docker.com) - - [Java SE 8 or later JDK](https://www.eclipse.org/openj9/) - - [Maven](https://maven.apache.org/download.cgi) -- A [Docker Hub account](https://hub.docker.com/) to which you are able to - upload your sample's container image. - -## Getting the code - -You can either clone a working copy of the sample code from the repository, or -following the steps in the -[Recreating the sample code](#recreating-the-sample-code) to walk through the -steps of updating all the files. - -### Cloning the sample code - -Use this method to clone and then immediate run the sample. To clone the sample -code, run the following commands: - -``` -git clone -b "{{< branch >}}" https://github.com/knative/docs.git knative/docs -cd knative/docs/community/samples/serving/helloworld-java-quarkus -``` - -You are now ready to [run the sample locally](#locally-testing-your-sample). - -### Recreating the sample code - -Use the following steps to obtain an incomplete copy of the sample code for -which you update and create the necessary build and configuration files: - -1. From the console, create a new empty web project using the Maven archetype - commands: - - ```shell - mvn io.quarkus:quarkus-maven-plugin:0.13.3:create \ - -DprojectGroupId=com.redhat.developer.demos \ - -DprojectArtifactId=helloworld-java-quarkus \ - -DclassName="com.redhat.developer.demos.GreetingResource" \ - -Dpath="/" - ``` - -1. Update the `GreetingResource` class in - `src/main/java/com/redhat/developer/demos/GreetingResource.java` to handle - the "/" mapping and also add a `@ConfigProperty` field to provide the TARGET - environment variable: - - ```java - package com.redhat.developer.demos; - - import javax.ws.rs.GET; - import javax.ws.rs.Path; - import javax.ws.rs.Produces; - import javax.ws.rs.core.MediaType; - import org.eclipse.microprofile.config.inject.ConfigProperty; - - @Path("/") - public class GreeterResource { - @ConfigProperty(name = "TARGET", defaultValue="World") - String target; - - @GET - @Produces(MediaType.TEXT_PLAIN) - public String greet() { - return "Hello " + target + "!"; - } - } - ``` - -1. Update `src/main/resources/application.properties` to configuration the - application to default to port 8080, but allow the port to be overridden by - the `PORT` environmental variable: - - ``` - # Configuration file - # key = value - - quarkus.http.port=${PORT:8080} - ``` - -1. Update `src/test/java/com/redhat/developer/demos/GreetingResourceTest.java` - test to reflect the change: - - ```java - package com.redhat.developer.demos; - - import io.quarkus.test.junit.QuarkusTest; - import org.junit.jupiter.api.Test; - - import static io.restassured.RestAssured.given; - import static org.hamcrest.CoreMatchers.is; - - @QuarkusTest - public class GreetingResourceTest { - - @Test - public void testHelloEndpoint() { - given() - .when().get("/") - .then() - .statusCode(200) - .body(is("Hello World!")); - } - } - - ``` - -1. Remove `src/main/resources/META-INF/resources/index.html` file since it's - unncessary for this example. - - ```shell - rm src/main/resources/META-INF/resources/index.html - ``` - -1. Remove `.dockerignore` file since it's unncessary for this example. - - ```shell - rm .dockerignore - ``` - -1. In your project directory, create a file named `Dockerfile` and copy the code - block below into it. - - ```docker - FROM quay.io/rhdevelopers/quarkus-java-builder:graal-1.0.0-rc15 as builder - COPY . /project - WORKDIR /project - # uncomment this to set the MAVEN_MIRROR_URL of your choice, to make faster builds - # ARG MAVEN_MIRROR_URL= - # e.g. - #ARG MAVEN_MIRROR_URL=http://192.168.64.1:8081/nexus/content/groups/public - - RUN /usr/local/bin/entrypoint-run.sh mvn -DskipTests clean package - - FROM fabric8/java-jboss-openjdk8-jdk:1.5.4 - USER jboss - ENV JAVA_APP_DIR=/deployments - - COPY --from=builder /project/target/lib/* /deployments/lib/ - COPY --from=builder /project/target/*-runner.jar /deployments/app.jar - - ENTRYPOINT [ "/deployments/run-java.sh" ] - ``` - - If you want to build Quarkus native image, then copy the following code block - in to file called `Dockerfile.native` - - ```docker - FROM quay.io/rhdevelopers/quarkus-java-builder:graal-1.0.0-rc15 as builder - COPY . /project - # uncomment this to set the MAVEN_MIRROR_URL of your choice, to make faster builds - # ARG MAVEN_MIRROR_URL= - # e.g. - # ARG MAVEN_MIRROR_URL=http://192.168.64.1:8081/nexus/content/groups/public - - RUN /usr/local/bin/entrypoint-run.sh mvn -DskipTests clean package -Pnative - - FROM registry.fedoraproject.org/fedora-minimal - - COPY --from=builder /project/target/helloworld-java-quarkus-runner /app - - ENTRYPOINT [ "/app" ] - ``` - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-java-quarkus - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-java-quarkus - env: - - name: TARGET - value: "Quarkus Sample v1" - ``` - -## Locally testing your sample - -1. Run the application locally: - - ```shell - ./mvnw compile quarkus:dev - ``` - - Go to `http://localhost:8080/` to see your `Hello World!` message. - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-java-quarkus . - - # (OR) - # Build the container on your local machine - Quarkus native mode - docker build -t {username}/helloworld-java-quarkus -f Dockerfile.native . - - # Push the container to docker registry - docker push {username}/helloworld-java-quarkus - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balancer - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. To find the URL for your service, use - - ```shell - kubectl get ksvc helloworld-java-quarkus - - NAME URL - helloworld-java-quarkus http://helloworld-java-quarkus.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-java-quarkus.default.1.2.3.4.xip.io - - Namaste Knative World! - ``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-java-quarkus/index.md b/community/samples/serving/helloworld-java-quarkus/index.md index 2f9ec732a..6ea760aec 100644 --- a/community/samples/serving/helloworld-java-quarkus/index.md +++ b/community/samples/serving/helloworld-java-quarkus/index.md @@ -5,4 +5,272 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple [JAX-RS REST API](https://github.com/jax-rs) application that is +written in Java and uses [Quarkus](https://quarkus.io/). + +This samples uses Docker to build locally. The app reads in a `TARGET` env +variable and then prints "Hello World: \${TARGET}!". If a value for `TARGET` is +not specified, the "NOT SPECIFIED" default value is used. + +## Before you begin + +You must meet the following requirements to run this sample: + +- Have a Kubernetes cluster running with the Knative Serving component + installed. For more information, see the + [Knative instruction guides](https://github.com/knative/docs/blob/main/docs/install/README.md). +- An installed version of the following tools: + - [Docker](https://www.docker.com) + - [Java SE 8 or later JDK](https://www.eclipse.org/openj9/) + - [Maven](https://maven.apache.org/download.cgi) +- A [Docker Hub account](https://hub.docker.com/) to which you are able to + upload your sample's container image. + +## Getting the code + +You can either clone a working copy of the sample code from the repository, or +following the steps in the +[Recreating the sample code](#recreating-the-sample-code) to walk through the +steps of updating all the files. + +### Cloning the sample code + +Use this method to clone and then immediate run the sample. To clone the sample +code, run the following commands: + +``` +git clone -b "{{< branch >}}" https://github.com/knative/docs.git knative/docs +cd knative/docs/community/samples/serving/helloworld-java-quarkus +``` + +You are now ready to [run the sample locally](#locally-testing-your-sample). + +### Recreating the sample code + +Use the following steps to obtain an incomplete copy of the sample code for +which you update and create the necessary build and configuration files: + +1. From the console, create a new empty web project using the Maven archetype + commands: + + ```shell + mvn io.quarkus:quarkus-maven-plugin:0.13.3:create \ + -DprojectGroupId=com.redhat.developer.demos \ + -DprojectArtifactId=helloworld-java-quarkus \ + -DclassName="com.redhat.developer.demos.GreetingResource" \ + -Dpath="/" + ``` + +1. Update the `GreetingResource` class in + `src/main/java/com/redhat/developer/demos/GreetingResource.java` to handle + the "/" mapping and also add a `@ConfigProperty` field to provide the TARGET + environment variable: + + ```java + package com.redhat.developer.demos; + + import javax.ws.rs.GET; + import javax.ws.rs.Path; + import javax.ws.rs.Produces; + import javax.ws.rs.core.MediaType; + import org.eclipse.microprofile.config.inject.ConfigProperty; + + @Path("/") + public class GreeterResource { + @ConfigProperty(name = "TARGET", defaultValue="World") + String target; + + @GET + @Produces(MediaType.TEXT_PLAIN) + public String greet() { + return "Hello " + target + "!"; + } + } + ``` + +1. Update `src/main/resources/application.properties` to configuration the + application to default to port 8080, but allow the port to be overridden by + the `PORT` environmental variable: + + ``` + # Configuration file + # key = value + + quarkus.http.port=${PORT:8080} + ``` + +1. Update `src/test/java/com/redhat/developer/demos/GreetingResourceTest.java` + test to reflect the change: + + ```java + package com.redhat.developer.demos; + + import io.quarkus.test.junit.QuarkusTest; + import org.junit.jupiter.api.Test; + + import static io.restassured.RestAssured.given; + import static org.hamcrest.CoreMatchers.is; + + @QuarkusTest + public class GreetingResourceTest { + + @Test + public void testHelloEndpoint() { + given() + .when().get("/") + .then() + .statusCode(200) + .body(is("Hello World!")); + } + } + + ``` + +1. Remove `src/main/resources/META-INF/resources/index.html` file since it's + unncessary for this example. + + ```shell + rm src/main/resources/META-INF/resources/index.html + ``` + +1. Remove `.dockerignore` file since it's unncessary for this example. + + ```shell + rm .dockerignore + ``` + +1. In your project directory, create a file named `Dockerfile` and copy the code + block below into it. + + ```docker + FROM quay.io/rhdevelopers/quarkus-java-builder:graal-1.0.0-rc15 as builder + COPY . /project + WORKDIR /project + # uncomment this to set the MAVEN_MIRROR_URL of your choice, to make faster builds + # ARG MAVEN_MIRROR_URL= + # e.g. + #ARG MAVEN_MIRROR_URL=http://192.168.64.1:8081/nexus/content/groups/public + + RUN /usr/local/bin/entrypoint-run.sh mvn -DskipTests clean package + + FROM fabric8/java-jboss-openjdk8-jdk:1.5.4 + USER jboss + ENV JAVA_APP_DIR=/deployments + + COPY --from=builder /project/target/lib/* /deployments/lib/ + COPY --from=builder /project/target/*-runner.jar /deployments/app.jar + + ENTRYPOINT [ "/deployments/run-java.sh" ] + ``` + + If you want to build Quarkus native image, then copy the following code block + in to file called `Dockerfile.native` + + ```docker + FROM quay.io/rhdevelopers/quarkus-java-builder:graal-1.0.0-rc15 as builder + COPY . /project + # uncomment this to set the MAVEN_MIRROR_URL of your choice, to make faster builds + # ARG MAVEN_MIRROR_URL= + # e.g. + # ARG MAVEN_MIRROR_URL=http://192.168.64.1:8081/nexus/content/groups/public + + RUN /usr/local/bin/entrypoint-run.sh mvn -DskipTests clean package -Pnative + + FROM registry.fedoraproject.org/fedora-minimal + + COPY --from=builder /project/target/helloworld-java-quarkus-runner /app + + ENTRYPOINT [ "/app" ] + ``` + +1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-java-quarkus + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-java-quarkus + env: + - name: TARGET + value: "Quarkus Sample v1" + ``` + +## Locally testing your sample + +1. Run the application locally: + + ```shell + ./mvnw compile quarkus:dev + ``` + + Go to `http://localhost:8080/` to see your `Hello World!` message. + +## Building and deploying the sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-java-quarkus . + + # (OR) + # Build the container on your local machine - Quarkus native mode + docker build -t {username}/helloworld-java-quarkus -f Dockerfile.native . + + # Push the container to docker registry + docker push {username}/helloworld-java-quarkus + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balancer + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. To find the URL for your service, use + + ```shell + kubectl get ksvc helloworld-java-quarkus + + NAME URL + helloworld-java-quarkus http://helloworld-java-quarkus.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-java-quarkus.default.1.2.3.4.xip.io + + Namaste Knative World! + ``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/community/samples/serving/helloworld-r/README.md b/community/samples/serving/helloworld-r/README.md deleted file mode 100644 index 1ff68d2f8..000000000 --- a/community/samples/serving/helloworld-r/README.md +++ /dev/null @@ -1,190 +0,0 @@ -A simple web app that executes an R script. The R script reads an env -variable `TARGET` and prints `Hello ${TARGET}!`. If the `TARGET` environment -variable is not specified, the script uses `World`. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/hello-world/helloworld-r -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed. Follow the - [installation instructions](../../../../docs/install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Recreating the sample code - -1. Create a new file named `HelloWorld.R` and paste the following script: - - ```R - #!/usr/bin/Rscript - TARGET <- Sys.getenv("TARGET", "World") - - message = paste("Hello ", TARGET, "!", sep = "") - print(message) - ``` - - 1. Create a new file named `invoke.go` and paste the following code. We use a - basic web server written in Go to execute the shell script: - - ```go - package main - - import ( - "fmt" - "log" - "net/http" - "os" - "os/exec" - ) - - func handler(w http.ResponseWriter, r *http.Request) { - cmd := exec.CommandContext(r.Context(), "Rscript", "HelloWorld.R") - cmd.Stderr = os.Stderr - out, err := cmd.Output() - if err != nil { - w.WriteHeader(500) - } - w.Write(out) - } - - func main() { - http.HandleFunc("/", handler) - - port := os.Getenv("PORT") - if port == "" { - port = "8080" - } - - log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil)) - } - ``` - - 1. Create a new file named `Dockerfile` and copy the code block below into it. - - ```docker - # Use the official Golang image to create a build artifact. - # This is based on Debian and sets the GOPATH to /go. - # https://hub.docker.com/_/golang - FROM golang:1.12 as builder - - # Copy local code to the container image. - WORKDIR /go/src/github.com/knative/docs/helloworld-r - COPY invoke.go . - - # Build the command inside the container. - # (You may fetch or manage dependencies here, - # either manually or with a tool like "godep".) - RUN CGO_ENABLED=0 GOOS=linux go build -v -o invoke - - # The official R base image - # https://hub.docker.com/_/r-base - # Use a Docker multi-stage build to create a lean production image. - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM r-base:3.6.0 - - # Copy Go binary - COPY --from=builder /go/src/github.com/knative/docs/helloworld-r/invoke /invoke - COPY HelloWorld.R . - - # Run the web service on container startup. - CMD ["/invoke"] - ``` - - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-r - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-r - env: - - name: TARGET - value: "R Sample v1" - ``` - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-r . - - # Push the container to docker registry - docker push {username}/helloworld-r - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative performs the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. Run the following command to find the domain URL for your service: - - ```shell - kubectl get ksvc helloworld-r --output=custom-columns=NAME:.metadata.name,URL:.status.url - ``` - - Example: - - ```shell - NAME URL - helloworld-r http://helloworld-r.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-r.default.1.2.3.4.xip.io - ``` - - Example: - - ```shell - curl http://helloworld-r.default.1.2.3.4.xip.io - [1] "Hello R Sample v1!" - ``` - - > Note: Add `-v` option to get more detail if the `curl` command failed. - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-r/index.md b/community/samples/serving/helloworld-r/index.md index 7bc817a1f..19230c91a 100644 --- a/community/samples/serving/helloworld-r/index.md +++ b/community/samples/serving/helloworld-r/index.md @@ -5,4 +5,194 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app that executes an R script. The R script reads an env +variable `TARGET` and prints `Hello ${TARGET}!`. If the `TARGET` environment +variable is not specified, the script uses `World`. + +Follow the steps below to create the sample code and then deploy the app to your +cluster. You can also download a working copy of the sample, by running the +following commands: + +```shell +git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs +cd knative-docs/docs/serving/samples/hello-world/helloworld-r +``` + +## Before you begin + +- A Kubernetes cluster with Knative installed. Follow the + [installation instructions](../../../../docs/install/README.md) if you need to + create one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). + +## Recreating the sample code + +1. Create a new file named `HelloWorld.R` and paste the following script: + + ```R + #!/usr/bin/Rscript + TARGET <- Sys.getenv("TARGET", "World") + + message = paste("Hello ", TARGET, "!", sep = "") + print(message) + ``` + + 1. Create a new file named `invoke.go` and paste the following code. We use a + basic web server written in Go to execute the shell script: + + ```go + package main + + import ( + "fmt" + "log" + "net/http" + "os" + "os/exec" + ) + + func handler(w http.ResponseWriter, r *http.Request) { + cmd := exec.CommandContext(r.Context(), "Rscript", "HelloWorld.R") + cmd.Stderr = os.Stderr + out, err := cmd.Output() + if err != nil { + w.WriteHeader(500) + } + w.Write(out) + } + + func main() { + http.HandleFunc("/", handler) + + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil)) + } + ``` + + 1. Create a new file named `Dockerfile` and copy the code block below into it. + + ```docker + # Use the official Golang image to create a build artifact. + # This is based on Debian and sets the GOPATH to /go. + # https://hub.docker.com/_/golang + FROM golang:1.12 as builder + + # Copy local code to the container image. + WORKDIR /go/src/github.com/knative/docs/helloworld-r + COPY invoke.go . + + # Build the command inside the container. + # (You may fetch or manage dependencies here, + # either manually or with a tool like "godep".) + RUN CGO_ENABLED=0 GOOS=linux go build -v -o invoke + + # The official R base image + # https://hub.docker.com/_/r-base + # Use a Docker multi-stage build to create a lean production image. + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM r-base:3.6.0 + + # Copy Go binary + COPY --from=builder /go/src/github.com/knative/docs/helloworld-r/invoke /invoke + COPY HelloWorld.R . + + # Run the web service on container startup. + CMD ["/invoke"] + ``` + + +1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-r + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-r + env: + - name: TARGET + value: "R Sample v1" + ``` + +## Building and deploying the sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-r . + + # Push the container to docker registry + docker push {username}/helloworld-r + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative performs the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. Run the following command to find the domain URL for your service: + + ```shell + kubectl get ksvc helloworld-r --output=custom-columns=NAME:.metadata.name,URL:.status.url + ``` + + Example: + + ```shell + NAME URL + helloworld-r http://helloworld-r.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-r.default.1.2.3.4.xip.io + ``` + + Example: + + ```shell + curl http://helloworld-r.default.1.2.3.4.xip.io + [1] "Hello R Sample v1!" + ``` + + > Note: Add `-v` option to get more detail if the `curl` command failed. + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` + diff --git a/community/samples/serving/helloworld-rserver/README.md b/community/samples/serving/helloworld-rserver/README.md deleted file mode 100644 index 7bd5fbd42..000000000 --- a/community/samples/serving/helloworld-rserver/README.md +++ /dev/null @@ -1,161 +0,0 @@ -A simple web app created with R package, [plumber](https://www.rplumber.io). -plumber creates a REST API by adding annotations to your R code. The R script -reads an environment variable `TARGET` and prints `Hello ${TARGET}!`. If the -`TARGET` environment variable is not specified, the script uses `World`. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/hello-world/helloworld-r -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed. Follow the - [installation instructions](../../../../docs/install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Recreating the sample code - -1. Create a new file named `HelloWorld.R` and paste the following script: - - ```R - #' HelloWorld function - #' @get / - #' @html - function() { - TARGET <- Sys.getenv("TARGET", "World") - - message = paste("Hello ", TARGET, "!", sep = "") - print(message) - } - ``` - - This file defines the endpoint `/`, using plumber annotations. - - 1. Create a new file named `server.R` and paste the following code: - - ```R - library(plumber) # https://www.rplumber.io/ - - # Translate the HelloWorld file into a Plumber API - r <- plumb("HelloWorld.R") - # Get the PORT env var - PORT <- strtoi(Sys.getenv("PORT", 8080)) - # Run the API - r$run(port=PORT, host="0.0.0.0") - ``` - - 1. Create a new file named `Dockerfile` and paste the following code: - - ```docker - # The official R base image - # https://hub.docker.com/_/r-base - FROM r-base:3.6.0 - - # Copy local code to the container image. - WORKDIR /usr/src/app - COPY . . - - # Install R packages - RUN Rscript -e "install.packages('plumber', repos='http://cran.us.r-project.org/')" - - # Run the web service on container startup. - CMD ["Rscript", "server.R"] - ``` - - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-rserver - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-rserver - env: - - name: TARGET - value: "R Server Sample v1" - ``` - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-rserver . - - # Push the container to docker registry - docker push {username}/helloworld-rserver - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative performs the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. Run the following command to find the domain URL for your service: - - ```shell - kubectl get ksvc helloworld-r --output=custom-columns=NAME:.metadata.name,URL:.status.url - ``` - - Example: - - ```shell - NAME URL - helloworld-r http://helloworld-r.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-rserver.default.1.2.3.4.xip.io - ``` - - Example: - - ```shell - curl http://helloworld-rserver.default.1.2.3.4.xip.io - [1] "Hello R Sample v1!" - ``` - - > Note: Add `-v` option to get more detail if the `curl` command failed. - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-rserver/index.md b/community/samples/serving/helloworld-rserver/index.md index 51004ef04..4c87f2a37 100644 --- a/community/samples/serving/helloworld-rserver/index.md +++ b/community/samples/serving/helloworld-rserver/index.md @@ -5,4 +5,164 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app created with R package, [plumber](https://www.rplumber.io). +plumber creates a REST API by adding annotations to your R code. The R script +reads an environment variable `TARGET` and prints `Hello ${TARGET}!`. If the +`TARGET` environment variable is not specified, the script uses `World`. + +Follow the steps below to create the sample code and then deploy the app to your +cluster. You can also download a working copy of the sample, by running the +following commands: + +```shell +git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs +cd knative-docs/docs/serving/samples/hello-world/helloworld-r +``` + +## Before you begin + +- A Kubernetes cluster with Knative installed. Follow the + [installation instructions](../../../../docs/install/README.md) if you need to + create one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). + +## Recreating the sample code + +1. Create a new file named `HelloWorld.R` and paste the following script: + + ```R + #' HelloWorld function + #' @get / + #' @html + function() { + TARGET <- Sys.getenv("TARGET", "World") + + message = paste("Hello ", TARGET, "!", sep = "") + print(message) + } + ``` + + This file defines the endpoint `/`, using plumber annotations. + + 1. Create a new file named `server.R` and paste the following code: + + ```R + library(plumber) # https://www.rplumber.io/ + + # Translate the HelloWorld file into a Plumber API + r <- plumb("HelloWorld.R") + # Get the PORT env var + PORT <- strtoi(Sys.getenv("PORT", 8080)) + # Run the API + r$run(port=PORT, host="0.0.0.0") + ``` + + 1. Create a new file named `Dockerfile` and paste the following code: + + ```docker + # The official R base image + # https://hub.docker.com/_/r-base + FROM r-base:3.6.0 + + # Copy local code to the container image. + WORKDIR /usr/src/app + COPY . . + + # Install R packages + RUN Rscript -e "install.packages('plumber', repos='http://cran.us.r-project.org/')" + + # Run the web service on container startup. + CMD ["Rscript", "server.R"] + ``` + + +1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-rserver + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-rserver + env: + - name: TARGET + value: "R Server Sample v1" + ``` + +## Building and deploying the sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-rserver . + + # Push the container to docker registry + docker push {username}/helloworld-rserver + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative performs the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. Run the following command to find the domain URL for your service: + + ```shell + kubectl get ksvc helloworld-r --output=custom-columns=NAME:.metadata.name,URL:.status.url + ``` + + Example: + + ```shell + NAME URL + helloworld-r http://helloworld-r.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-rserver.default.1.2.3.4.xip.io + ``` + + Example: + + ```shell + curl http://helloworld-rserver.default.1.2.3.4.xip.io + [1] "Hello R Sample v1!" + ``` + + > Note: Add `-v` option to get more detail if the `curl` command failed. + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/community/samples/serving/helloworld-rust/README.md b/community/samples/serving/helloworld-rust/README.md deleted file mode 100644 index 78327ebcc..000000000 --- a/community/samples/serving/helloworld-rust/README.md +++ /dev/null @@ -1,179 +0,0 @@ -A simple web app written in Rust that you can use for testing. It reads in an -env variable `TARGET` and prints "Hello \${TARGET}!". If - -TARGET is not specified, it will use "World" as the TARGET. - -## Prerequisites - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../docs/install/README.md) if you need to create - one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Steps to recreate the sample code - -While you can clone all of the code from this directory, hello world apps are -generally more useful if you build them step-by-step. The following instructions -recreate the source files from this folder. - -1. Create a new file named `Cargo.toml` and paste the following code: - - ```toml - [package] - name = "hellorust" - version = "0.0.0" - publish = false - - [dependencies] - hyper = "0.12.3" - pretty_env_logger = "0.2.3" - ``` - -1. Create a `src` folder, then create a new file named `main.rs` in that folder - and paste the following code. This code creates a basic web server which - listens on port 8080: - - ```rust - #![deny(warnings)] - extern crate hyper; - extern crate pretty_env_logger; - - use hyper::{Body, Response, Server}; - use hyper::service::service_fn_ok; - use hyper::rt::{self, Future}; - use std::env; - - fn main() { - pretty_env_logger::init(); - - let mut port: u16 = 8080; - match env::var("PORT") { - Ok(p) => { - match p.parse::() { - Ok(n) => {port = n;}, - Err(_e) => {}, - }; - } - Err(_e) => {}, - }; - let addr = ([0, 0, 0, 0], port).into(); - - let new_service = || { - service_fn_ok(|_| { - - let mut hello = "Hello ".to_string(); - match env::var("TARGET") { - Ok(target) => {hello.push_str(&target);}, - Err(_e) => {hello.push_str("World")}, - }; - - Response::new(Body::from(hello)) - }) - }; - - let server = Server::bind(&addr) - .serve(new_service) - .map_err(|e| eprintln!("server error: {}", e)); - - println!("Listening on http://{}", addr); - - rt::run(server); - } - ``` - -1. In your project directory, create a file named `Dockerfile` and copy the code - block below into it. - - ```docker - # Use the official Rust image. - # https://hub.docker.com/_/rust - FROM rust:1.27.0 - - # Copy local code to the container image. - WORKDIR /usr/src/app - COPY . . - - # Install production dependencies and build a release artifact. - RUN cargo install - - # Run the web service on container startup. - CMD ["hellorust"] - ``` - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-rust - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-rust - env: - - name: TARGET - value: "Rust Sample v1" - ``` - -## Build and deploy this sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, enter these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-rust . - - # Push the container to docker registry - docker push {username}/helloworld-rust - ``` - -1. After the build has completed and the container is pushed to Docker Hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. To find the URL for your service, enter: - - ``` - kubectl get ksvc helloworld-rust --output=custom-columns=NAME:.metadata.name,URL:.status.url - NAME URL - helloworld-rust http://helloworld-rust.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-rust.default.1.2.3.4.xip.io - Hello World! - ``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-rust/index.md b/community/samples/serving/helloworld-rust/index.md index 3f29b4cc4..f3dcf07b0 100644 --- a/community/samples/serving/helloworld-rust/index.md +++ b/community/samples/serving/helloworld-rust/index.md @@ -5,4 +5,183 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in Rust that you can use for testing. It reads in an +env variable `TARGET` and prints "Hello \${TARGET}!". If + +TARGET is not specified, it will use "World" as the TARGET. + +## Prerequisites + +- A Kubernetes cluster with Knative installed and DNS configured. Follow the + [installation instructions](../../../../docs/install/README.md) if you need to create + one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). + +## Steps to recreate the sample code + +While you can clone all of the code from this directory, hello world apps are +generally more useful if you build them step-by-step. The following instructions +recreate the source files from this folder. + +1. Create a new file named `Cargo.toml` and paste the following code: + + ```toml + [package] + name = "hellorust" + version = "0.0.0" + publish = false + + [dependencies] + hyper = "0.12.3" + pretty_env_logger = "0.2.3" + ``` + +1. Create a `src` folder, then create a new file named `main.rs` in that folder + and paste the following code. This code creates a basic web server which + listens on port 8080: + + ```rust + #![deny(warnings)] + extern crate hyper; + extern crate pretty_env_logger; + + use hyper::{Body, Response, Server}; + use hyper::service::service_fn_ok; + use hyper::rt::{self, Future}; + use std::env; + + fn main() { + pretty_env_logger::init(); + + let mut port: u16 = 8080; + match env::var("PORT") { + Ok(p) => { + match p.parse::() { + Ok(n) => {port = n;}, + Err(_e) => {}, + }; + } + Err(_e) => {}, + }; + let addr = ([0, 0, 0, 0], port).into(); + + let new_service = || { + service_fn_ok(|_| { + + let mut hello = "Hello ".to_string(); + match env::var("TARGET") { + Ok(target) => {hello.push_str(&target);}, + Err(_e) => {hello.push_str("World")}, + }; + + Response::new(Body::from(hello)) + }) + }; + + let server = Server::bind(&addr) + .serve(new_service) + .map_err(|e| eprintln!("server error: {}", e)); + + println!("Listening on http://{}", addr); + + rt::run(server); + } + ``` + +1. In your project directory, create a file named `Dockerfile` and copy the code + block below into it. + + ```docker + # Use the official Rust image. + # https://hub.docker.com/_/rust + FROM rust:1.27.0 + + # Copy local code to the container image. + WORKDIR /usr/src/app + COPY . . + + # Install production dependencies and build a release artifact. + RUN cargo install + + # Run the web service on container startup. + CMD ["hellorust"] + ``` + +1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-rust + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-rust + env: + - name: TARGET + value: "Rust Sample v1" + ``` + +## Build and deploy this sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, enter these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-rust . + + # Push the container to docker registry + docker push {username}/helloworld-rust + ``` + +1. After the build has completed and the container is pushed to Docker Hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. To find the URL for your service, enter: + + ``` + kubectl get ksvc helloworld-rust --output=custom-columns=NAME:.metadata.name,URL:.status.url + NAME URL + helloworld-rust http://helloworld-rust.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-rust.default.1.2.3.4.xip.io + Hello World! + ``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` + diff --git a/community/samples/serving/helloworld-swift/README.md b/community/samples/serving/helloworld-swift/README.md deleted file mode 100644 index af5a8516a..000000000 --- a/community/samples/serving/helloworld-swift/README.md +++ /dev/null @@ -1,162 +0,0 @@ -A simple web app written in Swift that you can use for testing. The app reads in -an env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not -specified, the app uses "World" as the TARGET. - -## Prerequisites - -- You must have a Kubernetes cluster with Knative installed and DNS configured. - If you need to create a cluster, follow the - [installation instructions](../../../../docs/install/README.md). -- You must have [Docker](https://www.docker.com) installed and running on your - local machine, and a Docker Hub account configured (used for container - registry). - -## Recreating the sample code - -While you can clone all of the code from this directory, it might be more useful -if you build this app step-by-step. The following instructions recreate the -source files from this folder. - -1. Create a the `Package.swift` to declare your package and its dependencies. - This app uses [Swifter](https://github.com/httpswift/swifter), a tiny http - server engine for Swift. - - ```swift - // swift-tools-version:4.0 - - import PackageDescription - - let package = Package( - name: "HelloSwift", - dependencies: [ - .package(url: "https://github.com/httpswift/swifter.git", .upToNextMajor(from: "1.4.5")) - ], - targets: [ - .target( - name: "HelloSwift", - dependencies: ["Swifter"], - path: "./Sources") - ] - ) - ``` - -1. Add the web server code to a file named `main.swift` in a - `Sources/HelloSwift/` folder: - - ```swift - import Swifter - import Dispatch - import Foundation - - let server = HttpServer() - server["/"] = { r in - let target = ProcessInfo.processInfo.environment["TARGET"] ?? "World" - return HttpResponse.ok(.html("Hello \(target)")) - } - - let semaphore = DispatchSemaphore(value: 0) - do { - let port = UInt16(ProcessInfo.processInfo.environment["PORT"] ?? "8080") - try server.start(port!, forceIPv4: true) - print("Server has started ( port = \(try server.port()) ). Try to connect now...") - semaphore.wait() - } catch { - print("Server start error: \(error)") - semaphore.signal() - } - ``` - -1. In your project directory, create a file named `Dockerfile` and copy the code - block below into it. - - ```Dockerfile - # Use the official Swift image. - # https://hub.docker.com/_/swift - FROM swift:4.2 - - # Copy local code to the container image. - WORKDIR /app - COPY . . - - # Install dependencies and build. - RUN swift build -c release - - # Run the web service on container startup. - CMD [ ".build/release/HelloSwift"] - ``` - -1. Create a new file, `service.yaml`, and copy the following service definition - into the file. Replace `{username}` with your Docker Hub username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-swift - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-swift - env: - - name: TARGET - value: "Swift" - ``` - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands, replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-swift . - - # Push the container to docker registry - docker push {username}/helloworld-swift - ``` - -1. After the build has completed and the container is pushed to Docker Hub, you - can deploy the app into your cluster. Ensure that the container image value - in the `service.yaml` file matches the container you built in the previous - step. Apply the configuration using the `kubectl` command: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative performs the following steps: - - - Creates a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balancing - for your app. - - Automatically scales your pods up and down (including to zero active pods). - -1. To find the URL for your service, use the following command: - - ``` - kubectl get ksvc helloworld-swift --output=custom-columns=NAME:.metadata.name,URL:.status.url - NAME URL - helloworld-swift http://helloworld-swift.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-swift.default.1.2.3.4.xip.io - Hello Swift - ``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-swift/index.md b/community/samples/serving/helloworld-swift/index.md index ba903a885..5ea4b7c1d 100644 --- a/community/samples/serving/helloworld-swift/index.md +++ b/community/samples/serving/helloworld-swift/index.md @@ -5,4 +5,165 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in Swift that you can use for testing. The app reads in +an env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not +specified, the app uses "World" as the TARGET. + +## Prerequisites + +- You must have a Kubernetes cluster with Knative installed and DNS configured. + If you need to create a cluster, follow the + [installation instructions](../../../../docs/install/README.md). +- You must have [Docker](https://www.docker.com) installed and running on your + local machine, and a Docker Hub account configured (used for container + registry). + +## Recreating the sample code + +While you can clone all of the code from this directory, it might be more useful +if you build this app step-by-step. The following instructions recreate the +source files from this folder. + +1. Create a the `Package.swift` to declare your package and its dependencies. + This app uses [Swifter](https://github.com/httpswift/swifter), a tiny http + server engine for Swift. + + ```swift + // swift-tools-version:4.0 + + import PackageDescription + + let package = Package( + name: "HelloSwift", + dependencies: [ + .package(url: "https://github.com/httpswift/swifter.git", .upToNextMajor(from: "1.4.5")) + ], + targets: [ + .target( + name: "HelloSwift", + dependencies: ["Swifter"], + path: "./Sources") + ] + ) + ``` + +1. Add the web server code to a file named `main.swift` in a + `Sources/HelloSwift/` folder: + + ```swift + import Swifter + import Dispatch + import Foundation + + let server = HttpServer() + server["/"] = { r in + let target = ProcessInfo.processInfo.environment["TARGET"] ?? "World" + return HttpResponse.ok(.html("Hello \(target)")) + } + + let semaphore = DispatchSemaphore(value: 0) + do { + let port = UInt16(ProcessInfo.processInfo.environment["PORT"] ?? "8080") + try server.start(port!, forceIPv4: true) + print("Server has started ( port = \(try server.port()) ). Try to connect now...") + semaphore.wait() + } catch { + print("Server start error: \(error)") + semaphore.signal() + } + ``` + +1. In your project directory, create a file named `Dockerfile` and copy the code + block below into it. + + ```Dockerfile + # Use the official Swift image. + # https://hub.docker.com/_/swift + FROM swift:4.2 + + # Copy local code to the container image. + WORKDIR /app + COPY . . + + # Install dependencies and build. + RUN swift build -c release + + # Run the web service on container startup. + CMD [ ".build/release/HelloSwift"] + ``` + +1. Create a new file, `service.yaml`, and copy the following service definition + into the file. Replace `{username}` with your Docker Hub username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-swift + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-swift + env: + - name: TARGET + value: "Swift" + ``` + +## Building and deploying the sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands, replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-swift . + + # Push the container to docker registry + docker push {username}/helloworld-swift + ``` + +1. After the build has completed and the container is pushed to Docker Hub, you + can deploy the app into your cluster. Ensure that the container image value + in the `service.yaml` file matches the container you built in the previous + step. Apply the configuration using the `kubectl` command: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative performs the following steps: + + - Creates a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balancing + for your app. + - Automatically scales your pods up and down (including to zero active pods). + +1. To find the URL for your service, use the following command: + + ``` + kubectl get ksvc helloworld-swift --output=custom-columns=NAME:.metadata.name,URL:.status.url + NAME URL + helloworld-swift http://helloworld-swift.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-swift.default.1.2.3.4.xip.io + Hello Swift + ``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/community/samples/serving/helloworld-vertx/README.md b/community/samples/serving/helloworld-vertx/README.md deleted file mode 100644 index cadcbc9fe..000000000 --- a/community/samples/serving/helloworld-vertx/README.md +++ /dev/null @@ -1,250 +0,0 @@ -Learn how to deploy a simple web app that is written in Java and uses Eclipse -Vert.x. This samples uses Docker to build locally. The app reads in a `TARGET` -env variable and then prints "Hello World: \${TARGET}!". If a value for `TARGET` -is not specified, the "NOT SPECIFIED" default value is used. - -Use this sample to walk you through the steps of creating and modifying the -sample app, building and pushing your container image to a registry, and then -deploying your app to your Knative cluster. - -## Before you begin - -You must meet the following requirements to complete this sample: - -- A version of the Knative Serving component installed and running on your - Kubernetes cluster. Follow the - [Knative installation instructions](../../../../docs/install/README.md) if you need to - create a Knative cluster. -- The following software downloaded and install on your loacal machine: - - [Java SE 8 or later JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html). - - [Eclipse Vert.x v3.5.4](https://vertx.io/). - - [Docker](https://www.docker.com) for building and pushing your container - image. - - [curl](https://curl.haxx.se/) to test the sample app after deployment. -- A [Docker Hub](https://hub.docker.com/) account where you can push your - container image. - -**Tip**: You can clone the [Knative/docs repo](https://github.com/knative/docs) -and then modify the source files. Alternatively, learn more by manually creating -the files yourself. - -## Creating and configuring the sample code - -To create and configure the source files in the root of your working directory: - -1. Create the `pom.xml` file: - - ```xml - - 4.0.0 - com.example.vertx - helloworld - 1.0.0-SNAPSHOT - - - - io.vertx - vertx-core - ${version.vertx} - - - io.vertx - vertx-rx-java2 - ${version.vertx} - - - - - - - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.0 - - - package - - shade - - - - - - io.vertx.core.Launcher - com.example.helloworld.HelloWorld - - - - - - - - - - - - - 3.5.4 - - - ``` - -1. Create the `HelloWorld.java` file in the - `src/main/java/com/example/helloworld` directory. The - `[ROOT]/src/main/java/com/example/helloworld/HelloWorld.java` file creates a - basic web server that listens on port `8080`. - - ```java - package com.example.helloworld; - - import io.reactivex.Flowable; - import io.vertx.reactivex.core.AbstractVerticle; - import io.vertx.reactivex.core.http.HttpServer; - import io.vertx.reactivex.core.http.HttpServerRequest; - - public class HelloWorld extends AbstractVerticle { - - public void start() { - - final HttpServer server = vertx.createHttpServer(); - final Flowable requestFlowable = server.requestStream().toFlowable(); - - requestFlowable.subscribe(httpServerRequest -> { - - String target = System.getenv("TARGET"); - if (target == null) { - target = "NOT SPECIFIED"; - } - - httpServerRequest.response().setChunked(true) - .putHeader("content-type", "text/plain") - .setStatusCode(200) // OK - .end("Hello World: " + target); - }); - - server.listen(8080); - } - } - ``` - -1. Create the `Dockerfile` file: - - ```docker - # Use fabric8's s2i Builder image. - # https://hub.docker.com/r/fabric8/s2i-java - FROM fabric8/s2i-java:2.0 - - # Copy the JAR file to the deployment directory. - ENV JAVA_APP_DIR=/deployments - COPY target/helloworld-1.0.0-SNAPSHOT.jar /deployments/ - ``` - -1. Create the `service.yaml` file. You must specify your Docker Hub username in - `{username}`. You can also configure the `TARGET`, for example you can modify - the `Eclipse Vert.x Sample v1` value. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-vertx - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-vertx - env: - - name: TARGET - value: "Eclipse Vert.x Sample v1" - ``` - -## Building and deploying the sample - -To build a container image, push your image to the registry, and then deploy -your sample app to your cluster: - -1. Use Docker to build your container image and then push that image to your - Docker Hub registry. You must replace the `{username}` variables in the - following commands with your Docker Hub username. - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-vertx . - - # Push the container to docker registry - docker push {username}/helloworld-vertx - ``` - -1. Now that your container image is in the registry, you can deploy it to your - Knative cluster by running the `kubectl apply` command: - - ```shell - kubectl apply --filename service.yaml - ``` - - Result: A service name `helloworld-vertx` is created in your cluster along - with the following resources: - - - A new immutable revision for the version of the app that you just deployed. - - The following networking resources are created for your app: - - route - - ingress - - service - - load balancer - - Auto scaling is enable to allow your pods to scale up to meet traffic, and - also back down to zero when there is no traffic. - -## Testing the sample app - -To verify that your sample app has been successfully deployed: - -1. Retrieve the URL for your service, by running the following `kubectl get` - command: - - ```shell - kubectl get ksvc helloworld-vertx --output=custom-columns=NAME:.metadata.name,URL:.status.url - ``` - - Example result: - - ```shell - NAME URL - helloworld-vertx http://helloworld-vertx.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-vertx.default.1.2.3.4.xip.io - ``` - - Example result: - - ```shell - Hello World: Eclipse Vert.x Sample v1 - ``` - -Congratulations on deploying your sample Java app to Knative! - -## Removing the sample app deployment - -To remove the sample app from your cluster, run the following `kubectl delete` -command: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/community/samples/serving/helloworld-vertx/index.md b/community/samples/serving/helloworld-vertx/index.md index a4affb750..afe70544f 100644 --- a/community/samples/serving/helloworld-vertx/index.md +++ b/community/samples/serving/helloworld-vertx/index.md @@ -5,4 +5,253 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +Learn how to deploy a simple web app that is written in Java and uses Eclipse +Vert.x. This samples uses Docker to build locally. The app reads in a `TARGET` +env variable and then prints "Hello World: \${TARGET}!". If a value for `TARGET` +is not specified, the "NOT SPECIFIED" default value is used. + +Use this sample to walk you through the steps of creating and modifying the +sample app, building and pushing your container image to a registry, and then +deploying your app to your Knative cluster. + +## Before you begin + +You must meet the following requirements to complete this sample: + +- A version of the Knative Serving component installed and running on your + Kubernetes cluster. Follow the + [Knative installation instructions](../../../../docs/install/README.md) if you need to + create a Knative cluster. +- The following software downloaded and install on your loacal machine: + - [Java SE 8 or later JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html). + - [Eclipse Vert.x v3.5.4](https://vertx.io/). + - [Docker](https://www.docker.com) for building and pushing your container + image. + - [curl](https://curl.haxx.se/) to test the sample app after deployment. +- A [Docker Hub](https://hub.docker.com/) account where you can push your + container image. + +**Tip**: You can clone the [Knative/docs repo](https://github.com/knative/docs) +and then modify the source files. Alternatively, learn more by manually creating +the files yourself. + +## Creating and configuring the sample code + +To create and configure the source files in the root of your working directory: + +1. Create the `pom.xml` file: + + ```xml + + 4.0.0 + com.example.vertx + helloworld + 1.0.0-SNAPSHOT + + + + io.vertx + vertx-core + ${version.vertx} + + + io.vertx + vertx-rx-java2 + ${version.vertx} + + + + + + + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.0 + + + package + + shade + + + + + + io.vertx.core.Launcher + com.example.helloworld.HelloWorld + + + + + + + + + + + + + 3.5.4 + + + ``` + +1. Create the `HelloWorld.java` file in the + `src/main/java/com/example/helloworld` directory. The + `[ROOT]/src/main/java/com/example/helloworld/HelloWorld.java` file creates a + basic web server that listens on port `8080`. + + ```java + package com.example.helloworld; + + import io.reactivex.Flowable; + import io.vertx.reactivex.core.AbstractVerticle; + import io.vertx.reactivex.core.http.HttpServer; + import io.vertx.reactivex.core.http.HttpServerRequest; + + public class HelloWorld extends AbstractVerticle { + + public void start() { + + final HttpServer server = vertx.createHttpServer(); + final Flowable requestFlowable = server.requestStream().toFlowable(); + + requestFlowable.subscribe(httpServerRequest -> { + + String target = System.getenv("TARGET"); + if (target == null) { + target = "NOT SPECIFIED"; + } + + httpServerRequest.response().setChunked(true) + .putHeader("content-type", "text/plain") + .setStatusCode(200) // OK + .end("Hello World: " + target); + }); + + server.listen(8080); + } + } + ``` + +1. Create the `Dockerfile` file: + + ```docker + # Use fabric8's s2i Builder image. + # https://hub.docker.com/r/fabric8/s2i-java + FROM fabric8/s2i-java:2.0 + + # Copy the JAR file to the deployment directory. + ENV JAVA_APP_DIR=/deployments + COPY target/helloworld-1.0.0-SNAPSHOT.jar /deployments/ + ``` + +1. Create the `service.yaml` file. You must specify your Docker Hub username in + `{username}`. You can also configure the `TARGET`, for example you can modify + the `Eclipse Vert.x Sample v1` value. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-vertx + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-vertx + env: + - name: TARGET + value: "Eclipse Vert.x Sample v1" + ``` + +## Building and deploying the sample + +To build a container image, push your image to the registry, and then deploy +your sample app to your cluster: + +1. Use Docker to build your container image and then push that image to your + Docker Hub registry. You must replace the `{username}` variables in the + following commands with your Docker Hub username. + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-vertx . + + # Push the container to docker registry + docker push {username}/helloworld-vertx + ``` + +1. Now that your container image is in the registry, you can deploy it to your + Knative cluster by running the `kubectl apply` command: + + ```shell + kubectl apply --filename service.yaml + ``` + + Result: A service name `helloworld-vertx` is created in your cluster along + with the following resources: + + - A new immutable revision for the version of the app that you just deployed. + - The following networking resources are created for your app: + - route + - ingress + - service + - load balancer + - Auto scaling is enable to allow your pods to scale up to meet traffic, and + also back down to zero when there is no traffic. + +## Testing the sample app + +To verify that your sample app has been successfully deployed: + +1. Retrieve the URL for your service, by running the following `kubectl get` + command: + + ```shell + kubectl get ksvc helloworld-vertx --output=custom-columns=NAME:.metadata.name,URL:.status.url + ``` + + Example result: + + ```shell + NAME URL + helloworld-vertx http://helloworld-vertx.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-vertx.default.1.2.3.4.xip.io + ``` + + Example result: + + ```shell + Hello World: Eclipse Vert.x Sample v1 + ``` + +Congratulations on deploying your sample Java app to Knative! + +## Removing the sample app deployment + +To remove the sample app from your cluster, run the following `kubectl delete` +command: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/community/samples/serving/machinelearning-python-bentoml/README.md b/community/samples/serving/machinelearning-python-bentoml/README.md deleted file mode 100644 index 183a24f9a..000000000 --- a/community/samples/serving/machinelearning-python-bentoml/README.md +++ /dev/null @@ -1,186 +0,0 @@ -A simple machine learning model with API serving that is written in python and -using [BentoML](https://github.com/bentoml/BentoML). BentoML is an open source -framework for high performance ML model serving, which supports all major machine -learning frameworks including Keras, Tensorflow, PyTorch, Fast.ai, XGBoost and etc. - -This sample will walk you through the steps of creating and deploying a machine learning -model using python. It will use BentoML to package a classifier model trained -on the Iris dataset. Afterward, it will create a container image and -deploy the image to Knative. - -Knative deployment guide with BentoML is also available in the -[BentoML documentation](https://docs.bentoml.org/en/latest/deployment/knative.html) - -## Before you begin - -- A Kubernetes cluster with Knative installed. Follow the - [installation instructions](../../../../docs/install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured. Docker Hub will be used for a container registry). -- Python 3.6 or above installed and running on your local machine. - - Install `scikit-learn` and `bentoml` packages: - - ```shell - pip install scikit-learn - pip install bentoml - ``` - -## Recreating sample code - -Run the following code on your local machine, to train a machine learning model and deploy it -as API endpoint with KNative Serving. - -1. BentoML creates a model API server, via prediction service abstraction. In - `iris_classifier.py`, it defines a prediction service that requires a scikit-learn - model, asks BentoML to figure out the required pip dependencies, also defines an - API, which is the entry point for accessing this machine learning service. - - {{% readfile file="iris_classifier.py" %}} - -2. In `main.py`, it uses the classic - [iris flower data set](https://en.wikipedia.org/wiki/Iris_flower_data_set) - to train a classification model which can predict the species of an iris flower with - given data and then save the model with BentoML to local disk. - - {{% readfile file="main.py" %}} - - Run the `main.py` file to train and save the model: - - ```shell - python main.py - ``` - -3. Use BentoML CLI to check saved model's information. - - ```shell - bentoml get IrisClassifier:latest - ``` - - Example: - - ```shell - > bentoml get IrisClassifier:latest - { - "name": "IrisClassifier", - "version": "20200305171229_0A1411", - "uri": { - "type": "LOCAL", - "uri": "/Users/bozhaoyu/bentoml/repository/IrisClassifier/20200305171229_0A1411" - }, - "bentoServiceMetadata": { - "name": "IrisClassifier", - "version": "20200305171229_0A1411", - "createdAt": "2020-03-06T01:12:49.431011Z", - "env": { - "condaEnv": "name: bentoml-IrisClassifier\nchannels:\n- defaults\ndependencies:\n- python=3.7.3\n- pip\n", - "pipDependencies": "bentoml==0.6.2\nscikit-learn", - "pythonVersion": "3.7.3" - }, - "artifacts": [ - { - "name": "model", - "artifactType": "SklearnModelArtifact" - } - ], - "apis": [ - { - "name": "predict", - "handlerType": "DataframeHandler", - "docs": "BentoService API", - "handlerConfig": { - "orient": "records", - "typ": "frame", - "input_dtypes": null, - "output_orient": "records" - } - } - ] - } - } - ``` - -4. Test run API server. BentoML can start an API server from the saved model. Use - BentoML CLI command to start an API server locally and test it with the `curl` command. - - ```shell - bentoml serve IrisClassifier:latest - ``` - - In another terminal window, make `curl` request with sample data to the API server - and get prediction result: - - ```shell - curl -v -i \ - --header "Content-Type: application/json" \ - --request POST \ - --data '[[5.1, 3.5, 1.4, 0.2]]' \ - 127.0.0.1:5000/predict - ``` - -## Building and deploying the sample - -BentoML supports creating an API server docker image from its saved model directory, where -a Dockerfile is automatically generated when saving the model. - -1. To build an API model server docker image, replace `{username}` with your Docker Hub - username and run the following commands. - - ```shell - # jq might not be installed on your local system, please follow jq install - # instruction at https://stedolan.github.io/jq/download/ - saved_path=$(bentoml get IrisClassifier:latest -q | jq -r ".uri.uri") - - # Build the container on your local machine - docker build - t {username}/iris-classifier $saved_path - - # Push the container to docker registry - docker push {username}/iris-classifier - ``` - -2. In `service.yaml`, replace `{username}` with your Docker hub username, and then deploy - the service to Knative Serving with `kubectl`: - - {{% readfile file="service.yaml" %}} - - ```shell - kubectl apply --filename service.yaml - ``` - -3. Now that your service is created, Knative performs the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load - balance for your application. - - Automatically scale your pods up and down (including to zero active - pods). - -4. Run the following command to find the domain URL for your service: - - ```shell - kubectl get ksvc iris-classifier --output=custom-columns=NAME:.metadata.name,URL:.status.url - - NAME URL - iris-classifier http://iris-classifer.default.example.com - ``` - -5. Replace the request URL with the URL return in the previous command, and execute the - command to get prediction result from the deployed model API endpoint. - - ```shell - curl -v -i \ - --header "Content-Type: application/json" \ - --request POST \ - --data '[[5.1, 3.5, 1.4, 0.2]]' \ - http://iris-classifier.default.example.com/predict - - [0] - ``` - -## Removing the sample app deployment - -To remove the application from your cluster, delete the service record: - - ```shell - kubectl delete --filename service.yaml - ``` diff --git a/community/samples/serving/machinelearning-python-bentoml/index.md b/community/samples/serving/machinelearning-python-bentoml/index.md index e7ad73815..6c867e0ab 100644 --- a/community/samples/serving/machinelearning-python-bentoml/index.md +++ b/community/samples/serving/machinelearning-python-bentoml/index.md @@ -5,4 +5,189 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple machine learning model with API serving that is written in python and +using [BentoML](https://github.com/bentoml/BentoML). BentoML is an open source +framework for high performance ML model serving, which supports all major machine +learning frameworks including Keras, Tensorflow, PyTorch, Fast.ai, XGBoost and etc. + +This sample will walk you through the steps of creating and deploying a machine learning +model using python. It will use BentoML to package a classifier model trained +on the Iris dataset. Afterward, it will create a container image and +deploy the image to Knative. + +Knative deployment guide with BentoML is also available in the +[BentoML documentation](https://docs.bentoml.org/en/latest/deployment/knative.html) + +## Before you begin + +- A Kubernetes cluster with Knative installed. Follow the + [installation instructions](../../../../docs/install/README.md) if you need to + create one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured. Docker Hub will be used for a container registry). +- Python 3.6 or above installed and running on your local machine. + - Install `scikit-learn` and `bentoml` packages: + + ```shell + pip install scikit-learn + pip install bentoml + ``` + +## Recreating sample code + +Run the following code on your local machine, to train a machine learning model and deploy it +as API endpoint with KNative Serving. + +1. BentoML creates a model API server, via prediction service abstraction. In + `iris_classifier.py`, it defines a prediction service that requires a scikit-learn + model, asks BentoML to figure out the required pip dependencies, also defines an + API, which is the entry point for accessing this machine learning service. + + {{% readfile file="iris_classifier.py" %}} + +2. In `main.py`, it uses the classic + [iris flower data set](https://en.wikipedia.org/wiki/Iris_flower_data_set) + to train a classification model which can predict the species of an iris flower with + given data and then save the model with BentoML to local disk. + + {{% readfile file="main.py" %}} + + Run the `main.py` file to train and save the model: + + ```shell + python main.py + ``` + +3. Use BentoML CLI to check saved model's information. + + ```shell + bentoml get IrisClassifier:latest + ``` + + Example: + + ```shell + > bentoml get IrisClassifier:latest + { + "name": "IrisClassifier", + "version": "20200305171229_0A1411", + "uri": { + "type": "LOCAL", + "uri": "/Users/bozhaoyu/bentoml/repository/IrisClassifier/20200305171229_0A1411" + }, + "bentoServiceMetadata": { + "name": "IrisClassifier", + "version": "20200305171229_0A1411", + "createdAt": "2020-03-06T01:12:49.431011Z", + "env": { + "condaEnv": "name: bentoml-IrisClassifier\nchannels:\n- defaults\ndependencies:\n- python=3.7.3\n- pip\n", + "pipDependencies": "bentoml==0.6.2\nscikit-learn", + "pythonVersion": "3.7.3" + }, + "artifacts": [ + { + "name": "model", + "artifactType": "SklearnModelArtifact" + } + ], + "apis": [ + { + "name": "predict", + "handlerType": "DataframeHandler", + "docs": "BentoService API", + "handlerConfig": { + "orient": "records", + "typ": "frame", + "input_dtypes": null, + "output_orient": "records" + } + } + ] + } + } + ``` + +4. Test run API server. BentoML can start an API server from the saved model. Use + BentoML CLI command to start an API server locally and test it with the `curl` command. + + ```shell + bentoml serve IrisClassifier:latest + ``` + + In another terminal window, make `curl` request with sample data to the API server + and get prediction result: + + ```shell + curl -v -i \ + --header "Content-Type: application/json" \ + --request POST \ + --data '[[5.1, 3.5, 1.4, 0.2]]' \ + 127.0.0.1:5000/predict + ``` + +## Building and deploying the sample + +BentoML supports creating an API server docker image from its saved model directory, where +a Dockerfile is automatically generated when saving the model. + +1. To build an API model server docker image, replace `{username}` with your Docker Hub + username and run the following commands. + + ```shell + # jq might not be installed on your local system, please follow jq install + # instruction at https://stedolan.github.io/jq/download/ + saved_path=$(bentoml get IrisClassifier:latest -q | jq -r ".uri.uri") + + # Build the container on your local machine + docker build - t {username}/iris-classifier $saved_path + + # Push the container to docker registry + docker push {username}/iris-classifier + ``` + +2. In `service.yaml`, replace `{username}` with your Docker hub username, and then deploy + the service to Knative Serving with `kubectl`: + + {{% readfile file="service.yaml" %}} + + ```shell + kubectl apply --filename service.yaml + ``` + +3. Now that your service is created, Knative performs the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load + balance for your application. + - Automatically scale your pods up and down (including to zero active + pods). + +4. Run the following command to find the domain URL for your service: + + ```shell + kubectl get ksvc iris-classifier --output=custom-columns=NAME:.metadata.name,URL:.status.url + + NAME URL + iris-classifier http://iris-classifer.default.example.com + ``` + +5. Replace the request URL with the URL return in the previous command, and execute the + command to get prediction result from the deployed model API endpoint. + + ```shell + curl -v -i \ + --header "Content-Type: application/json" \ + --request POST \ + --data '[[5.1, 3.5, 1.4, 0.2]]' \ + http://iris-classifier.default.example.com/predict + + [0] + ``` + +## Removing the sample app deployment + +To remove the application from your cluster, delete the service record: + + ```shell + kubectl delete --filename service.yaml + ```