wasp icon indicating copy to clipboard operation
wasp copied to clipboard

Providers - Railway / deployment only

Open OlegGulevskyy opened this issue 1 year ago • 8 comments

Deploy stuff to Railway

Take into account things

  1. railway login does not work in non-interactive mode. Current implementation checks if user logged in, otherwise throw out of the process with a friendly hint what to do next
  2. Global options --wasp-exe <path> and --wasp-project-dir <dir> are being added to each subcommand in the global scope
  3. This implementation expects a specific file for railway deployments to be present in the main root directory of Wasp - wasp.deployrc.railway.json It's expected signature is:
	"environment": "production",
	"projectId": "bef41c2c-b1a9-42ef-adb9-e3afa84fbbea",
	"clientService": {
		"name": "client",
		"url": "client-production-6ea1.up.railway.app"
	},
	"serverService": {
		"name": "server",
		"url": "server-production-dfaf.up.railway.app"
	}

Environment - required by Railway as there can exist multiple envs ProjectID - build folder has to be linked with a respective project Client / Server Service - info about the client service (ID and its URL). Railways projects consist of services, that you can spin up pretty easily. Each service has its own env variables etc.

Whenever "setup" feature is implemented, we can ensure that this file is create automatically, but I am not entirely sure if that's a good idea to do. Need peoplez thoughts on this. Alternative, we force users to provide those values as flags / arguments.. ?

Refactor suggestions things

  1. Suggesting to keep all types in .d.ts files to clearly indicate what they are

  2. Even though haven't done it properly myself, but I'd probably also remove Capital casing on type files, as I see no benefit in this, if we mark the file with .d.ts extension, it should be clear enough what file is for.

  3. Stick to naming convention of types to indicate where they belong to - FlyDeployOptions, Railway(Rw)DeployOptions. Eases search of specific options across the codebase instead of doing a global search and having 10+ same names

  4. Installed fs-extra package, hoping it's allowed :) otherwise, can be reimplemented (mainly used for ensureDir, but it provides other convenient stuffs)

  5. await $railway up --service ${clientService.name} - is a stream of logs for deploying. Atm this implementation just fires & forgets, giving a URL of logs as an output, so maybe for v1 it's ok, but later do a re-stream? No idea how to re-stream output logs tho

  6. Fn HACK_PACKAGES_JSON has to die, but it allows to continue with implementation, as types are not used in Docker and tsc is run, that leads to bunch of types missing. This is because Server is not built inside the Docker container, so I'd like opinions on what could be / should be done. It might come across as pretty obvious one - just build the server - but do we then cherry pick specific folders from server, aiming just specific types folders etc? I am not fan of this option because if we add a library tomorrow to the server side, and forget to cherry pick its types inside this deployment Docker, we will have a failing build.

  7. Added prettier config for a consist styling, feedback / suggestions on its content is appreciated! For now, I just tried to mirror what has already been put together in terms of style by Shayne :)

A lot has been moved around from /fly provider, as a lot of nice conveniences were living in it, so had to move it up a scope to make them shareable.

It is a very breaking change as I moved a lot of things around, but it was building fine for me... (as always). As I am not a Fly.io user and I have very limited time, I'd appreciate someone's help with testing this to ensure no regression.

Select what type of change this PR introduces:

  1. [ ] Just code/docs improvement (no functional change).
  2. [ ] Bug fix (non-breaking change which fixes an issue).
  3. [ ] New feature (non-breaking change which adds functionality).
  4. [x] Breaking change (fix or feature that would cause existing functionality to not work as expected).

Update Waspc ChangeLog and version if needed

If you did a bug fix, new feature, or breaking change, that affects waspc, make sure you satisfy the following:

  1. [ ] I updated ChangeLog.md with description of the change this PR introduces.
  2. [ ] I bumped waspc version in waspc.cabal to reflect changes I introduced, with regards to the version of the latest wasp release, if the bump was needed.

OlegGulevskyy avatar Apr 21 '23 07:04 OlegGulevskyy

Very nice, @OlegGulevskyy 🚀. This seems like a really great start. This is the first time I've actually looked at the deploy code as this isn't really my domain. Learning new things myself here :)

The one thing I could comment on here concerns the wasp.deployrc.railway.json file. From what I know about Railway, the user would have to set up a "service" and "generate a domain" for both the client and server first, before defining it in the json file. Currently, it seems that its not possible to create a service via the CLI (https://docs.railway.app/reference/cli-api#service), which would make the script a lot friendlier, although it does seem like you can generate a domain via CLI with railway domain. Do you know if there is a possible way to add a service programatically, without the user having to define it first within the Railway dashboard?

Also, would be nice at some point to use railway add to add the Postgres database and seed it with wasp db seed (https://wasp-lang.dev/docs/language/features#seeding).

But, yeah, great work. Looking forward to following the progress here 👏

vincanger avatar Apr 21 '23 08:04 vincanger

This is the first time I've actually looked at the deploy code as this isn't really my domain. Learning new things myself here :)

Yeah, deploy code is just a node cli with TS, so we all can contribute :)

Do you know if there is a possible way to add a service programatically

Not that I know of, no. It seems their CLI is very limited when it comes to setting things up. That's also one of the reasons why I solely focused on deploying as a first feature. At least you can configure your stuff in their UI and just do one line command re-deployments. But I do agree that comparing to fly provider, this is much more humble functionality (even if we just compare deploy part and not entirely the provider).

Also, would be nice at some point to use railway add to add the Postgres database

