R
Railway16mo ago
amorfati

Can I run `arm64` images in railway?

currently image breaks when using arm64
451 Replies
Percy
Percy16mo ago
Project ID: N/A
Brody
Brody16mo ago
railway is amd64 only
amorfati
amorfatiOP16mo ago
got it thanks. ipfs which is what I'm using offers amd64 but for some reason it doesn't work. Only arm64 works for me any plans for arm support?
Brody
Brody16mo ago
it's unlikely that railway will support arm you may want to find out whats going wrong with the amd64 version
amorfati
amorfatiOP16mo ago
why won't railway support arm? I'm very curious. I don't use it all the time (arm) but I would think it's a win to support it
Brody
Brody16mo ago
I'll answer that with a question, why should railway support arm?
amorfati
amorfatiOP16mo ago
plenty of reasons one of which is more customers. Apple Silicon machines are extremely common now and arm is much more prevalent now arm64 is more performant than amd64 (at some cost) i think
Brody
Brody16mo ago
would it be neet? absolutely, is there a great benefit over amd64 from a business perspective, not really
amorfati
amorfatiOP16mo ago
there is for example myself. You would gain me as a permanent customer
Brody
Brody16mo ago
I mean I'm sure there's actually nothing wrong with the ipfs amd64 image
amorfati
amorfatiOP16mo ago
you're right. I haven't yet ran it in railway. Been having problems with it locally in my arm64 machine so deployment platform requires amd64 local machine requires arm64
Brody
Brody16mo ago
wait would you even be able to run ipfs on railway? what protocol does that use
angelo
angelo16mo ago
Instances that we have would need to be ARM based which atm, we don't have. Open to it in the future but we are a long way away from that. (Unless we start wrapping Gravitron instances.)
Brody
Brody16mo ago
he can read my mind, I was just about to silent ping for your 2 cents
angelo
angelo16mo ago
Angelo is just a Brody-alt
Brody
Brody16mo ago
I've been caught but yeah from a quick google search, ipfs does not communicate the data over http, therfore it would not work on railway for public access
angelo
angelo16mo ago
Would need to run Ngrok in front of it (assuming it supports IPFS)
amorfati
amorfatiOP16mo ago
I'm running ipfs on railway right now got it working amd64
Brody
Brody16mo ago
what proxy are you using
amorfati
amorfatiOP16mo ago
i'm using ipfs/kubo implementation bifrost-gateway single index.ts as proxy
amorfati
amorfatiOP16mo ago
GitHub
GitHub - o-az/eyepfs: Hosted IPFS Gateway & HTTP Proxy
Hosted IPFS Gateway & HTTP Proxy. Contribute to o-az/eyepfs development by creating an account on GitHub.
angelo
angelo16mo ago
hell ya
amorfati
amorfatiOP16mo ago
railway too good
Brody
Brody16mo ago
awsome!
angelo
angelo16mo ago
Make this into a Template, you won't
Brody
Brody16mo ago
beat me to it
amorfati
amorfatiOP16mo ago
on it right now! gimme a min
Brody
Brody16mo ago
he just won't stop predicting my moves
amorfati
amorfatiOP16mo ago
lmao
amorfati
amorfatiOP16mo ago
GitHub
GitHub - o-az/eyepfs: Hosted IPFS Gateway & HTTP Proxy
Hosted IPFS Gateway & HTTP Proxy. Contribute to o-az/eyepfs development by creating an account on GitHub.
Brody
Brody16mo ago
wheres the deploy to railway button
amorfati
amorfatiOP16mo ago
oh you mean railway template
Brody
Brody16mo ago
yeah that's what we mean
amorfati
amorfatiOP16mo ago
FRscuffed as well
Brody
Brody16mo ago
definitely!
amorfati
amorfatiOP16mo ago
i'm gonna tweet it once i add the button. Can the official railway on twitter rt me <a:wave_bear:1013524488652079254>
angelo
angelo16mo ago
above my paygrade but its likely David will
amorfati
amorfatiOP16mo ago
should I name it just ipfs or same as repo name?
angelo
angelo16mo ago
I have been banned from tweeting after I said "Go is a employment program for distinguished engineers at Google."
amorfati
amorfatiOP16mo ago
ok so the way I started this is the same way I start all my railway projects: create project create empty service deploy with:
RAILWAY_DOCKERFILE_PATH='Dockerfile' railway up --service 'api' --detach --environment 'production'
RAILWAY_DOCKERFILE_PATH='Dockerfile' railway up --service 'api' --detach --environment 'production'
idk how to translate this into the template
amorfati
amorfatiOP16mo ago
Railway
Deploy eyepfs on Railway
Railway is an infrastructure platform where you can provision infrastructure, develop with that infrastructure locally, and then deploy to the cloud.
amorfati
amorfatiOP16mo ago
Brody
Brody16mo ago
what port does the proxy listen on damn right
amorfati
amorfatiOP16mo ago
you going to add arm64 support now? 3031
Brody
Brody16mo ago
does gcp have arm?
amorfati
amorfatiOP16mo ago
don't know don't care don't wanna know
Brody
Brody16mo ago
that's odd since you want railway to have arm, railway runs on gcp
amorfati
amorfatiOP16mo ago
will quit before i use gcp directly again
Brody
Brody16mo ago
if gcp doesn't have it, then railway can't have it
amorfati
amorfatiOP16mo ago
yeah and railway hates gcp don't you? i was hoping you'd be leaving them soon thanks for abstracting hell away 😹
angelo
angelo16mo ago
We are working on racking our own stuff, POPing in GCP for regions and co-lo
Brody
Brody16mo ago
then you are missing the PORT variable in your template that tells railway your app listens on 3031, can you deploy your template and work out all the kinks before publishing it?
amorfati
amorfatiOP16mo ago
it's in Dockerfile as ENV. That should works? i don't have the variable in my personal deployment Just added it
Brody
Brody16mo ago
your index.ts listens on PORT
amorfati
amorfatiOP16mo ago
oh good catch
Brody
Brody16mo ago
so no need to add a PORT to the template but still deploy your template to make sure it works
amorfati
amorfatiOP16mo ago
i do have it locally in .env. Does railway grab envs from there when running deploy command?
Brody
Brody16mo ago
no they don't .env is only loaded if you copy it into the raw editor or use something like dotenv
amorfati
amorfatiOP16mo ago
i'm slightly confused by the naming service in templates. Is that the same service in a project? or does it refer to project in templates?
Brody
Brody16mo ago
the project name is the template name when deployed, the service name is the service name
amorfati
amorfatiOP16mo ago
let's see
amorfati
amorfatiOP16mo ago
i can very likely cut the image size by 60% later
Brody
Brody16mo ago
your dockerfile is a little odd
amorfati
amorfatiOP16mo ago
say more
Brody
Brody16mo ago
words are hard you are downloading and installing bun yourself, why not do this in a multistage build with bun's official docker image being one of the stages
amorfati
amorfatiOP16mo ago
i had that originally then i needed go then i just wanted to get it working asap. You're right though multi stage build is the way to go
Brody
Brody16mo ago
also, alpine > bullseye
amorfati
amorfatiOP16mo ago
this can have multiple improvements. My main goal is to reduce image size' i seldom use go tbh so idk what's all out there has alpine img?
Brody
Brody16mo ago
yes they have an alpine image
amorfati
amorfatiOP16mo ago
cool so golang is just like any other language. Why do people hate it?
Brody
Brody16mo ago
multistage build, with the last stage being maybe just the default alpine image with only the stuff you need to run copied into it idk, I love it, it's my main language I use
amorfati
amorfatiOP16mo ago
i was thinking of having last stage be a distroless image https://github.com/GoogleContainerTools/distroless grab the minimum necessary executables needed to run stuff and copy them over to the stage too much work. I'll go for alpine 👍
Brody
Brody16mo ago
I use distroless in all my go Dockerfiles, but yeah I thought that would be way overkill for what you are doing given the fact that the base alpine image is under 6mb there's no shell in distroless and it looks like you will need a shell, alpine provides the sh shell instead of bash
amorfati
amorfatiOP16mo ago
also the Makefile is not necessary. I left it as an option for people but maybe it causes more confusion
Brody
Brody16mo ago
best to eliminate all points of possible confusion
amorfati
amorfatiOP16mo ago
originally i ran kubo as a docker container and bifrost also as a container but had to switch to this cause no docker compose in railway
Brody
Brody16mo ago
but there is internal networking
amorfati
amorfatiOP16mo ago
sounds too technical
Brody
Brody16mo ago
it would sound less technical if I could spell it correctly
amorfati
amorfatiOP16mo ago
tell me more about it. If I have a simple project where I'm running 2 docker containers, not using compose let's say, how would i use internal networking?
Brody
Brody16mo ago
you could run ipfs separately, then your proxy service on another service, then proxy requests to the ipfs service through the internal network
amorfati
amorfatiOP16mo ago
amorfati
amorfatiOP16mo ago
oh i see, split them into 3 services
Brody
Brody16mo ago
3?
amorfati
amorfatiOP16mo ago
ipfs kubo bifrost-gateway bun proxy
Brody
Brody16mo ago
ah yeah forgot about the gateway
amorfati
amorfatiOP16mo ago
thanks for the info
amorfati
amorfatiOP16mo ago
alright I think it's good as it is right now. Next do the dockerfile improvements next week so i got the template published: https://railway.app/template/PhPjgz source code: https://github.com/o-az/eyepfs template demo deployed test: https://api-production-bcc4.up.railway.app/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi thank you both
GitHub
GitHub - o-az/eyepfs: Hosted IPFS Gateway & HTTP Proxy
Hosted IPFS Gateway & HTTP Proxy. Contribute to o-az/eyepfs development by creating an account on GitHub.
Brody
Brody16mo ago
awesome!! very pog
amorfati
amorfatiOP16mo ago
if only David knew how many people I've converted over to Railway just over the last 12 months. Crazy #
angelo
angelo16mo ago
do you want a nice Template code?
amorfati
amorfatiOP16mo ago
i'm actually dumb for not leveraging referral codes
amorfati
amorfatiOP16mo ago
i just saw it's a thing smh
angelo
angelo16mo ago
we now do it automatically fwiw
amorfati
amorfatiOP16mo ago
wym?
Brody
Brody16mo ago
you're taking about account referrals not template referrals
amorfati
amorfatiOP16mo ago
yeah ops i see what you mean @Angelo idc about template referral i want that big buck
angelo
angelo16mo ago
lemme credit you anyway one sec
amorfati
amorfatiOP16mo ago
can you get that arm64 thing setup on the way
Brody
Brody16mo ago
that is a gigantic ask
angelo
angelo16mo ago
massive
amorfati
amorfatiOP16mo ago
it was a joke lol beauty don't need it so far above your pay grade? upgrading entire infrastructure. Probably above owner/ceo/chair's paygrade need vc's signed approval man time really fast this year. It was more than a year ago that I was here asking many questions while trying to get bun to run on railway lost in the sauce. Look at everything now. Railway simply became a much smoother and more seamless experience. I can't pin exactly what changed by everything is better thank ya'll
angelo
angelo16mo ago
just consistent dedication to improving the product one week at a time
amorfati
amorfatiOP16mo ago
I'm sort of in the middle of this weeks-lasting discussion w/ a friend comparing railway, fly, render. Specifically which platform can take you from dockerfile to deployed the fastest don't want to keep taking your time. Thanks a lot what's your twitter? @ both of you
angelo
angelo16mo ago
@ ngeloxyz
Brody
Brody16mo ago
I have two followers and I think that's plenty
angelo
angelo16mo ago
be ruthless in your feedback
Brody
Brody16mo ago
spoiler alert, it's railway
angelo
angelo16mo ago
and sometimes it might not be; but we need to be honest where we suck and work hard to improve it
amorfati
amorfatiOP16mo ago
yes! for just dockerfile. Otherwise my answer is it depends on the project
Brody
Brody16mo ago
php
angelo
angelo16mo ago
we should just give people an FTP server for PHP zoom the files up, no build
amorfati
amorfatiOP16mo ago
but the thing is 80% of projects just need to run a server so dockerfile + node. In that case objectively railway better for some other services fly wins and for some other other services render wins because only render offers those services
angelo
angelo16mo ago
More info pls?
amorfati
amorfatiOP16mo ago
i would like to opt out of this upgrade followed you we got a bnuch in common lol that's a neat pfp
Brody
Brody16mo ago
tell us why fly wins!?
angelo
angelo16mo ago
seriously what a cliffhanger
amorfati
amorfatiOP16mo ago
1. edge 2. innovations like this: https://fly.io/docs/litefs/
angelo
angelo16mo ago
1. Does Edge matter to you? 2. Fair, getting the one of the lead SQLite maintainers gets ya that
amorfati
amorfatiOP16mo ago
a possible 3 though I haven't used it much: Fly Machines - the fact that it lets you use and interact with Firecracker VMs programmatically is amazing unfortunately yeah. Everything I work on has global users
angelo
angelo16mo ago
How much local fidelity do you expect, would just having traffic proxy to the region be good enough?
amorfati
amorfatiOP16mo ago
angelo
angelo16mo ago
may you never get liquidated
amorfati
amorfatiOP16mo ago
Base line performance is cloudflare workers. I never use fly/railway or any server if I can use cloudflare workers but sometimes it's just not possible (payloads too large, etc etc.) fly ends up showing closer performance to cloudflare workers than a railway server i already did. got rekt, small one thankfully on the other hand fly has been extremely unreliable at times last 12-16 months down a bunch of times, randomly upgrading my projects and messing with my config I'll sacrifice even a whole 1s for reliability at least when railway is unreliable it's bc of gcp
angelo
angelo16mo ago
To be frank, a lot of our issues is with scaling builds knocking on all pieces of wood
amorfati
amorfatiOP16mo ago
I don't know what that means. "Scaling builds"? Too broad
angelo
angelo16mo ago
Meaning, if we do have incidents, its with deploys, not workload availibility. We'd rather stop builds rather than effect raw workload uptime. Preferably never any incident.
amorfati
amorfatiOP16mo ago
one annoying thing with railway is the changes to team and project policies. I haven't even looked into it yet but I just now kinda assume I will get an email every now and then telling me structure is changing or I will try to setup a project with a team and the path I took last time doesn't work anymore3 ooh and lest I forget. Railway nuked my production postgres db about 6 months ago. It was so painful. Still bruised nuked is the wrong word, more like it stopped working and remained stuck at extremely high resource usage. Worse, wasn't possible to stop it or delete the service & project
angelo
angelo16mo ago
I remember... Our DBs falling over were top 10 most frustrating parts of Railway Thats going to be fixed with DBs2
amorfati
amorfatiOP16mo ago
what's DBs2?
angelo
angelo16mo ago
Now DBs will be services backed by volumes and we will allow you to SSH in
Brody
Brody16mo ago
oh no, a whole new class of help requests
amorfati
amorfatiOP16mo ago
there you go
amorfati
amorfatiOP16mo ago
Railway Docs
Priority Boarding | Railway Docs
Documentation for Railway
amorfati
amorfatiOP16mo ago
trie the /beta
Brody
Brody16mo ago
you are beta
amorfati
amorfatiOP16mo ago
how dare you
Brody
Brody16mo ago
I didn't do anything /beta is how you join
angelo
angelo16mo ago
its not out yet but JR is working on it as we speak our DBs leave a lot to be desired we want automatic backups, tuning, and live config
amorfati
amorfatiOP16mo ago
priority boarding. The name gives me airport vibes never seen it in docs
Brody
Brody16mo ago
you board trains too lol
amorfati
amorfatiOP16mo ago
google priority boarding. First results airplane, on page 200 train
Brody
Brody16mo ago
skill issue
angelo
angelo16mo ago
Amtrak has it!
amorfati
amorfatiOP16mo ago
never ridden a train never priority boarded a train
Brody
Brody16mo ago
missing out fr fr
amorfati
amorfatiOP16mo ago
apparently you can ship your car coast to coast and ride the train? Wish I knew this last year are you serious? Is it actually a pleasent experience?
Brody
Brody16mo ago
brb texting friends trains? yeah for sure
amorfati
amorfatiOP16mo ago
ok good time to call it. I'll go take my dog out. Will comeback with more feedback about railway. Where is a good channel to post?
Brody
Brody16mo ago
#🤗|feedback
amorfati
amorfatiOP16mo ago
A ++++++++++++++ on railway's side. UI is amazing. Great aesthetics. I wish you would make a public npm library of some css / tailwind components
Brody
Brody16mo ago
amorfati
amorfatiOP16mo ago
Doesn't cut it 😦
Brody
Brody16mo ago
i know
amorfati
amorfatiOP16mo ago
Railway
Changelog #0145
Introducing Template Bounties, New Plan Migration
amorfati
amorfatiOP16mo ago
Like these icons are fireee More designer work kinda
amorfati
amorfatiOP16mo ago
Railway
Changelog #0141
Deploy Docker Images, New Pricing Rollout, Increased Volumes Limit, Speedups
amorfati
amorfatiOP16mo ago
Look at that well crafted docker square
Brody
Brody16mo ago
why is there a dot on the whale Angelo did this one
angelo
angelo16mo ago
wrong
Brody
Brody16mo ago
and you can tell Angelo didn't do this one /j
angelo
angelo16mo ago
I did 145 someone else did 141
Brody
Brody16mo ago
okay getting funky with figma, i see the thumbnail for 145 has a template that didn't even exist at that time lol
angelo
angelo16mo ago
aspirational
Brody
Brody16mo ago
well it exists now 😉
amorfati
amorfatiOP16mo ago
Wow Can't unsee Btw did you know you can COPY from a remote image in dockerfile? So basically no need to even install bun. Just COPY bin Better, you can COPY from a remote git repository Won't always work obviously but does work in a surprising # of cases
Brody
Brody16mo ago
yes I did know those things
amorfati
amorfatiOP16mo ago
Actually I'm wrong I think. Only works with ADD?
Brody
Brody16mo ago
yeah I had assumed you meant that
amorfati
amorfatiOP16mo ago
Does railway support nix / any plans?
Brody
Brody16mo ago
be more specific
amorfati
amorfatiOP16mo ago
Same way I can deploy apps using dockerfile I can deploy those apps using nix Nix can replace docker
Brody
Brody16mo ago
https://nixpacks.com/docs applicable? dockerfile* railway uses docker whether you use a Dockerfile or nixpacks
amorfati
amorfatiOP16mo ago
@Brody everything is 10x harder in alpine nod
Brody
Brody16mo ago
how so
amorfati
amorfatiOP16mo ago
musl glibc
Brody
Brody16mo ago
those are easily added
amorfati
amorfatiOP16mo ago
also the fact that I'm deving on an arm machine and some of these tools are amd only (bun hard to do in alpine) i got this working so far:
FROM ipfs/kubo:latest as KUBO_BINARY
FROM ipfs/bifrost-gateway as BIFROST_BINARY

