From f78b0b02b8ce612774d20ee3e723858a2f337162 Mon Sep 17 00:00:00 2001 From: Hellgren Heikki Date: Wed, 10 Sep 2025 12:23:26 +0300 Subject: [PATCH] feat(dev): allow running example app with docker this PR allows backstage contributors to run the example app against actual postgres, opensearch and redis services using docker and docker compose file. no changeset as this doesn't affect any published packages. Signed-off-by: Hellgren Heikki --- CONTRIBUTING.md | 10 +++++++++ app-config.docker.yaml | 23 +++++++++++++++++++++ docker-compose.deps.yml | 39 +++++++++++++++++++++++++++++++++++ package.json | 1 + packages/backend/package.json | 1 + packages/backend/src/index.ts | 13 ++++++++++-- yarn.lock | 3 ++- 7 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 app-config.docker.yaml create mode 100644 docker-compose.deps.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9413206197..ba40be86c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -102,6 +102,16 @@ Visit and you should see the bleeding edge of Backstage If you want to get a better understanding of the layout of the repo now that you have a local copy running feel free to review the [Backstage Project Structure](https://backstage.io/docs/getting-started/#general-folder-structure) documentation. +#### Using Docker for the Example App + +You can run the Example App using Docker with Postgres, OpenSearch and Redis services. This setup very closely resembles how Backstage is run in production in many occasions. + +To start the Example App with Docker, make sure you have Docker and Docker Compose installed on your machine, then run the following command from the root of the repository: + +```bash +yarn start:docker +``` + ## Coding Guidelines All code is formatted with `prettier` using the configuration in the repo. If possible, we recommend configuring your editor to format automatically, but you can also use the `yarn prettier --write ` command to format files. diff --git a/app-config.docker.yaml b/app-config.docker.yaml new file mode 100644 index 0000000000..07f7c7ac8c --- /dev/null +++ b/app-config.docker.yaml @@ -0,0 +1,23 @@ +# To run local backstage instance with docker services, +# run: +# 1. `docker compose -f docker-compose.deps.yml up --wait` +# 2. `BACKSTAGE_ENV=docker yarn dev` +backend: + database: + client: pg + connection: + host: localhost + port: 5432 + user: postgres + password: postgres + cache: + store: redis + connection: redis://localhost:6379 + +search: + elasticsearch: + provider: opensearch + node: 'http://localhost:9200' + auth: + username: admin + password: admin diff --git a/docker-compose.deps.yml b/docker-compose.deps.yml new file mode 100644 index 0000000000..c7515eca04 --- /dev/null +++ b/docker-compose.deps.yml @@ -0,0 +1,39 @@ +#!/usr/bin/env docker compose -f +name: backstage +services: + psql: + image: postgres:17.6 + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - '5432:5432' + healthcheck: + test: ['CMD-SHELL', 'pg_isready'] + interval: 10s + retries: 5 + start_period: 30s + timeout: 10s + redis: + image: redis:8.2.1-alpine + ports: + - '6379:6379' + healthcheck: + test: ['CMD-SHELL', 'redis-cli ping | grep PONG'] + interval: 1s + timeout: 3s + retries: 5 + opensearch: + image: opensearchproject/opensearch:2.19.3 + environment: + plugins.security.disabled: true + discovery.type: single-node + OPENSEARCH_INITIAL_ADMIN_PASSWORD: Opensearch1! + ports: + - '9200:9200' + - '9600:9600' + healthcheck: + test: 'curl --fail opensearch:9200/_cat/health >/dev/null || exit 1' + interval: 5s + timeout: 5s + retries: 30 diff --git a/package.json b/package.json index 7aed18ab74..2a5dad098a 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "snyk:test:package": "yarn snyk:test --include", "start": "backstage-cli repo start", "start-backend": "echo \"Use 'yarn start example-backend' instead\"", + "start:docker": "docker compose -f docker-compose.deps.yml up --wait && BACKSTAGE_ENV=docker yarn start", "start:microsite": "cd microsite/ && yarn start", "start:next": "yarn start example-app-next example-backend", "storybook": "storybook dev -p 6006", diff --git a/packages/backend/package.json b/packages/backend/package.json index 64c2f1dd47..ad34f429f8 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -60,6 +60,7 @@ "@backstage/plugin-scaffolder-backend-module-notifications": "workspace:^", "@backstage/plugin-search-backend": "workspace:^", "@backstage/plugin-search-backend-module-catalog": "workspace:^", + "@backstage/plugin-search-backend-module-elasticsearch": "workspace:^", "@backstage/plugin-search-backend-module-explore": "workspace:^", "@backstage/plugin-search-backend-module-techdocs": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index e32d3148b3..541c3bd791 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -15,18 +15,27 @@ */ import { createBackend } from '@backstage/backend-defaults'; -import { createBackendFeatureLoader } from '@backstage/backend-plugin-api'; +import { + coreServices, + createBackendFeatureLoader, +} from '@backstage/backend-plugin-api'; const backend = createBackend(); // An example of how to group together and load multiple features. You can also // access root-scoped services by adding `deps`. const searchLoader = createBackendFeatureLoader({ - *loader() { + deps: { + config: coreServices.rootConfig, + }, + *loader({ config }) { yield import('@backstage/plugin-search-backend'); yield import('@backstage/plugin-search-backend-module-catalog'); yield import('@backstage/plugin-search-backend-module-explore'); yield import('@backstage/plugin-search-backend-module-techdocs'); + if (config.has('search.elasticsearch')) { + yield import('@backstage/plugin-search-backend-module-elasticsearch'); + } }, }); diff --git a/yarn.lock b/yarn.lock index 50a73bb657..b267519b8f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6710,7 +6710,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-search-backend-module-elasticsearch@workspace:plugins/search-backend-module-elasticsearch": +"@backstage/plugin-search-backend-module-elasticsearch@workspace:^, @backstage/plugin-search-backend-module-elasticsearch@workspace:plugins/search-backend-module-elasticsearch": version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-elasticsearch@workspace:plugins/search-backend-module-elasticsearch" dependencies: @@ -30142,6 +30142,7 @@ __metadata: "@backstage/plugin-scaffolder-backend-module-notifications": "workspace:^" "@backstage/plugin-search-backend": "workspace:^" "@backstage/plugin-search-backend-module-catalog": "workspace:^" + "@backstage/plugin-search-backend-module-elasticsearch": "workspace:^" "@backstage/plugin-search-backend-module-explore": "workspace:^" "@backstage/plugin-search-backend-module-techdocs": "workspace:^" "@backstage/plugin-search-backend-node": "workspace:^"