manual deploy gcp
I am trying to manuelly deploy to gcp cloud run and when doing the wasp build i get that the database url is not found but i did set it in .env.server
Then when deploying cloud run it says that the app couldnt be deployed kn port 8080 (which i dont know where it gets from) but even when puttin port = 8080 in .env.server
36 Replies
Wohooo @tomas.morales, you just became a Waspeteer level 2!
Hi @tomas.morales. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Hmm, I don't know enough to give you a confident answer yet. However, I can provide some insights based on the information available.
The
DATABASE_URL
environment variable is crucial for your PostgreSQL database connection. It should be provided to the server and the database should be accessible from the server source (https://wasp-lang.dev/docs/advanced/deployment/manually#4-deploying-the-database).
The error message you're seeing might be related to an open issue in Wasp where the DATABASE_URL
environment variable is not found during the wasp build
process source (https://github.com/wasp-lang/wasp/issues/1321). This issue seems to be a duplicate of another open issue where the DATABASE_URL
is not found by Prisma during the wasp build
process source (https://github.com/wasp-lang/wasp/issues/1282).
As for the port issue, currently, Wasp uses default values from CRA and Node for client and server port numbers. There is a closed issue about making these port numbers configurable source (https://github.com/wasp-lang/wasp/issues/146). However, there is an open issue about allowing automatic and/or manual choosing of another port than 5432 source (https://github.com/wasp-lang/wasp/issues/1049).
Unfortunately, I don't have specific information about deploying to GCP Cloud Run. I recommend checking the official Wasp documentation or reaching out to the Wasp community for more specific guidance.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @tomas.morales, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?what about the firewall rules for opening ports on cloud run
Hi @tomas.morales I'm not familiar with Google Cloud Run. What's your reasoning for choosing it over Fly.io or Railway, for example. We have one-command deploy for your entire app, DB + server + cleint, for fly with
wasp deploy fly launch ...
and it's all well documented hereDeploying with the Wasp CLI | Wasp
Wasp CLI can deploy your full-stack application with only a single command.
Its just because i have my infrastructure in google cloud and i understand it could scale easier. Havent used fly before
I think you can get a lot of info by reading this bit in the docs: https://wasp-lang.dev/docs/advanced/deployment/manually
It's related to other providers, but it should be useful to understand how Wasp is just a React + Node.js + Postgres app in the end
Deploying Manually | Wasp
This document explains how to build and prepare your Wasp app for deployment.
Ok thx
How did it go? Were you successful?
I ended up going with fly for now, in case i need to migrate in the future ill deal with this haha
Ok great. I assume you got everything running successfully then?
Yep, thanks for your help
@tomas.morales , back to your initial issue here: that "database url is not found" during build, that error didn't really stop you from doing anything, right? That is a spurious error actually, I just fixed it recently here https://github.com/wasp-lang/wasp/pull/2070 , but we didn't cut this release yet. But you can in any case just ignore it, it shouldn't be causing you any trouble.
As for port 8080 -> that sounds GCP specific, so I don't have an answer out of the box. But I can tell you that .env.server is only for local development -> up there, once you deploy an app, you will want to set those env vars directly up there. So, if GCP expects the server to be listening on 8080, you will have to set PORT=8080 as an env var for the deployed server via whatever mechanism GCP has for that.
Check out instructions for deploying server manually here https://wasp-lang.dev/docs/advanced/deployment/manually#2-deploying-the-api-server-backend, this is what you need.
But you will also need to undrestand here what GCP expects from you regarding that 8080 port.
Yes didnt stop me from anything
8080 cloud run default
Env vars i just like to keep control of those so i did a script that reads a local env file
Everything okay now, thx
I actually solved the issue you've had with port 8080 on cloud run. The server by default was launching on port 3001, just setting the env variable "PORT" to 8080 solved the issue.
Additionally you have to set the appropriate env variable, else the container will fail at the beginning and you'll likely get the same error, this is a bit hard to debug as the log is the same but the reason for it is different !
Nontheless I'm still having some issue, the server is up and running no problem but the frontend doesn't want to work.
As I'm on GCP, I deployed the frontend using firebase hosting but I get a blank page.
When looking at console logs I get:
I'm going to investigate, if I succeed and I have some time left I'm probably going to document it 🙂
Ok I succeeded finally ! I was deploying the wrong folder, the documentation was clear I just ignored it for some reason 😦
@TomD documentation would be awesome! If you can make a PR toward our docs ( https://github.com/wasp-lang/wasp/tree/main/web ) for instructions on deployment to GCP and/or firebase hosting, we would be happy to review it and get it merged.
If that is too much "birocracy", even opening an issue on our Github where you document your experience and important steps is already great, as we can then work from there to turn that into the page in the docs.
Hah, well maybe it is up to us, could we have made it more obvious in the docs? Maybe mentioned sooner? What were you deploying vs what you should have been deploying?
It was fine I think.
After running
npm install && REACT_APP_API_URL=<url_to_wasp_backend> npm run build
I deployed the content of .wasp/build/web-app/ and not .wasp/build/web-app/build so the frontend was obviously not what I expected
Do you know if there is a way to prefix every routes of the server ?
Firebase offer the possibility to do some automatic route rewrites but I must add a prefix for some reason . So I can link the backend and frontend URL only if the backend route looks like this (any prefix would work but /api
makes more sense).
For example :
https://my-super-exceptional-backend.run.app/auth/me --> https://my-super-exceptional-backend.run.app/api/auth/me
https://my-super-exceptional-backend.run.app/auth/google/login --> https://my-super-exceptional-backend.run.app/api/auth/google/login
etc...Actually I do think we can improve those docs a bit! It isn't emphasized enough that the contents of
web-app/build
dir should be deployed. I emphasized it now with this commit https://github.com/wasp-lang/wasp/commit/74a2977ad8ce6c0a169c499c64e044dabcd21040, it will come out with the next release.
@TomD the thing with the Firebase is tricky! We don't have a built-in way to add such prefix.
Interesting enough, we do have support to do it for the client: https://wasp-lang.dev/docs/project/client-config#basedir-string, but we don't have it for the server, as nobody needed it so far.
You could maybe do this by adding nginx inside the Dockerfile that would be rewrtiing the routes, and possibly by setting REACT_APP_API_URL for to this url with subdir included, but we haven't tried this out, it could be problematic, I am really just doing a wild guesss here.
I wonder how you even got into this situation, why does Firebase require you to do this? How is it even that you are hosting the server on Firebase, I thought you were hosting it on GCP? Can Firebase even host proper server apps, I though it is for hosting static content only?Okok, I see the use of nginx. I probably won't go that road and I'll try to find a workaround.
Actually, GCP offers "cloud run" that can run the backend. Firebase, since it is a GCP product, offers the possibility to automatically redirect traffic of the website under a specific route, to the cloud run backend.
See this documentation: https://firebase.google.com/docs/hosting/cloud-run?hl=en
This make connecting the front and back really easy when you have full access on your code usually. Still there is some workaround I guess, I just need to find it
I've done this issue to document my journey to deploy it, I've not added the automatic redirect to have the front and back under the same domain name as I'm not completly sure on how to do it yet.
https://github.com/wasp-lang/open-saas/issues/178
GitHub
deploy open-saas on Google Cloud Platform (firebase + cloud run) · ...
Hello, I've recently gone through the steps to deploy open-saas on GCP and I believe it could be useful to document it here for now. This could be added to the real documentation in the future,...
@TomD it seems a bit weird to me that you have to do this configuration with Firebase. I quickly read the docs you linked and I don't quite get the part with Firebase, it seems to me it is focused on actually using the server to render html when part of your website is accessed, which is not what we need here, we just need it to serve as an API server that is in the background and answers to web client's requests.
I also asked GPT :D, and it confirmed this idea that the step with Firebase Hosting is not needed for the server. But let's take that with a grain of salt.
My question is, couldn't you get it to work without this step with Firebase?
Gave it a look, this is awesome, thanks a lot! Especially the CI action!
Aha I see it now in the issue, you say it does work but URL for backend is ugly and not under same domain. Ok, reading more, it indeed seems the way to solve that is to go the Firebase route as you did. So it makes sense to me now. But yeah, Wasp doesn't have built-in support for serving the backend under the directory.
Also, did you indeed have any CORS issues?
Btw a nice way to do this, and I would say actually a typical/nicer solution, is to set up your cloud run service (server) to be behind the subdomain, instead of a dir. So if you client is currently on
example.com
, you can put the server on api.example.com
instead of example.com/api
. I don't think you need to do any Firebase set up for this, instead you will need to set this up on your domain provider (configure DNS records) and possibly set something up on the GCP Cloud Run side, GPT says you will need to set sometihng under "Domain mappings", which sounds reasonable.
Yeah, and this is also nice because then you don't have this weird situation of your web client being hosted at example.com but there is this one special route on it under example.com/api
that takes you to server, ... . You can ask GPT about using api.example.com
vs example.com/api
, it is quite good at explaining the pros of the api.example.com
.Thanks for the brainstorming ! You are right with everything you said, the cleanest way is what you specified with an api.example.com I think.
Unfortunately to do this in GCP you need to provision your own load balancer, then you can basically do whatever you want with it with any redirect to subdomains, url rewrite, etc..
I can do this but this cost a something like 5/10 e per month for the load balancer to be up and running, so I'm not going to go that way for now. I believe for clean production, this is definitely the way tho.
But to come back to the the idea of having a prefix route, creating a custom api route under '"/api/**" that redirects to the same path but stripping the api would work ?
When requesting https://backend-url.com/api/auth/me you would get redirected to https://backend-url.com/auth/me .
This is not ideal but this is a minimal workaround I think
I didn't with wasp, but for an old website with python fastAPI I went with this approach and I believe I did so I'm always precautious
Yeah Wasp is currently made to work accross different domains on purpose, so you shouldn't ahve CORS issues
custom api route -> how would you do that, in which tool / tech?
I think if you have some kind of redirection, like nxingx that I mentioned, in theory it should work, but I am not 100% that there might not be some edge case. I think there shouldn't actually.
I'm trying to do something like:
With a new route in the main.wasp file:
I tihnk that is a decent try, but it is hard for me to guess at the moment if it will work for all the edge cases! Doing sometihng like nxingx in Dockerfile sounds like a cleaner solution. That said, how did this go for you?
I tried for a few hours, I couldn't make it work for some edge case indeed..
So I rolled back to use the ugly URL path, if I want to go the clean way someday I'll settle for your recommandation with api.example.com
Thanks for the help, if someone ever has a problem to deploy it on GCP I'd be happy to help 🙂
Wohooo @TomD, you just became a Waspeteer level 2!
That sounds like the best solution!
The issue you opened already helps a lot: if you learn something more feel free to add more info there!
Tom, you still around 🤣 ?
No clue why, but I have followed your steps point for point and still can't get past:
The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable within the allocated timeout.
when gcloud run deploy backend
Did you set the
PORT
variable in the GCP context somehow? I have to admit I haven't tried it, but just a heads up - setting vars in .env.server
is for local development only. You have to set the env vars somehow in GCP - it differs from provider to provider, but it's usually some dashboard or CLI.Thanks Miho,
I've got the env vars figured out, verified in console.cloud.google.com that they're properly being set in the cloud run dash, including the port but the issues I'm having seem to be related to connecting to the database & container calling exit.
here's my deploy.sh which I made executable using chmod - it runs each command in sequence (wasp build, deploy to firebase, build, tag and push the docker image, gcloud deploy)
It passes the specified env vars from .env.sever when executed (also validated in GCP secrets that it is successfully passing these)
I’m using cloud SQL PostgreSQLin google cloud for my database.
I’ve verified I’m setting the database url and configuring the username and password correctly, but still no luck.
I tried also connecting through Unix sockets but can't seem to get this to work.. been 3 days of testing and failing at the cloud deploy stage
https://cloud.google.com/sql/docs/postgres/connect-run#node.js
Do you have access to the server logs?
I see you are using the
--port 8080
option for gcloud run deploy
but I don't see you setting the server env var called PORT
(by default the server listens on port 3001
).Yes! I had to take a break for a couple of days. This was getting me seriously frustrated.
Nothing but issue after issue. The file I sent here was hot garbable & riddled with issues, I cleaned this up and made sure everything is set properly. now and I switched to using gcloud builds submit --config=cloudbuild.yaml .
For the port I am using a Dockerfile in my /app directory with the following:
ENV PORT=8080
EXPOSE 8080
ENTRYPOINT ["npm", "run", "start-production"]
Then "wasp build" and verify that the Dockerfile in the .wasp/build directory has correctly appended my directions after line 67.
GCP doesn't allow me to set the env var PORT it is "reserved", but in GCP I can see my container port is set to 8080
For some reason I get Error: P1010: User user was denied access on the database
I whitelisted the IPs that google requires in aws console, verified that I can access the database from my local machine (By whitelisting my personal IP address)
But ultimately the error code I get is the "The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable within the allocated timeout."
with respect to logs yes absolutely I have the log files, I'm going to try to redeploy and get a fresh set
I'm not sure this is specific to Wasp anymore 🤷♂️ if you are building the app with
wasp build
and using the Dockerfile
we provide (or one that you modified a bit) and you set the env variables (your server doesn't crash, it days "Listening on port XXXX) that should be good enough from my point of view. And you did all that.
You are using a database on AWS and hosting the backend on GCP with Cloud Run? Have you tried Googling / using ChatGPT for that specific issue?No it wasn't a wasp issue, you're absolutely right. It was a few different issues related to docker build args & how my environment variables were being set, and the database issue I had was being caused by a VPC connector in GCP. Good news is, I finally was able to get the server deployed.
Going to add more info than necessary in case it helps someone in the future.
Regarding the docker build, I was using:
docker build --no-cache --platform linux/amd64 -t backend-image .
and I kept getting the following error:
Dockerfile:40
--------------------
38 | RUN npm install && cd .wasp/build/server && npm install
39 | COPY db/schema.prisma .wasp/build/db/
40 | >>> RUN cd .wasp/build/server && npx prisma generate --schema='../db/schema.prisma'
41 | # Building the server should come after Prisma generation.
42 | RUN cd .wasp/build/server && npm run bundle
--------------------
ERROR: failed to solve: process "/bin/sh -c cd .wasp/build/server && npx prisma generate --schema='../db/schema.prisma'" did not complete successfully: exit code: 1
I tried many different configurations of deployment methods and spent a couple of days tinkering with Gcloud builds submit to try to eliminate my environment from the docker build process to no avail.
In the end I had to use this command locally:
PRISMA_CLI_BINARY_TARGETS=linux-musl \
PRISMA_CLIENT_ENGINE_TYPE=library \
docker build --no-cache --platform linux/amd64 \
--build-arg PRISMA_CLI_BINARY_TARGETS=linux-musl \
--build-arg PRISMA_CLIENT_ENGINE_TYPE=library \
--build-arg NODE_ENV=production \
-t backend-image .
Then eliminated the Google VPC connector since it wasn't playing nice with my RDS DB despite whitelisting the Google IPs.
And finally I stopped using Google secret manager for my env variables.. and success!
Bad news is.
Now I'm getting some CORS issues, I think it might be a configuration issue. Wondering if you have any insights you can provide on how to fix this?
Access to XMLHttpRequest at 'https://backend-xxxxxxx.us-central1.run.app/operations/get-tables' from origin 'https://xxxxxx-xxxx.web.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Wohooo @G35x, you just became a Waspeteer level 2!