Skip to main content
This guide walks you through building and deploying a simple Go API to Magic Containers using GitHub Container Registry. You’ll need:
  • A GitHub account for source code and container registry
  • A bunny.net account with Magic Containers enabled

Create the Go API

Create a new directory with the following files:
package main

import (
	"encoding/json"
	"log"
	"net/http"
	"os"
)

type Response struct {
	Message string `json:"message"`
}

func main() {
	port := os.Getenv("PORT")
	if port == "" {
		port = "80"
	}

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(Response{Message: "Hello from Bunny 🐰"})
	})

	log.Printf("Server starting on port %s", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}

Run locally

Start the development server:
go run main.go
Test the API:
curl http://localhost:80/

Create the Dockerfile

Dockerfile
FROM golang:1.23-alpine AS builder

WORKDIR /app
COPY go.mod ./
COPY main.go ./
RUN go build -o server .

FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/server .
ENV PORT=80
EXPOSE 80
CMD ["./server"]

Build and push to GitHub Container Registry

Create .github/workflows/build.yml to automatically build and push on every commit to main:
.github/workflows/build.yml
name: Build and Push

on:
  push:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - uses: actions/checkout@v4

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
Push your code to trigger the workflow:
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/YOUR_USERNAME/app-go-api.git
git push -u origin main
If your package is private, set the visibility to Public in GitHub or configure Magic Containers with registry credentials.

Deploy to Magic Containers

1

Create a new app

In the bunny.net dashboard, go to Magic Containers and click Add App. Enter a name and select your deployment option.
2

Add a container

Click Add Container, then configure:
FieldValue
RegistryGitHub Container Registry
ImageYOUR_USERNAME/{imageName}
Taglatest
3

Add an endpoint

Go to the Endpoints tab, click Add New Endpoint, and set the container port to 80.
4

Deploy

Click Add Container, then Next Step, and Confirm and Create.
For more details, see the quickstart guide.

Test your API

curl https://mc-xxx.bunny.run/
Response
{ "message": "Hello from Bunny 🐰" }
You can add a custom hostname from the Endpoints section in your app settings.

Connect a database

You can connect your app to Bunny Database directly from the dashboard:
  1. Go to Database > [Your Database] > Access
  2. Click Generate Tokens
  3. Click Add Secrets to Magic Container App
  4. Select your app
The DB_URL and DB_TOKEN environment variables are now available in your app:
import (
	"database/sql"
	"fmt"
	"os"

	_ "github.com/tursodatabase/libsql-client-go/libsql"
)

url := fmt.Sprintf("%s?authToken=%s",
	os.Getenv("DB_URL"),
	os.Getenv("DB_TOKEN"),
)

db, err := sql.Open("libsql", url)
if err != nil {
	fmt.Fprintf(os.Stderr, "failed to open db %s: %s", url, err)
	os.Exit(1)
}
defer db.Close()
See the Go SDK documentation for more details.

Next steps

  1. Automate deploys with GitHub Actions
  2. Add a custom hostname
  3. Add a persistent volume