How to pass Prisma database url at build time with docker secrets? - docker

I am trying to dockerize an express app using prisma and supabase, but am unable to get prisma to set the supabase url at build time with docker. Prisma is expecting the url to be in an environment variable named DATABASE_URL. To avoid exposing the url I am passing it as a secret to docker and trying to set it an an environment variable but cannot get it to work. Here are two different approaches I've tried with my Dockerfile:
Dockerfile
# syntax=docker/dockerfile:1.2
FROM node:18.9.0
WORKDIR /app
COPY package*.json .
COPY yarn.lock .
COPY prisma .
RUN --mount=type=secret,id=_env,dst=/etc/secrets/.env \
export $(egrep -v '^#' /etc/secrets/.env | xargs) \
&& yarn install
RUN --mount=type=secret,id=_env,dst=/etc/secrets/.env \
export $(egrep -v '^#' /etc/secrets/.env | xargs) \
&& yarn prisma generate
COPY . .
RUN yarn build
CMD ["yarn", "start:dev"]
Dockerfile2
# syntax=docker/dockerfile:1.2
FROM node:18.9.0
WORKDIR /app
COPY package*.json .
COPY yarn.lock .
COPY prisma .
RUN --mount=type=secret,id=dburl \
DATABASE_URL="$(cat /run/secrets/dburl)" \
&& yarn install
RUN --mount=type=secret,id=dburl \
DATABASE_URL="$(cat /run/secrets/dburl)" \
&& yarn prisma generate
COPY . .
RUN yarn build
CMD ["yarn", "start:dev"]
The build commands for each one are the following respectively:
docker build --progress=plain --no-cache --secret id=_env,src=.env .
docker build --progress=plain --no-cache --secret id=dburl,src=dburl.txt .
Whenever I try this the first call to the prisma client inside the app produces a segmentation fault and crashes the app, whereas it works fine outside of the docker container.
Any help would be greatly appreciated.

Turns out either method actually works. The segmentation fault issue is another problem entirely:
https://github.com/prisma/prisma/issues/10649

Related

Docker build is using cache for COPY command even if my files have changed

I have a Dockerfile that is as follow:
FROM node:14-alpine as frontend-builder
WORKDIR /app/frontend
COPY ./frontend .
ENV PATH ./node_modules/.bin/:$PATH
RUN set -ex; \
yarn install --frozen-lockfile --production; \
yarn cache clean; \
yarn run build
CMD ["tail", "-f", "/dev/null"]
I have changed one file in frontend folder and re-run the build and docker is using the cache...I know i can force to build with --no-cache but how can i tweak docker so it detects changes in my files instead of no-cache option ?

Lambda docker image won't start if i overwrite entrypoint from lambda console

