← Back to posts
comparison guide self-hosted · · 16 min read

Self-Hosted API Schema Validation & Governance: Spectral vs Prism vs OpenAPI Tools 2026

Complete guide to self-hosted API schema validation, mocking, and governance tools in 2026. Compare Spectral, Prism, Swagger Validator, and open-source alternatives for enforcing API quality standards.

OS
Editorial Team

Every modern engineering team relies on APIs — REST, GraphQL, gRPC — but without proper schema validation and governance, APIs become inconsistent, undocumented, and fragile. Teams ship breaking changes, forget to update specs, and create endpoint sprawl that makes onboarding miserable.

Self-hosted API schema validation tools solve this by enforcing OpenAPI, JSON Schema, and AsyncAPI standards directly in your CI/CD pipeline, without sending your proprietary API definitions to third-party SaaS platforms. This guide covers the best open-source tools for API linting, validation, mocking, and governance that you can run entirely on your own infrastructure.

Why Self-Host API Schema Validation

You might wonder: why not just use a cloud-based API management platform? Here are the core reasons teams choose self-hosted solutions:

Data Privacy and Security. API schemas encode your entire service architecture — endpoint structures, authentication flows, data models, and business logic. Sending these specifications to external SaaS vendors creates unnecessary exposure, especially in regulated industries like finance, healthcare, and government.

CI/CD Integration. Self-hosted tools run natively inside your pipeline. They block PRs that introduce breaking changes, validate specs on every commit, and generate client SDKs automatically. Cloud tools often require webhook integrations or manual upload steps that break automation.

No Vendor Lock-In. Open-source API tooling uses standard formats (OpenAPI 3.x, JSON Schema Draft 2020-12, AsyncAPI 2.x). Switching vendors means rewriting everything. Self-hosted open-source tools keep your workflow portable.

Offline and Air-Gapped Environments. Many organizations operate in environments with restricted or no internet access. Self-hosted tools run on internal networks with zero external dependencies.

Cost at Scale. SaaS API governance platforms charge per API, per user, or per validation request. Open-source alternatives run on your existing infrastructure with predictable costs regardless of how many APIs your team maintains.

What Is API Schema Validation?

API schema validation ensures your API specifications conform to established standards and your team’s custom rules. The workflow typically looks like this:

  1. Define — Write or update an OpenAPI/AsyncAPI specification (YAML or JSON)
  2. Lint — Check for syntax errors, structural issues, and style violations
  3. Validate — Ensure the spec conforms to the OpenAPI/AsyncAPI standard
  4. Govern — Apply custom organizational rules (naming conventions, required fields, security requirements)
  5. Test/Mock — Generate mock servers from the spec to test consumers without a live backend
  6. Generate — Produce client SDKs, server stubs, and documentation from validated specs

The tools below cover different stages of this pipeline. Most teams use a combination — one for linting and governance, another for mocking and testing.


1. Spectral — API Linting and Governance

Spectral by Stoplight is the most widely adopted open-source API linter. It reads OpenAPI 2.0/3.0/3.1 and AsyncAPI 2.x specifications, applies rule sets, and reports violations. Think of it as ESLint for your API specs.

What Spectral Does Well

Spectral’s core strength is its ruleset system. You define rules in YAML, and Spectral evaluates every node in your API spec against those rules. Rules can check anything from simple style conventions to complex cross-reference validations:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# .spectral.yaml
extends: ["spectral:oas"]
rules:
  # Built-in rule: all operations must have a description
  operation-description: true

  # Built-in rule: all path params must be defined
  path-params: true

  # Custom rule: all endpoints must use HTTPS
  https-only:
    description: "All API endpoints must use https protocol"
    given: "$.servers[*].url"
    severity: error
    then:
      function: pattern
      functionOptions:
        match: "^https://"

  # Custom rule: all operations must have a tag
  operation-tags-required:
    description: "Every operation must have at least one tag"
    given: "$.paths[*][?( @property === 'get' || @property === 'post' || @property === 'put' || @property === 'delete' || @property === 'patch' )]"
    severity: warn
    then:
      field: tags
      function: truthy

  # Custom rule: response schemas must include examples
  response-examples:
    description: "All 200 responses must include an example"
    given: "$.paths[*][*].responses['200'].content[*].schema"
    severity: warn
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          required: ["example"]

The extends: ["spectral:oas"] line pulls in Stoplight’s recommended OpenAPI ruleset as a baseline — over 30 rules covering operation IDs, tag definitions, schema naming, security requirements, and more. You override or extend from there.

