From bc43a6858d3392e53a335dbe44879623a9e7b2ac Mon Sep 17 00:00:00 2001 From: Luca Seritan Date: Wed, 5 Jun 2024 11:18:14 +0300 Subject: [PATCH] feat(examples): Add nginx-golang compose example This example is dervied from the nginx-golang docker/awesome-compose example. Signed-off-by: Luca Seritan --- .github/workflows/examples-nginx-golang.yaml | 45 ++++++++++ examples/nginx-golang/README.md | 95 ++++++++++++++++++++ examples/nginx-golang/backend/Dockerfile | 29 ++++++ examples/nginx-golang/backend/Kraftfile | 8 ++ examples/nginx-golang/backend/go.mod | 5 ++ examples/nginx-golang/backend/go.sum | 2 + examples/nginx-golang/backend/main.go | 35 ++++++++ examples/nginx-golang/compose.yaml | 25 ++++++ examples/nginx-golang/proxy/nginx.conf | 26 ++++++ 9 files changed, 270 insertions(+) create mode 100644 .github/workflows/examples-nginx-golang.yaml create mode 100644 examples/nginx-golang/README.md create mode 100644 examples/nginx-golang/backend/Dockerfile create mode 100644 examples/nginx-golang/backend/Kraftfile create mode 100644 examples/nginx-golang/backend/go.mod create mode 100644 examples/nginx-golang/backend/go.sum create mode 100644 examples/nginx-golang/backend/main.go create mode 100644 examples/nginx-golang/compose.yaml create mode 100644 examples/nginx-golang/proxy/nginx.conf diff --git a/.github/workflows/examples-nginx-golang.yaml b/.github/workflows/examples-nginx-golang.yaml new file mode 100644 index 00000000..9f0e2198 --- /dev/null +++ b/.github/workflows/examples-nginx-golang.yaml @@ -0,0 +1,45 @@ +name: examples/nginx-golang + +on: + repository_dispatch: + types: [core_merge] + + workflow_dispatch: + + schedule: + - cron: '0 0 * * *' # Everyday at 12AM + + push: + branches: [main] + paths: + - 'examples/nginx-golang/**' + - '.github/workflows/examples-nginx-golang.yaml' + - '!examples/nginx-golang/README.md' + + pull_request: + types: [opened, synchronize, reopened] + branches: [main] + paths: + - 'examples/nginx-golang/**' + - '.github/workflows/examples-nginx-golang.yaml' + - '!examples/nginx-golang/README.md' + +jobs: + up: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: kraft compose up + uses: unikraft/kraftkit@staging + with: + loglevel: debug + workdir: examples/nginx-golang + runtimedir: /github/workspace/.kraftkit + privileged: true + run: | + set -xe + + sudo kraft compose up -d + curl localhost:8080 diff --git a/examples/nginx-golang/README.md b/examples/nginx-golang/README.md new file mode 100644 index 00000000..01dfb936 --- /dev/null +++ b/examples/nginx-golang/README.md @@ -0,0 +1,95 @@ +## Compose sample application + +### NGINX proxy with Go backend + +This example was derived from the [nginx-golang docker/awesome-compose example](https://github.com/docker/awesome-compose/tree/master/nginx-golang). + +Project structure: + +```bash +. +├── backend +│   ├── Kraftfile +│   ├── Dockerfile +│   └── main.go +├── compose.yaml +├── proxy +│   └── nginx.conf +└── README.md +``` + +[`compose.yaml`](compose.yaml) + +```yml +services: + proxy: + image: nginx:1.25 + volumes: + - ./proxy:/etc/nginx + ports: + - 8080:80 + depends_on: + - backend + networks: + internal: + + backend: + build: + context: backend + networks: + internal: + ipv4_address: 172.23.0.2 + +networks: + internal: + ipam: + config: + - subnet: 172.23.0.1/16 +``` + +The compose file defines an application with two services `proxy` and `backend`. +When deploying the application, kraft compose maps port 80 of the frontend service VM to port 8080 of the host as specified in the file. +Make sure port 8080 on the host is not already in use. + +## Deploy with kraft compose + +```bash +$ kraft compose up -d +creating network nginx-golang_internal... +nginx-golang_internal + i building service backend... +... +nginx-golang-backend +nginx-golang-proxy +``` + +## Expected result + +Listing VMs must show two VMs running and the port mapping as below: + +```bash +$ kraft compose ps +NAME KERNEL ARGS CREATED STATUS MEM PORTS PLAT +nginx-golang-backend oci://unikraft.org/base:latest /server 23 seconds ago running 64M qemu/x86_64 +nginx-golang-proxy oci://nginx:1.25 /usr/bin/nginx 22 seconds ago running 64M 0.0.0.0:8080->80/tcp qemu/x86_64 +``` + +After the application starts, navigate to `http://localhost:8080` in your web browser or run: + +```bash +$ curl localhost:8080 + .--------------------. +( Hello from Unikraft! ) + '--------------------' + \\ + \\ + _ + c'o'o .--. + (| |)_/ +``` + +Stop and remove the VMs + +```bash +kraft compose down +``` diff --git a/examples/nginx-golang/backend/Dockerfile b/examples/nginx-golang/backend/Dockerfile new file mode 100644 index 00000000..8250590f --- /dev/null +++ b/examples/nginx-golang/backend/Dockerfile @@ -0,0 +1,29 @@ +FROM golang:1.21.3-bookworm AS build + +WORKDIR /src + +COPY ./main.go /src/server.go + +COPY go.mod go.sum ./ +RUN --mount=type=cache,target=/go/pkg/mod/cache \ + go mod download + +COPY . . + +RUN set -xe; \ + CGO_ENABLED=1 \ + go build \ + -buildmode=pie \ + -ldflags "-linkmode external -extldflags '-static-pie'" \ + -tags netgo \ + -o /server server.go \ + ; + +FROM scratch + +COPY --from=build /server /server +COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/ +COPY --from=build /lib64/ld-linux-x86-64.so.2 /lib64/ + +CMD ["/server"] + diff --git a/examples/nginx-golang/backend/Kraftfile b/examples/nginx-golang/backend/Kraftfile new file mode 100644 index 00000000..d4ccae32 --- /dev/null +++ b/examples/nginx-golang/backend/Kraftfile @@ -0,0 +1,8 @@ +spec: v0.6 + +runtime: base:latest + +rootfs: ./Dockerfile + +cmd: ["/server"] + diff --git a/examples/nginx-golang/backend/go.mod b/examples/nginx-golang/backend/go.mod new file mode 100644 index 00000000..60f6a49a --- /dev/null +++ b/examples/nginx-golang/backend/go.mod @@ -0,0 +1,5 @@ +module module github.com/unikraft/catalog/examples/nginx-golang/backend + +go 1.18 + +require github.com/go-chi/chi/v5 v5.0.7 diff --git a/examples/nginx-golang/backend/go.sum b/examples/nginx-golang/backend/go.sum new file mode 100644 index 00000000..433d6716 --- /dev/null +++ b/examples/nginx-golang/backend/go.sum @@ -0,0 +1,2 @@ +github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= +github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= diff --git a/examples/nginx-golang/backend/main.go b/examples/nginx-golang/backend/main.go new file mode 100644 index 00000000..83dfeea9 --- /dev/null +++ b/examples/nginx-golang/backend/main.go @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + "log" + "net/http" + + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" +) + +func handler(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf( + w, ` + .--------------------. +( Hello from Unikraft! ) + '--------------------' + \\ + \\ + _ + c'o'o .--. + (| |)_/ + +`, + ) +} + +func main() { + r := chi.NewRouter() + r.Use(middleware.Logger) + r.Get("/", handler) + + fmt.Println("Go backend started!") + log.Fatal(http.ListenAndServe(":80", r)) +} diff --git a/examples/nginx-golang/compose.yaml b/examples/nginx-golang/compose.yaml new file mode 100644 index 00000000..7eddef34 --- /dev/null +++ b/examples/nginx-golang/compose.yaml @@ -0,0 +1,25 @@ +--- +services: + proxy: + image: nginx:1.25 + volumes: + - ./proxy:/etc/nginx + ports: + - 8080:80 + depends_on: + - backend + networks: + internal: + + backend: + build: + context: backend + networks: + internal: + ipv4_address: 172.23.0.2 + +networks: + internal: + ipam: + config: + - subnet: 172.23.0.1/16 diff --git a/examples/nginx-golang/proxy/nginx.conf b/examples/nginx-golang/proxy/nginx.conf new file mode 100644 index 00000000..99a76429 --- /dev/null +++ b/examples/nginx-golang/proxy/nginx.conf @@ -0,0 +1,26 @@ +worker_processes 1; +daemon off; +master_process off; +user root root; + +events { + worker_connections 32; +} + +http { + error_log stderr error; + access_log off; + + keepalive_timeout 10s; + keepalive_requests 10000; + send_timeout 10s; + + server { + listen 80; + server_name localhost; + + location / { + proxy_pass http://172.23.0.2; + } + } +}