Initial Docker and docker compose setup

This commit is contained in:
Eric Allam
2023-06-21 17:07:14 +01:00
parent fd94a32b95
commit 8bba30e290
11 changed files with 344 additions and 99 deletions
-67
View File
@@ -1,67 +0,0 @@
FROM node:18-bullseye-slim AS pruner
RUN apt-get update && apt-get install -y openssl
WORKDIR /app
RUN yarn global add turbo
COPY . .
RUN turbo prune --scope=webapp --docker
RUN find . -name "node_modules" -type d -prune -exec rm -rf '{}' +
# Base strategy to have layer caching
FROM node:18-bullseye-slim AS base
RUN apt-get update && apt-get install -y openssl
WORKDIR /app
COPY .gitignore .gitignore
COPY --from=pruner /app/out/json/ .
COPY --from=pruner /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
COPY --from=pruner /app/out/pnpm-workspace.yaml ./pnpm-workspace.yaml
FROM base AS dev-deps
WORKDIR /app
RUN corepack enable
RUN pnpm install --ignore-scripts --no-frozen-lockfile
FROM base AS production-deps
WORKDIR /app
RUN corepack enable
ENV NODE_ENV production
RUN pnpm install --prod --no-frozen-lockfile
COPY --from=pruner /app/out/full/packages/database/prisma/schema.prisma /app/packages/database/prisma/schema.prisma
RUN pnpx prisma generate --schema /app/packages/database/prisma/schema.prisma
FROM base AS builder
WORKDIR /app
RUN corepack enable
# ENV NODE_ENV production
COPY --from=pruner /app/out/full/ .
COPY --from=dev-deps /app/ .
COPY turbo.json turbo.json
RUN pnpm run generate
RUN pnpm run build --filter=webapp...
# Runner
FROM node:18-bullseye-slim AS runner
RUN apt-get update && apt-get install -y openssl
WORKDIR /app
RUN corepack enable
ENV NODE_ENV production
# RUN addgroup --system --gid 1001 nodejs
# RUN adduser --system --uid 1001 remixjs
# RUN chown -R remixjs:nodejs /app
# USER remixjs
# COPY --from=pruner --chown=remixjs:nodejs /app/out/full/ .
# COPY --from=production-deps --chown=remixjs:nodejs /app .
# COPY --from=builder --chown=remixjs:nodejs /app/apps/remix-app/app/styles/tailwind.css ./apps/remix-app/app/styles/tailwind.css
# COPY --from=builder --chown=remixjs:nodejs /app/apps/remix-app/build/server.js ./apps/remix-app/build/server.js
# COPY --from=builder --chown=remixjs:nodejs /app/apps/remix-app/build ./apps/remix-app/build
# COPY --from=builder --chown=remixjs:nodejs /app/apps/remix-app/public ./apps/remix-app/public
COPY --from=pruner /app/out/full/ .
COPY --from=production-deps /app .
COPY --from=builder /app/apps/remix-app/app/styles/tailwind.css ./apps/remix-app/app/styles/tailwind.css
COPY --from=builder /app/apps/remix-app/build/server.js ./apps/remix-app/build/server.js
COPY --from=builder /app/apps/remix-app/build ./apps/remix-app/build
COPY --from=builder /app/apps/remix-app/public ./apps/remix-app/public
ENTRYPOINT ["pnpm", "--filter", "webapp", "run", "start"]
+1 -2
View File
@@ -11,7 +11,6 @@
"format": "prettier --write .",
"lint": "eslint --cache --cache-location ./node_modules/.cache/eslint .",
"start": "cross-env NODE_ENV=production node --max-old-space-size=8192 ./build/server.js",
"docker:build": "cd ../.. && docker build -t trigger-webapp -f ./apps/webapp/Dockerfile .",
"test": "vitest run",
"test:cov": "vitest run --coverage",
"test:e2e:dev": "start-server-and-test dev http://localhost:3000 \"npx cypress open\"",
@@ -238,4 +237,4 @@
"engines": {
"node": ">=16.0.0"
}
}
}
+2
View File
@@ -66,6 +66,8 @@ async function seedIntegrationAuthMethods() {
async function seed() {
await seedIntegrationAuthMethods();
// TODO: extract this into a separate file and put it behind some kind of env var
// Create a user, organization, and project
const user = await prisma.user.upsert({
where: {
-26
View File
@@ -1,26 +0,0 @@
version: "3.7"
volumes:
database:
driver: local
pulsardatav:
driver: local
services:
db:
image: postgres:latest
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
ports:
- "5432:5432"
volumes:
- database:/var/lib/postgresql/data
networks:
- app_network
networks:
app_network:
external: true
+24
View File
@@ -0,0 +1,24 @@
LOGIN_ORIGIN=http://localhost:3000
APP_ORIGIN=http://localhost:3000
# Encryption key that will be used to encrypt magic link tokens
MAGIC_LINK_SECRET=secret
# Encryption key that will be used to encrypt session cookies
SESSION_SECRET=secret
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=postgres
DATABASE_HOST=database:5432
DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB}
# Github sign in OAUTH client id and secret
GITHUB_CLIENT_ID=
GITHUB_SECRET=
# E-mail settings
FROM_EMAIL=
REPLY_TO_EMAIL=
RESEND_API_KEY=
NODE_ENV=production
+63
View File
@@ -0,0 +1,63 @@
FROM node:18 AS pruner
WORKDIR /triggerdotdev
COPY . .
RUN npx turbo prune --scope=webapp --docker
RUN find . -name "node_modules" -type d -prune -exec rm -rf '{}' +
# Base strategy to have layer caching
FROM node:18 AS base
RUN apt-get update && apt-get install -y openssl
WORKDIR /triggerdotdev
COPY .gitignore .gitignore
COPY --from=pruner /triggerdotdev/out/json/ .
COPY --from=pruner /triggerdotdev/out/pnpm-lock.yaml ./pnpm-lock.yaml
COPY --from=pruner /triggerdotdev/out/pnpm-workspace.yaml ./pnpm-workspace.yaml
## Dev deps
FROM base AS dev-deps
WORKDIR /triggerdotdev
# Corepack is used to install pnpm
RUN corepack enable
ENV NODE_ENV development
RUN pnpm install --ignore-scripts --no-frozen-lockfile
## Production deps
FROM base AS production-deps
WORKDIR /triggerdotdev
# Corepack is used to install pnpm
RUN corepack enable
ENV NODE_ENV production
RUN pnpm install --prod --no-frozen-lockfile
COPY --from=pruner /triggerdotdev/packages/database/prisma/schema.prisma /triggerdotdev/packages/database/prisma/schema.prisma
RUN pnpx prisma generate --schema /triggerdotdev/packages/database/prisma/schema.prisma
## Builder (builds the webapp)
FROM base AS builder
WORKDIR /triggerdotdev
# Corepack is used to install pnpm
RUN corepack enable
COPY --from=pruner /triggerdotdev/out/full/ .
COPY --from=dev-deps /triggerdotdev/ .
COPY turbo.json turbo.json
COPY docker/scripts ./scripts
RUN chmod +x ./scripts/entrypoint.sh
RUN pnpm run generate
RUN pnpm run build --filter=webapp...
# Runner
FROM node:18 AS runner
RUN apt-get update && apt-get install -y openssl
WORKDIR /triggerdotdev
RUN corepack enable
ENV NODE_ENV production
COPY --from=pruner /triggerdotdev/out/full/ .
COPY --from=production-deps /triggerdotdev .
COPY --from=builder /triggerdotdev/apps/webapp/build/server.js ./apps/webapp/build/server.js
COPY --from=builder /triggerdotdev/apps/webapp/build ./apps/webapp/build
COPY --from=builder /triggerdotdev/apps/webapp/public ./apps/webapp/public
COPY --from=builder /triggerdotdev/scripts ./scripts
CMD ["./scripts/entrypoint.sh"]
+21
View File
@@ -0,0 +1,21 @@
version: "3"
volumes:
database-data:
networks:
app_network:
external: false
services:
database:
container_name: database
image: postgres:latest
restart: always
volumes:
- database-data:/var/lib/postgresql/data/
env_file: .env
networks:
- app_network
ports:
- 5432:5432
+35
View File
@@ -0,0 +1,35 @@
version: "3"
volumes:
database-data:
networks:
app_network:
external: false
services:
webapp:
build:
context: ../
dockerfile: docker/Dockerfile
ports:
- 3000:3000
depends_on:
- database
env_file: .env
environment:
- DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB}
networks:
- app_network
database:
container_name: database
image: postgres:latest
restart: always
volumes:
- database-data:/var/lib/postgresql/data/
env_file: .env
networks:
- app_network
ports:
- 5432:5432
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
set -x
scripts/wait-for-it.sh ${DATABASE_HOST}:5432 -- echo "database is up"
npx prisma migrate deploy --schema /triggerdotdev/packages/database/prisma/schema.prisma
npx ts-node@latest --transpile-only /triggerdotdev/apps/webapp/prisma/seed.ts
npx turbo run start
+184
View File
@@ -0,0 +1,184 @@
#!/bin/sh
# The MIT License (MIT)
#
# Copyright (c) 2017 Eficode Oy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
set -- "$@" -- "$TIMEOUT" "$QUIET" "$PROTOCOL" "$HOST" "$PORT" "$result"
TIMEOUT=15
QUIET=0
# The protocol to make the request with, either "tcp" or "http"
PROTOCOL="tcp"
echoerr() {
if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
}
usage() {
exitcode="$1"
cat << USAGE >&2
Usage:
$0 host:port|url [-t timeout] [-- command args]
-q | --quiet Do not output any status messages
-t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit "$exitcode"
}
wait_for() {
case "$PROTOCOL" in
tcp)
if ! command -v nc >/dev/null; then
echoerr 'nc command is missing!'
exit 1
fi
;;
wget)
if ! command -v wget >/dev/null; then
echoerr 'wget command is missing!'
exit 1
fi
;;
esac
while :; do
case "$PROTOCOL" in
tcp)
nc -w 1 -z "$HOST" "$PORT" > /dev/null 2>&1
;;
http)
wget --timeout=1 -q "$HOST" -O /dev/null > /dev/null 2>&1
;;
*)
echoerr "Unknown protocol '$PROTOCOL'"
exit 1
;;
esac
result=$?
if [ $result -eq 0 ] ; then
if [ $# -gt 7 ] ; then
for result in $(seq $(($# - 7))); do
result=$1
shift
set -- "$@" "$result"
done
TIMEOUT=$2 QUIET=$3 PROTOCOL=$4 HOST=$5 PORT=$6 result=$7
shift 7
exec "$@"
fi
exit 0
fi
if [ "$TIMEOUT" -le 0 ]; then
break
fi
TIMEOUT=$((TIMEOUT - 1))
sleep 1
done
echo "Operation timed out" >&2
exit 1
}
while :; do
case "$1" in
http://*|https://*)
HOST="$1"
PROTOCOL="http"
shift 1
;;
*:* )
HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
shift 1
;;
-q | --quiet)
QUIET=1
shift 1
;;
-q-*)
QUIET=0
echoerr "Unknown option: $1"
usage 1
;;
-q*)
QUIET=1
result=$1
shift 1
set -- -"${result#-q}" "$@"
;;
-t | --timeout)
TIMEOUT="$2"
shift 2
;;
-t*)
TIMEOUT="${1#-t}"
shift 1
;;
--timeout=*)
TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
break
;;
--help)
usage 0
;;
-*)
QUIET=0
echoerr "Unknown option: $1"
usage 1
;;
*)
QUIET=0
echoerr "Unknown argument: $1"
usage 1
;;
esac
done
if ! [ "$TIMEOUT" -ge 0 ] 2>/dev/null; then
echoerr "Error: invalid timeout '$TIMEOUT'"
usage 3
fi
case "$PROTOCOL" in
tcp)
if [ "$HOST" = "" ] || [ "$PORT" = "" ]; then
echoerr "Error: you need to provide a host and port to test."
usage 2
fi
;;
http)
if [ "$HOST" = "" ]; then
echoerr "Error: you need to provide a host to test."
usage 2
fi
;;
esac
wait_for "$@"
+7 -4
View File
@@ -21,9 +21,12 @@
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"generate": "turbo run generate",
"lint": "turbo run lint",
"docker": "docker-compose -f docker-compose.yml up -d",
"docker:stop": "docker-compose -f docker-compose.yml stop",
"docker:build": "turbo run docker:build",
"docker:services": "docker-compose -f docker/compose-without-app.yml up -d",
"docker:services:stop": "docker-compose -f docker/compose-without-app.yml stop",
"docker:app": "docker-compose -p triggerv2 -f docker/compose.yml up -d",
"docker:app:build": "docker-compose -p triggerv2 -f docker/compose.yml build webapp",
"docker:app:stop": "docker-compose -p triggerv2 -f docker/compose.yml stop",
"docker:app:down": "docker-compose -p triggerv2 -f docker/compose.yml down",
"test": "turbo run test",
"test:dev": "turbo run test:dev",
"start": "turbo run start",
@@ -63,4 +66,4 @@
"@changesets/cli": "^2.26.0",
"node-fetch": "2.6.x"
}
}
}