Go API server + Container Registry

    Selles juhendis loome Go API serveri ja paigaldame selle Pilvio VM-ile Docker konteinerina. Container Registry on Pilviol hetkel arenduses — praegu kasutame Docker Hub'i või lokaalselt ehitatud imaget.

    ⏳ Tulemas: Pilvio Container Registry võimaldab tulevikus konteinerite image'eid hoida otse Pilvio infrastruktuuris. Seni kasutame Docker Hub'i või ehitame image'i otse serveris.

    Mida ehitame

    • Go REST API koos chi routeriga
    • Dockeriga pakendatud rakendus
    • Deploy Pilvio VM-ile cloud-init abil

    Eeldused

    • Pilvio konto ja API token (vaata ülevaadet)
    • Go 1.22+ lokaalselt paigaldatud
    • Docker lokaalselt paigaldatud (valikuline)

    1. samm: Go API rakenduse loomine

    Lokaalselt arvutis:

    mkdir pilvio-go-api && cd pilvio-go-api
    go mod init pilvio-go-api
    go get github.com/go-chi/chi/v5
    go get github.com/go-chi/cors
    

    Loo fail main.go:

    package main
    
    import (
    	"encoding/json"
    	"fmt"
    	"log"
    	"net/http"
    	"os"
    	"time"
    
    	"github.com/go-chi/chi/v5"
    	"github.com/go-chi/chi/v5/middleware"
    	"github.com/go-chi/cors"
    )
    
    func main() {
    	port := os.Getenv("PORT")
    	if port == "" {
    		port = "8080"
    	}
    
    	r := chi.NewRouter()
    
    	// Vahevara
    	r.Use(middleware.Logger)
    	r.Use(middleware.Recoverer)
    	r.Use(middleware.Timeout(30 * time.Second))
    	r.Use(cors.Handler(cors.Options{
    		AllowedOrigins: []string{"*"},
    		AllowedMethods: []string{"GET", "POST", "PUT", "DELETE"},
    		AllowedHeaders: []string{"Content-Type", "X-API-Key"},
    	}))
    
    	// Avalikud endpointid
    	r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
    		json.NewEncoder(w).Encode(map[string]string{
    			"status":    "ok",
    			"timestamp": time.Now().Format(time.RFC3339),
    		})
    	})
    
    	// Kaitstud endpointid
    	r.Group(func(r chi.Router) {
    		r.Use(apiKeyAuth)
    
    		r.Get("/api/v1/items", listItems)
    		r.Post("/api/v1/items", createItem)
    	})
    
    	log.Printf("Go API server käivitatud pordil %s", port)
    	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), r))
    }
    
    // Lihtne API võtme kontroll
    func apiKeyAuth(next http.Handler) http.Handler {
    	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    		key := r.Header.Get("X-API-Key")
    		expected := os.Getenv("APP_API_KEY")
    		if key == "" || key != expected {
    			http.Error(w, `{"error":"Autentimine ebaõnnestus"}`, http.StatusUnauthorized)
    			return
    		}
    		next.ServeHTTP(w, r)
    	})
    }
    
    // Näiteks mälusisesed andmed (tootmises kasuta andmebaasi)
    var items []map[string]string
    
    func listItems(w http.ResponseWriter, r *http.Request) {
    	w.Header().Set("Content-Type", "application/json")
    	json.NewEncoder(w).Encode(map[string]interface{}{"items": items})
    }
    
    func createItem(w http.ResponseWriter, r *http.Request) {
    	var item map[string]string
    	if err := json.NewDecoder(r.Body).Decode(&item); err != nil {
    		http.Error(w, `{"error":"Vigane JSON"}`, http.StatusBadRequest)
    		return
    	}
    	items = append(items, item)
    	w.WriteHeader(http.StatusCreated)
    	json.NewEncoder(w).Encode(item)
    }
    

    2. samm: Dockeriga pakendamine

    Loo fail Dockerfile:

    FROM golang:1.22-alpine AS builder
    WORKDIR /app
    COPY go.mod go.sum ./
    RUN go mod download
    COPY . .
    RUN CGO_ENABLED=0 GOOS=linux go build -o server .
    
    FROM alpine:3.19
    RUN apk --no-cache add ca-certificates
    WORKDIR /app
    COPY --from=builder /app/server .
    EXPOSE 8080
    CMD ["./server"]
    

    Ehita ja testi lokaalselt:

    docker build -t pilvio-go-api .
    docker run -p 8080:8080 -e APP_API_KEY=test123 pilvio-go-api
    

    3. samm: Deploy Pilvio VM-ile

    Variant A: Cloud-init abil (automaatne)

    Loo VM koos cloud-init skriptiga, mis paigaldab Dockeri ja käivitab rakenduse:

    curl "https://api.pilvio.com/v1/user-resource/vm" \
      -H "apikey: SINU_PILVIO_TOKEN" \
      -X POST \
      -d "name=go-api-server" \
      -d "os_name=ubuntu" \
      -d "os_version=24.04" \
      -d "vcpu=2" \
      -d "ram=2048" \
      -d "disks=20" \
      -d "username=deploy" \
      -d "password=TurvalineParool123!" \
      -d 'cloud_init={
        "runcmd": [
          "curl -fsSL https://get.docker.com | sh",
          "usermod -aG docker deploy"
        ]
      }'
    

    Pärast VM-i loomist ja Docker'i paigaldamist (oota ~2 minutit):

    ssh deploy@SINU_FLOATING_IP
    
    # Kopeeri projekti failid serverisse (lokaalarvutist)
    # scp -r ./* deploy@SINU_FLOATING_IP:~/go-api/
    
    # Ehita image otse serveris
    cd ~/go-api
    docker build -t pilvio-go-api .
    docker run -d \
      --name go-api \
      --restart unless-stopped \
      -p 8080:8080 \
      -e APP_API_KEY=sinu-tugev-api-vooti \
      pilvio-go-api
    

    Variant B: Docker Hub kaudu

    Kui kasutad Docker Hub'i (või mõnda muud registrit):

    # Lokaalselt
    docker tag pilvio-go-api sinu-kasutaja/pilvio-go-api:latest
    docker push sinu-kasutaja/pilvio-go-api:latest
    
    # Serveris
    docker pull sinu-kasutaja/pilvio-go-api:latest
    docker run -d \
      --name go-api \
      --restart unless-stopped \
      -p 8080:8080 \
      -e APP_API_KEY=sinu-tugev-api-vooti \
      sinu-kasutaja/pilvio-go-api:latest
    

    4. samm: Docker Compose tootmiskeskkonnaks

    Loo fail docker-compose.yml:

    services:
      api:
        build: .
        restart: unless-stopped
        ports:
          - "127.0.0.1:8080:8080"
        environment:
          - PORT=8080
          - APP_API_KEY=${APP_API_KEY}
        healthcheck:
          test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/health"]
          interval: 30s
          timeout: 5s
          retries: 3
    
      nginx:
        image: nginx:alpine
        restart: unless-stopped
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
          - certbot-data:/etc/letsencrypt:ro
        depends_on:
          - api
    
    volumes:
      certbot-data:
    
    docker compose up -d
    

    Testimine

    # Health check
    curl http://SINU_FLOATING_IP:8080/health
    
    # Elemendi lisamine
    curl -X POST http://SINU_FLOATING_IP:8080/api/v1/items \
      -H "X-API-Key: sinu-tugev-api-vooti" \
      -H "Content-Type: application/json" \
      -d '{"name": "Test", "description": "Pilvio Go API näide"}'
    
    # Elementide loetelu
    curl -H "X-API-Key: sinu-tugev-api-vooti" http://SINU_FLOATING_IP:8080/api/v1/items
    

    ⏳ Container Registry (tulemas): Kui Pilvio Container Registry on saadaval, saad oma image'eid hostida otse Pilvio infrastruktuuris ilma väliste registriteta. See vähendab latentsust ja hoiab su andmed Eestis.

    Järgmised sammud: Lisa PostgreSQL andmebaas mälusiseste andmete asendamiseks või kasuta StorageVault't failide salvestamiseks.