Closed tcbyrd closed 6 months ago
Awesome! Thank you for posting this!
I definitely want to add a "Deploying" section to the guide; it's been my intention since day one, but so much else has taken precedence. I'm hoping to open source the guide soon, and I'd love it if you could contribute these steps to the soon-to-exist "Deploying" section of the guide!
P.S: I really enjoyed reading through your adventures. π
Does this still work?
It seems to be ignoring ROCKET_PORT
for me, so I'm having trouble binding to the port heroku wants me to use.
Since this issue is only 18 hours old, I'll say I'm using rocket 0.1.6
@RustyRails Looking at this issue, the ROCKET_PARAM feature shipped in 0.2.
I'm running into a different issue. I successfully get the port to show up but encounter this error:
thread 'main' panicked at 'Permission denied (os error 13)', /app/tmp/cache/cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.1.6/src/rocket.rs:474
Full backtrace
Starting process with command `ROCKET_PORT="30861" ROCKET_ENV=prod ./target/release/app`
Process exited with status 101
Error: Failed to start server.
1: 0x7f8d4dff793c - std::sys::imp::backtrace::tracing::imp::write::hf7294f5e24536b4a
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
2: 0x7f8d4dffae2e - std::panicking::default_hook::{{closure}}::h9a07d0b00c43fbee
thread 'main' panicked at 'Permission denied (os error 13)', /app/tmp/cache/cargo/registry/src/github.com-1ecc6299db9ec823/rocket-0.1.6/src/rocket.rs:474
stack backtrace:
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:367
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:351
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:555
6: 0x7f8d4dffb089 - std::panicking::begin_panic_fmt::h7bf5635a07d66272
3: 0x7f8d4dffaa34 - std::panicking::default_hook::hf25feff2d08bf39b
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:501
7: 0x7f8d4dfa22f8 - rocket::rocket::Rocket::launch::hd7f438e43cdd8762
4: 0x7f8d4dffb2cb - std::panicking::rust_panic_with_hook::h4cb8c6fbb8386ccf
5: 0x7f8d4dffb164 - std::panicking::begin_panic::heb3517ba798e470b
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:517
10: 0x7f8d4dffba36 - std::rt::lang_start::h0637c2e100ff36fc
8: 0x7f8d4df6f01b - app::main::h9e9dbfcfb36fe94a
Edit: Looks like that's here which points to the server not being able to launch.
I definitely want to add a "Deploying" section to the guide
Yes! This is exactly what I wanted. I kept looking at your docs thinking a natural next step would be a few quick examples of how to deploy it on a server or container.
I'm running into a different issue. I successfully get the port to show up but encounter this error:
Are you sure it's not just ignoring it? That's the error you'll get if it tries to bind to port 80 (e.g. it's not using ROCKET_PORT). As per @tcbyrd's comment it seems you need to use master to have that feature
Looks like that was my issue. Thanks for the quick help π
I've changed my dependencies to:
[dependencies]
rocket = { git = "https://github.com/SergioBenitez/Rocket.git" }
rocket_codegen = "*"
and it's now working
For reference (and because I like spelunking through code), here is the new function that was added: https://github.com/SergioBenitez/Rocket/blob/master/lib/src/config/mod.rs#L311-L342
That should be in the /lib/src/config
directory of your project if you have the right version.
Updated the OP to make it more clear this uses a relatively :new: feature.
this is my repo https://github.com/mozillaperu/rustpe I have an error
remote: error[E0004]: non-exhaustive patterns: GlobalAsm(_)
not covered
remote: --> /app/tmp/cache/cargo/registry/src/github.com-1ecc6299db9ec823/rocketcodegen-0.2.4/src/lints/utils.rs:157:15
remote: |
remote: 157 | match *self {
remote: | ^^^^^ pattern `GlobalAsm()not covered remote: remote: error: aborting due to previous error remote: remote: error: Could not compile
rocket_codegen`.
remote: Build failed, waiting for other jobs to finish...
@marti1125 This was caused by a change in the latest nightly. Since the nightly was released later than usual, my cron job missed it. In any case, 0.2.5 was just published; using 0.2.5 will remedy the issue you're seeing.
Thanks a lot!! https://vast-fjord-26312.herokuapp.com/ π π
This helped out a lot.
Any chance you need help writing up documentation for the deployment section @SergioBenitez?
@hiimtaylorjones I'd love the help! I imagine that such a section would be composed of at least two subsections:
That will likely cover 75%+ of use cases, is my guess. Maybe there's a third, popular deployment strategy? In any case, I'd be more than happy to review an addition of such a section to the guide. As I've previously stated, it's something I've wanted for a while.
I am happy to write one up about building a Rocket app into a docker container. If it is compiled with musl-libc it can be placed in a "scratch" image which is less than a megabyte so a simple Rocket app wrapped in a container is about 5mb
@corbinu Here is an example of building a statically compiled Rocket app docker image:
https://github.com/fede1024/kafka-view/blob/ff4453b2230a41002e770cd5862dff8cf802acc6/Dockerfile
The resulting image is only 7MB
@messense Cool thanks had been waiting on rustup to support musl
Thanks @tcbyrd, nice explanation! I was using a Dockerfile for deploying Rocket on Hasura cloud provider and having both ENV ROCKET_ADDRESS=0.0.0.0
, ENV ROCKET_PORT=8080
worked for me. π
Yup, default localhost
does not work on any docker file images I tried, and must always be set to 0.0.0.0
it would seem (trust me, I tried several). I did discover how to build rust-musl files along the way though, and my docker image size for a simple API has gone from 1.8Gb to 15.1Mb!!!!!!! Insane, go musl!
Zeit also supports deploying Rust-Rocket applications in their new beta. ( https://zeit.co/blog/serverless-docker )
An example how to do it can be found here: https://github.com/zeit/now-examples/tree/master/rust-rocket
If a deploy section is available, I'm happy to add a proper example for deploying to Zeit.
I have tried deploying a Rust web app in Now and failed. My deployment just died after 15 mins. My app takes longer to compile from scratch. I don't know if they have a way to do caching between deployments, but I couldn't get the first deployment to succeed.
Maybe Heroku does this better as they have CACHE_DIR
. I will like to hear how long it takes for you.
Because how long the Rust compiler takes for non-trivial apps, it doesn't seem like deploying with Now (or maybe Heroku) is a great way. It would be nicer to document a way that works by creating a binary locally or in CI and deploying that.
@sporto
Maybe Heroku does this better as they have
CACHE_DIR
. I will like to hear how long it takes for you.Because how long the Rust compiler takes for non-trivial apps, it doesn't seem like deploying with Now (or maybe Heroku) is a great way. It would be nicer to document a way that works by creating a binary locally or in CI and deploying that.
The rust build pack makes use of CACHE_DIR to allow fast deploy.
Hi everyone, we've just launched native Rust support for Render, a new cloud provider. We've also created a couple of examples using Rocket:
https://render.com/docs/deploy-rocket-rust https://render.com/docs/deploy-rust-graphql
With Render you can:
Is anyone actively working on a Deployment Guide? If not, I'd be happy to contribute one.
Assuming no one is working on it, I'll submit a deployment guide for Render, and hopefully others can add guides for other providers as well.
@anurag If you can do this, I can add one native kubernetes if anyone is interested. It's a very nice idea, and I wish it existed when I started.
Working on it now.
On Thu, Jun 13, 2019 at 11:23 AM, Colin MacRae < notifications@github.com > wrote:
@ anurag ( https://github.com/anurag ) If you can do this, I can add one native kubernetes if anyone is interested. It's a very nice idea, and I wish it existed when I started.
β You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub ( https://github.com/SergioBenitez/Rocket/issues/171?email_source=notifications&email_token=AAAOUAJ3KKJORZMHCOZR3BDP2KGDHA5CNFSM4C65GVVKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXUTYNY#issuecomment-501824567 ) , or mute the thread ( https://github.com/notifications/unsubscribe-auth/AAAOUAJYUNKZRE6TY6H463DP2KGDHANCNFSM4C65GVVA ).
@SergioBenitez thoughts on the deployment guide PR?
Happy to edit as needed.
Bumping: we're already seeing Rocket users using the links above to deploy Rocket on Render. It would be helpful to get this as an option in the official guide.
I have tried many things for deploying a Rocket app, including Heroku. So far Render has been the only service that provided me with a good experience. +1, will use again.
+1 for need of a deployment guide. Definitely needs a section on the Guide.
I rolled my own service with systemd last night, and just do a simple scp of the binary and the Rocket.toml to the production service. Working really nicely.
The systemd service /etc/systemd/system/FOO.service
looks something like this:
[Unit]
Description=example.com internal contact page service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=5
User=FOOservice
WorkingDirectory=/opt/FOO-contact
ExecStart=/opt/FOO-contact/FOO
[Install]
WantedBy=multi-user.target
Then it's a simple
sudo systemctl start FOO
sudo journalctl -f -u FOO
to check on if it's working
sudo systemctl enable FOO
for persistence after reboot
My rocket.toml
is super simple:
[production]
address = "localhost"
port = 50088
And I then use nginx to reverse proxy to port 50088 for the corresponding url and children of that url. Nginx is set up with lets encrypt so it is handling encryption so I'm not bothering with rocket's TLS or SASL. Assuming your nginx is already otherwise working, all I needed was to add this block to my nginx config:
location /contact {
proxy_pass http://localhost:50088;
}
and then run sudo systemctl restart nginx
.
@jrmiller82 that example is excellent and fits perfectly into one of the two aims @SergioBenitez listed earlier:
- Deploying on a VPS (using NGINX as a reverse proxy)
I almost started a deployment guide a while back, but I have been focusing on #1065 now instead.
Please feel free to use that in any future documentation. I think the only thing I left out was making a system user account with shell set to /bin/false.
Thank you everyone, I have read all of the comments. I have problem when deploying Rocket to Heroku. I have 3 files: 1 binary and 2 library (the 2 library use in binary file) What should I do to host it? Do I need to upload the 2 library first then main lastly. Is it the correct way to do it?
Is it the correct way to do it?
This depends very much on what the libraries are and how much control Heroku gives you over the environment. Usually it's easiest to compile on the same operating system you are deploying to. If the libraries are common (like openssl
) Heroku probably already provides them. If Heroku does not have them, then you will need to install or bundle them with your application. I do not use Heroku, but it looks like you can create and deploy a docker container from one of heroku's base images - that may be an option here.
I got error
2020-06-13T08:27:14.282528+00:00 heroku[web.1]: State changed from crashed to starting
2020-06-13T08:27:15.487135+00:00 heroku[web.1]: Starting process with command ROCKET_PORT=10975 ROCKET_ENV=prod ./target/release/main
2020-06-13T08:27:18.610270+00:00 app[web.1]: bash: ./target/release/main: No such file or directory
2020-06-13T08:27:18.673628+00:00 heroku[web.1]: Process exited with status 127
2020-06-13T08:27:18.761046+00:00 heroku[web.1]: State changed from starting to crashed
EDIT
Fixed, renamed _web: ROCKET_PORT=$PORT ROCKETENV=prod ./target/release/main to _web: ROCKET_PORT=$PORT ROCKET_ENV=prod ./target/release/sbadminrust
Thanks for this. I added the PORT to project but I forgot to add the ROCKET_ADDRESS This is my Procfile working:
web: ROCKET_ADDRESS=0.0.0.0 ROCKET_PORT=$PORT ROCKET_ENV=prod ./target/release/<myAppName>
First off I'd like to just say I'm really enjoying this framework and big π to @SergioBenitez for the β¨ work and great documentation and examples so far. I'm just getting started with Rust and this has been a great introduction to the language for me.
I'm not sure what other platforms people are using to deploy Rust web servers, but since most of my experience on the back-end has been with NodeJS and Ruby, I typically deploy to Heroku so I can take advantage of their free dynos while getting built-in Git/GitHub integrations. Unfortunately, Heroku doesn't have an officially supported buildpack or any documentation on how to work with Rust, so I was venturing into uncharted territory. I was originally going to open an Issue here to see if anybody had tips, but I decided to see if I could piece it together since the documentation seemed already pretty thorough.
A big part of getting this working is thanks to an actively maintained custom Heroku buildpack for Rust that supports Cargo here: https://github.com/emk/heroku-buildpack-rust.
TL;DR - Using the steps outlined in that :point_up: repo and a π recently shipped feature to override Rocket's config parameters via environment variables, here is what ultimately worked for me:
Slightly longer explanation
Outlined below are the some of the problems I ran into and how I ultimately ended up getting it all working properly (I Think :wink:). I know an Issue probably isn't the best place for this kind of stuff long term, so feel free to use any of this to enhance existing documentation where it makes sense.
Config variables
While it made complete since that I could modify the port manually and have independent configurations for different environments, because Heroku dynamically allocates the port every time a dyno (container) is executed, this can't be defined in a
.toml
file ahead of time.It wasn't until I found this issue that I realized I could use
CONFIG_PORT
to override the config variables on the command line. This allows you to doCONFIG_PORT=$PORT
on Heroku to dynamically define the port at launch time.Which worked great! To get the right port, at least. But I still ran into problems getting the server started. In NodeJS (what I'm most familiar with), once you get the port right, it works. But Heroku was still complaining that the process wasn't binding to $PORT:
In some cases in Node, an application needs to be aware of the URL that gets created by Heroku, so I thought I would pass that in as the address. This made sense to me because the default was "localhost", but doing it this way, once Heroku finished with the deploy, I would get an "internal application error" when I tried to browse to that URL. Looking at the logs, this was caused by a panic from Hyper when trying to create the server at that address:
Looking at the function that caused the panic, basically it just means I was trying to bind to an invalid address.
Ok so that didn't work, but in tracing down that error, I came across the defaults that get used by Rocket in different stages and noticed this: https://github.com/SergioBenitez/Rocket/blob/master/lib/src/config/config.rs#L157
Of course! Bind the server to 0.0.0.0!
It works!!! :boom:π:boom: π :boom:
This also made me realize that if I configured the Heroku Procfile command to launch in the production configuration, it would default to 0.0.0.0, meaning I could leave out the address config variable and only define the port:
Conclusion
This is ultimately a very simple solution, which I'm sure speaks to my inexperience with Rust/Hyper and the incredible engineering going on under the hood. So far though, this server is blazingly fast and handles a lot more concurrent connections than a similar NodeJS server I was using on Heroku. Great work again and let me know if anything isn't clear. Cheers! π