Installing and Running Spectral

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Install via npm
npm install -g @stoplight/spectral-cli

# Lint a single spec file
spectral lint openapi.yaml

# Lint with a custom ruleset
spectral lint openapi.yaml --ruleset .spectral.yaml

# Output as JSON for CI integration
spectral lint openapi.yaml --format json

# Fail on errors only (ignore warnings)
spectral lint openapi.yaml --fail-[docker](https://www.docker.com/)ty error

Docker Deployment for CI/CD

For teams running CI/CD on self-hosted runners, the Docker image is the cleanest option:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# .github/workflows/api-lint.yml (GitHub Actions)
name: API Spec Linting
on:
  pull_request:
    paths:
      - "api-specs/**/*.yaml"
      - ".spectral.yaml"

jobs:
  lint:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
      - name: Run Spectral
        run: |
          docker run --rm -v $PWD:/spec stoplight/spectral:latest \
            lint /spec/api-specs/openapi.yaml \
            --ruleset /spec/.spectral.yaml \
            --fail-severity error \
            --format junit \
            --output results.xml
      - name: Publish test results
        if: always()
        uses: EnricoMi/publish-unit-test-result-action@v2
        with:
          files: results.xml

For GitLab CI:

1
2
3
4
5
6
7
8
9
# .gitlab-ci.yml
api-lint:
  image: stoplight/spectral:latest
  script:
    - spectral lint api-specs/openapi.yaml --ruleset .spectral.yaml --fail-severity error
  rules:
    - changes:
        - api-specs/**/*.yaml
        - .spectral.yaml

Breaking Change Detection

Spectral doesn’t natively detect breaking changes between spec versions, but you can pair it with openapi-diff:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Install openapi-diff
npm install -g @osstdev/openapi-diff

# Compare old vs new spec, fail on breaking changes
openapi-diff ./api-specs/v1.yaml ./api-specs/v2.yaml --json > diff-report.json

# Check if there are breaking changes
if jq -e '.[] | select(.compatibility == "incompatible")' diff-report.json > /dev/null; then
  echo "Breaking changes detected!"
  exit 1
fi

Key Strengths

  • Largest ecosystem of pre-built rulesets
  • Supports both OpenAPI and AsyncAPI
  • Custom functions via JavaScript/TypeScript
  • JUnit, JSON, and HTML output formats
  • VS Code extension for real-time feedback
  • Integrates with Stoplight Studio for visual editing

Limitations

  • No built-in API mocking
  • No automatic SDK generation (needs external tools)
  • Custom rules require JavaScript knowledge for complex logic
  • Breaking change detection requires a companion tool

2. Prism — API Mock Server and Contract Testing

Prism is also by Stoplight and serves a different purpose: it turns any OpenAPI or AsyncAPI specification into a fully functional mock HTTP server. Consumers can test against your API before a single line of backend code is written.

How Prism Works

Prism reads your OpenAPI spec and automatically generates responses based on the schemas you’ve defined. It returns realistic mock data that matches your response types, respects example values when provided, and validates incoming requests against the spec.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Install Prism
npm install -g @stoplight/prism-cli

# Start a mock server from an OpenAPI spec
prism mock ./api-specs/openapi.yaml

# Start with CORS enabled for frontend development
prism mock ./api-specs/openapi.yaml --cors

# Bind to a specific port
prism mock ./api-specs/openapi.yaml --port 4010

# Dynamic mode: Prism generates realistic mock data
prism mock ./api-specs/openapi.yaml --dynamic

# Proxy mode: forward unmatched requests to a real backend
prism proxy ./api-specs/openapi.yaml https://api.production.example.com --port 4010

Docker Setup for Teams

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# docker-compose.yml for API mock server
version: "3.8"
services:
  api-mock:
    image: stoplight/prism:5
    command: mock /specs/openapi.yaml --cors --host 0.0.0.0
    ports:
      - "4010:4010"
    volumes:
      - ./api-specs:/specs:ro
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:4010/health"]
      interval: 30s
      timeout: 10s
      retries: 3

Contract Testing with Prism

Prism doubles as a contract testing tool. In proxy mode, it validates that your real backend’s responses match the spec:

1
2
3
4
5
6
# Run Prism in proxy mode during integration tests
prism proxy ./api-specs/openapi.yaml https://staging-api.internal:8443 --port 4010

# In your test suite, point the test client at Prism's proxy
# Prism validates every request and response against the spec
# and logs violations to stderr

When a backend response doesn’t match the spec, Prism logs the mismatch:

1
2
3
[VALIDATION ERROR] Response status 422 does not match any defined response for this operation
[VALIDATION ERROR] Response body missing required field 'error_code'
[VALIDATION ERROR] Response header 'X-Rate-Limit-Remaining' is defined in spec but not present

CI/CD Integration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Run Prism validation as part of integration tests
api-contract-test:
  image: stoplight/prism:5
  services:
    - name: staging-api
      alias: backend
  script:
    # Start Prism in proxy mode pointing to staging
    - prism proxy /specs/openapi.yaml http://backend:8080 --port 4010 &
    # Run your test suite against Prism
    - curl -f http://localhost:4010/users/1
    - curl -f http://localhost:4010/orders --data '{"item_id": 42, "qty": 2}'
    # Prism outputs violations; check for errors
    - prism proxy --validate /specs/openapi.yaml http://backend:8080 2>&1 | grep -c "VALIDATION ERROR" | xargs test 0 -eq

Key Strengths

  • Instant mock server from any OpenAPI spec
  • Contract testing catches spec-to-implementation drift
  • Proxy mode validates live traffic against the spec
  • Generates realistic mock datkafkah --dynamic
  • Supports both REST and async (Kafka, WebSockets) via AsyncAPI

Limitations

  • Mock data quality depends on spec completeness
  • Heavy specs (1000+ operations) can have slow startup times
  • No built-in linting (pairs with Spectral)
  • No SDK generation

3. Swagger Editor + Swagger Validator

The Swagger Editor and Swagger Validator form the original open-source API tooling stack. While Spectral and Prism have gained popularity, the Swagger toolchain remains widely used for its simplicity and direct integration with the OpenAPI ecosystem.

Swagger Validator

The validator is a Node.js package that checks OpenAPI 2.0/3.0 specs against the official JSON Schema:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Install
npm install -g swagger-validator

# Validate a spec file
swagger-validator ./openapi.yaml

# Validate and get structured output
swagger-validator ./openapi.yaml --json

# Validate as part of a build script
npm install --save-dev swagger-validator
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// validate.js — use in build scripts or CI
const validate = require("swagger-validator");

async function checkSpec() {
  try {
    const result = await validate("./api-specs/openapi.yaml");
    console.log("Spec is valid!");
    console.log(`Found ${result.api.info.title} v${result.api.info.version}`);
    console.log(`${Object.keys(result.api.paths).length} paths defined`);
  } catch (errors) {
    console.error("Validation errors:");
    errors.forEach((err) => console.error(`  ${err.message}`));
    process.exit(1);
  }
}

checkSpec();

Swagger Editor (Self-Hosted)

For teams that want a web-based interface for writing and editing API specs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# docker-compose.yml — self-hosted Swagger Editor
version: "3.8"
services:
  swagger-editor:
    image: swaggerapi/swagger-editor
    ports:
      - "8080:8080"
    environment:
      - URL=/api-specs/openapi.yaml
    volumes:
      - ./api-specs:/api-specs:ro
    restart: unless-stopped

  swagger-ui:
    image: swaggerapi/swagger-ui
    ports:
      - "8081:8080"
    environment:
      - SWAGGER_JSON=/api-specs/openapi.yaml
    volumes:
      - ./api-specs:/api-specs:ro
    restart: unless-stopped

Access the editor at http://your-server:8080 and the rendered documentation at http://your-server:8081.

Generating Code with OpenAPI Generator

The Swagger ecosystem’s most powerful companion is OpenAPI Generator, which produces client SDKs and server stubs in 50+ languages:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Generate a TypeScript client
docker run --rm -v $PWD:/local openapitools/openapi-generator-cli generate \
  -i /local/api-specs/openapi.yaml \
  -g typescript-axios \
  -o /local/generated/typescript-client

# Generate a Python FastAPI server stub
docker run --rm -v $PWD:/local openapitools/openapi-generator-cli generate \
  -i /local/api-specs/openapi.yaml \
  -g python-fastapi \
  -o /local/generated/python-server

# Generate a Go client
docker run --rm -v $PWD:/local openapitools/openapi-generator-cli generate \
  -i /local/api-specs/openapi.yaml \
  -g go \
  -o /local/generated/go-client

# List all available generators
docker run --rm openapitools/openapi-generator-cli list

CI integration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Generate SDKs on every spec change
generate-sdks:
  image: openapitools/openapi-generator-cli:v7.4.0
  script:
    - mkdir -p sdks
    - openapi-generator-cli generate -i api-specs/openapi.yaml -g typescript-axios -o sdks/typescript
    - openapi-generator-cli generate -i api-specs/openapi.yaml -g python -o sdks/python
    - openapi-generator-cli generate -i api-specs/openapi.yaml -g go -o sdks/go
  artifacts:
    paths:
      - sdks/
  rules:
    - changes:
        - api-specs/openapi.yaml

4. Dredd — HTTP API Testing Framework

Dredd takes a different approach: it reads your API specification and sends real HTTP requests to your running API, validating that responses match the spec. It’s contract testing in the opposite direction of Prism — instead of mocking the backend, it tests the backend.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Install
npm install -g dredd

# Run against a running API
dredd ./openapi.yaml http://localhost:3000

# Run with verbose output
dredd ./openapi.yaml http://localhost:3000 --level=verbose

# Use a hook file to handle authentication
dredd ./openapi.yaml http://localhost:3000 --hookfiles=./hooks.js

# Output JUnit XML for CI
dredd ./openapi.yaml http://localhost:3000 --reporter=junit --output=dredd-results.xml

Hooks for Authentication

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// hooks.js — handle API auth in Dredd tests
const hooks = require("hooks");
const jwt = require("jsonwebtoken");

hooks.beforeEach((transaction) => {
  // Generate a test JWT token
  const token = jwt.sign(
    { sub: "test-user", role: "admin" },
    "test-secret-key",
    { expiresIn: "1h" }
  );

  // Add Authorization header to every request
  transaction.request.headers["Authorization"] = `Bearer ${token}`;
});

// Skip tests for endpoints that need real data
hooks.before("POST /orders > 201 > application/json", (transaction) => {
  transaction.skip = true;
});

Docker + Docker Compose for Full Test Suite

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# docker-compose.test.yml
version: "3.8"
services:
  api:
    build: ./my-api
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=test
      - DB_HOST=db

  db:
    image: postgres:16
    environment:
      - POSTGRES_PASSWORD=test

  dredd:
    image: apiaryio/dredd:latest
    command: /specs/openapi.yaml http://api:3000
    volumes:
      - ./api-specs:/specs:ro
    depends_on:
      - api

Comparison Table

FeatureSpectralPrismSwagger ValidatorDreddOpenAPI Generator
Primary UseLinting & GovernanceMock ServerValidationContract TestingCode Generation
OpenAPI 3.1❌ (3.0 only)
AsyncAPI
Custom Rules✅ (JS functions)✅ (hooks)N/A
Mock ServerServer stubs
SDK Generation✅ (50+ languages)
Breaking ChangesVia openapi-diff
Docker Image
CI/CD OutputJUnit, JSON, HTMLStderr logsJSONJUnit, HTMLGenerated code
PerformanceFast (<1s typical)Moderate (startup)FastSlow (HTTP calls)Moderate
Best ForEnforcing standardsFrontend dev / testingQuick validationBackend verificationMulti-language SDKs

The most effective self-hosted API governance setup combines multiple tools into a cohesive pipeline:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
Developer writes/updates OpenAPI spec
         
   Spectral lints the spec
   (blocks on style/governance errors)
         
   Swagger Validator confirms spec
   (blocks on structural errors)
         
   openapi-diff compares with previous
   (blocks on breaking changes)
         
   Prism generates mock server
   (frontend teams test immediately)
         
   Dredd tests real backend
   (validates implementation matches spec)
         
   OpenAPI Generator creates SDKs
   (published to package registry)
         
   Swagger UI publishes docs
   (auto-deployed to docs site)

Full CI/CD Pipeline Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# .github/workflows/api-governance.yml
name: API Governance Pipeline
on:
  pull_request:
    paths:
      - "api-specs/**"

jobs:
  lint:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
      - run: docker run --rm -v $PWD:/spec stoplight/spectral:latest lint /spec/api-specs/openapi.yaml --fail-severity error

  validate:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
      - run: npx swagger-validator api-specs/openapi.yaml

  breaking-changes:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - run: |
          git checkout main -- api-specs/openapi.yaml
          mv api-specs/openapi.yaml api-specs/openapi-base.yaml
          git checkout HEAD -- api-specs/openapi.yaml
          npx @osstdev/openapi-diff api-specs/openapi-base.yaml api-specs/openapi.yaml --json
          if jq -e '.[] | select(.compatibility == "incompatible")' diff.json; then
            echo "Breaking changes detected — PR blocked"
            exit 1
          fi

  mock-test:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
      - run: |
          docker run -d --name prism -p 4010:4010 \
            -v $PWD/api-specs:/specs stoplight/prism:latest \
            mock /specs/openapi.yaml --cors
          sleep 5
          curl -f http://localhost:4010/health

  generate-sdks:
    runs-on: self-hosted
    needs: [lint, validate, breaking-changes]
    steps:
      - uses: actions/checkout@v4
      - run: |
          docker run --rm -v $PWD:/local openapitools/openapi-generator-cli:v7.4.0 generate \
            -i /local/api-specs/openapi.yaml \
            -g typescript-axios \
            -o /local/sdks/typescript
          docker run --rm -v $PWD:/local openapitools/openapi-generator-cli:v7.4.0 generate \
            -i /local/api-specs/openapi.yaml \
            -g python \
            -o /local/sdks/python

Custom Rulesets: Advanced Governance

For organizations with dozens of APIs, custom rulesets enforce consistency across teams:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# .spectral.yaml — Enterprise API Governance Ruleset
extends: ["spectral:oas"]

functions:
  - custom-validators.js

rules:
  # All APIs must have consistent versioning
  api-version-format:
    description: "API version must follow semver (v1, v2, etc.)"
    given: "$.info.version"
    severity: error
    then:
      function: pattern
      functionOptions:
        match: "^v[0-9]+$"

  # All endpoints must support pagination
  list-endpoints-pagination:
    description: "All list endpoints must support pagination parameters"
    given: "$.paths[?(@property.match(/^\\/.*s$/))].get.parameters[*].name"
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "(limit|offset|page|cursor)"

  # All error responses must follow standard format
  error-response-format:
    description: "Error responses must include code, message, and details fields"
    given: "$.paths[*][*].responses[?(@property.match(/^(4|5)/))].content.application/json.schema"
    severity: error
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          required: ["error"]
          properties:
            error:
              type: object
              required: ["code", "message"]
              properties:
                code:
                  type: "string"
                message:
                  type: "string"

  # Security: all endpoints must use authentication
  no-open-endpoints:
    description: "All operations must define security requirements"
    given: "$.paths[*][*]"
    severity: error
    then:
      function: defined
      field: security

  # Naming: all property names must use snake_case
  property-names-snake-case:
    description: "Schema property names must use snake_case"
    given: "$.components.schemas[*].properties.*~"
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^[a-z][a-z0-9]*(_[a-z0-9]+)*$"

  # All responses must define a schema (no empty responses)
  response-schema-defined:
    description: "Every response must define a response schema"
    given: "$.paths[*][*].responses[*]"
    severity: error
    then:
      function: truthy
      field: content

Summary: Which Tool to Choose

If you need…Use…
API linting with custom organizational rulesSpectral
Instant mock server for frontend teamsPrism
Contract testing against a real backendDredd
SDK generation in multiple languagesOpenAPI Generator
Quick spec validation in build scriptsSwagger Validator
Visual API editing in a browserSwagger Editor
Complete API governance pipelineSpectral + Prism + OpenAPI Generator

For most teams starting with API governance, the minimum viable setup is Spectral for linting in CI plus Prism for mocking during development. As your API program matures, add openapi-diff for breaking change detection, Dredd for contract testing, and OpenAPI Generator for SDK automation.

All of these tools are open-source, run on self-hosted infrastructure, and keep your API specifications entirely under your control. No SaaS subscriptions, no external data sharing, no vendor lock-in — just reliable API quality enforcement that scales with your engineering organization.

Frequently Asked Questions (FAQ)

Which one should I choose in 2026?

The best choice depends on your specific requirements:

  • For beginners: Start with the simplest option that covers your core use case
  • For production: Choose the solution with the most active community and documentation
  • For teams: Look for collaboration features and user management
  • For privacy: Prefer fully open-source, self-hosted options with no telemetry

Refer to the comparison table above for detailed feature breakdowns.

Can I migrate between these tools?

Most tools support data import/export. Always:

  1. Backup your current data
  2. Test the migration on a staging environment
  3. Check official migration guides in the documentation

Are there free versions available?

All tools in this guide offer free, open-source editions. Some also provide paid plans with additional features, priority support, or managed hosting.

How do I get started?

  1. Review the comparison table to identify your requirements
  2. Visit the official documentation (links provided above)
  3. Start with a Docker Compose setup for easy testing
  4. Join the community forums for troubleshooting
Advertise here