Docker build updates
This commit is contained in:
parent
3e36aef9c5
commit
67a5b60ad5
34 changed files with 89 additions and 52 deletions
|
|
@ -33,18 +33,15 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
dumb-init
|
dumb-init
|
||||||
RUN mkdir -p ${APP_DIR}
|
RUN mkdir -p ${APP_DIR}
|
||||||
RUN chown -R node ${APP_DIR}/
|
|
||||||
|
|
||||||
USER node
|
|
||||||
WORKDIR ${APP_DIR}
|
WORKDIR ${APP_DIR}
|
||||||
COPY --from=installer ${APP_DIR}/node_modules/ ./node_modules/
|
COPY --from=installer ${APP_DIR}/node_modules/ ./node_modules/
|
||||||
COPY --from=installer ${APP_DIR}/apps/bridge-frontend/ ./apps/bridge-frontend/
|
COPY --from=installer ${APP_DIR}/apps/bridge-frontend/ ./apps/bridge-frontend/
|
||||||
COPY --from=installer ${APP_DIR}/package.json ./package.json
|
COPY --from=installer ${APP_DIR}/package.json ./package.json
|
||||||
USER root
|
RUN chown -R node:node ${APP_DIR}/
|
||||||
WORKDIR ${APP_DIR}/apps/bridge-frontend/
|
WORKDIR ${APP_DIR}/apps/bridge-frontend/
|
||||||
RUN chmod +x docker-entrypoint.sh
|
RUN chmod +x docker-entrypoint.sh
|
||||||
USER node
|
USER node
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
ENV PORT 3000
|
ENV PORT 3000
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
ENTRYPOINT ["/opt/link/apps/bridge-frontend/docker-entrypoint.sh"]
|
ENTRYPOINT ["/opt/bridge-frontend/apps/bridge-frontend/docker-entrypoint.sh"]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
echo "running migrations"
|
||||||
|
npm run migrate:up:all
|
||||||
echo "starting bridge-frontend"
|
echo "starting bridge-frontend"
|
||||||
exec dumb-init npm run start
|
exec dumb-init npm run start
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,11 @@
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint"
|
"lint": "next lint",
|
||||||
|
"migrate:up:all": "tsx database/migrate.ts up:all",
|
||||||
|
"migrate:up:one": "tsx database/migrate.ts up:one",
|
||||||
|
"migrate:down:all": "tsx database/migrate.ts down:all",
|
||||||
|
"migrate:down:one": "tsx database/migrate.ts down:one"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@auth/kysely-adapter": "^1.1.0",
|
"@auth/kysely-adapter": "^1.1.0",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
FROM node:18-alpine as base
|
FROM node:20-bookworm AS base
|
||||||
|
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
ARG APP_DIR=/opt/bridge-worker
|
ARG APP_DIR=/opt/bridge-worker
|
||||||
|
|
@ -11,22 +11,26 @@ RUN turbo prune --scope=bridge-worker --docker
|
||||||
FROM base AS installer
|
FROM base AS installer
|
||||||
ARG APP_DIR=/opt/bridge-worker
|
ARG APP_DIR=/opt/bridge-worker
|
||||||
WORKDIR ${APP_DIR}
|
WORKDIR ${APP_DIR}
|
||||||
COPY --from=builder ${APP_DIR}/.gitignore .gitignore
|
|
||||||
COPY --from=builder ${APP_DIR}/out/json/ .
|
COPY --from=builder ${APP_DIR}/out/json/ .
|
||||||
COPY --from=builder ${APP_DIR}/out/package-lock.json ./package-lock.json
|
|
||||||
COPY --from=builder ${APP_DIR}/out/full/ .
|
COPY --from=builder ${APP_DIR}/out/full/ .
|
||||||
|
COPY --from=builder ${APP_DIR}/out/package-lock.json ./package-lock.json
|
||||||
RUN npm ci
|
RUN npm ci
|
||||||
RUN npm i -g turbo
|
RUN npm i -g turbo
|
||||||
RUN turbo run build --filter=bridge-worker
|
RUN turbo run build --filter=bridge-worker
|
||||||
|
|
||||||
FROM graphile/worker:0.16.5 as runner
|
FROM base as runner
|
||||||
|
ARG BUILD_DATE
|
||||||
|
ARG VERSION
|
||||||
ARG APP_DIR=/opt/bridge-worker
|
ARG APP_DIR=/opt/bridge-worker
|
||||||
RUN mkdir -p ${APP_DIR}/
|
RUN mkdir -p ${APP_DIR}/
|
||||||
ARG BUILD_DIR=${APP_DIR}/apps/bridge-worker/build/main
|
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
|
||||||
RUN mkdir -p ${APP_DIR}/
|
apt-get install -y --no-install-recommends \
|
||||||
WORKDIR /worker
|
dumb-init
|
||||||
COPY --from=installer ${BUILD_DIR}/lib ${APP_DIR}/lib
|
WORKDIR ${APP_DIR}
|
||||||
COPY --from=installer ${BUILD_DIR}/tasks ${APP_DIR}/tasks
|
COPY --from=installer ${APP_DIR} ./
|
||||||
COPY --from=installer ${APP_DIR}/apps/bridge-worker/graphile.config.prod.js ./graphile.config.js
|
RUN chown -R node:node ${APP_DIR}
|
||||||
COPY --from=installer ${APP_DIR}/node_modules ${APP_DIR}/node_modules
|
WORKDIR ${APP_DIR}/apps/bridge-worker/
|
||||||
COPY --from=installer ${APP_DIR}/package.json ${APP_DIR}/package.json
|
RUN chmod +x docker-entrypoint.sh
|
||||||
|
USER node
|
||||||
|
ENV NODE_ENV production
|
||||||
|
ENTRYPOINT ["/opt/bridge-worker/apps/bridge-worker/docker-entrypoint.sh"]
|
||||||
|
|
|
||||||
5
apps/bridge-worker/docker-entrypoint.sh
Normal file
5
apps/bridge-worker/docker-entrypoint.sh
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
echo "starting bridge-worker"
|
||||||
|
exec dumb-init npm run start
|
||||||
|
|
@ -4,7 +4,7 @@ module.exports = {
|
||||||
maxPoolSize: 10,
|
maxPoolSize: 10,
|
||||||
pollInterval: 2000,
|
pollInterval: 2000,
|
||||||
concurrentJobs: 3,
|
concurrentJobs: 3,
|
||||||
taskDirectory: "/opt/bridge/tasks",
|
taskDirectory: "/opt/bridge-worker/apps/bridge-worker/build/main/tasks",
|
||||||
fileExtensions: [".js", ".cjs", ".mjs"],
|
fileExtensions: [".js", ".cjs", ".mjs"],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
26
apps/bridge-worker/index.ts
Normal file
26
apps/bridge-worker/index.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { run } from "graphile-worker";
|
||||||
|
import * as path from "path";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
|
||||||
|
const startWorker = async () => {
|
||||||
|
await run({
|
||||||
|
connectionString: process.env.DATABASE_URL,
|
||||||
|
concurrency: 10,
|
||||||
|
noHandleSignals: false,
|
||||||
|
pollInterval: 1000,
|
||||||
|
taskDirectory: `${__dirname}/tasks`,
|
||||||
|
// crontabFile: `${__dirname}/crontab`,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
|
await startWorker();
|
||||||
|
};
|
||||||
|
|
||||||
|
main().catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// import { SavedVoiceProvider } from "@digiresilience/bridge-db";
|
// import { SavedVoiceProvider } from "@digiresilience/bridge-db";
|
||||||
import Twilio from "twilio";
|
import Twilio from "twilio";
|
||||||
import { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
|
import { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
|
||||||
import { Zammad, getOrCreateUser } from "./zammad";
|
import { Zammad, getOrCreateUser } from "./zammad.js";
|
||||||
|
|
||||||
type SavedVoiceProvider = any;
|
type SavedVoiceProvider = any;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,13 @@
|
||||||
"name": "bridge-worker",
|
"name": "bridge-worker",
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"main": "build/main/index.js",
|
||||||
"author": "Darren Clarke <darren@redaranj.com>",
|
"author": "Darren Clarke <darren@redaranj.com>",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -p tsconfig.json",
|
"build": "tsc -p tsconfig.json",
|
||||||
"dev": "dotenv -- graphile-worker"
|
"dev": "dotenv -- graphile-worker",
|
||||||
|
"start": "node build/main/index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hapi/wreck": "^18.1.0",
|
"@hapi/wreck": "^18.1.0",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import { convert } from "html-to-text";
|
import { convert } from "html-to-text";
|
||||||
import { URLSearchParams } from "url";
|
import { URLSearchParams } from "url";
|
||||||
import { withDb, AppDatabase } from "../../lib/db";
|
import { withDb, AppDatabase } from "../../lib/db.js";
|
||||||
// import { loadConfig } from "@digiresilience/bridge-config";
|
// import { loadConfig } from "@digiresilience/bridge-config";
|
||||||
import { tagMap } from "../../lib/tag-map";
|
import { tagMap } from "../../lib/tag-map.js";
|
||||||
|
|
||||||
const config: any = {};
|
const config: any = {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
import { URLSearchParams } from "url";
|
import { URLSearchParams } from "url";
|
||||||
import { withDb, AppDatabase } from "../../lib/db";
|
import { withDb, AppDatabase } from "../../lib/db.js";
|
||||||
// import { loadConfig } from "@digiresilience/bridge-config";
|
// import { loadConfig } from "@digiresilience/bridge-config";
|
||||||
|
|
||||||
const config: any = {};
|
const config: any = {};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { db, getWorkerUtils } from "bridge-common";
|
// import { db, getWorkerUtils } from "bridge-common";
|
||||||
|
|
||||||
interface ReceiveSignalMessageTaskOptions {
|
interface ReceiveSignalMessageTaskOptions {
|
||||||
message: any;
|
message: any;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { db, getWorkerUtils } from "bridge-common";
|
// import { db, getWorkerUtils } from "bridge-common";
|
||||||
|
|
||||||
interface SendSignalMessageTaskOptions {
|
interface SendSignalMessageTaskOptions {
|
||||||
message: any;
|
message: any;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
// import logger from "../logger";
|
// import logger from "../logger";
|
||||||
// import { IncomingMessagev1 } from "@digiresilience/node-signald/build/main/generated";
|
// import { IncomingMessagev1 } from "@digiresilience/node-signald/build/main/generated";
|
||||||
import { withDb, AppDatabase } from "../../lib/db";
|
import { withDb, AppDatabase } from "../../lib/db.js";
|
||||||
import workerUtils from "../../lib/utils";
|
import workerUtils from "../../lib/utils.js";
|
||||||
|
|
||||||
type IncomingMessagev1 = any;
|
type IncomingMessagev1 = any;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { db, getWorkerUtils } from "bridge-common";
|
// import { db, getWorkerUtils } from "bridge-common";
|
||||||
|
|
||||||
interface ReceiveVoiceMessageTaskOptions {
|
interface ReceiveVoiceMessageTaskOptions {
|
||||||
message: any;
|
message: any;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { db, getWorkerUtils } from "bridge-common";
|
// import { db, getWorkerUtils } from "bridge-common";
|
||||||
|
|
||||||
interface SendVoiceMessageTaskOptions {
|
interface SendVoiceMessageTaskOptions {
|
||||||
message: any;
|
message: any;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import Wreck from "@hapi/wreck";
|
import Wreck from "@hapi/wreck";
|
||||||
import { withDb, AppDatabase } from "../../lib/db";
|
import { withDb, AppDatabase } from "../../lib/db.js";
|
||||||
import { twilioClientFor } from "../../lib/common";
|
import { twilioClientFor } from "../../lib/common.js";
|
||||||
import { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
|
import { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
|
||||||
import workerUtils from "../../lib/utils";
|
import workerUtils from "../../lib/utils.js";
|
||||||
|
|
||||||
interface WebhookPayload {
|
interface WebhookPayload {
|
||||||
startTime: string;
|
startTime: string;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { createHash } from "crypto";
|
import { createHash } from "crypto";
|
||||||
import { withDb, AppDatabase } from "../../lib/db";
|
import { withDb, AppDatabase } from "../../lib/db.js";
|
||||||
import { convert } from "../../lib/media-convert";
|
import { convert } from "../../lib/media-convert.js";
|
||||||
|
|
||||||
interface VoiceLineAudioUpdateTaskOptions {
|
interface VoiceLineAudioUpdateTaskOptions {
|
||||||
voiceLineId: string;
|
voiceLineId: string;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Twilio from "twilio";
|
import Twilio from "twilio";
|
||||||
// import config from "@digiresilience/bridge-config";
|
// import config from "@digiresilience/bridge-config";
|
||||||
import { withDb, AppDatabase } from "../../lib/db";
|
import { withDb, AppDatabase } from "../../lib/db.js";
|
||||||
|
|
||||||
const config: any = {};
|
const config: any = {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Twilio from "twilio";
|
import Twilio from "twilio";
|
||||||
// import config from "@digiresilience/bridge-config";
|
// import config from "@digiresilience/bridge-config";
|
||||||
import { withDb, AppDatabase } from "../../lib/db";
|
import { withDb, AppDatabase } from "../../lib/db.js";
|
||||||
|
|
||||||
const config: any = {};
|
const config: any = {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { db, getWorkerUtils } from "bridge-common";
|
// import { db, getWorkerUtils } from "bridge-common";
|
||||||
|
|
||||||
interface ReceiveWhatsappMessageTaskOptions {
|
interface ReceiveWhatsappMessageTaskOptions {
|
||||||
message: any;
|
message: any;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { db, getWorkerUtils } from "bridge-common";
|
// import { db, getWorkerUtils } from "bridge-common";
|
||||||
|
|
||||||
interface SendWhatsappMessageTaskOptions {
|
interface SendWhatsappMessageTaskOptions {
|
||||||
message: any;
|
message: any;
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,19 @@
|
||||||
"extends": "ts-config",
|
"extends": "ts-config",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "build/main",
|
"outDir": "build/main",
|
||||||
"module": "CommonJS",
|
"module": "esnext",
|
||||||
|
"target": "esnext",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"skipLibCheck": true
|
"skipLibCheck": true,
|
||||||
|
"moduleResolution": "node"
|
||||||
},
|
},
|
||||||
"ts-node": {
|
"ts-node": {
|
||||||
"esm": true,
|
"esm": true,
|
||||||
"experimentalSpecifierResolution": "node",
|
"experimentalSpecifierResolution": "node",
|
||||||
"transpileOnly": true,
|
"transpileOnly": true,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "ESNext",
|
"module": "esNext",
|
||||||
"target": "ESNext",
|
"target": "esNext",
|
||||||
"moduleResolution": "node"
|
"moduleResolution": "node"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
FROM node:20-bookworm AS base
|
FROM node:20-bookworm AS base
|
||||||
|
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
export { db } from "./lib/database";
|
export { db } from "./lib/database.js";
|
||||||
export type {
|
export type {
|
||||||
Database,
|
Database,
|
||||||
FacebookBot,
|
FacebookBot,
|
||||||
|
|
@ -7,5 +7,5 @@ export type {
|
||||||
VoiceLine,
|
VoiceLine,
|
||||||
Webhook,
|
Webhook,
|
||||||
User,
|
User,
|
||||||
} from "./lib/database";
|
} from "./lib/database.js";
|
||||||
export { getWorkerUtils } from "./lib/utils";
|
export { getWorkerUtils } from "./lib/utils.js";
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,7 @@
|
||||||
"author": "Darren Clarke <darren@redaranj.com>",
|
"author": "Darren Clarke <darren@redaranj.com>",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -p tsconfig.json",
|
"build": "tsc -p tsconfig.json"
|
||||||
"migrate:up:all": "tsx database/migrate.ts up:all",
|
|
||||||
"migrate:up:one": "tsx database/migrate.ts up:one",
|
|
||||||
"migrate:down:all": "tsx database/migrate.ts down:all",
|
|
||||||
"migrate:down:one": "tsx database/migrate.ts down:one"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@auth/kysely-adapter": "^1.1.0",
|
"@auth/kysely-adapter": "^1.1.0",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue