Skip to content
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

Add docker compose support #217

Merged
merged 9 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 100 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,35 @@
[![codecov](https://codecov.io/gh/dapr/dashboard/branch/master/graph/badge.svg)](https://codecov.io/gh/dapr/dashboard)
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fdapr%2Fdashboard.svg?type=shield)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fdapr%2Fdashboard?ref=badge_shield)

Dapr Dashboard is a web-based UI for Dapr, allowing users to see information, view logs and more for the Dapr applications, components, and configurations running either locally or in a Kubernetes cluster.
Dapr Dashboard is a web-based UI for Dapr, allowing users to see information, view logs and more for the Dapr applications, components, and configurations running on a supported Dapr Dashboard platform.

Supported Dapr Dashboard plaforms are:
- Standalone - running locally via Dapr CLI
- Kubernetes - running inside a Kubernetes cluster
- Docker Compose - running inside a docker compose network

<p style="text-align:center">
<img src="img/img.PNG">
</p>

## Features

Dapr Dashboard provides information about Dapr applications, components, configurations, and control plane services. Users can view metadata, manifests and deployment files, actors, logs, and more on both Kubernetes and self-hosted platforms. For more information, check out the [changelog](docs/development/changelog.md).
Dapr Dashboard provides information about Dapr applications, components, configurations, and control plane services (Kubernetes only). Users can view metadata, manifests and deployment files, actors, logs, and more. For more information, check out the [changelog](docs/development/changelog.md).

## Getting started

### Prerequisites
[Dapr Runtime](https://github.com/dapr/dapr)

[Dapr CLI](https://github.com/dapr/cli)
If you intend to run in the Standalone or Kubernetes platform mode you will need to have the following:

### Installation
- [Dapr Runtime](https://github.com/dapr/dapr)
- [Dapr CLI](https://github.com/dapr/cli)

Dapr Dashboard comes pre-packaged with the Dapr CLI. To learn more about the dashboard command, use the CLI command `dapr dashboard -h`.

If you intend to run in the Docker Compose platform mode, you don't need to install anything. Instead you specify Dapr docker images to use.

### Installation
If you want to install via Helm, run:
```sh
helm repo add dapr https://dapr.github.io/helm-charts/
Expand All @@ -37,6 +45,93 @@ Run `dapr dashboard -k`, or if you installed Dapr in a non-default namespace, `d
#### Standalone
Run `dapr dashboard`, and navigate to http://localhost:8080.

#### Docker Compose
Construct a docker compose file that references the specific Dapr pieces that you want to use. The following example defines an application and its corresponding daprd sidecar, the Dapr Placement service, and the Dapr Dashboard.

When running inside docker compose, the dashboard needs access to the component and configuration files that are passed to the daprd services. It also needs to know about all daprd services running inside the docker compose network - it retrieves this by parsing the docker-compose.yml file. To achieve this, you define docker bind mounts to these files/directories and pass them as command args to the dashboard process. In addition, you must specify the command arg `--docker-compose=true` to tell the dashboard to use the docker compose platform type.

```yml
version: '3.8'
services:

my-application-webhost:
build:
context: .
dockerfile: src/My.Application.WebHost/Dockerfile
ports:
- "5002:80"
networks:
- my-network

my-application-webhost-dapr:
image: "daprio/daprd:1.8.0"
command: [ "./daprd",
"-app-id", "MyApplication.DaprSidecar",
"-app-port", "80",
"-placement-host-address", "dapr-placement:50000",
"-components-path", "/components",
"-config", "/configuration/config.yaml" ]
volumes:
- "./dockercompose/dapr/components/:/components"
- "./dockercompose/dapr/config/:/configuration"
depends_on:
- my-application-webhost
- dapr-placement
network_mode: "service:my-application-webhost"

dapr-placement:
image: "daprio/dapr:1.8.0"
command: [ "./placement", "-port", "50000" ]
ports:
- "50000:50000"
networks:
- my-network

dapr-dashboard:
image: "daprio/dashboard:latest"
command: [ "--docker-compose=true",
"--components-path=/home/nonroot/components",
"--config-path=/home/nonroot/configuration",
"--docker-compose-path=/home/nonroot/docker-compose.yml" ]
ports:
- "8080:8080"
volumes:
- "./dockercompose/dapr/components/:/home/nonroot/components"
- "./dockercompose/dapr/config/:/home/nonroot/configuration"
- ./docker-compose.yml:/home/nonroot/docker-compose.yml
networks:
- my-network

networks:
my-network:
```

The above example assumes the following file system layout

```
dockercompose
dapr
components
(component yaml files e.g. pubsub.yaml, statestore.yaml etc.)
config
config.yaml
src
My.Application.WebHost
Dockerfile
docker-compose.yml
```

If you have configured your Dapr sidecars to require [API token authentication](https://docs.dapr.io/operations/security/api-token/), you can set the environment variable `DAPR_API_TOKEN: {your token}` on the Dapr Dashboard service declaration as follows
```yml
dapr-dashboard:
image: "daprio/dashboard:latest"
environment:
DAPR_API_TOKEN: {your token}
...
```

For more information about running Dapr with docker compose see [Run using Docker-Compose](https://docs.dapr.io/operations/hosting/self-hosted/self-hosted-with-docker/#run-using-docker-compose)

### Contributing
Anyone is free to open an issue, a feature request, or a pull request.

Expand Down
28 changes: 27 additions & 1 deletion cmd/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,39 @@ import (
func RunDashboard() {
dashboardVersion := flag.Bool("version", false, "Prints the dashboard version")
port := flag.Int("port", 8080, "Port to listen to")
dockerCompose := flag.Bool("docker-compose", false, "Is running inside docker compose")
componentsPath := flag.String("components-path", "", "Path to volume mounted dapr components (docker-compose only)")
configPath := flag.String("config-path", "", "Path to volume mounted dapr configuration (docker-compose only)")
dockerComposePath := flag.String("docker-compose-path", "", "Path to volume mounted docker compose file (docker-compose only)")

flag.Parse()

fmt.Println(*dockerCompose)
artursouza marked this conversation as resolved.
Show resolved Hide resolved
fmt.Println(*componentsPath)
fmt.Println(*configPath)
fmt.Println(*dockerComposePath)

if *dockerCompose {
if len(*componentsPath) == 0 {
fmt.Println("--components-path required when --docker-compose=true")
os.Exit(1)
}

if len(*configPath) == 0 {
fmt.Println("--config-path required when --docker-compose=true")
os.Exit(1)
}

if len(*dockerComposePath) == 0 {
fmt.Println("--docker-compose-path required when --docker-compose=true")
os.Exit(1)
}
}

if *dashboardVersion {
fmt.Println(version.GetVersion())
os.Exit(0)
} else {
RunWebServer(*port)
RunWebServer(*port, *dockerCompose, *componentsPath, *configPath, *dockerComposePath)
}
}
21 changes: 11 additions & 10 deletions cmd/webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
instances "github.com/dapr/dashboard/pkg/instances"
kube "github.com/dapr/dashboard/pkg/kube"
dashboard_log "github.com/dapr/dashboard/pkg/log"
"github.com/dapr/dashboard/pkg/platforms"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
)
Expand Down Expand Up @@ -77,18 +78,18 @@ var (
)

// RunWebServer starts the web server that serves the Dapr UI dashboard and the API
func RunWebServer(port int) {
platform := ""
func RunWebServer(port int, isDockerCompose bool, componentsPath string, configPath string, dockerComposePath string) {
platform := platforms.Standalone
kubeClient, daprClient, _ := kube.Clients()
if kubeClient != nil {
platform = "kubernetes"
} else {
platform = "standalone"
platform = platforms.Kubernetes
} else if isDockerCompose {
platform = platforms.DockerCompose
}

inst = instances.NewInstances(platform, kubeClient)
comps = components.NewComponents(platform, daprClient)
configs = configurations.NewConfigurations(platform, daprClient)
inst = instances.NewInstances(platform, kubeClient, dockerComposePath)
comps = components.NewComponents(platform, daprClient, componentsPath)
configs = configurations.NewConfigurations(platform, daprClient, configPath)

r := mux.NewRouter()
api := r.PathPrefix("/api/").Subrouter()
Expand Down Expand Up @@ -213,15 +214,15 @@ func getFeaturesHandler(w http.ResponseWriter, r *http.Request) {
if configs.Supported() {
features = append(features, "configurations")
}
if inst.CheckPlatform() == "kubernetes" {
if inst.CheckPlatform() == platforms.Kubernetes {
features = append(features, "status")
}
respondWithJSON(w, 200, features)
}

func getPlatformHandler(w http.ResponseWriter, r *http.Request) {
resp := inst.CheckPlatform()
respondWithPlainString(w, 200, resp)
respondWithPlainString(w, 200, string(resp))
}

func getContainersHandler(w http.ResponseWriter, r *http.Request) {
Expand Down
17 changes: 15 additions & 2 deletions docs/development/platform.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# Adding a new platform

Dashboard currently supports 2 platforms: Kubernetes and self-hosted (August 2020).
Dashboard currently supports 3 platforms: Kubernetes, self-hosted and docker-compose (April 2023).


## Backend

The application platform is defined in `cmd/webserver.go:RunWebServer()`. To add a new platform, logic needs to be defined here to determine how Dashboard will recognize it. Any API clients or other necessary structures should be passed as arguments to the constructor of `instances.NewInstances(...)` and the other backend struct constructors along with the platform.
Platform definitions are contained in [platforms.go](../../pkg/platforms/platforms.go). When adding a new platform, define a new constant for the platform in `platforms.go`.

If the new platform requires configuration arguments you can define optional go flags in [dashboard.go](../../cmd/dashboard.go) and pass them to `RunWebServer(...)` in [webserver.go](../../cmd/webserver.go).

The runtime application platform is defined in `cmd/webserver.go:RunWebServer()`. To add a new platform, logic needs to be defined here to determine how Dashboard will recognize it. Any API clients or other necessary structures should be passed as arguments to the constructor of `instances.NewInstances(...)` and the other backend struct constructors along with the platform.

In `pkg/instances.go`, `pkg/components.go`, and `pkg/configurations.go`, new methods should be defined for each new platform, following the current pattern. In these files, functions such as `GetInstance(scope string, id string)` and `GetScopes()` are defined. These abstracted functions will call the correct platform-specific function:

Expand All @@ -18,6 +22,15 @@ func (i *instances) GetInstances(scope string) []Instance {

Where `i.getInstanceFn` is defined in the constructor as `getPlatformInstances`, e.g. `getKubernetesInstances` or `getStandaloneInstances` according to the platform supplied.

If the new platform supports a feature (e.g. components) make sure you update the `func (c *type) Supported() bool` method in the corresponding package to include the platform definition. For example, in [components.go](../../pkg/components/components.go)

```go
// Supported checks whether or not the supplied platform is able to access Dapr components
func (c *components) Supported() bool {
return c.platform == platforms.Kubernetes || c.platform == platforms.Standalone || c.platform == platforms.DockerCompose
}
```

## Frontend

For platform-specific features of Dashboard, there is a service defined in `web/src/app/globals/globals.service.ts` that retrieves platform information from the backend. Any component that needs to know the current platform can make a call to this service and handle the returned data appropriately:
Expand Down
19 changes: 14 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ module github.com/dapr/dashboard
go 1.19

require (
github.com/compose-spec/compose-go v1.13.3
github.com/dapr/cli v1.10.0-rc.3
github.com/dapr/components-contrib v1.10.0-rc.4
github.com/dapr/dapr v1.10.0-rc.5
github.com/dapr/kit v0.0.4
github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0
github.com/stretchr/testify v1.8.1
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/stretchr/testify v1.8.2
k8s.io/api v0.26.1
k8s.io/apimachinery v0.26.1
k8s.io/client-go v1.5.2
Expand All @@ -26,12 +30,12 @@ require (
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/briandowns/spinner v1.21.0 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/containerd/containerd v1.6.16 // indirect
github.com/dapr/components-contrib v1.10.0-rc.4 // indirect
github.com/dapr/kit v0.0.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/distribution/distribution/v3 v3.0.0-20230214150026-36d8c594d7aa // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/docker v23.0.0+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
Expand Down Expand Up @@ -61,6 +65,7 @@ require (
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/grandcat/zeroconf v1.0.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
Expand All @@ -69,7 +74,7 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.1 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/jhump/protoreflect v1.14.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
Expand All @@ -80,8 +85,10 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/microsoft/durabletask-go v0.1.3 // indirect
github.com/miekg/dns v1.1.43 // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 // indirect
Expand All @@ -102,7 +109,6 @@ require (
github.com/prometheus/statsd_exporter v0.23.0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/sony/gobreaker v0.5.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
Expand All @@ -114,6 +120,9 @@ require (
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.44.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.13.0 // indirect
Expand Down
Loading