FROM --platform=linux/amd64 amd64/alpine:latest as ALPINE_BUILDER

RUN apk add --no-cache gcompat && \
rm -rf /var/cache/apk/* && \
rm -rf /tmp/*

COPY --from=KUBO_BINARY /usr/local/bin/ipfs /usr/local/bin/ipfs
COPY --from=BIFROST_BINARY /usr/local/bin/bifrost-gateway /usr/local/bin/bifrost-gateway

RUN which ipfs && \
ipfs --version && \
ipfs init

VOLUME /data/ipfs
VOLUME /export

EXPOSE 4001/tcp
EXPOSE 4001/udp
EXPOSE 5001/tcp
EXPOSE 8080/tcp

COPY ./scripts/entrypoint.sh /entrypoint.sh

RUN chmod +x /entrypoint.sh && cat /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
FROM ipfs/kubo:latest as KUBO_BINARY
FROM ipfs/bifrost-gateway as BIFROST_BINARY

FROM --platform=linux/amd64 amd64/alpine:latest as ALPINE_BUILDER

RUN apk add --no-cache gcompat && \
rm -rf /var/cache/apk/* && \
rm -rf /tmp/*

COPY --from=KUBO_BINARY /usr/local/bin/ipfs /usr/local/bin/ipfs
COPY --from=BIFROST_BINARY /usr/local/bin/bifrost-gateway /usr/local/bin/bifrost-gateway

RUN which ipfs && \
ipfs --version && \
ipfs init

VOLUME /data/ipfs
VOLUME /export

EXPOSE 4001/tcp
EXPOSE 4001/udp
EXPOSE 5001/tcp
EXPOSE 8080/tcp

COPY ./scripts/entrypoint.sh /entrypoint.sh

RUN chmod +x /entrypoint.sh && cat /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
the missing piece is bun build step. No luck with that
Brody
Brody16mo ago
honestly I really think you should take the multi service approach
amorfati
amorfatiOP16mo ago
Totally agree
Brody
Brody16mo ago
run ipfs and bitfrost in their own services and then your bun proxy in another
amorfati
amorfatiOP16mo ago
this is definitely not a job for 1 dockerfile
Brody
Brody16mo ago
some tips, the rm -f stuff you do after apk add is redundant since you have the no-cache flag. expose is not necessary, volume also isn't necessary and for styling, as should be capital case, while the image names should be lower case
amorfati
amorfatiOP16mo ago
I do EXPOSE for comments purposes just to show intent. I guess not the convention?
Brody
Brody16mo ago
meh
amorfati
amorfatiOP16mo ago
FROM ipfs/kubo:latest AS kubo_binary? do you write sql queries lower case or uppercase?
Brody
Brody16mo ago
I don't do sql
amorfati
amorfatiOP16mo ago
what do you do
Brody
Brody16mo ago
I don't use databases
amorfati
amorfatiOP16mo ago
nice
Brody
Brody16mo ago
I'm happier that way
amorfati
amorfatiOP16mo ago
GitHub
bun/dockerhub/Dockerfile-alpine at main · oven-sh/bun
Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one - oven-sh/bun
amorfati
amorfatiOP16mo ago
# Not officially supported (yet) distroless version too
Brody
Brody16mo ago
just use the bun image that's in dockerhub
amorfati
amorfatiOP16mo ago
that;s what i'm doing but i'm checking if i can do bun in alpine so that i can run bun --compile to generate a binary. The binary will only be able to run in the same env and distro as the one it was built in
Brody
Brody16mo ago
what's wrong with doing that in buns image
amorfati
amorfatiOP16mo ago
doing bun --compile?
Brody
Brody16mo ago
yeah
amorfati
amorfatiOP16mo ago
nothing. It works there, but if you want to use multistage and copy over the binary to an alpine stage, it won't work so you'd need all stages be debian
Brody
Brody16mo ago
so? the bun image is only ~100mb
amorfati
amorfatiOP16mo ago
what do you mean so? As in so why not use debian?
Brody
Brody16mo ago
whatever the bun image is based on, just use the bun image
amorfati
amorfatiOP16mo ago
it's what I'm doing just need to remove alpine stuff rm -rf Dockerfile vi compose.yml
Brody
Brody16mo ago
why was the original message deleted nvm, discord buggin out
amorfati
amorfatiOP16mo ago
Is there any railway way of adding rate limiter to public service API? I normally use a redis table for that. Curious if there's any specific tools in railway before I setup redis
Brody
Brody16mo ago
there is not, up to your app or cloudflare
Brody
Brody16mo ago
also, doesn't that defeat the point??
amorfati
amorfatiOP16mo ago
The point of it is to use it for one's own project only but im thinking of adding rate limiter option if someone wants it for another use case For my own use case I don't actually need it. Just need ip check and cors config'd
amorfati
amorfatiOP16mo ago
Oof. Too high. I didn't know ipfs took that much
Brody
Brody16mo ago
yikes
amorfati
amorfatiOP16mo ago
Tbf I have everything enabled just not exposed But still too high right?
Brody
Brody16mo ago
just ram costs alone would be 10$ /month
amorfati
amorfatiOP16mo ago
Kms
amorfati
amorfatiOP16mo ago
Nice
amorfati
amorfatiOP16mo ago
I'm probably moving the js api part to cloudflare
Brody
Brody16mo ago
volume file browser lol
amorfati
amorfatiOP16mo ago
Good job Despite having 0 volumes I added it Before I add vols
Brody
Brody16mo ago
i hope you read the readme
amorfati
amorfatiOP16mo ago
Yup. It's perfect once I have everything setup Speed things up Cause I need to volumes. I haven't added them yey Yet
amorfati
amorfatiOP16mo ago
Install IPFS Kubo inside Docker | IPFS Docs
You can run IPFS inside Docker to simplify your deployment processes, and horizontally scale your IPFS infrastructure.
amorfati
amorfatiOP16mo ago
Got more nice templates to look at? Not for this project just in general
Brody
Brody16mo ago
two volumes for the ipfs and bitfrost services?
amorfati
amorfatiOP16mo ago
just ipfs
Brody
Brody16mo ago
you can only have one volume per service
amorfati
amorfatiOP16mo ago
I just learned that literally 5 mins ago
Brody
Brody16mo ago
meh who needs an export volume
amorfati
amorfatiOP16mo ago
BUT. It's possible to have just one if you're not planning on uploading files which I don't need So we good Is that common? Im volumes rookie
Brody
Brody16mo ago
i think multiple volumes per service and multiple volumes attached to multiple services are coming at some point i dont know lol, just joking around
amorfati
amorfatiOP16mo ago
evilllama
amorfati
amorfatiOP16mo ago
I literally only swapped the runtime from bun to deno
Brody
Brody16mo ago
damn bun used a lot of memory I've heard about that, bun may be fast, but at the cost of increased memory usage?
amorfati
amorfatiOP16mo ago
i'm sensing deno to be faster here
Brody
Brody16mo ago
haha rip bun
amorfati
amorfatiOP16mo ago
does this look leaky?
Brody
Brody16mo ago
not many people would want to deploy something that uses 1gb of ram at idle over that time frame, nah not really, I'd need to see a longer timeframe without any restarts
amorfati
amorfatiOP16mo ago
not fully true. I also reduced Dockerfile and am not doing any build steps inside docker
ARG DENO_VERSION=1.36.1
FROM denoland/deno:bin-${DENO_VERSION} AS deno_bin

FROM ipfs/kubo:latest AS kubo_binary
FROM ipfs/bifrost-gateway:latest AS bifrost_binary

FROM debian:stable-slim AS final

ENV PORT="3031"
ENV ENV="production"
ENV IPFS_GATEWAY_HOST="http://127.0.0.1:8081"
ENV PROXY_GATEWAY_URL="http://127.0.0.1:8080"

# copy ipfs/kubo
COPY --from=kubo_binary /usr/local/bin/ipfs /usr/local/bin/ipfs
# # copy ipfs/bifrost-gateway
COPY --from=bifrost_binary /usr/local/bin/bifrost-gateway /usr/local/bin/bifrost-gateway
# # copy deno binary
COPY --from=deno_bin /deno /usr/local/bin/deno

WORKDIR /app

COPY ./scripts/entrypoint.sh ./src/* /app/

RUN chmod +x /app/entrypoint.sh

ENTRYPOINT ["/app/entrypoint.sh"]
ARG DENO_VERSION=1.36.1
FROM denoland/deno:bin-${DENO_VERSION} AS deno_bin

FROM ipfs/kubo:latest AS kubo_binary
FROM ipfs/bifrost-gateway:latest AS bifrost_binary

FROM debian:stable-slim AS final

ENV PORT="3031"
ENV ENV="production"
ENV IPFS_GATEWAY_HOST="http://127.0.0.1:8081"
ENV PROXY_GATEWAY_URL="http://127.0.0.1:8080"

# copy ipfs/kubo
COPY --from=kubo_binary /usr/local/bin/ipfs /usr/local/bin/ipfs
# # copy ipfs/bifrost-gateway
COPY --from=bifrost_binary /usr/local/bin/bifrost-gateway /usr/local/bin/bifrost-gateway
# # copy deno binary
COPY --from=deno_bin /deno /usr/local/bin/deno

WORKDIR /app

COPY ./scripts/entrypoint.sh ./src/* /app/

RUN chmod +x /app/entrypoint.sh

ENTRYPOINT ["/app/entrypoint.sh"]
just grabbing bins now idk how much that affects memory though
Brody
Brody16mo ago
that's not 3 separate services 😦
amorfati
amorfatiOP16mo ago
i have to defeat this boss first don't worry 3 services are coming soon and deployed to both railway and fly so we can see live 1:1 comparison finale
Brody
Brody16mo ago
pog
amorfati
amorfatiOP16mo ago
I'm trying to figure out now if somehow I can disable ipfs peer connections from using mine so like 5-8 hours? at start it was 165 MB now 195 MB
Brody
Brody16mo ago
yeah that would give a better idea
amorfati
amorfatiOP16mo ago
this is kinda hilarous
amorfati
amorfatiOP16mo ago
bun wants more
Brody
Brody16mo ago
damn
amorfati
amorfatiOP16mo ago
this is the same old one just looking at it it looks like if there was 2GB it woud've gone for it lmao
Brody
Brody16mo ago
there is 8gb
amorfati
amorfatiOP16mo ago
don't tell bun about it pls
Brody
Brody16mo ago
lmao
amorfati
amorfatiOP16mo ago
Brody
Brody16mo ago
lol what happened there
amorfati
amorfatiOP16mo ago
i think it's just showing past from bun deployment until now i removed deployment for a few hours
Brody
Brody16mo ago
strange there's no dashed line at the cliff
amorfati
amorfatiOP16mo ago
it was on then I off'd it then deployed again this doesn't look right?
amorfati
amorfatiOP16mo ago
this doesn't look right
amorfati
amorfatiOP16mo ago
3am is 8am?
Brody
Brody16mo ago
oops minor display bug
amorfati
amorfatiOP16mo ago
it's cirrect in other points post-clif it's off
amorfati
amorfatiOP16mo ago
this is right
amorfati
amorfatiOP16mo ago
all of post-cliff is at 8:28 am until the deployment 30-45mins ago
Brody
Brody16mo ago
odd
amorfati
amorfatiOP16mo ago
fun
amorfati
amorfatiOP16mo ago
Massive benefit of fly: serverless containers https://aws.amazon.com/fargate/
Amazon Web Services, Inc.
Serverless Compute Engine – AWS Fargate – AWS
AWS Fargate is a serverless compute engine for containers that works with both Amazon Elastic Container Service (ECS) and Amazon Elastic Kubernetes (EKS).
Brody
Brody16mo ago
the CEO of railway on multiple occasions has poked fun at server less, and I agree with him, why server less when you can just do servers lol
amorfati
amorfatiOP16mo ago
Depends on use case If you have a site that receives heavy traffic in the morning but very little traffic between 8pm and 5am then fargate is economically saner The overhead is 100x when running ec2 vs fargate (serverless) Also fargate economically better for things like cron jobs
Brody
Brody16mo ago
meh
amorfati
amorfatiOP16mo ago
Brody
Brody16mo ago
ay not bad
amorfati
amorfatiOP16mo ago
boss doesn't like it. Said switch to rust
Brody
Brody16mo ago
Go*
amorfati
amorfatiOP16mo ago
GOat what's the go-to way of converting to go?
Brody
Brody16mo ago
just the proxy part that used to use bun?
Brody
Brody16mo ago
well, do you know go?
amorfati
amorfatiOP16mo ago
i've written 1 go "app" in the past https://github.com/o-az/gomark lol what's the lightest web framework in go?
Brody
Brody16mo ago
either chi or gorilla mux, i recommend chi, but both are 100% stdlib (good thing)
amorfati
amorfatiOP16mo ago
stdlib is the homie we go way back
Brody
Brody16mo ago
the same proxy in go should be sub 20mb in mem
amorfati
amorfatiOP16mo ago
financially irresponsible to not go for it
Brody
Brody16mo ago
railway rewards code golfing!
amorfati
amorfatiOP16mo ago
what does that mean?
Brody
Brody16mo ago
in a nutshell, write better code, pay less
amorfati
amorfatiOP16mo ago
what's the perfect go project setup? dir structure, linter/formatter, etc.
Brody
Brody16mo ago
i am not the one to ask about that lol, i can write go code all day long, but my weak point is structure
Adam
Adam16mo ago
@Vin 👀
MantisInABox
MantisInABox16mo ago
?
Adam
Adam16mo ago
Aren’t you a GO-getter?
MantisInABox
MantisInABox16mo ago
Yessum
Adam
Adam16mo ago
A Go-od dooer? A Pokémon-Go-To-The-Polls fiend?
Brody
Brody16mo ago
🤨
Adam
Adam16mo ago
person above could use some go help is what I’m getting at
Brody
Brody16mo ago
slap everything in the single main.go file and call it a day I joke, but the original code is nearly just index.ts so a nicely formatted single main.go file would be perfectly adequate to be honest
MantisInABox
MantisInABox16mo ago
If you’re looking for a decent way to structure go projects, you can check this video out https://youtu.be/dxPakeBsgl4
Melkey
YouTube
This Is The BEST Way To Structure Your GO Projects
World of Go programming language! 🚀 Whether you're a complete beginner or an experienced developer looking to explore Go, this video has something for everyone. 🔧 Installing Go Lang: With easy-to-follow instructions, you'll have Go up and running on your machine in no time. 📁 Directory Layout Best Practices: We discuss the recommended directo...
Brody
Brody16mo ago
too long
MantisInABox
MantisInABox16mo ago
Not everyone has the attention span of a gopher Brody! 🤣🤣🤣
Brody
Brody16mo ago
it's about 11 minutes too long
amorfati
amorfatiOP16mo ago
aka forward request my go rn
package main

import (
"fmt"
"net/http"
"os"
"strings"

"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)

func main() {
ipfsGatewayHost, exists := os.LookupEnv("IPFS_GATEWAY_HOST")
if !exists {
fmt.Println("Error: IPFS_GATEWAY_HOST environment variable not set")
os.Exit(1)
}

allowOrigins := strings.Split(os.Getenv("ALLOW_ORIGINS"), ",")

r := chi.NewRouter()
r.Use(middleware.Logger)

r.Route("/", func(r chi.Router) {
r.Use(corsMiddleware(allowOrigins))

r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
// TODO
})
})

http.ListenAndServe(":3031", r)
}

func corsMiddleware(allowOrigins []string) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
for _, allowedOrigin := range allowOrigins {
if origin == allowedOrigin {
w.Header().Set("Access-Control-Allow-Origin", origin)
break
}
}
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS, HEAD")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusNoContent)
return
}

next.ServeHTTP(w, r)
})
}
}
package main

import (
"fmt"
"net/http"
"os"
"strings"

"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)

func main() {
ipfsGatewayHost, exists := os.LookupEnv("IPFS_GATEWAY_HOST")
if !exists {
fmt.Println("Error: IPFS_GATEWAY_HOST environment variable not set")
os.Exit(1)
}

allowOrigins := strings.Split(os.Getenv("ALLOW_ORIGINS"), ",")

r := chi.NewRouter()
r.Use(middleware.Logger)

r.Route("/", func(r chi.Router) {
r.Use(corsMiddleware(allowOrigins))

r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
// TODO
})
})

http.ListenAndServe(":3031", r)
}

func corsMiddleware(allowOrigins []string) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
for _, allowedOrigin := range allowOrigins {
if origin == allowedOrigin {
w.Header().Set("Access-Control-Allow-Origin", origin)
break
}
}
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS, HEAD")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusNoContent)
return
}

next.ServeHTTP(w, r)
})
}
}
why my comment gets deleted https
Brody
Brody16mo ago
you cant edit links
amorfati
amorfatiOP16mo ago
evilllama
Brody
Brody16mo ago
resp, err := http.Get(...)
if err != nil{
//handle the error
return
}

defer resp.Body.Close()

io.Copy(rw, resp.Body)
resp, err := http.Get(...)
if err != nil{
//handle the error
return
}

defer resp.Body.Close()

io.Copy(rw, resp.Body)
pseudo code
amorfati
amorfatiOP16mo ago
is it a go convention to short name things? resp, err, w, r
Brody
Brody16mo ago
yes, at least thats how ive always seen it done chi has its own cors middleware btw
amorfati
amorfatiOP16mo ago
package main

import (
"fmt"
"io"
"net/http"
"os"
"path"
"regexp"
"strings"

"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)

func main() {
ipfsGatewayHost, exists := os.LookupEnv("IPFS_GATEWAY_HOST")
if !exists {
fmt.Println("Error: IPFS_GATEWAY_HOST environment variable not set")
os.Exit(1)
}

allowOrigins := strings.Split(os.Getenv("ALLOW_ORIGINS"), ",")

r := chi.NewRouter()
r.Use(middleware.Logger)

r.Route("/", func(r chi.Router) {
r.Use(corsMiddleware(allowOrigins))

r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
cid := path.Base(r.URL.Path)
if !isPossiblyCID(cid) {
http.Error(w, fmt.Sprintf("Invalid pathname: %s", r.URL.Path), http.StatusBadRequest)
return
}

ipfsURL := fmt.Sprintf("%s/ipfs/%s", ipfsGatewayHost, cid)
resp, err := http.Get(ipfsURL)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to fetch IPFS URL: %s", ipfsURL), http.StatusBadRequest)
return
}
defer resp.Body.Close()

io.Copy(w, resp.Body)
})
})

http.ListenAndServe(":3031", r)
}

func corsMiddleware(allowOrigins []string) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
for _, allowedOrigin := range allowOrigins {
if origin == allowedOrigin {
w.Header().Set("Access-Control-Allow-Origin", origin)
break
}
}
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS, HEAD")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusNoContent)
return
}

next.ServeHTTP(w, r)
})
}
}

func isPossiblyCID(possibleCID string) bool {
cidRegex := regexp.MustCompile(`Qm[1-9A-HJ-NP-Za-km-z]{44,}|b[A-Za-z2-7]{58,}|B[A-Z2-7]{58,}|z[1-9A-HJ-NP-Za-km-z]{48,}|F[0-9A-F]{50,}`)
return cidRegex.MatchString(possibleCID)
}
package main

import (
"fmt"
"io"
"net/http"
"os"
"path"
"regexp"
"strings"

"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)

func main() {
ipfsGatewayHost, exists := os.LookupEnv("IPFS_GATEWAY_HOST")
if !exists {
fmt.Println("Error: IPFS_GATEWAY_HOST environment variable not set")
os.Exit(1)
}

allowOrigins := strings.Split(os.Getenv("ALLOW_ORIGINS"), ",")

r := chi.NewRouter()
r.Use(middleware.Logger)

r.Route("/", func(r chi.Router) {
r.Use(corsMiddleware(allowOrigins))

r.Get("/*", func(w http.ResponseWriter, r *http.Request) {
cid := path.Base(r.URL.Path)
if !isPossiblyCID(cid) {
http.Error(w, fmt.Sprintf("Invalid pathname: %s", r.URL.Path), http.StatusBadRequest)
return
}

ipfsURL := fmt.Sprintf("%s/ipfs/%s", ipfsGatewayHost, cid)
resp, err := http.Get(ipfsURL)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to fetch IPFS URL: %s", ipfsURL), http.StatusBadRequest)
return
}
defer resp.Body.Close()

io.Copy(w, resp.Body)
})
})

http.ListenAndServe(":3031", r)
}

func corsMiddleware(allowOrigins []string) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
for _, allowedOrigin := range allowOrigins {
if origin == allowedOrigin {
w.Header().Set("Access-Control-Allow-Origin", origin)
break
}
}
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS, HEAD")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusNoContent)
return
}

next.ServeHTTP(w, r)
})
}
}

func isPossiblyCID(possibleCID string) bool {
cidRegex := regexp.MustCompile(`Qm[1-9A-HJ-NP-Za-km-z]{44,}|b[A-Za-z2-7]{58,}|B[A-Z2-7]{58,}|z[1-9A-HJ-NP-Za-km-z]{48,}|F[0-9A-F]{50,}`)
return cidRegex.MatchString(possibleCID)
}
sorry for the wall of code lol
Brody
Brody16mo ago
wow you move fast af
amorfati
amorfatiOP16mo ago
with the help of 4 ai agents
Brody
Brody16mo ago
oh, nvm i take that back then
amorfati
amorfatiOP16mo ago
it's still fast thoguh though*
Brody
Brody16mo ago
not impressed anymore
amorfati
amorfatiOP16mo ago
understandable
Brody
Brody16mo ago
that is not an effective method for learning to code imo
amorfati
amorfatiOP16mo ago
my goal here is not to learn code though lol. When I'm trying to learn I don't copy paste I just need to get this going for now
Brody
Brody16mo ago
i dont agree with that approach but oh well
amorfati
amorfatiOP16mo ago
approach pays the bills
Brody
Brody16mo ago
but still, chi has its own cors middleware you have no error checking or validation for the ALLOW_ORIGINS variable instead of a route on the route, just use a group
amorfati
amorfatiOP16mo ago
so better value, exists := os.LookupEnv(...)
Brody
Brody16mo ago
you would want to check if it exists yeah is the call to ipfsURL always going to be a get call?
amorfati
amorfatiOP16mo ago
yup
Brody
Brody16mo ago
whats the purpose of proxing a get request to another get request anyway? seems redundant?
amorfati
amorfatiOP16mo ago
it's so i can rate limit and only allow myself to call that endpoint if i call my ipfs directly in a public website then others will see it and be able to call it but if i call my proxy then i can set checks and only allow myself
Brody
Brody16mo ago
gotcha
amorfati
amorfatiOP16mo ago
used the chi cors middleware. Much cleaner 👍
amorfati
amorfatiOP16mo ago
Brody
Brody16mo ago
no, that looks silly
amorfati
amorfatiOP16mo ago
it's just a custom makefile why silly I looked up package.json / Makefile equivalent in go
Brody
Brody16mo ago
why needed? want to run the go app? go run . job done
amorfati
amorfatiOP16mo ago
what if you have 10 long scripts, do you memorize all or have a scripts runner? it's handy
Brody
Brody16mo ago
why would you have so many scripts?
amorfati
amorfatiOP16mo ago
Many reasons. Could be a large monorepo for example this is one example i have, not monorepo
"tasks": {
"dev": "IPFS_GATEWAY_HOST='http://127.0.0.1:8080' ALLOW_ORIGINS='127.0.0.1,eyepfs.railway.app,tokens.evn.workers.dev' deno run --unstable --allow-all --watch ./src/index.ts",
"docker:build": "docker buildx build . --progress 'plain' --file 'Dockerfile' --tag 'ipfs_gateway_proxy' --platform 'linux/amd64'",
"docker:run": "docker run --rm -it --name 'ipfs_gateway_proxy' --env IPFS_GATEWAY_HOST='http://127.0.0.1:8080' --env ALLOW_ORIGINS='http://127.0.0.1,https://eyepfs.railway.app,https://tokens.evn.workers.dev' --publish '3031:3031' 'ipfs_gateway_proxy' --platform 'linux/amd64'",
"deploy": "RAILWAY_DOCKERFILE_PATH='Dockerfile' railway up --service 'api' --detach --environment 'production'",
"lint": "deno lint --unstable . src",
"fmt": "deno fmt --unstable . src",
"typecheck": "deno check *.ts src/**/*.ts",
"clean": "rm -rf ./dist deno.lock"
}
"tasks": {
"dev": "IPFS_GATEWAY_HOST='http://127.0.0.1:8080' ALLOW_ORIGINS='127.0.0.1,eyepfs.railway.app,tokens.evn.workers.dev' deno run --unstable --allow-all --watch ./src/index.ts",
"docker:build": "docker buildx build . --progress 'plain' --file 'Dockerfile' --tag 'ipfs_gateway_proxy' --platform 'linux/amd64'",
"docker:run": "docker run --rm -it --name 'ipfs_gateway_proxy' --env IPFS_GATEWAY_HOST='http://127.0.0.1:8080' --env ALLOW_ORIGINS='http://127.0.0.1,https://eyepfs.railway.app,https://tokens.evn.workers.dev' --publish '3031:3031' 'ipfs_gateway_proxy' --platform 'linux/amd64'",
"deploy": "RAILWAY_DOCKERFILE_PATH='Dockerfile' railway up --service 'api' --detach --environment 'production'",
"lint": "deno lint --unstable . src",
"fmt": "deno fmt --unstable . src",
"typecheck": "deno check *.ts src/**/*.ts",
"clean": "rm -rf ./dist deno.lock"
}
Brody
Brody16mo ago
that just looks like a mess, ive never had anything like that in any project
amorfati
amorfatiOP16mo ago
it's extremely common. I'm surprised
Brody
Brody16mo ago
messy codebases are common, indeed
amorfati
amorfatiOP16mo ago
that makes it less messy it's the same as Makefile, been around forever
Brody
Brody16mo ago
mess has been around forever*
amorfati
amorfatiOP16mo ago
https://github.com/go-chi/chi/blob/master/Makefile here they have scripts organized same way
GitHub
chi/Makefile at master · go-chi/chi
lightweight, idiomatic and composable router for building Go HTTP services - go-chi/chi
amorfati
amorfatiOP16mo ago
You're saying organizing scripts is messy?
Brody
Brody16mo ago
makefile looks messy too
amorfati
amorfatiOP16mo ago
f bout to go ahead and deploy this go app
Brody
Brody16mo ago
lol the puns
amorfati
amorfatiOP16mo ago
no bun intended
FROM ipfs/kubo:latest AS kubo_binary
FROM golang:latest AS final

