Tailwind infinite build loop
jkellogg01
HOBBYOP

2 years 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() 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.

67 Replies

jkellogg01
HOBBYOP

2 years ago

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


2 years 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


jkellogg01
HOBBYOP

2 years ago

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


2 years ago

yeah 500MB on trial


jkellogg01
HOBBYOP

2 years 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


2 years 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?


jkellogg01
HOBBYOP

2 years ago

if i can be so real


jkellogg01
HOBBYOP

2 years ago

i thought this way would be easier


jkellogg01
HOBBYOP

2 years ago

that is the main reason


jkellogg01
HOBBYOP

2 years ago

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


jkellogg01
HOBBYOP

2 years ago

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


jkellogg01
HOBBYOP

2 years ago

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


2 years 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


jkellogg01
HOBBYOP

2 years ago

i see


jkellogg01
HOBBYOP

2 years ago

gotta go learn docker then. brb


2 years ago

you dont though


2 years ago

its just a text file


jkellogg01
HOBBYOP

2 years ago

oh i see


2 years ago

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


jkellogg01
HOBBYOP

2 years ago

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


2 years 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


jkellogg01
HOBBYOP

2 years ago

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


jkellogg01
HOBBYOP

2 years 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"]

jkellogg01
HOBBYOP

2 years ago

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


2 years 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


jkellogg01
HOBBYOP

2 years ago

ohhhh okay i can take care of that lol thank you


jkellogg01
HOBBYOP

2 years 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?


2 years ago

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


jkellogg01
HOBBYOP

2 years ago

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


2 years ago

it wont stay unless you copy it with --from


jkellogg01
HOBBYOP

2 years 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```


2 years 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"]

2 years ago

you where copying the wrong way


jkellogg01
HOBBYOP

2 years ago

oh okay


jkellogg01
HOBBYOP

2 years ago

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


jkellogg01
HOBBYOP

2 years 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


2 years ago

everything goes away unless you specifically copy it over


jkellogg01
HOBBYOP

2 years ago

okay cool


jkellogg01
HOBBYOP

2 years 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


2 years ago

updated


jkellogg01
HOBBYOP

2 years ago

gotcha


jkellogg01
HOBBYOP

2 years ago

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


jkellogg01
HOBBYOP

2 years ago

that makes sense


jkellogg01
HOBBYOP

2 years ago

oh wait


jkellogg01
HOBBYOP

2 years ago

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


2 years ago

good catch, you are right, updated


2 years ago

you catch on fast


jkellogg01
HOBBYOP

2 years ago

lol I try


jkellogg01
HOBBYOP

2 years ago

let's see if this works then


jkellogg01
HOBBYOP

2 years ago

oh oh oh my bad


jkellogg01
HOBBYOP

2 years ago

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


jkellogg01
HOBBYOP

2 years ago

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


jkellogg01
HOBBYOP

2 years ago

OKAYYYYYY 🎉 IT WORKED


2 years ago

are you keeping the dist folder out of github?


jkellogg01
HOBBYOP

2 years 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!


jkellogg01
HOBBYOP

2 years ago

yep


jkellogg01
HOBBYOP

2 years ago

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


jkellogg01
HOBBYOP

2 years ago

now


jkellogg01
HOBBYOP

2 years 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


2 years 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


2 years ago

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


jkellogg01
HOBBYOP

2 years ago

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


jkellogg01
HOBBYOP

2 years ago

glad that was the right call


jkellogg01
HOBBYOP

2 years ago

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


jkellogg01
HOBBYOP

2 years ago

but first im gonna go make some coffee lol


jkellogg01
HOBBYOP

2 years ago

thanks so much for your help!


2 years ago

happy to help!


Loading...