oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
73.26k stars 2.69k forks source link

How do you deploy Bun? #211

Open swyxio opened 2 years ago

swyxio commented 2 years ago

Hey Jarred, awesome project!

I'm a bit confused about the deployment model. In your docs you mention:

To deploy to production with bun, you’ll want to get the code from the .bun file and stick that somewhere your web server can find it (or if you’re using Vercel or a Rails app, in a public folder).

However I'm not confident that Vercel can run something like this? because i tried to build my Next.js project with /node_modules.bun > node_modules.js and run it in Node and it didn't work - probably to no surprise. So I'm guessing this usage is purely for clientside bundles?

Any recommendations how to deploy fullstack/serverside Bun projects?

swyxio commented 2 years ago

I have tried to deploy Bun on Fly.io and on Railway.app. Recording my attempts for others also trying: https://www.youtube.com/watch?v=VFKQvdWwuxw

Here is the dockerfile I made for Railway (i made a simple http.js file first):

FROM ubuntu:latest
FROM jarredsumner/bun:edge

CMD bun run http.js

I then ran railway init and railway up to deploy it. The build worked, but not the run:

Link: http://localhost:3000/
error: Failed to initialize network thread: SystemOutdated.
HTTP requests will not work. Please file an issue and run strace().
[1.00ms] bun!! v0.0.82

image

Railway doesn't offer a terminal/shell, so i tried to run strace inside of the dockerfile itself and got nowhere.

I suspect the error might be related to https://github.com/Jarred-Sumner/bun/issues/164 since similar error but I can't be sure. I have no way to set the ulimit here if that is the issue.

moderation commented 2 years ago

The docker images at https://hub.docker.com/r/jarredsumner/bun/tags haven't been updated for quite a while. You are pulling 0.0.82 which is pretty old considering the big changes with each release. I'm sure the project will get around to updating the Docker images shortly. In the meantime could you build an image directly using the latest release binary from https://github.com/Jarred-Sumner/bun/releases/tag/bun-v0.1.1 ?

itsMapleLeaf commented 2 years ago

I just tried deploying to Railway with the install script, using this Dockerfile:

FROM ubuntu:latest

WORKDIR /opt/app

ENV BUN_INSTALL="/root/.bun"

RUN apt-get update
RUN apt-get install curl unzip -y
RUN curl -fsSL https://bun.sh/install | bash
RUN ln -s $BUN_INSTALL/bin/bun /usr/local/bin/bun

COPY . ./

RUN bun install

CMD ["bun", "server.ts"]

It works locally! But in Railway, I get this error:

Step 9/10 : RUN bun install

--> Running in 0f7a37f88736

error: Failed to initialize network thread: SystemResources.
HTTP requests will not work. Please file an issue and run strace().
The command '/bin/sh -c bun install' returned a non-zero code: 1

Here's the repo: https://github.com/itsMapleLeaf/hi-bun

I'm not sure what run strace() means :sweat_smile:

aulisius commented 2 years ago

Hey everyone, I got a base bun server up and running at https://wooden-arch-production.up.railway.app/

Using this Dockerfile

FROM ubuntu:22.04

WORKDIR /bun

RUN apt-get update
RUN apt-get install curl unzip -y
RUN curl --fail --location --progress-bar --output "/bun/bun.zip" "https://github.com/Jarred-Sumner/bun/releases/download/bun-v0.1.2/bun-linux-x64.zip"
RUN unzip -d /bun -q -o "/bun/bun.zip"
RUN mv /bun/bun-linux-x64/bun /usr/local/bin/bun
RUN chmod 777 /usr/local/bin/bun

WORKDIR /app
RUN addgroup --gid 101 --system appuser && adduser --uid 101 --system appuser
RUN chown -R 101:101 /app && chmod -R g+w /app
USER appuser
COPY . ./

CMD bun run server.js

with this app code

// server.js
export default {
  port: Number(process.env.PORT ?? 3000),
  fetch(request) {
    return new Response("hello world")
  }
}

I did face some difficulties with an alpine image probably because the musl build is still not complete.

swyxio commented 2 years ago

@mrkurt from Fly also offered up a deployable Bun setup https://github.com/fly-apps/bun

JakeCooper commented 2 years ago

@mrkurt from Fly also offered up a deployable Bun setup https://github.com/fly-apps/bun

I think @aulisius' dockerfile should also work fine on Fly. We can add support to Nixpacks if there's a discernable guarantee that a repo uses bun

Detection of a .bun file is probably the best bet right @Jarred-Sumner?

EDIT: h/t aulisius. Beat me to getting it working on our own platform <3

mrkurt commented 2 years ago

Yeah I just cribbed some of the @aulisius Dockerfile anyway. It was better than my first take. :)

nadilas commented 2 years ago

Yeah I just cribbed some of the @aulisius Dockerfile anyway. It was better than my first take. :)

Did that work for you? I run into

######################################################################## 100.0%
#11 2.183 qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory
philosofonusus commented 2 years ago

Yeah I just cribbed some of the @aulisius Dockerfile anyway. It was better than my first take. :)

Did that work for you? I run into

######################################################################## 100.0%
#11 2.183 qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory

I get the same issue, we need a container image for bun!

aulisius commented 2 years ago

@philosofonusus are you seeing this in your local? or on some cloud platform?

If local, can you mention details about your OS

adi-g15 commented 2 years ago

error: Failed to initialize network thread: SystemResources.

