5

Summary

I am running a Sveltkit (JS Framework) application with Prisma (ORM) which connects to PlanetScale (MySQL cloud database) without issue. When I run it in docker the application installs and runs but cannot connect to PlanetScale. How would I allow Docker to connect to PlanetScale?

Error

Failed to get with error Invalid prisma.category.findMany() invocation: Can't reach database server at aws-eu-west-2.connect.psdb.cloud:3306 Please make sure your database server is running at aws-eu-west-2.connect.psdb.cloud:3306.

I have confirmed the docker can connect to the internet but just has trouble connecting to PlanetScale database.

Code

MySQL Connection URI

Password is starred out but is correct in my .env file

DATABASE_URL='mysql://7m9rl9ecwydgs7d2oobp:********@aws-eu-west-2.connect.psdb.cloud/blog-database?sslaccept=strict'

Prisma

schema.prisma

generator client {     
    provider = "prisma-client-js"
    previewFeatures = ["referentialIntegrity"]
}

datasource db {
    provider = "mysql"
    url = env("DATABASE_URL")
    referentialIntegrity = "prisma"
}

prisma.ts

Helper functions

import { PrismaClient, type PrismaPromise, type Category } from '@prisma/client'

const prisma = new PrismaClient()

export function findAllCategory(): Promise<Array<Category>> {
    return prisma.category.findMany()
}

Docker

DockerFile

FROM node:18-alpine3.15 AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npx prisma generate
RUN npm run build && npm prune --production


FROM node:18-alpine3.15 
USER node:node
WORKDIR /app
COPY --from=builder --chown=node:node /app/build ./build
COPY --from=builder --chown=node:node /app/node_modules ./node_modules
COPY --chown=node:node prisma .
COPY --chown=node:node package.json .
COPY --chown=node:node .env .
ENV PORT 5050
EXPOSE 5050
CMD ["node", "build"]

Docker Commands

docker build . -t sveltekit:alpine
docker run -d -p 5050:5050 --name sveltekit-app sveltekit:alpine

Docker runs without issue but the error is displayed when going to http://localhost:5050

Update

I have moved environment variables into the docker command as suggested.

I have attempted the following but the error remains the same.

Env

I have also changed the environment variable to:

DATABASE_URL='mysql://7m9rl9ecwydgs7d2oobp:pscale_pw_6KmIc1RUngdwn3sURKzxfDe3Oo7GM0NFeoATFxxNSAG@aws-eu-west-2.connect.psdb.cloud/blog-database?sslaccept=strict&connect_timeout=300'

as suggested by other articles.

Dockerfile

I also updated to include all files and same ca-certificate.crt to check if it worked if all environments were the same and upped the version as some sources had issues with 16:

FROM node:17-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
RUN npm i mysql
COPY . .
RUN npx prisma generate
RUN npm run build

FROM node:17-alpine 
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/build ./build
COPY package.json .
COPY prisma ./prisma
COPY . .
COPY ca-certificates.crt /etc/ssl/certs/

EXPOSE 3000
ENTRYPOINT ["node", "build"]

Running MySQL CLI from Docker

Based on the comment I received from this post I installed mysql and mysql-client on my docker box.

mysql -h aws-eu-west-2.connect.psdb.cloud -u 7m9rl9ecwydgs7d2oobp -p************* --ssl-ca=
/etc/ssl/cert.pem

The following command worked successfully and I was able to access my PlanetScale database successfully. However prisma still throws the error. They are both using the same URI and port.

Workaround

After refreshing multiple times I was able to load the page, however it is very intermittent and refreshing again will cause the error again. I don't have this issue when I am not using docker.

Jed Peel
  • 166
  • 5
  • 1
    So, Docker uses (at least should use) the same network as your host machine. You shouldn't use a `.env` file in your container, though. Pass variables in the run command using `-e` or `--env-file` flags – OneCricketeer Sep 19 '22 at 13:17
  • me same so good question – dontknowhy Oct 26 '22 at 05:21

1 Answers1

4

After a long amount of searching I found a github issues page which contained some solutions.

Updating my docker file to node:16.15-alpine (the exact same node version as on my Ubuntu subsystem) and combining this with a previously attempted fix of adding 'connection_timeout=300' to my Database URL solved the issue with some caveats.

Dockerfile

FROM node:16.15-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npx prisma generate
RUN npm run build

FROM node:16.15-alpine 
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/build ./build
COPY package.json .
COPY prisma ./prisma
COPY .env /app/.env

EXPOSE 3000
ENTRYPOINT ["node", "build"]

.env

DATABASE_URL='mysql://7m9rl9ecwydgs7d2oobp:pscale_pw_6KmIc1RUngdwn3sURKzxfDe3Oo7GM0NFeoATFxxNSAG@aws-eu-west-2.connect.psdb.cloud/blog-database?sslaccept=strict&connect_timeout=300'

Caveats

Prisma fails on initial load after starting docker but refreshing resolves this. Reloading some pages for the first time also causes this issue but after this page load is reliable even when switching to incognito to remove cache.

This is a sufficient fix for my solution but I welcome further answers if there is a more reliable solution.

Jed Peel
  • 166
  • 5
  • I accidentally exposed my password above. New credentials have been made and old ones removed – Jed Peel Oct 01 '22 at 15:34
  • In my case, I forgot to run `sudo ufw allow 3306/tcp`. The only reason the connection was working from my home office was because I'd already allow-listed that IP address. – Ryan Feb 20 '23 at 02:21