exoframejs / exoframe

Exoframe is a self-hosted tool that allows simple one-command deployments using Docker
https://exoframejs.github.io/exoframe/
1.14k stars 57 forks source link

v7.0 rewrite checklist #311

Open yamalight opened 3 years ago

yamalight commented 3 years ago

This is an issue to track overall progress on v7.0 rewrite. Plan is to rewrite / update code to use latest libs (not just versions) and ES modules (ES modules are not ready yet, dropping them?). Additionally, I'm planning to implement exoframe-client library that provides simple API for interacting with server (would allow to create new client, e.g. dashboard as some people wanted).

All work is done on v7-rewrite branch.

Packages:

Planned major changes:

Things to address in code / deps:

Planned issues:

ToDos:

Things to document:

Breaking changes (to keep track of them somehow):

Any feedback welcome.

yamalight commented 3 years ago

Apparently, jest currently doesn't support ES module mocking (see https://github.com/facebook/jest/issues/10025), so server rewrite is blocked on that feature.

Upd 1: ~Possible solution - use esm package as transformer?~ Doesn't work well with jest :(

Upd 2: Tried using babel-jest to compile modules - that doesn't work because import.meta is not compiled (for some reason), so you can't have 100% compatible code. Seems like waiting for jest ES compat is the best way?

Upd 3: jest just added basic unstable ESM support. gotta give it a shot.

Upd 4: And it works! πŸ₯³

yamalight commented 3 years ago

I wanted to use Ink for new cli, but it seems like it also has issues with ES modules support (import-jsx package specifically). So CLI is also blocked πŸ™ƒ

~Possible solution - use esm package?~ - doesn't work because import-jsx uses require to load modules, while esm expects import for all ES modules.

Update: Managed to make it work using htm package! πŸŽ‰πŸ₯³

Update 2: Not sure I like how the resulting code with html tagged template looks. Lack of syntax highlighting makes it quite hard to read πŸ€”

Update 3: Tried to use swc and esbuild to transpile jsx. both don't seem to play well with ESM (at least from the first basic attempt)

Update 4: Found a bug in swc, send a PR to fix it. This might fix most of issues(?)

Update 5: Using @babel/preset-env with custom config that emits ESM seems to work for now! Migrating to swc/esbuild would be nice for build speed, but for now it's fine.

Update 6: came to a conclusion that React/Ink is waaaay to complex for what exoframe CLI does. Dropped it. Tried using enquirer instead - it has some nice features, but some of the things are not quite what we need here. Seems like sticking with inquirer and building a custom prompt for config might be the best / easiest way to go πŸ€”

yamalight commented 3 years ago

Great collection of CLI websites on HN, ones I like most:

Frameworks for docs that looks nice:

yamalight commented 3 years ago

Alright, few months later - doesn't seem like native ESM support in Node.js ecosystem is going to happen anytime soon. Will probably scrap the plan to use pure ESM and use babel (with e.g. rollup) to compile to cjs. Well, was worth a try I guess πŸ™ƒ

yamalight commented 2 years ago

Initial server rewrite to ESM is finished πŸŽ‰

Things to keep in mind:

yamalight commented 2 years ago

I'm starting to think it might be easier to rewrite whole thing to typescript at this stage. So many tools are still not quite there yet with ESM support. The pain πŸ™ƒ

FDiskas commented 2 years ago

Yes please 😊

yamalight commented 2 years ago

I've tried doing that yesterday and as just a solution to ESM issues - it's no longer viable. There already are ESM-only modules that won't work in CJS envs, so you have to compile ts to ESM. Which just means you have ts on top of all existing issues πŸ˜…

FDiskas commented 2 years ago

I can try to make my hands dirty πŸ˜‰

yamalight commented 2 years ago

@FDiskas I'd prefer to first finish ESM version and then do anything else. There's too many issues as it is to add yet another thing on top πŸ˜…

niieani commented 11 months ago

Hi @yamalight! I'm really sad to see "Drop docker-compose support." on the list. This is basically how 90% of my exoframe deployments are done.

I really love this feature and it would be really sad to see it go, as I'll have to either keep using the old version or create a fork. At this point I'd be willing to even contribute a small amount of cash to support for docker-compose, or help by contributing to maintaining that feature myself.

I've previously contributed a PR related to this feature, and as you can see I've been using exoframe for over 5 years now.

I really don't mind the fact that I need to specify labels manually, in fact, I prefer it, because it gives me more flexibility as to how the deployments should be routed via traefik.

I really hope you reconsider. Let me know if you'd like to know more about how my use cases. Using exoframe over the years has been fantastic!

yamalight commented 11 months ago

@niieani I still think it's one of the worst ways to deploy things via exoframe - you make your server tear-down, re-build and re-start all containers defined in the compose file on every deployment. it's incredibly wasteful in all sorts of ways. vast majority of the time you want to update just one (app) container, and keep all the others unchanged (database, message queue, etc).

this is the main reason I think "exoframe way" (tm) is just a better approach. and it's not like doing it "exoframe way" is a lot of work - it takes a few minutes more than deploying compose, but only once.

here's an example. Imagine you have following compose file:

version: '3.6'
services:
  postgres:
    image: postgres:15
    ports:
      - 5432:5432
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgrespassword
  redis:
    image: redis:7
    ports:
      - '6379:6379'
  app:
    build: .
    ports:
      - 8080:8080
    depends_on:
      - postgres
      - redis
    environment:
      DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
      REDIS_HOST: redis

volumes:
  db_data:

This work perfectly fine for local testing / dev, but deploying it via exoframe 6 will tear-down and re-start postgres and redis every time you deploy. Why waste that time?

Here's how you would deploy it using exoframe configs: First, you define config for postgres:

{
  "name": "my-postgres",
  "domain": false,
  "image": "postgres:15",
  "volumes": ["db_data:/var/lib/postgresql/data"],
  "hostname": "mypostgres",
  "env": {
    "POSTGRES_PASSWORD": "postgrespassword"
  }
}

Next, you define exoframe config for redis:

{
  "name": "my-redis",
  "domain": false,
  "image": "redis:7",
  "hostname": "myredis"
}

And finally, you define config for your app:

{
  "name": "my-app",
  "domain": "my-app.com",
  "env": {
    "DATABASE_URL": "postgres://postgres:postgrespassword@postgres:5432/postgres",
    "REDIS_HOST": "askaredis"
  }
}

That's it, that's all the work it takes and you do it once. After doing that - you can individually (re-)deploy any of the containers without touching the other ones.

I think it's a fairly simple procedure that does make deployments a lot faster / simpler. It obviously has to be documented a lot better than it is right now - but that should come along with a new website.

I was also thinking about a possibility of writing a CLI script that would auto-convert compose files into sub-deployments like this.

Would love to know your thoughts on this - is that easy enough? Would you still want compose?

FDiskas commented 11 months ago

@yamalight hi, sorry about offtopic - I noticed that repository with a website is archived. Do you need a help on building the new one? Thinking about astrojs

yamalight commented 11 months ago

@FDiskas website will also be part of current monorepo (old repo was folded into it as-is). appreciate the offer, but haven't gotten around to that part yet! πŸ˜