ENV PORT="3031"
ENV ENV="production"
ENV IPFS_GATEWAY_HOST="http://127.0.0.1:8080"

COPY --from=kubo_binary /usr/local/bin/ipfs /usr/local/bin/ipfs
WORKDIR /app

COPY ./scripts/entrypoint.sh ./* /app/
RUN chmod +x /app/entrypoint.sh

ENTRYPOINT ["/app/entrypoint.sh"]
FROM ipfs/kubo:latest AS kubo_binary
FROM golang:latest AS final

ENV PORT="3031"
ENV ENV="production"
ENV IPFS_GATEWAY_HOST="http://127.0.0.1:8080"

COPY --from=kubo_binary /usr/local/bin/ipfs /usr/local/bin/ipfs
WORKDIR /app

COPY ./scripts/entrypoint.sh ./* /app/
RUN chmod +x /app/entrypoint.sh

ENTRYPOINT ["/app/entrypoint.sh"]
alpine better but glibc scary
Brody
Brody16mo ago
why do you need a dockerfile for this?
amorfati
amorfatiOP16mo ago
cause kubo is much cleaner this way
Brody
Brody16mo ago
and why does the go proxy need the ipfs bin
amorfati
amorfatiOP16mo ago
ipfs has to run and I proxy requests through go server
Brody
Brody16mo ago
weren't you gonna run ipfs in another service?
amorfati
amorfatiOP16mo ago
this works why need another service
Brody
Brody16mo ago
this way messy
amorfati
amorfatiOP16mo ago
i reduced # of services now just 2 that's a tiny dockerfile
Brody
Brody16mo ago
you could do no dockerfile, with 3 services
amorfati
amorfatiOP16mo ago
in compose?
Brody
Brody16mo ago
no, railway doesnt support compose
amorfati
amorfatiOP16mo ago
that seems messy Dockerfile global standard
Brody
Brody16mo ago
youre funny
amorfati
amorfatiOP16mo ago
response time 429.229389ms
Brody
Brody16mo ago
for?
amorfati
amorfatiOP16mo ago
amorfati
amorfatiOP16mo ago
4ms!
Brody
Brody16mo ago
well yeah of course a request across the internet is going to take longer than a request to localhost
amorfati
amorfatiOP16mo ago
it was the same exact request first time 400ms then it got cached
Brody
Brody16mo ago
oh
amorfati
amorfatiOP16mo ago
Brody
Brody16mo ago
cache is cool
amorfati
amorfatiOP16mo ago
HTTP/1.1 cache invalidation is messy
amorfati
amorfatiOP16mo ago
amorfati
amorfatiOP16mo ago
yellow
amorfati
amorfatiOP16mo ago
I keep making it worse
amorfati
amorfatiOP16mo ago
Better Go Playground
Better Go Playground with syntax highlight support
amorfati
amorfatiOP16mo ago
😍
Brody
Brody16mo ago
haha
amorfati
amorfatiOP16mo ago
os.Environ() what's up with the shorthands. Don't like it
Brody
Brody16mo ago
what should it be
amorfati
amorfatiOP16mo ago
os.Environment()
Brody
Brody16mo ago
meh it's incredibly inconsequential
amorfati
amorfatiOP16mo ago
When I first started coding I was so confused with req and res, e, etc. https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prevent-abbreviations.md
Brody
Brody16mo ago
it's okay you use AI anyway
amorfati
amorfatiOP16mo ago
boom roasted
amorfati
amorfatiOP16mo ago
multistage build ftw
amorfati
amorfatiOP16mo ago
-10MB with alpine
Brody
Brody16mo ago
so when are you gonna do 3 services
amorfati
amorfatiOP16mo ago
i'm gonna host on fly first to see what's better
Brody
Brody16mo ago
you could then run the go service in a distroless image
amorfati
amorfatiOP16mo ago
fly
Brody
Brody16mo ago
what does this show lol
amorfati
amorfatiOP16mo ago
that it works
amorfati
amorfatiOP16mo ago
when i switched to go railway don't work
Brody
Brody16mo ago
amorfati
amorfatiOP16mo ago
I knew this from past experience but didn't use the provided solution I did
port, portEnvVariableExists := os.LookupEnv("PORT")
if !portEnvVariableExists {
port = "3031"
}

err := http.ListenAndServe(fmt.Sprintf(":%s", port), router)
port, portEnvVariableExists := os.LookupEnv("PORT")
if !portEnvVariableExists {
port = "3031"
}

err := http.ListenAndServe(fmt.Sprintf(":%s", port), router)
Brody
Brody16mo ago
yikes
amorfati
amorfatiOP16mo ago
yikes
Brody
Brody16mo ago
🙂 I will say, it's kind dumb how go doesn't have an standard function for environmental variable fallback like every other language does
amorfati
amorfatiOP16mo ago
undefined: envPortOrcompilerUndeclaredName i'm importing net/http already
Brody
Brody16mo ago
where did you put that function? in the example in the doc, it's just under the main() function
amorfati
amorfatiOP16mo ago
that's what i have too
Brody
Brody16mo ago
show code please
amorfati
amorfatiOP16mo ago
func main() {
_, hostEnvVariableExists := os.LookupEnv("IPFS_GATEWAY_HOST")
if !hostEnvVariableExists {
fmt.Println("Error: IPFS_GATEWAY_HOST environment variable not set")
os.Exit(1)
}
_, allowOriginsEnvVariableExists := os.LookupEnv("ALLOW_ORIGINS")
if !allowOriginsEnvVariableExists {
fmt.Println("Error: ALLOW_ORIGINS environment variable not set")
os.Exit(1)
}

router := chi.NewRouter()
router.Use(middleware.Logger)
router.Use(middleware.RealIP, middleware.Recoverer, middleware.RedirectSlashes, middleware.RequestID, middleware.CleanPath)

router.NotFound(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
_, _ = w.Write([]byte("Route does not exist"))
})

router.MethodNotAllowed(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusMethodNotAllowed)
_, _ = w.Write([]byte("Method not allowed"))
})

router.Get("/*", handleRequest)
router.Head("/*", handleRequest)
router.Options("/*", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})

var port = envPortOr("3000")

log.Fatal(http.ListenAndServe(port, router))
}
func main() {
_, hostEnvVariableExists := os.LookupEnv("IPFS_GATEWAY_HOST")
if !hostEnvVariableExists {
fmt.Println("Error: IPFS_GATEWAY_HOST environment variable not set")
os.Exit(1)
}
_, allowOriginsEnvVariableExists := os.LookupEnv("ALLOW_ORIGINS")
if !allowOriginsEnvVariableExists {
fmt.Println("Error: ALLOW_ORIGINS environment variable not set")
os.Exit(1)
}

router := chi.NewRouter()
router.Use(middleware.Logger)
router.Use(middleware.RealIP, middleware.Recoverer, middleware.RedirectSlashes, middleware.RequestID, middleware.CleanPath)

router.NotFound(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
_, _ = w.Write([]byte("Route does not exist"))
})

router.MethodNotAllowed(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusMethodNotAllowed)
_, _ = w.Write([]byte("Method not allowed"))
})

router.Get("/*", handleRequest)
router.Head("/*", handleRequest)
router.Options("/*", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})

var port = envPortOr("3000")

log.Fatal(http.ListenAndServe(port, router))
}
Brody
Brody16mo ago
I don't see a envPortOr function?
amorfati
amorfatiOP16mo ago
smh i thought it's a built in lmao i see now pls add syntax highlight for rookies like me
Brody
Brody16mo ago
above my pay grade jokes, I don't actually know how
amorfati
amorfatiOP16mo ago
whatever static site generator or tool you're using for the docs should have syntax highlight
amorfati
amorfatiOP16mo ago
actually already does
Brody
Brody16mo ago
yeah it just doesn't have highlighting for golang
amorfati
amorfatiOP16mo ago
maybe this needs go in beginning
amorfati
amorfatiOP16mo ago
Brody
Brody16mo ago
you don't think I did that lmao?
amorfati
amorfatiOP16mo ago
no otherwise there would be rainbow wild. So it has syntax highlight for node but not go? disrespectful
amorfati
amorfatiOP16mo ago
damn so the tool sucks personally I wouldn't let that one slide
Brody
Brody16mo ago
like i said, above my paygrade
amorfati
amorfatiOP16mo ago
sure
Brody
Brody16mo ago
you are welcome to pr it though!
amorfati
amorfatiOP16mo ago
👀
Brody
Brody16mo ago
while youre at it, add in styling for single backtick code blocks
Brody
Brody16mo ago
Brody
Brody16mo ago
Go / net/http see, single backtick codeblock
amorfati
amorfatiOP16mo ago
this is next contentlayer by default. It adds the extra backtick
Brody
Brody16mo ago
well pr it to format the codeblock properly 🙂
amorfati
amorfatiOP16mo ago
the single backtick? It's supposedly desirable personally I wouldn't use nextjs
Brody
Brody16mo ago
what would you use? whatever chat gpt recommends? sorry, i couldnt help it
amorfati
amorfatiOP16mo ago
VitePress
VitePress | Vite & Vue Powered Static Site Generator
Vite & Vue powered static site generator.
Brody
Brody16mo ago
can vitepress do ssr?
amorfati
amorfatiOP16mo ago
don't need that for docs
Brody
Brody16mo ago
railways docs has server side features that use prisma
amorfati
amorfatiOP16mo ago
yes it's vue btw. Doubt your team will accept not using react
Brody
Brody16mo ago
i think ive told you this before, but i dont work for railway
amorfati
amorfatiOP16mo ago
I don't remember. Did you? I don't think you did you did https://discord.com/channels/713503345364697088/1139335435982741534/1139357413942771733 not to me though
Brody
Brody16mo ago
close enough
amorfati
amorfatiOP16mo ago
now that both fly and railway deployed, I think I prefer railway. Pending more tests
Brody
Brody16mo ago
thats the spirit
amorfati
amorfatiOP16mo ago
Brody
Brody16mo ago
does this show railway is faster?
amorfati
amorfatiOP16mo ago
3x look @ last line wow fly slow "fly"
Brody
Brody16mo ago
well, where is flys server located relative to you?
amorfati
amorfatiOP16mo ago
same town good point! it's even slower than what I thought fly is in the same city
Brody
Brody16mo ago
i assume you dont live near oregon though? (gcp us-west1)
amorfati
amorfatiOP16mo ago
sea i'm currently as close as physically possible to the fly server where's the railway server
Brody
Brody16mo ago
oregon us-west1
amorfati
amorfatiOP16mo ago
close
Brody
Brody16mo ago
fly uses aws right?
amorfati
amorfatiOP16mo ago
don't know
amorfati
amorfatiOP16mo ago
amorfati
amorfatiOP16mo ago
also fly app sleeps every like 20 seconds
Brody
Brody16mo ago
i tried to tell you serverless aint it
amorfati
amorfatiOP16mo ago
McDoomer
Brody
Brody16mo ago
ive tried to tell you a few things
amorfati
amorfatiOP16mo ago
i'm deploying to aws next
Brody
Brody16mo ago
like just an ec2 or lightsail instance?
amorfati
amorfatiOP16mo ago
ec2
Brody
Brody16mo ago
lightsail > ec2
amorfati
amorfatiOP16mo ago
i'll check it out!'
Want results from more Discord servers?
Add your server