This seems to be a viable option, but needs to be played around with (maybe next item on the agenda), however I do have my doubts:

  • output results (if we don't know the details of the created DB, it's kind of pointless, as we need to link server and DB together, so it's easier to do it through UI potentially)
  • setting env variables on services. without those env variables on each service, they are pretty useless in terms of one click deployments. Maybe I am just not seeing the elephant in the room and I don't know if that's handled in fly.io but if we can't retrieve newly created DB's URL and set it as env variable in server service, I am not sure it's useful at all (just do it altogether in UI)

OlegGulevskyy avatar Apr 21 '23 09:04 OlegGulevskyy

Hi @OlegGulevskyy, nice work again! I got a chance to play with it today and my thoughts are below.

  1. Fly stuff looks good and still appears to work as expected, nice!

  2. If the wasp.deployrc.railway.json file is missing, perhaps we can check and provide a nicer message?

🚀  Deploying your Wasp app to Railway!
$ cd /tmp/wasp/waspc/examples/todoApp/
node:fs:600
  handleErrorFromBinding(ctx);
  ^

Error: wasp.deployrc.railway.json: ENOENT: no such file or directory, open 'wasp.deployrc.railway.json'
    at Object.openSync (node:fs:600:3)
    at Object.readFileSync (node:fs:468:35)
    at Object.readFileSync (/tmp/wasp/waspc/data/packages/deploy/node_modules/jsonfile/index.js:50:22)
    at getRailwayConfig (file:///tmp/wasp/waspc/data/packages/deploy/dist/providers/railway/helpers/helpers.js:49:15)
    at RailwayCommand.deploy (file:///tmp/wasp/waspc/data/packages/deploy/dist/providers/railway/deploy/deploy.js:10:22)
    at RailwayCommand.listener [as _actionHandler] (/tmp/wasp/waspc/data/packages/deploy/node_modules/commander/lib/command.js:482:17)
    at /tmp/wasp/waspc/data/packages/deploy/node_modules/commander/lib/command.js:1264:65
    at /tmp/wasp/waspc/data/packages/deploy/node_modules/commander/lib/command.js:1155:33
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Command.parseAsync (/tmp/wasp/waspc/data/packages/deploy/node_modules/commander/lib/command.js:916:5) {
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path: 'wasp.deployrc.railway.json'
}
  1. I set up a Railway app with the two services in the file, but despite the CLI saying it was deployed, it actually failed to build. Here is the output from the client and server services:
=========================
Using Detected Dockerfile
=========================
context: 8061f20702d6d02060c6efe45a69e52c
#1 [internal] load .dockerignore
 
#1 transferring context: 2B 0.0s done
 
#1 DONE 0.1s
 
 
 
#2 [internal] load build definition from Dockerfile
 
#2 transferring dockerfile: 47B 0.0s done
 
#2 DONE 0.1s
Dockerfile:1
-------------------
1 | >>> ## HELLO!
2 |
-------------------
ERROR: failed to solve: file with no instructions

 
=========================
Using Detected Dockerfile
=========================
context: e3702485d84e1a5ad0ac8661e46a05cc
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 47B done
 
#1 DONE 0.1s
 
#2 [internal] load .dockerignore
#2 transferring context: 2B done
#2 DONE 0.1s
Dockerfile:1
-------------------
1 | >>> ## HELLO!
2 |
-------------------
ERROR: failed to solve: file with no instructions

I was attempting to build this project: https://github.com/wasp-lang/wasp/tree/main/waspc/examples/todoApp

Here is my JSON file:

{
  "environment": "production",
	"projectId": "0a469ab4-78b6-4283-8674-1d80c09a0fb8",
	"clientService": {
		"name": "client",
		"url": "client-production-7866.up.railway.app"
	},
	"serverService": {
		"name": "server",
		"url": "server-production-22f3.up.railway.app"
	}
}

Any ideas on what may be up?

  1. Where/how should I wire in a DB?

Thanks for the help in getting my first Railway deploy up! 🚀

shayneczyzewski avatar Apr 24 '23 20:04 shayneczyzewski

P.S. I've asked @sodic to review this as time permits, so you will have someone better than me for your TS stuff @OlegGulevskyy :)

shayneczyzewski avatar Apr 24 '23 20:04 shayneczyzewski

Hey @shayneczyzewski , yep sorry I am tad busy currently in my things, so all my activity is on pause, but I should get back to the PR some time soon Your comments look great, thank you! (quite few to read haha)

OlegGulevskyy avatar May 03 '23 13:05 OlegGulevskyy

Hey @shayneczyzewski , yep sorry I am tad busy currently in my things, so all my activity is on pause, but I should get back to the PR some time soon Your comments look great, thank you! (quite few to read haha)

Awesome, no worries take your time and thanks for keeping it going when you free up! And yes, quite a few haha welcome to the team :D 😎

shayneczyzewski avatar May 04 '23 14:05 shayneczyzewski

Pplz @OlegGulevskyy @shayneczyzewski how are we with this PR, any idea when we could progress further? Should I just rewrite it all to Haskell, has that moment finally come :D?

Martinsos avatar Jun 01 '23 14:06 Martinsos

Pplz @OlegGulevskyy @shayneczyzewski how are we with this PR, any idea when we could progress further? Should I just rewrite it all to Haskell, has that moment finally come :D?

It is stalled at the moment. I think the refactor part is looking good, but I wasn't able to deploy to Railway using it. It could have just been me, though. @infomiho also gave it a try and eventually got it.

Note: there have been a few deploy updates that will need to be rebased into this.

shayneczyzewski avatar Jun 02 '23 19:06 shayneczyzewski