Skip to content
This repository was archived by the owner on Aug 2, 2025. It is now read-only.

Conversation

@Its4Nik
Copy link
Owner

@Its4Nik Its4Nik commented Mar 11, 2025

@sourcery-ai

Summary by Sourcery

Refactor the project to use Bun instead of Node.js, improving performance and simplifying the development process. The API is now built with Elysia.js.

New Features:

  • Implement stack management endpoints for deploying, starting, stopping, restarting, and pulling images for Docker Compose stacks.
  • Add a WebSocket endpoint for streaming Docker container statistics in real-time.
  • Introduce plugin support for extending the functionality of the API.
  • Implement API endpoints for managing Docker hosts and API configuration.
  • Add API endpoints for retrieving and clearing backend logs.
  • Serve a custom 404 error page.
  • Add health check endpoint.
  • Add package information endpoint

@Its4Nik Its4Nik self-assigned this Mar 11, 2025
@sourcery-ai
Copy link

sourcery-ai bot commented Mar 11, 2025

Reviewer's Guide by Sourcery

This pull request represents a significant refactoring and enhancement of the DockStatAPI project. It includes a migration to Bun, adoption of Elysia.js, implementation of SQLite, refactoring of logging, implementation of a plugin system, implementation of Docker Compose stack management, implementation of a WebSocket endpoint for streaming container statistics, implementation of scheduled tasks, addition of a check for 'CHANGE_ME' in plugin files, implementation of a relay controller, and addition of a 404 page.

Sequence diagram for WebSocket container statistics stream

sequenceDiagram
  participant Client
  participant WebSocket
  participant Dockerode
  participant SplitStream

  Client->>WebSocket: Connects to /docker/stats
  activate WebSocket
  WebSocket->>Client: Connection established
  WebSocket->>Dockerode: docker.listContainers()
  activate Dockerode
  Dockerode-->>WebSocket: ContainerInfo[]
  loop for each container
    WebSocket->>Dockerode: container.stats({stream: true})
    activate Dockerode
    Dockerode-->>WebSocket: statsStream (Readable)
    WebSocket->>SplitStream: statsStream.pipe(splitStream)
    activate SplitStream
    SplitStream-->>WebSocket: line (string)
    WebSocket->>Client: JSON.stringify(data)
    Client-->>WebSocket: pong (heartbeat)
  end
  deactivate Dockerode
  deactivate SplitStream
  Client->>WebSocket: Close connection
  WebSocket->>SplitStream: statsStream.destroy()
  deactivate WebSocket
Loading

Updated class diagram for database repository

classDiagram
  class dbFunctions {
    + init()
    + addDockerHost(hostId: string, url: string, secure: boolean)
    + getDockerHosts(): DockerHost[]
    + addLogEntry(level: string, message: string, file_name: string, line: number)
    + getAllLogs()
    + getLogsByLevel(level: string)
    + updateDockerHost(name: string, url: string, secure: boolean)
    + deleteDockerHost(name: string)
    + clearAllLogs()
    + clearLogsByLevel(level: string)
    + updateConfig(polling_rate: number, fetching_interval: number, keep_data_for: number)
    + getConfig()
    + deleteOldData(days: number)
    + addContainerStats(id: string, hostId: string, name: string, image: string, status: string, state: string, cpu_usage: number, memory_usage: number)
    + updateHostStats(stats: HostStats)
    + addStack(stack_config: stacks_config)
    + getStacks()
    + deleteStack(name: string)
    + updateStack(stack_config: stacks_config)
  }

  class DockerHost {
    + name: string
    + url: string
    + secure: boolean
  }

  class HostStats {
    + hostId: string
    + dockerVersion: string
    + apiVersion: string
    + os: string
    + architecture: string
    + totalMemory: number
    + totalCPU: number
    + labels: string[]
    + containers: number
    + containersRunning: number
    + containersStopped: number
    + containersPaused: number
    + images: number
  }

  class stacks_config {
    + name: string
    + version: number
    + custom: Boolean
    + source: string
    + container_count: number
    + stack_prefix: string
    + automatic_reboot_on_error: Boolean
    + image_updates: Boolean
  }

dbFunctions -- DockerHost : returns
dbFunctions -- HostStats : uses
dbFunctions -- stacks_config : uses
Loading

File-Level Changes

Change Details Files
Migrated the project from TypeScript/Node.js to Bun, leveraging Bun's speed and efficiency.
  • Replaced ts-node and nodemon with bun for development and production execution.
  • Updated the build script to use bun build for creating optimized builds.
  • Adjusted the start script to use bun run for production execution.
  • Removed TypeScript-specific configurations and dependencies.
  • Updated the tsconfig to be compatible with Bun.
  • Removed npm and yarn specific files.
  • Removed node_modules specific files.
package.json
tsconfig.json
Adopted Elysia.js as the primary web framework, replacing Express.js.
  • Installed @elysiajs/static and @elysiajs/swagger.
  • Replaced Express.js imports and usage with Elysia.js equivalents.
  • Refactored route definitions to align with Elysia.js syntax.
  • Adjusted middleware configurations to suit Elysia.js.
  • Removed Express.js-specific dependencies.
package.json
src/index.ts
src/routes/api-config.ts
src/routes/docker-manager.ts
src/routes/docker-stats.ts
src/routes/docker-websocket.ts
src/routes/logs.ts
src/routes/stacks.ts
Implemented SQLite as the primary database solution.
  • Installed bun:sqlite.
  • Created a repository for database functions.
  • Implemented functions for initializing the database, adding/getting/updating/deleting docker hosts, adding/getting logs, updating/getting config, deleting old data, adding container stats, updating host stats, and adding/getting/deleting/updating stacks.
  • Removed old database configurations.
