kratos Documentation

Your ultimate Go microservices framework for the cloud-native era.

25,836 stars Go Go 1 file ยท ~8,746 tokens #ai#architecture#cloud-native#framework#generate#go#golang#grpc
RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy kratos on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name kratos --restart always ory/kratos:latest

File: README.md

Translations: English | ็ฎ€ไฝ“ไธญๆ–‡

Kratos

Kratos is a lightweight Go framework for building cloud-native microservices. It provides small, explicit APIs for transport, middleware, registry, configuration, logging, encoding, and code generation so applications can focus on business logic.

Features

  • API-first development with Protobuf and generated HTTP/gRPC code.
  • Unified transport layer for HTTP and gRPC.
  • Composable middleware for recovery, logging, validation, tracing, metrics, auth, and more.
  • Pluggable registry, configuration, and encoding components.
  • Standard-library log/slog based logging with OpenTelemetry extensions in contrib packages.
  • Consistent metadata, errors, validation, OpenAPI, and code-generation workflows.
  • A contrib ecosystem for optional integrations such as registries, config stores, middleware, encodings, and observability.

Installation

Requirements

Install the CLI

shell
go install github.com/go-kratos/kratos/cmd/kratos/v3@latest
kratos upgrade

Create a Service

shell
kratos new helloworld
cd helloworld
go mod tidy
kratos run

Visit http://localhost:8000/helloworld/kratos after the service starts.

For a fuller generated service flow:

shell
kratos proto add api/helloworld/helloworld.proto
kratos proto client api/helloworld/helloworld.proto
kratos proto server api/helloworld/helloworld.proto -t internal/service
go generate ./...
kratos run

Usage Example

go
package main

import (
	"github.com/go-kratos/kratos/v3"
	"github.com/go-kratos/kratos/v3/transport/grpc"
	"github.com/go-kratos/kratos/v3/transport/http"
)

func main() {
	httpSrv := http.NewServer(http.Address(":8000"))
	grpcSrv := grpc.NewServer(grpc.Address(":9000"))

	app := kratos.New(
		kratos.Name("helloworld"),
		kratos.Version("v1.0.0"),
		kratos.Server(httpSrv, grpcSrv),
	)
	if err := app.Run(); err != nil {
		panic(err)
	}
}

v3 Migration

Kratos v3 reduces core dependencies and makes previously implicit behavior explicit. Review the v2 to v3 migration guide before upgrading production services.

Further Reading

Development

shell
make test
make lint

Community

Security

If you discover a security vulnerability in Kratos, please contact [email protected]. Security reports are handled privately before disclosure.

Contributors

Thank you for contributing to Kratos. The contribution guide is available in the Kratos documentation.

Acknowledgments

The following projects influenced Kratos design:

License

Kratos is open-sourced software licensed under the MIT license.


File: config/README.md

Config

kubernetes

shell
go get -u github.com/go-kratos/kratos/contrib/config/kubernetes/v3

apollo

shell
go get -u github.com/go-kratos/kratos/contrib/config/apollo/v3

etcd

shell
go get -u github.com/go-kratos/kratos/contrib/config/etcd/v3

nacos

shell
go get -u github.com/go-kratos/kratos/contrib/config/nacos/v3

File: contrib/transport/mcp/README.md

MCP Transport

This module implements the MCP server in Kratos based on mcp-go.

Quick start

go
import(
    tm "github.com/go-kratos/kratos/contrib/transport/mcp/v3"
    mcp "github.com/mark3labs/mcp-go/mcp"
)

func helloHandler(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
    name, ok := request.Params.Arguments["name"].(string)
    if !ok {
        return nil, errors.New("name must be a string")
    }
    return mcp.NewToolResultText(fmt.Sprintf("Hello, %s!", name)), nil
}

