epicweb-dev / epic-stack

This is a Full Stack app starter with the foundational things setup and configured for you to hit the ground running on your next EPIC idea.
https://www.epicweb.dev/epic-stack
MIT License
4.89k stars 397 forks source link

Deployment fails on fly.io with healthchecks failing #234

Closed SangeetAgarwal closed 1 year ago

SangeetAgarwal commented 1 year ago

I'm attempting to deploy an app source code. This has no database access whatsoever so my new Dockerfile looks like so. I haven't changed any of the defaults except for nuking all the dB related stuff.

I had successfully deployed an indie stack version [source ] earlier and all I'm attempting to do is deploy an epic stack version.

base node image

FROM node:18-bullseye-slim as base

set for base and all layer that inherit from it

ENV NODE_ENV production

Install all node_modules, including dev dependencies

FROM base as deps

WORKDIR /myapp

ADD package.json package-lock.json .npmrc ./ RUN npm install --include=dev

Setup production node_modules

FROM base as production-deps

WORKDIR /myapp

COPY --from=deps /myapp/node_modules /myapp/node_modules ADD package.json package-lock.json .npmrc ./ RUN npm prune --omit=dev

Build the app

FROM base as build

WORKDIR /myapp

COPY --from=deps /myapp/node_modules /myapp/node_modules

ADD . . RUN npm run build

Finally, build the production image with minimal footprint

FROM base

ENV FLY="true" ENV INTERNAL_PORT="8080" ENV PORT="8081" ENV NODE_ENV="production"

WORKDIR /myapp

COPY --from=production-deps /myapp/node_modules /myapp/node_modules

COPY --from=build /myapp/server-build /myapp/server-build COPY --from=build /myapp/build /myapp/build COPY --from=build /myapp/public /myapp/public COPY --from=build /myapp/package.json /myapp/package.json COPY --from=build /myapp/app/data /myapp/app/data COPY --from=build /myapp/app/components /myapp/app/components COPY --from=build /myapp/app/layouts /myapp/app/layouts COPY --from=build /myapp/app/lib /myapp/app/lib

ADD . .

CMD ["mount"]

fly.toml is as follows

app = "epic-starter-blog" primary_region = "iad" kill_signal = "SIGINT" kill_timeout = 5 processes = [ ]

[experimental] allowed_public_ports = [ ] auto_rollback = true

[mounts] source = "data" destination = "/data"

[deploy] release_command = "node ./other/sentry-create-release"

[[services]] internal_port = 8080 processes = [ "app" ] protocol = "tcp" script_checks = [ ]

[services.concurrency] hard_limit = 100 soft_limit = 80 type = "connections"

[[services.ports]] handlers = [ "http" ] port = 80 force_https = true

[[services.ports]] handlers = [ "tls", "http" ] port = 443

[[services.tcp_checks]] grace_period = "1s" interval = "15s" restart_limit = 0 timeout = "2s"

[[services.http_checks]] interval = "10s" grace_period = "5s" method = "get" path = "/healthcheck" protocol = "http" timeout = "2000s" tls_skip_verify = false headers = { }

When I do fly logs then the o/p where it fails is as follows

2023-06-29T12:32:29Z app[91859e5a3e4e83] iad [info] INFO Main child exited normally with code: 0
the health check passes. 2023-06-29T12:32:41Z health[91859e5a3e4e83] iad [error]Health check on port 8080 has failed. Your app is not responding properly. Services exposed on ports [80, 443] will have intermittent failures until the health check passes.

I have been struggling with this for 24 hours or so, if someone could take a quick look & let me know what I might be missing.

kentcdodds commented 1 year ago

I suggest reaching out on https://community.fly.io because they can often look at your app and give you ideas of what could be wrong. Sorry you're having so much trouble!

eXaminator commented 1 year ago

I also came across this problem today and found the reason. The dockerfile specifies port 8081 as the default (ENV PORT="8081") but the fly.toml file specifies port 3000 as the default internal_port (at least that was the case for my project I just created today). This mismatch seems to be the reason. After changing the internal_port in fly.toml to 8081 it worked for me.

So it does seem to be a problem with the epic stack template?

kentcdodds commented 1 year ago

The template configures this correctly: https://github.com/epicweb-dev/epic-stack/blob/main/fly.toml#L19

eXaminator commented 1 year ago

Strange, it was wrong for me. That being said, 8080 is defined as INTERNAL_PORT in the Dockerfile, which I can only find being used in litefs.yml, while the servers index.ts seems to use the PORT variable, which is defined as 8081: https://github.com/epicweb-dev/epic-stack/blob/a55ca78909007099c2cdab073377fc74e262753b/server/index.ts#L137 https://github.com/epicweb-dev/epic-stack/blob/a55ca78909007099c2cdab073377fc74e262753b/other/Dockerfile#L53

So I still think there is a mistake or am I missing something else? I had to make sure that both PORT in Dockerfile and internal_port in fly.toml are the same for it to work, which they don't seem to be right now.

kentcdodds commented 1 year ago

The current setup is correct (it's used exactly this way to deploy the template app to https://www.epicstack.dev).

LiteFS runs a proxy server on 8080 and proxies all requests to 8081 which is where our app runs.

The 3000 is the fallback and is only used for local development.