Analysis 1: Stack and architecture
Martin Maikov edited this page 2026-09-24 10:23:31 +00:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

title
Analysis 1: Stack and architecture

Analysis 1: Stack and architecture

What we chose

  1. Frontend: JavaScript and Vue.js, because everyone in team has used this before.
  2. Backend: Javascript with Node.js (Express), same reason as frontend, everyone has experience with it. Also JavaScript on both sides reduces context switching.
  3. Data: PostgreSQL and S3 Garage. PostgreSQL because it's the most familiar to the team. S3 Garage because we were warned that wrong architecture chosen early could later make development difficult. Considering image storage, object-storage- S3 Garage seemed like a popular reliable way to store images.
  4. Repository layout: A root meta-repository holds infrastructure files and links the frontend and backend as Git submodules. This keeps each application independently buildable and gives each submodule its own CI and package configuration, while the root repository owns the integration environment.

What we rejected

  1. React instead of Vue: No meaningful benefits would have come from React, it's just a very popular and well supported library, so we just considered it.
  2. Rust instead of JavaScript: Rust would have been more exiting and better performance wise, but JavaScript still more reliable if all team members are experienced in it.
  3. MinIO instead of Garage: MinIO is a familiar S3-compatible choice, but was announced that community version of MinIO is not maintained as of 2026, so good practice would be to choose Garage instead. Otherwise no meaningul benefits from MinIO.
  4. RustFS instead of MinIO: While considered as an alternative, this option was dismissed because it mirrors MinIO’s governance model—relying on a private company, dual licensing, and contributor licensing agreements (CLAs). Consequently, RustFS is predicted to follow the exact same trajectory as MinIO, making it an unwise long-term choice with no real strategic benefit.
  5. SeaweedFS and other S3 alternatives: Excluded from consideration due to excessive feature richness and operational complexity. These systems introduced heavy, multi-layered architectures, such as separate master, volume, and filer components paired with external metadata stores, that over-engineered our requirements and carried an unnecessary maintenance burden.
  6. A single application repository instead of submodules: We considered putting the frontend and backend in one repository. That would make it easier to change both at the same time. We still chose separate repositories, preparing ahead, frontend and backend can be developed and tested independently. The disadvantage is seperate commits and merge requests and more difficult cross-repository reviews.

What we expect to be difficult in phase 3

  • Configuration and local-host assumptions: Compose injects values from the root .env, but some URLs, ports, bind addresses, and Docker service names are hard-coded in the application and files. In Kubernetes, these values must be supplied through appropriately scoped ConfigMaps, Secrets, Services, and environment variables.

  • Persistent state and storage: PostgreSQL and Garage are both stateful services, so deploying them to Kubernetes will be more complicated than deploying the frontend or backend. Their data must survive pod restarts and rescheduling, which means we will need to understand persistent volumes, storage configuration, and how the applications connect to these services when their individual pods are not permanent. Garage may be especially difficult because it is a separate storage service with its own configuration and persistent data. This part is probably going to be most time consuming.

  • Logging and debugging across containers: During local development, logs are easy to see directly in the terminal where each process was started. In Kubernetes, logs will be spread across several pods and potentially several replicas of the backend. If the application currently writes any logs to files, this will also be problematic because pod filesystems are temporary. We expect debugging failures across the frontend, backend, PostgreSQL, and Garage to be less straightforward.