func Health(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/health/ready" {
			w.WriteHeader(http.StatusOK)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func main() {
    srv := tm.NewServer("kratos-mcp", "v1.0.0", tm.Address(":8000"), tm.Middleware(Health))
    tool := mcp.NewTool("hello_world",
        mcp.WithDescription("Say hello to someone"),
        mcp.WithString("name",
            mcp.Required(),
            mcp.Description("Name of the person to greet"),
        ),
    )
    // Add tool handler
    srv.AddTool(tool, helloHandler)
    // creates a kratos application
    app := kratos.New(
        kratos.Name("kratos-app"),
        kratos.Server(srv),
    )
    if err := app.Run(); err != nil {
        panic(err)
    }
}

File: contrib/registry/servicecomb/README.md

Servicecomb Registry

example

server

go
package main

import (
	"log"

	"github.com/go-chassis/sc-client"
	"github.com/go-kratos/kratos/contrib/registry/servicecomb/v3"
	"github.com/go-kratos/kratos/v3"
)

func main() {
	c, err := sc.NewClient(sc.Options{
		Endpoints: []string{"127.0.0.1:30100"},
	})
	if err != nil {
		log.Panic(err)
	}
	r := servicecomb.NewRegistry(c)
	app := kratos.New(
		kratos.Name("helloServicecomb"),
		kratos.Registrar(r),
	)
	if err := app.Run(); err != nil {
		log.Fatal(err)
	}
}

client

go
package main

import (
	"context"
	"log"

	"github.com/go-chassis/sc-client"
	"github.com/go-kratos/kratos/contrib/registry/servicecomb/v3"
	"github.com/go-kratos/kratos/v3/transport/grpc"
)

func main() {
	c, err := sc.NewClient(sc.Options{
		Endpoints: []string{"127.0.0.1:30100"},
	})
	if err != nil {
		log.Panic(err)
	}
	r := servicecomb.NewRegistry(c)
	ctx := context.Background()
	conn, err := grpc.NewClient(
		ctx,
		grpc.WithEndpoint("discovery:///helloServicecomb"),
		grpc.WithDiscovery(r),
	)
	if err != nil {
		return
	}
	defer conn.Close()
}

File: contrib/registry/nacos/README.md

Nacos Registry

example

server

go
package main

import (
	"log"

	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"

	"github.com/go-kratos/kratos/contrib/registry/nacos/v3"
	"github.com/go-kratos/kratos/v3"
)

func main() {
	sc := []constant.ServerConfig{
		*constant.NewServerConfig("127.0.0.1", 8848),
	}

	client, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ServerConfigs: sc,
		},
	)

	if err != nil {
		log.Panic(err)
	}

	r := nacos.New(client)

	// server
	app := kratos.New(
		kratos.Name("helloworld"),
		kratos.Registrar(r),
	)
	if err := app.Run(); err != nil {
		log.Fatal(err)
	}
}

client

go
package main

import (
	"context"
	"log"

	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"

	"github.com/go-kratos/kratos/contrib/registry/nacos/v3"
	"github.com/go-kratos/kratos/v3/transport/grpc"
)

func main() {
	cc := constant.ClientConfig{
		NamespaceId: "public",
		TimeoutMs:   5000,
	}

	client, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig: &cc,
		},
	)

	if err != nil {
		log.Panic(err)
	}

	r := nacos.New(client)

	// client
	conn, err := grpc.NewClient(
		context.Background(),
		grpc.WithEndpoint("discovery:///helloworld"),
		grpc.WithDiscovery(r),
	)
	defer conn.Close()
}

File: contrib/registry/discovery/README.md

Discovery Registry

This module implements a registry.Registrar and registry.Discovery interface in kratos based bilibili/discovery.

Quick Start

Register a service

go
import (
	"github.com/go-kratos/kratos/contrib/registry/discovery/v3"
)

func main() {
	// initialize a registry
	r := discovery.New(&discovery.Config{
		Nodes:  []string{"0.0.0.0:7171"},
		Env:    "dev",
		Region: "sh1",
		Zone:   "zone1",
		Host:   "hostname",
	})

	// construct srv instance
	// ...

	app := kratos.New(
		kratos.Name("helloworld"),
		kratos.Server(
			httpSrv,
			grpcSrv,
		),
		kratos.Metadata(map[string]string{"color": "gray"}),
		// use Registrar
		kratos.Registrar(r),
	)

	if err := app.Run(); err != nil {
		log.Fatal(err)
	}
}

Discover a service

