-
-
Notifications
You must be signed in to change notification settings - Fork 494
feat: add Cloudflare Container Workers example with Go Fiber v3 #3248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| node_modules/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # syntax=docker/dockerfile:1 | ||
|
|
||
| FROM golang:1.24-alpine AS build | ||
|
|
||
| # Set destination for COPY | ||
| WORKDIR /app | ||
|
|
||
| # Download any Go modules | ||
| COPY container_src/go.mod container_src/go.sum ./ | ||
| RUN go mod download | ||
|
|
||
| # Copy container source code | ||
| COPY container_src/*.go ./ | ||
|
|
||
| # Build with optimizations | ||
| RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ | ||
| -ldflags="-w -s" \ | ||
| -o /server | ||
|
|
||
| # Use distroless for minimal attack surface | ||
| FROM gcr.io/distroless/static-debian12:latest | ||
|
|
||
| # Copy the binary | ||
| COPY --from=build /server /server | ||
|
|
||
| # Expose port | ||
| EXPOSE 8080 | ||
|
|
||
| # Run | ||
| ENTRYPOINT ["/server"] | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,67 @@ | ||||||||||||||||
| # Cloudflare Container Workers with Go Fiber | ||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add required Docusaurus metadata for recipes. Based on the contributing guidelines for the gofiber/recipes repository, the README should include Docusaurus metadata at the top of the file. Add this metadata block at the beginning of the file: +---
+id: cloudflare-workers
+title: Cloudflare Container Workers
+---
+
# Cloudflare Container Workers with Go Fiber📝 Committable suggestion
Suggested change
🧰 Tools🪛 LanguageTool[grammar] ~1-~1: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) 🤖 Prompt for AI Agents |
||||||||||||||||
|
|
||||||||||||||||
| This example demonstrates how to use [Go Fiber v3](https://github.com/gofiber/fiber) with [Cloudflare Container Workers](https://developers.cloudflare.com/containers/). | ||||||||||||||||
|
|
||||||||||||||||
| ## Features | ||||||||||||||||
|
|
||||||||||||||||
| - **Go Fiber v3** framework | ||||||||||||||||
| - **Distroless container** for minimal attack surface (`gcr.io/distroless/static-debian12`) | ||||||||||||||||
| - **JSON API** response | ||||||||||||||||
| - **Environment variables** support | ||||||||||||||||
| - **Logger and Recover** middleware | ||||||||||||||||
|
|
||||||||||||||||
| ## Prerequisites | ||||||||||||||||
|
|
||||||||||||||||
| - Bun | ||||||||||||||||
| - Go 1.24+ | ||||||||||||||||
| - Wrangler CLI | ||||||||||||||||
| - Cloudflare account with Container Workers access | ||||||||||||||||
|
|
||||||||||||||||
| ## Getting Started | ||||||||||||||||
|
|
||||||||||||||||
| 1. Install dependencies: | ||||||||||||||||
| ```bash | ||||||||||||||||
| bun install | ||||||||||||||||
| ``` | ||||||||||||||||
|
|
||||||||||||||||
| 2. Run locally: | ||||||||||||||||
| ```bash | ||||||||||||||||
| bun run dev | ||||||||||||||||
| ``` | ||||||||||||||||
|
|
||||||||||||||||
| 3. Deploy to Cloudflare: | ||||||||||||||||
| ```bash | ||||||||||||||||
| bun run deploy | ||||||||||||||||
| ``` | ||||||||||||||||
|
|
||||||||||||||||
| ## Project Structure | ||||||||||||||||
|
|
||||||||||||||||
| ``` | ||||||||||||||||
| . | ||||||||||||||||
| ├── src/index.ts # Worker entry point | ||||||||||||||||
| ├── container_src/ | ||||||||||||||||
| │ ├── main.go # Go Fiber application | ||||||||||||||||
| │ ├── go.mod # Go module file | ||||||||||||||||
| │ └── go.sum # Go dependencies | ||||||||||||||||
| ├── Dockerfile # Container configuration | ||||||||||||||||
| └── wrangler.jsonc # Cloudflare Workers configuration | ||||||||||||||||
| ``` | ||||||||||||||||
|
|
||||||||||||||||
| ## How it Works | ||||||||||||||||
|
|
||||||||||||||||
| 1. The Worker (TypeScript) receives HTTP requests | ||||||||||||||||
| 2. Requests are forwarded to the Go Fiber container | ||||||||||||||||
| 3. The container responds with JSON data including environment variables | ||||||||||||||||
|
|
||||||||||||||||
| ## Container Configuration | ||||||||||||||||
|
|
||||||||||||||||
| The container is configured with: | ||||||||||||||||
| - 2 minute sleep timeout for inactivity | ||||||||||||||||
| - Environment variable `MESSAGE` passed from the container class | ||||||||||||||||
| - Port 8080 (default) | ||||||||||||||||
|
|
||||||||||||||||
| ## Learn More | ||||||||||||||||
|
|
||||||||||||||||
| - [Fiber Documentation](https://docs.gofiber.io/) | ||||||||||||||||
| - [Cloudflare Container Workers](https://developers.cloudflare.com/containers/) | ||||||||||||||||
| - [Cloudflare Workers](https://developers.cloudflare.com/workers/) | ||||||||||||||||
|
Comment on lines
+1
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify recipe integration tasks are completed. Ensure that the tasks from 🏁 Script executed: #!/bin/bash
# Verify the recipe follows the contributing guidelines
# Check if CONTRIBUTING.md exists and contains recipe guidelines
if [ -f ".github/CONTRIBUTING.md" ]; then
echo "=== CONTRIBUTING.md content about recipes ==="
grep -A 10 -B 5 -i "recipe\|directory\|generate" .github/CONTRIBUTING.md || echo "No recipe guidelines found"
else
echo "CONTRIBUTING.md not found"
fi
# Check if there's a Makefile with generate target
if [ -f "Makefile" ]; then
echo -e "\n=== Makefile generate target ==="
grep -A 5 -B 5 "generate" Makefile || echo "No generate target found"
else
echo "Makefile not found"
fi
# Check the current directory structure
echo -e "\n=== Current directory structure ==="
ls -la cloudflare-workers/Length of output: 2444 Add Docusaurus front-matter and update overview To comply with .github/CONTRIBUTING.md, please:
🧰 Tools🪛 LanguageTool[grammar] ~1-~1: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~3-~3: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~5-~5: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~11-~11: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~13-~13: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~18-~18: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~20-~20: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~22-~22: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~27-~27: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~32-~32: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~37-~37: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~50-~50: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~52-~52: There might be a mistake here. (QB_NEW_EN_OTHER) [grammar] ~53-~53: There might be a mistake here. (QB_NEW_EN_OTHER) [grammar] ~54-~54: There might be a mistake here. (QB_NEW_EN_OTHER) [grammar] ~54-~54: Place a period at the end of declarative sentences. (QB_NEW_EN_OTHER_ERROR_IDS_000178) [grammar] ~56-~56: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~59-~59: There might be a mistake here. (QB_NEW_EN_OTHER) [grammar] ~61-~61: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~63-~63: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) [grammar] ~67-~67: Use proper spacing conventions. (QB_NEW_EN_OTHER_ERROR_IDS_000007) 🪛 markdownlint-cli2 (0.17.2)39-39: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI Agents |
||||||||||||||||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| module server | ||
|
|
||
| go 1.24.3 | ||
|
|
||
| require github.com/gofiber/fiber/v3 v3.0.0-beta.4 | ||
|
|
||
| require ( | ||
| github.com/andybalholm/brotli v1.1.1 // indirect | ||
| github.com/fxamacker/cbor/v2 v2.7.0 // indirect | ||
| github.com/gofiber/schema v1.2.0 // indirect | ||
| github.com/gofiber/utils/v2 v2.0.0-beta.7 // indirect | ||
| github.com/google/uuid v1.6.0 // indirect | ||
| github.com/klauspost/compress v1.17.11 // indirect | ||
| github.com/mattn/go-colorable v0.1.13 // indirect | ||
| github.com/mattn/go-isatty v0.0.20 // indirect | ||
| github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect | ||
| github.com/tinylib/msgp v1.2.5 // indirect | ||
| github.com/valyala/bytebufferpool v1.0.0 // indirect | ||
| github.com/valyala/fasthttp v1.58.0 // indirect | ||
| github.com/valyala/tcplisten v1.0.0 // indirect | ||
| github.com/x448/float16 v0.8.4 // indirect | ||
| golang.org/x/crypto v0.31.0 // indirect | ||
| golang.org/x/net v0.31.0 // indirect | ||
| golang.org/x/sys v0.28.0 // indirect | ||
| golang.org/x/text v0.21.0 // indirect | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= | ||
| github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= | ||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
| github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= | ||
| github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= | ||
| github.com/gofiber/fiber/v3 v3.0.0-beta.4 h1:KzDSavvhG7m81NIsmnu5l3ZDbVS4feCidl4xlIfu6V0= | ||
| github.com/gofiber/fiber/v3 v3.0.0-beta.4/go.mod h1:/WFUoHRkZEsGHyy2+fYcdqi109IVOFbVwxv1n1RU+kk= | ||
| github.com/gofiber/schema v1.2.0 h1:j+ZRrNnUa/0ZuWrn/6kAtAufEr4jCJ+JuTURAMxNSZg= | ||
| github.com/gofiber/schema v1.2.0/go.mod h1:YYwj01w3hVfaNjhtJzaqetymL56VW642YS3qZPhuE6c= | ||
| github.com/gofiber/utils/v2 v2.0.0-beta.7 h1:NnHFrRHvhrufPABdWajcKZejz9HnCWmT/asoxRsiEbQ= | ||
| github.com/gofiber/utils/v2 v2.0.0-beta.7/go.mod h1:J/M03s+HMdZdvhAeyh76xT72IfVqBzuz/OJkrMa7cwU= | ||
| github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= | ||
| github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||
| github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= | ||
| github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= | ||
| github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= | ||
| github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= | ||
| github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= | ||
| github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= | ||
| github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= | ||
| github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY= | ||
| github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= | ||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
| github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= | ||
| github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
| github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po= | ||
| github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= | ||
| github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= | ||
| github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= | ||
| github.com/valyala/fasthttp v1.58.0 h1:GGB2dWxSbEprU9j0iMJHgdKYJVDyjrOwF9RE59PbRuE= | ||
| github.com/valyala/fasthttp v1.58.0/go.mod h1:SYXvHHaFp7QZHGKSHmoMipInhrI5StHrhDTYVEjK/Kw= | ||
| github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= | ||
| github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= | ||
| github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= | ||
| github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= | ||
| github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= | ||
| github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= | ||
| golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= | ||
| golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= | ||
| golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= | ||
| golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= | ||
| golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
| golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
| golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= | ||
| golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||
| golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= | ||
| golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= | ||
| gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
| gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "log" | ||
| "os" | ||
|
|
||
| "github.com/gofiber/fiber/v3" | ||
| "github.com/gofiber/fiber/v3/middleware/logger" | ||
| "github.com/gofiber/fiber/v3/middleware/recover" | ||
| ) | ||
|
|
||
| func main() { | ||
| // Create Fiber app | ||
| app := fiber.New(fiber.Config{ | ||
| // Production settings | ||
| AppName: "Cloudflare Container Worker", | ||
| ProxyHeader: "X-Forwarded-*", | ||
| }) | ||
|
|
||
| // Middleware | ||
| app.Use(logger.New()) | ||
| app.Use(recover.New()) | ||
|
|
||
| // Root handler | ||
| app.Get("/", func(c fiber.Ctx) error { | ||
| message := os.Getenv("MESSAGE") | ||
| instanceId := os.Getenv("CLOUDFLARE_DEPLOYMENT_ID") | ||
|
|
||
| return c.JSON(fiber.Map{ | ||
| "message": message, | ||
| "instance_id": instanceId, | ||
| "framework": "gofiber/v3", | ||
| "status": "ok", | ||
| }) | ||
| }) | ||
|
|
||
| // Start server | ||
| port := os.Getenv("PORT") | ||
| if port == "" { | ||
| port = "8080" | ||
| } | ||
|
|
||
| log.Fatal(app.Listen(":" + port)) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better reproducibility and to avoid unexpected changes from upstream, it's a best practice to pin base images to a specific digest instead of using the
:latesttag. This ensures that your builds are deterministic.