Skip to content

Ship your first app (ko)

This builds a small Go web server with ko (no Dockerfile), pushes it to your registry, and serves it over HTTPS.

It assumes:

Terminal window
mkdir hello && cd hello
go mod init example.com/hello
Terminal window
cat <<'EOF' > main.go
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello from skube - ko")
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
EOF

You’re already logged in to ghcr.io from the credentials guide, so ko just needs to know which repo to push to:

Terminal window
export KO_DOCKER_REPO=ghcr.io/<github-username>

The ko:// image reference tells ko to build main.go and substitute the pushed image:

Terminal window
cat <<'EOF' > deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
namespace: demo
spec:
replicas: 1
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: ko://example.com/hello
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: hello
namespace: demo
spec:
selector:
app: hello
ports:
- port: 80
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello
namespace: demo
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: traefik
tls:
- hosts:
- hello.example.com
secretName: hello-tls
rules:
- host: hello.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello
port:
number: 80
EOF
Terminal window
ko apply -f deploy.yaml

ko compiles the app, pushes the image to ghcr.io/<you>/hello, rewrites the ko:// reference, and applies the manifest. The pushed package is private by default, which is why the cluster needs the ghcr pull secret from the previous guide.

Terminal window
kubectl get certificate hello-tls -n demo -w

Once READY is True:

Terminal window
curl https://hello.example.com

You should get back hello from skube - ko.

Terminal window
kubectl delete namespace demo