I have this Dockerfile
ARG FUNCTION_DIR="/opt/"
FROM node:10.13-alpine#sha256:22c8219b21f86dfd7398ce1f62c48a022fecdcf0ad7bf3b0681131bd04a023a2 AS BUILD_IMAGE
ARG FUNCTION_DIR
RUN apk --update add cmake autoconf automake libtool binutils libexecinfo-dev python2 gcc make g++ zlib-dev
ENV NODE_ENV=production
ENV PYTHON=/usr/bin/python2
RUN mkdir -p ${FUNCTION_DIR}
WORKDIR ${FUNCTION_DIR}
COPY package.json yarn.lock ./
RUN yarn --frozen-lockfile
RUN npm prune --production
RUN yarn cache clean
RUN npm cache clean --force
FROM node:10.13-alpine#sha256:22c8219b21f86dfd7398ce1f62c48a022fecdcf0ad7bf3b0681131bd04a023a2
ARG FUNCTION_DIR
ENV NODE_ENV=production
ENV NODE_OPTIONS=--max_old_space_size=4096
RUN apk update \
&& apk upgrade \
&& apk add mongodb-tools fontconfig dumb-init \
&& rm -rf /var/cache/apk/*
RUN mkdir -p ${FUNCTION_DIR}
WORKDIR ${FUNCTION_DIR}
COPY --from=BUILD_IMAGE ${FUNCTION_DIR}/node_modules ./node_modules
COPY . .
RUN if [ -f core/config/local.js ]; then rm core/config/local.js; fi
RUN cp core/config/local.js.aws.readonly core/config/local.js
USER node
EXPOSE 8080
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["node", "app.js", "--app=search", "--env=production"]
I use this Dockerfile to generate an image (called core-a) that run our application in K8s. I've added some code inside my application to handle the case our application is launched from a lambda function and i've created another Dockerfile like the one above but using custom ENTRYPOINT and CMD setting this values.
ENTRYPOINT [ "/usr/local/bin/npx", "aws-lambda-ric" ]
CMD [ "apps/search/index.handler" ]
Than i deployed this image called core-b to ecr using core-b as docker image for a lambda function and everything works as expected.
After that i thought that i can use the possibility to overwrite entrypoint and CMD in order to use the same docker image for both environments, so i modified Lambda function's image pointing to core-a and using the entrypoint and cmd values i used in core-b dockerfile, but doing so i get an error
Couldn't find valid bootstrap(s): [\"/usr/local/bin/npx\"]
Did anyone have any suggestion ?
Try to remove the quotation marks (" ") when entering the override value in this web form.
These AWS docs unfortunately have an uncorrect note that say to use the quotation marks on each string.

Why can't I build and then run my container locally

I have a multi stage Dockerfile
# Base Build
FROM alpine:3.7 AS base
RUN apk add --no-cache nodejs
WORKDIR /root/app
COPY . .
ARG TARGET_ENV
COPY .env.$TARGET_ENV .env
RUN rm .env.*
RUN npm set progress=false && npm config set depth 0
RUN npm install --only=production
RUN cp -R node_modules prod_node_modules
RUN npm install
RUN npm run build
# Prod Build
FROM base AS release
COPY --from=base /root/app/prod_node_modules ./node_modules
COPY --from=base /root/app/package.json .
COPY --from=base /root/app/package-lock.json .
COPY --from=base /root/app/dist .
CMD npm start
EXPOSE 3000
I'd like to build my container and then run it locally.
It builds just fine but when I run it a hash is output, but the container is not running.
docker build --build-arg TARGET_ENV=local -t express-app .
docker run -d -p 3000:3000 -it express-app
Your container could be crashing on start.
Check the output of $ docker run -p 3000:3000 -it express-app for error messages.

Unable to find view inside docker container

I'm using a containerized ASP.Net Core (2.1) app. The container is running Debian Stretch. Everything is working fine except this one small detail - whenever I want to use Rotativa I get this message:
Unable to find view '/app/wwwroot/templates/IssuedInvoice.cshtml'. The following locations were searched:\n/app/wwwroot/templates/IssuedInvoice.cshtml
That would very probably mean that file does not exist. Fair enough, I go into the docker container and issue cat /app/wwwroot/templates/IssuedInvoice.cshtml and what do I find? The file is listed without any errors.
Have anyone encountered such problem? I don't think that's a permission issue since the app runs inside the container as root anyway.
I have tested this outside of the container and everything works fine, same on Debug and Release configurations.
Dockerfile
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ["JTEPanel.Api/JTEPanel.Api.csproj", "JTEPanel.Api/"]
COPY ["JTEPanel.Infrastructure/JTEPanel.Infrastructure.csproj", "JTEPanel.Infrastructure/"]
COPY ["JTEPanel.SmsApi/JTEPanel.SmsApi.csproj", "JTEPanel.SmsApi/"]
COPY ["JTEPanel.Domain/JTEPanel.Domain.csproj", "JTEPanel.Domain/"]
COPY ["JTEPanel.Common/JTEPanel.Common.csproj", "JTEPanel.Common/"]
RUN dotnet restore "JTEPanel.Api/JTEPanel.Api.csproj"
COPY . .
WORKDIR "/src/JTEPanel.Api"
RUN dotnet build "JTEPanel.Api.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "JTEPanel.Api.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
VOLUME /app/wwwroot
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y locales libgdiplus wkhtmltopdf
RUN ln -s /usr/bin/wkhtmltopdf /app/wwwroot/Rotativa/wkhtmltopdf
RUN sed -i -e 's/# pl_PL.UTF-8 UTF-8/pl_PL.UTF-8 UTF-8/' /etc/locale.gen && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=pl_PL.UTF-8
ENV LANG pl_PL.UTF-8
ENTRYPOINT ["dotnet", "JTEPanel.Api.dll"]

Dockerfile: How can I build my project before copying only the needed files to the image?

FROM golang:1.8
RUN apt-get -y update && apt-get install -y curl
RUN go get -u github.com/gorilla/mux
RUN go get github.com/mattn/go-sqlite3
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - && \
apt-get install -y nodejs
COPY . /go/src/beginnerapp
WORKDIR ./src/beginnerapp/beginner-app-react
RUN npm run build
RUN go install beginnerapp/
WORKDIR /go/src/beginnerapp/beginner-app-react
VOLUME /go/src/beginnerapp/local-db
WORKDIR /go/src/beginnerapp
ENTRYPOINT /go/bin/beginnerapp
EXPOSE 8080
At the start, the golang project as well as the reactjs code don't exist on the image and need to be copied over before being able to build (js) / install (golang). Is there a way I can do that build/install process before copying files over to the image? Ideally I'd only need to copy over the golang executable and reactjs production build.
Yes this is possible now using multi stage builds. The idea is that you can have multiple FROM in your docker file and your main image will be built using the last FROM. Below is a sample pseudo structure
FROM node:latest as reactbuild
WORKDIR /app
COPY . .
RUN webpack build
FROM golang:latest as gobuild
WORKDIR /app
COPY . .
RUN go build
FROM alpine
WORKDIR /app
COPY --from=gobuild /app/myapp /app/myapp
COPY --from=reactbuild /app/dist /app/dist
Please read below article for more details
https://docs.docker.com/engine/userguide/eng-image/multistage-build/

Resources