anza-xyz / octane

Octane is a gasless transaction relayer for Solana.
Apache License 2.0
226 stars 141 forks source link

Vercel deployment on current master branch not working #14

Closed bukatea closed 2 years ago

bukatea commented 2 years ago

Describe the bug Even after following SETUP.md step by step, the current vercel deployment does not work.

To Reproduce Steps to reproduce the behavior:

  1. Follow SETUP.md, and update values in config.json with mint and authority pubkeys.
  2. Commit those to the fork.
  3. Deploy with env variables SECRET_KEY, RATE_LIMIT, and RATE_LIMIT_INTERVAL.

Expected behavior The deployment works.

Screenshots

Screen Shot 2022-07-23 at 5 59 36 PM

Desktop

Additional context I'm guessing because of the recent changes (adding lerna), it does not build properly on Vercel, even with lerna.json in the root directory.

bukatea commented 2 years ago

I've figured out first that it's the .vercelignore that's causing the problems, because it's still relying on the pre-lerna directory structure. Changed mine to

/*
!packages
!config.json
!package.json
!lerna.json
!yarn.lock

Not sure if this is everything, and then I also added

"workspaces": [
    "packages/*"
]

to top-level package.json and "useWorkspaces": true to lerna.json.

However, it builds correctly, but doesn't seem to detect the serverless functions correctly:

Screen Shot 2022-07-24 at 5 20 18 PM

It still gives a 404 for the main page

sevazhidkov commented 2 years ago

Thank you for the report! I reproduced the issue.

Octane started used workspaces and lerna to bundle both a server and a library for other apps within one repo. The function sources are located in packages/server/pages/api. Next.js compiles them to packages/server/pages/api/.next/server. However, Vercel doesn't support Next.js functions located in places other than /api or /pages/api. Even more, it provides a special runtime for these functions, removing all of the build artifacts besides package.json and /api.

Quick workaround (if you need to get Octane up and running) would be deploying using any other service that uses yarn run start. I personally host an Octane instance on Render.com.

The actual solutions is one of: 1) Removing Vercel support altogether. Pros: their definition of serverless functions definitely limit the dev flexibility. Cons: Vercel is cool and free (however, Render has a free plan too). 2) Hacking Vercel to use the server package endpoints. There are a few problems to solve: a) getting dependencies from all packages to a single package.json (it seems like Vercel's runtime only allows a single package.json) b) creating a symlink-style module.exports = require(...). I'll do more research on feasibility of this tomorrow.

Additionally, if we decide to remove Vercel support, a separate repo could be created specifically for Vercel-deployed serverless functions that would utilize octane-core package as soon as it's published on NPM.

Personally, I'd like to go for the first option and a separate Vercel repo. @bukatea @jordansexton what do you think?

bukatea commented 2 years ago

Thanks much for the quick reply. I think it makes sense to separate this project from Vercel, to make more clear to the users the option to run it locally. And a repo could be provided with the Vercel functions in the case that users want that functionality. For now, I will go ahead and run my own server for it, but will take a stab at (2) myself as well to see how easy that might be.

Thanks much for this, keep me updated!

sevazhidkov commented 2 years ago

@bukatea, actually, I found a way to deal with monorepos out of the box on Vercel — not sure how I missed this earlier: https://vercel.com/docs/concepts/monorepos

Setup process:

  1. Update .vercelignore:
/*
!packages
!config.json
!package.json
!lerna.json
!yarn.lock
  1. Add "useWorkspaces": true to lerna.json

  2. Add the following to root package.json:

    "dependencies": {
        "next": "^12.1.0"
    },
    "workspaces": [
        "packages/*"
    ]

The Next.js dependency has to be global so Vercel recognizes the server as a Next.js app.

  1. Run vercel link with the following settings:
Vercel CLI 27.3.3
? Set up “~/[...]”? [Y/n] y
? Which scope should contain your project? [...]
? Link to different existing project? [Y/n] n
? What’s your project’s name? [...]
? In which directory is your code located? ./packages/server

The important part here is to set code location to server package.

Alternatively, you can do this using UI.

  1. Run vercel deploy as usual

Please check if it works for you. If it does, I'll submit the changes to the main repo.

bukatea commented 2 years ago

@sevazhidkov You're a genius! This works perfectly. Somehow, when I was playing around with Vercel settings, I did things that were very similar to what you did, because it turns out that changing the directory the code is located in vercel link actually is 1-to-1 to a change in the vercel dashboard settings page for the project, under "Root Directory".

I actually did change this in my testing to "packages/server", but for some reason it still wasn't deploying correctly. The only things that were different when I was doing it was that my project was listed under "Other" instead of "Next.js" for "Build & Development Settings", and my node version was 14, not 16. So, for a successful deployment on an existing project, all I needed to change was "Other" => "Next.js" for build and development settings, "14.x" => "16.x" for node version, and "" => "packages/server" for root directory. Once I did this though, it immediately started working! I think it might not be the node version and actually just the Other configuration was messing up some things, but fyi for anyone else out there.