Tailwind infinite build loop

jkellogg01HOBBY

9 months ago

TL;DR

I recently migrated my personal website from the tailwind CDN to tailwind proper. In my go code for starting my server, I'm using [exec.Run](exec.Run)() to run tailwind's build process on server startup. All of this is working excellently on my local machine, but when I deploy it to Railway it appears to be launching the server in a loop about every five seconds.

What changed

  • I added node as a dependency to my deploy so that npx could be used for the tailwind cli

  • I wrote the following function in order to do the automatic build:

func buildTailwind(infile, outfile string) error {
        build := exec.Command(
                "npx",
                "tailwindcss",
                "-i",
                infile,
                "-o",
                outfile,
        )
        build.Stdout = os.Stdout
        build.Stderr = os.Stderr
        return build.Run()
}
  • I'm not actually using the error return from that function, so even if the build fails it shouldn't be causing the server restart (and didn't when I initially deployed it without the node dependency)

  • I'm aware that it's silly to ignore that error and I'm going to fix that. But it doesn't explain the problem so I'm leaving it as-is for now

that's really it. I'm not super sure where to start looking for what the problem might be. For now the deployment has been canceled because it's just my personal site and I would rather have it down than run up my compute bill on a bug I don't know how to fix lol. Any suggestions would be greatly appreciated.

0 Replies

jkellogg01HOBBY

9 months ago

project id: 271ed33d-be6b-40ce-96ba-504a94362dac


9 months ago

you are likely trying to use more than 500MB of memory, if you still have issues after upgrading to the hobby plan we can then debug this further


jkellogg01HOBBY

9 months ago

oh, okay. I wasn't aware of the memory constraint, let me take a look at that and try upgrading


9 months ago

yeah 500MB on trial


jkellogg01HOBBY

9 months ago

ok looks like upgrading worked but now it's… not building properly? or not saving the output? Let me set it up to panic if the tailwind build fails and that'll probably give me some more info


9 months ago

why not run that tailwind build command as a regular build command? is there any specific reason you are doing it in such a convoluted way?


jkellogg01HOBBY

9 months ago

if i can be so real


jkellogg01HOBBY

9 months ago

i thought this way would be easier


jkellogg01HOBBY

9 months ago

that is the main reason


jkellogg01HOBBY

9 months ago

now i want it to work but if it doesn't i'll probably just cave and do it as a build command


jkellogg01HOBBY

9 months ago

but i thought it would be cool to have the server handle the tailwind build itself


jkellogg01HOBBY

9 months ago

oh it's saying that npx isn't in the path


9 months ago

id go with a multi stage Dockerfile where the first stage is a node image and it builds the css, then the second stage is a golang image and then you copy over the built files into the final image


jkellogg01HOBBY

9 months ago

i see


jkellogg01HOBBY

9 months ago

gotta go learn docker then. brb


9 months ago

you dont though


9 months ago

its just a text file


jkellogg01HOBBY

9 months ago

oh i see


9 months ago

in all my years of writing Dockerfiles, i have never once ran docker on my own computer


jkellogg01HOBBY

9 months ago

so this should be one dockerfile with two sections, one running a node image and the second running a go image?


9 months ago

you got your terminology wrong, but you have the idea more or less, if you want to share your repo i can try to write one for you


jkellogg01HOBBY

9 months ago

I think I have one that should work, but if you want to give it a sanity check that would be great


jkellogg01HOBBY

9 months ago

FROM node:20.12

WORKDIR /app

COPY package*.json ./

RUN npx tailwindcss -i static/input.css -o dist/style.css

FROM golang:1.22

COPY go.mod go.sum ./
RUN go mod download

COPY *.go ./

RUN go build -o bin/personal-site

ENV PORT=8080

CMD ["bin/personal-site"]

jkellogg01HOBBY

9 months ago

I just went off of docker's tutorial for building an image for go lol


9 months ago

you are on the right track, but your golang layer does not have a work dir, and you have no copied the built css into the golang layer either


jkellogg01HOBBY

9 months ago

ohhhh okay i can take care of that lol thank you


jkellogg01HOBBY

9 months ago

if I wanna just copy the whole dist dir onto a dist dir in the image, it would just be COPY dist/ ./dist right? or do I have to make a directory on the image first?


9 months ago

COPY will make paths as needed, but you need to copy the dist dir from the node layer


jkellogg01HOBBY

9 months ago

okay, and that will stay when you enter the go layer. gotcha. I was wondering about that


9 months ago

it wont stay unless you copy it with --from


jkellogg01HOBBY

9 months ago

like this? ```dockerfile
FROM node:20.12

WORKDIR /app

COPY package*.json ./

RUN npx tailwindcss -i static/input.css -o dist/style.css

COPY --from=golang:1.22 dist/ ./dist

FROM golang:1.22```


9 months ago

FROM node:20.12 AS assets

WORKDIR /app

COPY package*.json ./

RUN npm ci

COPY static ./static

RUN npx tailwindcss -i ./static/input.css -o ./dist/style.css

FROM golang:1.22

WORKDIR /app

COPY go.mod go.sum ./

RUN go mod download

COPY . ./

COPY --from=assets /app/dist ./dist

RUN go build -o bin/personal-site

CMD ["bin/personal-site"]

9 months ago

you where copying the wrong way


jkellogg01HOBBY

9 months ago

oh okay


jkellogg01HOBBY

9 months ago

and doing COPY . ./ instead of COPY *.go ./ will add my other packages as well I assume?


jkellogg01HOBBY

9 months ago

do I need to worry about node modules from the node step with that or do they go away when the stage changes to the go one


9 months ago

everything goes away unless you specifically copy it over


jkellogg01HOBBY

9 months ago

okay cool


jkellogg01HOBBY

9 months ago

and I assume I can just add COPY --from=assets /app/static ./static to keep the static dir as well? It's got my fonts and my resume lol


9 months ago

updated


jkellogg01HOBBY

9 months ago

gotcha


jkellogg01HOBBY

9 months ago

don't need to copy from assets because assets didn't change it


jkellogg01HOBBY

9 months ago

that makes sense


jkellogg01HOBBY

9 months ago

oh wait


jkellogg01HOBBY

9 months ago

if that's the case then COPY . ./ will already take care of that, right?


9 months ago

good catch, you are right, updated


9 months ago

you catch on fast


jkellogg01HOBBY

9 months ago

lol I try


jkellogg01HOBBY

9 months ago

let's see if this works then


jkellogg01HOBBY

9 months ago

oh oh oh my bad


jkellogg01HOBBY

9 months ago

did not copy the views folder into the assets phase so that tailwind could read from it


jkellogg01HOBBY

9 months ago

also the go build failed because I didn't organize my imports lol. hodl


jkellogg01HOBBY

9 months ago

OKAYYYYYY šŸŽ‰ IT WORKED


9 months ago

are you keeping the dist folder out of github?


jkellogg01HOBBY

9 months ago

I would post a screenshot of the successful build screen if I knew how to take a screenshot on this computer. I guess I should figure out how to do that. But it works!


jkellogg01HOBBY

9 months ago

yep


jkellogg01HOBBY

9 months ago

only because I'm only putting the style.css in it for not


jkellogg01HOBBY

9 months ago

now


jkellogg01HOBBY

9 months ago

I had a lot of internal turmoil about whether or not a font is distributable but I decided to just keep them in static so i could just put dist/ in my .gitignore


9 months ago

always, always make sure to keep the dist or build folders out of github, as whatever would end up in them should be done by the build


9 months ago

if its static like fonts then static is what you want and that goes to github


jkellogg01HOBBY

9 months ago

yeah that's what I was thinking putting fonts in static


jkellogg01HOBBY

9 months ago

glad that was the right call


jkellogg01HOBBY

9 months ago

now I have to rebuild the fonts from source because firefox doesn't like unhinted ttfs


jkellogg01HOBBY

9 months ago

but first im gonna go make some coffee lol


jkellogg01HOBBY

9 months ago

thanks so much for your help!


9 months ago

happy to help!