src/core/database/repository.ts
src/index.ts
package.json
Refactored logging using Winston.
  • Installed winston and winston-transport.
  • Created a logger utility with custom formatting and integration with the database.
  • Replaced console.log statements with logger calls throughout the application.
  • Added file and line number to log entries.
  • Implemented dynamic log level configuration.
package.json
src/core/utils/logger.ts
src/core/database/repository.ts
src/index.ts
src/routes/api-config.ts
src/routes/docker-manager.ts
src/routes/docker-stats.ts
src/routes/docker-websocket.ts
src/routes/logs.ts
src/routes/stacks.ts
src/core/docker/scheduler.ts
src/core/plugins/loader.ts
src/plugins/telegram.plugin.ts
src/core/docker/store-container-stats.ts
src/core/docker/store-host-stats.ts
Implemented a plugin system for extending the application's functionality.
  • Created a PluginManager class for registering, unregistering, and triggering plugin events.
  • Developed a plugin loader to discover and load plugins from a specified directory.
  • Defined a Plugin interface to standardize plugin structure.
  • Added example and Telegram plugins to demonstrate plugin capabilities.
  • Implemented plugin lifecycle hooks for container and host events.
src/core/plugins/plugin-manager.ts
src/core/plugins/loader.ts
src/typings/plugin.ts
src/plugins/example.plugin.ts
src/plugins/telegram.plugin.ts
src/core/plugins/plugin-actions.ts
Implemented Docker Compose stack management.
  • Added routes for deploying, starting, stopping, restarting, and pulling images for Docker Compose stacks.
  • Created functions for generating Docker Compose YAML files and managing stack lifecycle using the docker-compose library.
  • Integrated stack configurations with the database for persistence.
  • Implemented functions for getting stack status.
src/routes/stacks.ts
src/core/stacks/controller.ts
src/typings/docker-compose.ts
src/core/database/repository.ts
Implemented a WebSocket endpoint for streaming container statistics.
  • Created a WebSocket route for streaming container statistics in real-time.
  • Implemented functions for retrieving Docker hosts and containers from the database.
  • Utilized the dockerode library to fetch container statistics and stream them to connected clients.
  • Implemented functions for calculating CPU and memory usage.
  • Added stream lifecycle management to handle WebSocket disconnections and errors.
src/routes/docker-websocket.ts
src/core/utils/calculations.ts
src/typings/websocket.ts
Implemented scheduled tasks for fetching container statistics, updating host statistics, and cleaning up old data.
  • Created a scheduler utility for managing scheduled tasks.
  • Implemented functions for fetching container statistics and updating host statistics.
  • Implemented a function for cleaning up old data from the database.
  • Configured the scheduler to run these tasks at specified intervals.
src/core/docker/scheduler.ts
src/core/docker/store-container-stats.ts
src/core/docker/store-host-stats.ts
src/index.ts
Added a check for 'CHANGE_ME' in plugin files to prevent accidental deployment with default configurations.
  • Implemented a function to read files and check for the presence of 'CHANGE_ME'.
  • Added this check to the plugin loading process to ensure plugins are properly configured before registration.
src/core/utils/change-me-checker.ts
src/core/plugins/loader.ts
Implemented a relay controller for relaying events.
  • Created a relay controller.
  • Added functions for relaying stack events.
src/core/docker/relay-controller.ts
src/core/database/repository.ts
Added a 404 page.
  • Added a 404 page.
  • Added a route for the 404 page.
public/404.html
src/index.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai bot changed the title @sourcery-ai Refactor: Migrate to Bun, implement stacks and real-time stats Mar 11, 2025
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Its4Nik - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider adding a docker-compose.override.yaml to define configurations that override the base docker-compose.yaml.
Here's what I looked at during the review
  • 🟡 General issues: 6 issues found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟡 Complexity: 2 issues found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Its4Nik and others added 4 commits March 11, 2025 22:20
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
…rned-variable)

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
Its4Nik and others added 3 commits March 11, 2025 22:33
…rned-variable)

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
@Its4Nik Its4Nik moved this from In progress to Done in DockStatAPI Mar 11, 2025
@Its4Nik Its4Nik moved this from Done to In progress in DockStatAPI Mar 11, 2025
Copy link
Owner Author

@Its4Nik Its4Nik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #33 - v3

This PR includes a pretty big amount of changes, including:

  • switch to Bun with Elysia as Express alternative
  • Web sockets for container stats streaming
  • A SQLite Database, where everything is kept
  • Plugins!
  • Advanced Logging

This results in a whole new codebase but rather that and better structured then DockStatAPI v1 / v2

@Its4Nik Its4Nik merged commit bb9e1c1 into dev Mar 12, 2025
@github-project-automation github-project-automation bot moved this from In progress to Done in DockStatAPI Mar 12, 2025
@Its4Nik Its4Nik deleted the rewrite-elysia branch March 12, 2025 19:16
@Its4Nik Its4Nik moved this from Done to In progress in DockStatAPI Jun 26, 2025
@Its4Nik Its4Nik moved this from In progress to Done in DockStatAPI Jun 26, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Breaking change enhancement New feature or request new feature A new feature will be added by this PR

Projects

No open projects
Status: Done

2 participants