I also got this error:

Fetching package.json... error: Failed to initialize network thread: SystemResources.
HTTP requests will not work. Please file an issue and run strace().

I don't know much about using strace. Though the problem occurred when in one tab, bun create next napp was in process, and in other tab, bun create react rapp, the create react failed with above issue. I have failed to reproduce this issue since then, it was in a VM.

PS. Should this be a different issue ? I found this issue mentioning the error hence added it here.

syeo66 commented 2 years ago

However I'm not confident that Vercel can run something like this? because i tried to build my Next.js project with /node_modules.bun > node_modules.js and run it in Node and it didn't work - probably to no surprise. So I'm guessing this usage is purely for clientside bundles?

Also for client side projects it is not really clear. To me it seems I'd have to deploy the public folder seperately, 'unpack' de bun bundle, and then rewrite the script references in the public folder. But that's just me guessing. I'd love to see a little bit more about that in the docs.

baiirun commented 2 years ago

Has anybody been able to run bun in an edge or serverless environment yet, e.g., Cloudflare Workers? Does bun support this yet or do we have to run the full stateful HTTP server implementation for now?

I'm not too interested in running distributed full containers of stateful servers via Fly.

Milo123459 commented 2 years ago

We can add support to Nixpacks if there's a discernable guarantee that a repo uses bun

I've opened a PR to nixpacks adding support for bun: https://github.com/railwayapp/nixpacks/pull/290

Wulfre commented 2 years ago

@philosofonusus and anyone else who may need, I ran into the same issue with a few dockerfiles not working, so I wrote one that seems to be working well for me and a few others who helped me test in the discord.

Please note that the versions are supplied by the args at the top of the file, so when a new version is released, you'll need to update the arg if you want to use it.

### GLOBALS ###
ARG BUN_VERSION='0.1.2'
ARG GLIBC_VERSION='2.34-r0'

### GET ###
FROM alpine:latest as get

# prepare environment
WORKDIR /tmp
RUN apk --update add curl unzip

# get bun
ARG BUN_VERSION
RUN curl -LO https://github.com/oven-sh/bun/releases/download/bun-v${BUN_VERSION}/bun-linux-x64.zip && \
    unzip bun-linux-x64.zip

# get glibc
ARG GLIBC_VERSION
RUN curl -LO https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
    curl -LO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-${GLIBC_VERSION}.apk

### IMAGE ###
FROM alpine:latest

# prepare bun
COPY --from=get /tmp/bun-linux-x64/bun /usr/local/bin

# prepare glibc
ARG GLIBC_VERSION
COPY --from=get /tmp/sgerrand.rsa.pub /etc/apk/keys
COPY --from=get /tmp/glibc-${GLIBC_VERSION}.apk /tmp

# install and clean up
RUN apk --no-cache add /tmp/glibc-${GLIBC_VERSION}.apk && \
    rm /tmp/*
swyxio commented 2 years ago

@wulfre sorry if this is a noob question can i just ask about the strategy here - why is it recommended to download bun releases off github rather than use the docker image? like is publishing docker images so expensive/flaky that you dont want use to do that for some reason? genuine question.

also while we're at it, how does glibc interact with bun? if i were trying to level up as an engineer, how could i have figured this out on my own without asking you? is there something i should read?

Wulfre commented 2 years ago

@sw-yx

I actually contributed a slightly improved version of this dockerfile to the repo and automated the publication to dockerhub. Starting next release, there will be automatic updates along with all of the version tags you might be used to on other images. It's located here if you wanted to take a look. It was probably suggested to download the bun releases directly because Jarred was -- and to his credit still is -- doing almost everything alone, so if he didn't find time manually update the image on dockerhub, users would be out-of-date for a good while longer than everyone else.

To address your second question as best as I can: glibc is the implementation of c that most linux distros use, and that most programs as targeted towards / built with for linux -- bun included. Alpine is a very small distro, which is great for docker, but it's also based off of a different implementation of c called musl, so any glibc-based libraries that are linked when compiling the program will not be directly available on a musl-based system. The package that I am including alongside bun allows you to run glibc targeted builds on a musl system. That might have not been the most accurately-worded explanation, but I hope it helps you understand a bit better. You might be able to learn more if you read some of the documents on the musl welsite.

wobsoriano commented 2 years ago

@Wulfre I tried your Dockerfile on a M1 Pro machine and it hangs on RUN bun install command when building image - https://gist.github.com/wobsoriano/ec3b0cfb392964f3ed4251df22fe2d10

 => [stage-1  9/10] RUN bun install                                                                                                   5.9s
 => => # qemu: uncaught target signal 4 (Illegal instruction) - core dumped

Probably the same issue with @philosofonusus

Relevant line from Docker's M1 page:

However, attempts to run Intel-based containers on Apple silicon machines under emulation can crash as qemu sometimes fails to run the container. In addition, filesystem change notification APIs (inotify) do not work under qemu emulation. Even when the containers do run correctly under emulation, they will be slower and use more memory than the native equivalent.

swyxio commented 2 years ago

@Wulfre thats a really good explanation thank you... they certainly didnt teach any of this stuff in school lol. i just see pple copying black magic phrases without explanation and figured i would try asking... and you delivered!

niteshbalusu11 commented 2 years ago

Hello! Anyone was able to run an app with bun on a node buster-slim image?

dinojs commented 2 years ago

@wobsoriano Were you able to get it installed?