diff --git a/nginx-golang/.dockerignore b/nginx-golang/.dockerignore new file mode 100644 index 00000000..1b8123b9 --- /dev/null +++ b/nginx-golang/.dockerignore @@ -0,0 +1 @@ +/.unikraft/ diff --git a/nginx-golang/README.md b/nginx-golang/README.md new file mode 100644 index 00000000..fbe764cd --- /dev/null +++ b/nginx-golang/README.md @@ -0,0 +1,27 @@ +# Compose: Nginx and Golang + +This is a [Compose](https://unikraft.cloud/docs/guides/features/compose/)-based example of a [Go]() HTTP server and an [Nginx](https://nginx.org/en/) proxy. +It is imported from the [`awesome-compose` repository](https://github.com/docker/awesome-compose). + +To run Nginx and Golang with Compose on Unikraft Cloud, first [install the `kraft` CLI tool](https://unikraft.org/docs/cli). +Then clone this examples repository and `cd` into this directory, and invoke: + +```console +kraft cloud compose up +``` + +The command will deploy files in the current directory. + +After deploying, you can query the service using the provided URL for Nginx. +Golang is only running in the backend with a public URL. +Find out the Nginx provided URL by using: + +```console +kraft cloud instance list +``` + +## Learn more + +- [The Compose Specification](https://github.com/compose-spec/compose-spec/blob/main/spec.md) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) diff --git a/nginx-golang/backend/Dockerfile b/nginx-golang/backend/Dockerfile new file mode 100644 index 00000000..d9170308 --- /dev/null +++ b/nginx-golang/backend/Dockerfile @@ -0,0 +1,25 @@ +# syntax=docker/dockerfile:1.4 +FROM --platform=$BUILDPLATFORM golang:1.23-bookworm AS builder + +WORKDIR /app + +#ENV CGO_ENABLED 0 +ENV GOPATH /go +ENV GOCACHE /go-build + +COPY go.mod go.sum ./ +RUN --mount=type=cache,target=/go/pkg/mod/cache \ + go mod download + +COPY . . + +RUN --mount=type=cache,target=/go/pkg/mod/cache \ + --mount=type=cache,target=/go-build \ + go build \ + -buildmode=pie \ + -ldflags "-linkmode external -extldflags -static-pie" \ + -tags netgo \ + -o bin/backend main.go + +FROM scratch +COPY --from=builder /app/bin/backend /usr/local/bin/backend diff --git a/nginx-golang/backend/Kraftfile b/nginx-golang/backend/Kraftfile new file mode 100644 index 00000000..dae9484a --- /dev/null +++ b/nginx-golang/backend/Kraftfile @@ -0,0 +1,12 @@ +spec: v0.6 + +runtime: base:latest + +labels: + cloud.unikraft.v1.instances/scale_to_zero.policy: "off" + cloud.unikraft.v1.instances/scale_to_zero.stateful: "false" + cloud.unikraft.v1.instances/scale_to_zero.cooldown_time_ms: 1000 + +rootfs: ./Dockerfile + +cmd: ["/usr/local/bin/backend"] diff --git a/nginx-golang/backend/go.mod b/nginx-golang/backend/go.mod new file mode 100644 index 00000000..3db03c11 --- /dev/null +++ b/nginx-golang/backend/go.mod @@ -0,0 +1,5 @@ +module github.com/docker/awesome-compose/nginx-golang/backend + +go 1.18 + +require github.com/go-chi/chi/v5 v5.0.7 diff --git a/nginx-golang/backend/go.sum b/nginx-golang/backend/go.sum new file mode 100644 index 00000000..433d6716 --- /dev/null +++ b/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/nginx-golang/backend/main.go b/nginx-golang/backend/main.go new file mode 100644 index 00000000..8a36aa75 --- /dev/null +++ b/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, ` +o. .o _ _ __ _ +Oo Oo ___ (_) | __ __ __ _ ' _) :_ +oO oO ' _ '| | |/ / _)' _' | |_| _) +oOo oOO| | | | | (| | | (_) | _) :_ + OoOoO ._, ._:_:_,\_._, .__,_:_, \___) + + +Hello from Unikraft! + +`, + ) +} + +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/nginx-golang/compose.yaml b/nginx-golang/compose.yaml new file mode 100644 index 00000000..e227388d --- /dev/null +++ b/nginx-golang/compose.yaml @@ -0,0 +1,10 @@ +services: + proxy: + build: ./proxy + ports: + - 443:80 + depends_on: + - backend + + backend: + build: ./backend diff --git a/nginx-golang/proxy/Kraftfile b/nginx-golang/proxy/Kraftfile new file mode 100644 index 00000000..6f3c37da --- /dev/null +++ b/nginx-golang/proxy/Kraftfile @@ -0,0 +1,12 @@ +spec: v0.6 + +runtime: nginx:latest + +labels: + cloud.unikraft.v1.instances/scale_to_zero.policy: "on" + cloud.unikraft.v1.instances/scale_to_zero.stateful: "false" + cloud.unikraft.v1.instances/scale_to_zero.cooldown_time_ms: 1000 + +rootfs: ./rootfs + +cmd: ["/usr/bin/nginx", "-c", "/etc/nginx/nginx.conf"] diff --git a/nginx-golang/proxy/rootfs/etc/nginx/nginx.conf b/nginx-golang/proxy/rootfs/etc/nginx/nginx.conf new file mode 100644 index 00000000..53c9dfb6 --- /dev/null +++ b/nginx-golang/proxy/rootfs/etc/nginx/nginx.conf @@ -0,0 +1,17 @@ +worker_processes 1; +daemon off; +master_process off; +user root root; + +events { + worker_connections 64; +} + +http { + server { + listen 80; + location / { + proxy_pass http://nginx-golang-backend.internal:80; + } + } +}