[docs] Update R sample to use Go (#1676)

* Update R sample to use Go

* Dockerfile updates

* Update ReadMe
This commit is contained in:
Averi Kitsch 2019-08-29 14:25:46 -07:00 committed by Knative Prow Robot
parent b6313703d5
commit 2c2d37d58f
7 changed files with 107 additions and 80 deletions

View File

@ -1,6 +1,2 @@
Dockerfile
README.md
*.pyc
*.pyo
*.pyd
__pycache__

View File

@ -1,21 +1,26 @@
# Use the official Python image.
# https://hub.docker.com/_/python
FROM python:3.7
# Use the offical 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.
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . .
WORKDIR /go/src/github.com/knative/docs/helloworld-r
COPY invoke.go .
# Install production dependencies.
RUN pip install Flask gunicorn
# 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
# Install R
RUN apt-get update && \
apt-get install -y r-base
# 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
# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 app:app
# 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"]

View File

@ -1,4 +1,4 @@
#!/usr/bin/Rscript
#!/bin/Rscript
TARGET <- Sys.getenv("TARGET", "World")
message = paste("Hello ", TARGET, "!", sep = "")

View File

@ -38,57 +38,73 @@ cd knative-docs/docs/serving/samples/hello-world/helloworld-r
print(message)
```
1. Create a new file named `app.py` and paste the following code. We use a
basic web server written in Python to execute the R script:
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:
```py
import os
import subprocess
```go
package main
from flask import Flask
import (
"fmt"
"log"
"net/http"
"os"
"os/exec"
)
app = Flask(__name__)
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)
}
@app.route('/')
def hello_world():
try:
output = subprocess.check_output('/usr/bin/Rscript HelloWorld.R', shell=True)
print(output)
except subprocess.CalledProcessError:
return "Error in R script.", 500
func main() {
http.HandleFunc("/", handler)
return output
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}
```
if __name__ == "__main__":
app.run(debug=True,host='0.0.0.0',port=int(os.environ.get('PORT', 8080)))
```
1. Create a new file named `Dockerfile` and copy the code block below into it.
1. Create a new file named `Dockerfile` and copy the code block below into it.
```docker
# Use the offical 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
```docker
# Use the official Python image.
# https://hub.docker.com/_/python
FROM python:3.7
# Copy local code to the container image.
WORKDIR /go/src/github.com/knative/docs/helloworld-r
COPY invoke.go .
# Copy local code to the container image.
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . .
# 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
# Install production dependencies.
RUN pip install Flask gunicorn
# 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
# Install R
RUN apt-get update && \
apt-get install -y r-base
# 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"]
```
# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 app: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

View File

@ -1,20 +0,0 @@
import os
import subprocess
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
try:
output = subprocess.check_output('/usr/bin/Rscript HelloWorld.R', shell=True)
print(output)
except subprocess.CalledProcessError:
return "Error in R script.", 500
return output
if __name__ == "__main__":
app.run(debug=True,host='0.0.0.0',port=int(os.environ.get('PORT', 8080)))

View File

@ -0,0 +1,30 @@
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))
}

View File

@ -7,7 +7,7 @@ spec:
template:
spec:
containers:
- image: docker.io/akitsch/helloworld-r
- image: docker.io/{username}/helloworld-r
env:
- name: TARGET
value: "R Sample v1"