go
import (
	"github.com/go-kratos/kratos/contrib/registry/discovery/v3"
	"github.com/go-kratos/kratos/v3/transport/grpc"
)

func main() {
	// initialize a discovery
	r := discovery.New(&discovery.Config{
		Nodes:  []string{"0.0.0.0:7171"},
		Env:    "dev",
		Region: "sh1",
		Zone:   "zone1",
		Host:   "localhost",
	}, nil)

	conn, err := grpc.NewClient(
		context.Background(),
		grpc.WithEndpoint("discovery:///appid"),
		// use discovery
		grpc.WithDiscovery(r),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	// request and log
}

Config explain

go
type Config struct {
	Nodes  []string // discovery nodes address
	Region string   // region of the service, sh
	Zone   string   // zone of region, sh001
	Env    string   // env of service, dev, prod and etc
	Host   string   // hostname of service
}

References


File: contrib/opensergo/README.md

OpenSergo

Usage

go
osServer, err := opensergo.New(opensergo.WithEndpoint("localhost:9090"))
if err != nil {
	panic("init opensergo error")
}

s := &server{}
grpcSrv := grpc.NewServer(
	grpc.Address(":9000"),
	grpc.Middleware(
		recovery.Recovery(),
	),
)
helloworld.RegisterGreeterServer(grpcSrv, s)

app := kratos.New(
	kratos.Name(Name),
	kratos.Server(
		grpcSrv,
	),
)

osServer.ReportMetadata(context.Background(), app)

if err := app.Run(); err != nil {
	log.Fatal(err)
}

File: contrib/middleware/validate/README.md

Validator Middleware for Kratos Project

This module provides a middleware for Kratos to validate request parameters, using schema defined in .proto files.

There used to be a middleware named Validator in Kratos, which calls the generated validation functions
from PGV at runtime. Since PGV has been
in maintenance, and
recommend using protovalidate as an alternative.

That's why we provide a new middleware that uses the schema definitions and validation functions provided by
protovalidate.

protovalidate no longer requires code generation at build time, but for compatibility with existing Kratos
projects, we enable the legacy mode of protovalidate. For most users, no changes are needed to existing code. But for
users who have manually implemented the Validator interface, you need to migrate the relevant implementation yourself
.


File: contrib/errortracker/sentry/README.md

Sentry middleware for Kratos

This middleware helps you to catch panics and report them to sentry

Quick Start

You could check the full demo in example folder.

go
// Step 1:
// init sentry in the entry of your application
import "github.com/getsentry/sentry-go"

sentry.Init(sentry.ClientOptions{
	Dsn: "<your dsn>",
	AttachStacktrace: true, // recommended
})

// Step 2:
// set middleware
import (
	"context"

	ksentry "github.com/go-kratos/kratos/contrib/errortracker/sentry/v3"
	"github.com/go-kratos/kratos/contrib/otel/v3/tracing"
)

// for HTTP server, new HTTP server with sentry middleware options
var opts = []http.ServerOption{
	http.Middleware(
		recovery.Recovery(),
		tracing.Server(),
		ksentry.Server(
			ksentry.WithTags(map[string]string{
				"tag": "some-custom-constant-tag",
			}),
			ksentry.WithContextTags(func(ctx context.Context) map[string]string {
				return map[string]string{"trace_id": tracing.TraceID(ctx)}
			}),
		), // must after Recovery middleware, because of the exiting order will be reversed
		logging.Server(logger),
	),
}

// for gRPC server, new gRPC server with sentry middleware options
var opts = []grpc.ServerOption{
	grpc.Middleware(
		recovery.Recovery(),
		tracing.Server(),
		ksentry.Server(
			ksentry.WithTags(map[string]string{
				"tag": "some-custom-constant-tag",
			}),
			ksentry.WithContextTags(func(ctx context.Context) map[string]string {
				return map[string]string{"trace_id": tracing.TraceID(ctx)}
			}),
		), // must after Recovery middleware, because of the exiting order will be reversed
		logging.Server(logger),
	),
}

// Then, the framework will report events to Sentry when your trigger panics.
// Or your can push events to Sentry manually

Reference