first commit
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
# The web Dockerfile is copy-pasted into our main docs at /docs/handbook/deploying-with-docker.
|
||||
# Make sure you update this Dockerfile, the Dockerfile in the web workspace and copy that over to Dockerfile in the docs.
|
||||
FROM node:24.14.1-alpine AS base
|
||||
|
||||
FROM base AS builder
|
||||
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||
RUN apk add --no-cache libc6-compat
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
RUN npm install -g turbo
|
||||
COPY . .
|
||||
RUN turbo prune --scope=api --docker
|
||||
|
||||
# Add lockfile and package.json's of isolated subworkspace
|
||||
FROM base AS installer
|
||||
|
||||
RUN apk add --no-cache libc6-compat
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN npm install -g corepack@latest
|
||||
RUN corepack enable
|
||||
|
||||
# First install dependencies (as they change less often)
|
||||
COPY --from=builder /app/out/json/ .
|
||||
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
|
||||
RUN pnpm install --frozen-lockfile
|
||||
RUN pnpm install -w source-map-support
|
||||
|
||||
# Build the project and its dependencies
|
||||
COPY --from=builder /app/out/full/ .
|
||||
COPY turbo.json ./
|
||||
COPY .turbo/ ./.turbo/
|
||||
|
||||
RUN pnpm dlx turbo run build --filter=api...
|
||||
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
# Don't run production as root
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nestjs
|
||||
USER nestjs
|
||||
|
||||
COPY --from=installer --chown=nestjs:nodejs /app .
|
||||
|
||||
CMD ["node", "-r", "source-map-support/register", "apps/api/dist/main.js"]
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ ${1} == "help" || "$#" -lt 2 ]]; then
|
||||
echo "Usage: sh ${0} APP VER"
|
||||
echo "APP APP of docker image"
|
||||
echo " ex. api, web, docs"
|
||||
echo "VER Version of docker image"
|
||||
echo " ex. 1.0.0, 1.1.0, ..."
|
||||
exit;
|
||||
fi
|
||||
|
||||
APP=${1}
|
||||
VER=${2}
|
||||
IMAGE="user-feedback/${APP}"
|
||||
TAG="${IMAGE}:${VER}"
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
DOCKER_DIR="$( cd "${DIR}" >/dev/null 2>&1 && pwd )"
|
||||
APP_DIR="$( cd "${DIR}/../" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
DOCKER_FILE=${DOCKER_DIR}/${1}.dockerfile
|
||||
|
||||
echo ""
|
||||
echo "DOCKER_FILE:${DOCKER_FILE}"
|
||||
echo "TAG:${TAG}"
|
||||
echo ""
|
||||
echo "docker image build start - ${TAG}"
|
||||
|
||||
docker build -t ${TAG} -f ${DOCKER_FILE} ${APP_DIR}
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "docker image build failed - ${TAG}"
|
||||
exit -1;
|
||||
fi
|
||||
|
||||
echo "docker image build done - ${TAG}"
|
||||
@@ -0,0 +1,21 @@
|
||||
group "default" {
|
||||
targets = ["api", "web"]
|
||||
}
|
||||
|
||||
target "api" {
|
||||
context = "."
|
||||
dockerfile = "./docker/api.dockerfile"
|
||||
tags = ["line/abc-user-feedback-api:latest"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8"]
|
||||
cache-from = ["type=gha"]
|
||||
cache-to = ["type=gha,mode=max"]
|
||||
}
|
||||
|
||||
target "web" {
|
||||
context = "."
|
||||
dockerfile = "./docker/web.dockerfile"
|
||||
tags = ["line/abc-user-feedback-web:latest"]
|
||||
platforms = ["linux/amd64", "linux/arm64/v8"]
|
||||
cache-from = ["type=gha"]
|
||||
cache-to = ["type=gha,mode=max"]
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
name: abc-user-feedback
|
||||
|
||||
services:
|
||||
web:
|
||||
image: line/abc-user-feedback-web:latest
|
||||
environment:
|
||||
- NEXT_PUBLIC_API_BASE_URL=http://localhost:4000
|
||||
- SUPPORT_API_BASE_URL=http://secretary-api:8010
|
||||
ports:
|
||||
- 3002:3000
|
||||
depends_on:
|
||||
- api
|
||||
- secretary-api
|
||||
restart: unless-stopped
|
||||
|
||||
api:
|
||||
image: line/abc-user-feedback-api:latest
|
||||
environment:
|
||||
- JWT_SECRET=jwtsecretjwtsecretjwtsecret
|
||||
- MYSQL_PRIMARY_URL=mysql://userfeedback:userfeedback@mysql:3306/userfeedback
|
||||
- SMTP_HOST=smtp4dev
|
||||
- SMTP_PORT=25
|
||||
- SMTP_SENDER=user@feedback.com
|
||||
- OPENSEARCH_USE=true
|
||||
- OPENSEARCH_NODE=http://opensearch-node:9200
|
||||
ports:
|
||||
- 4000:4000
|
||||
restart: unless-stopped
|
||||
|
||||
secretary-api:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/secretary-api.dockerfile
|
||||
environment:
|
||||
- APP_NAME=secretary-api
|
||||
- APP_ENV=local
|
||||
- APP_HOST=0.0.0.0
|
||||
- APP_PORT=8010
|
||||
- DATABASE_URL=mysql+pymysql://baron_support:baron_support@mysql-secretary:3306/baron_support
|
||||
- ABC_API_BASE_URL=http://api:4000
|
||||
- ABC_API_KEY=3B1B08761D2DD0B9C021
|
||||
- ABC_PROJECT_ID=1
|
||||
- ABC_CHANNEL_ID=1
|
||||
- UPLOAD_ROOT_DIR=/app/uploads
|
||||
ports:
|
||||
- 8010:8010
|
||||
depends_on:
|
||||
- api
|
||||
- mysql-secretary
|
||||
volumes:
|
||||
- ../uploads:/app/uploads
|
||||
restart: unless-stopped
|
||||
@@ -0,0 +1,38 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
web:
|
||||
hostname: web
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/web.dockerfile
|
||||
restart: always
|
||||
ports:
|
||||
- 3000:3000
|
||||
extra_hosts:
|
||||
- 'host.docker.internal:host-gateway'
|
||||
environment:
|
||||
- NEXT_PUBLIC_API_BASE_URL=http://localhost:4000
|
||||
depends_on:
|
||||
- api
|
||||
|
||||
api:
|
||||
hostname: api
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/api.dockerfile
|
||||
restart: always
|
||||
ports:
|
||||
- 4000:4000
|
||||
extra_hosts:
|
||||
- 'host.docker.internal:host-gateway'
|
||||
environment:
|
||||
- JWT_SECRET=jwtsecretjwtsecretjwtsecret
|
||||
- MYSQL_PRIMARY_URL=mysql://userfeedback:userfeedback@host.docker.internal:13307/e2e
|
||||
- SMTP_HOST=localhost
|
||||
- SMTP_PORT=25
|
||||
- SMTP_SENDER=abc@feedback.user
|
||||
- APP_PORT=4000
|
||||
- AUTO_MIGRATION=true
|
||||
- MASTER_API_KEY=MASTER_API_KEY
|
||||
- NODE_OPTIONS="--max_old_space_size=3072"
|
||||
@@ -0,0 +1,115 @@
|
||||
name: abc-user-feedback
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
command:
|
||||
[
|
||||
"--default-authentication-plugin=mysql_native_password",
|
||||
"--collation-server=utf8mb4_bin",
|
||||
]
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: userfeedback
|
||||
MYSQL_DATABASE: userfeedback
|
||||
MYSQL_USER: userfeedback
|
||||
MYSQL_PASSWORD: userfeedback
|
||||
TZ: UTC
|
||||
ports:
|
||||
- 13306:3306
|
||||
volumes:
|
||||
- mysql:/var/lib/mysql
|
||||
restart: unless-stopped
|
||||
|
||||
mysql-secretary:
|
||||
hostname: mysql-secretary
|
||||
image: mysql:8.0
|
||||
command:
|
||||
[
|
||||
"--default-authentication-plugin=mysql_native_password",
|
||||
"--collation-server=utf8mb4_bin",
|
||||
]
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: baron_support
|
||||
MYSQL_DATABASE: baron_support
|
||||
MYSQL_USER: baron_support
|
||||
MYSQL_PASSWORD: baron_support
|
||||
TZ: UTC
|
||||
ports:
|
||||
- 13308:3306
|
||||
volumes:
|
||||
- mysql-secretary:/var/lib/mysql
|
||||
restart: unless-stopped
|
||||
|
||||
mysql-for-e2e:
|
||||
hostname: mysql-for-e2e
|
||||
image: mysql:8.0
|
||||
command:
|
||||
[
|
||||
"--default-authentication-plugin=mysql_native_password",
|
||||
"--collation-server=utf8mb4_bin",
|
||||
]
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: userfeedback
|
||||
MYSQL_DATABASE: e2e
|
||||
MYSQL_USER: userfeedback
|
||||
MYSQL_PASSWORD: userfeedback
|
||||
TZ: UTC
|
||||
ports:
|
||||
- 13307:3306
|
||||
volumes:
|
||||
- mysql-for-e2e:/var/lib/mysql-for-e2e
|
||||
restart: unless-stopped
|
||||
|
||||
smtp4dev:
|
||||
image: rnwood/smtp4dev:v3
|
||||
ports:
|
||||
- 5080:80
|
||||
- 25:25
|
||||
- 143:143
|
||||
volumes:
|
||||
- smtp4dev:/smtp4dev
|
||||
restart: unless-stopped
|
||||
|
||||
# optional for better performance on searching feedbacks
|
||||
opensearch-node:
|
||||
image: opensearchproject/opensearch:2.16.0
|
||||
restart: always
|
||||
environment:
|
||||
- cluster.name=opensearch-cluster
|
||||
- node.name=opensearch-node
|
||||
- discovery.type=single-node
|
||||
- bootstrap.memory_lock=true
|
||||
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
- plugins.security.disabled=true
|
||||
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=UserFeedback123!@#
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
nofile:
|
||||
soft: 65536
|
||||
hard: 65536
|
||||
volumes:
|
||||
- opensearch:/usr/share/opensearch/data
|
||||
ports:
|
||||
- 9200:9200
|
||||
- 9600:9600
|
||||
|
||||
# optional for opensearch
|
||||
opensearch-dashboards:
|
||||
image: opensearchproject/opensearch-dashboards:2.16.0
|
||||
restart: always
|
||||
ports:
|
||||
- 5601:5601
|
||||
environment:
|
||||
- 'OPENSEARCH_HOSTS=["http://opensearch-node:9200"]'
|
||||
- "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true"
|
||||
depends_on:
|
||||
- opensearch-node
|
||||
|
||||
volumes:
|
||||
mysql:
|
||||
mysql-secretary:
|
||||
mysql-for-e2e:
|
||||
smtp4dev:
|
||||
opensearch:
|
||||
@@ -0,0 +1,52 @@
|
||||
name: abc-user-feedback-vector
|
||||
|
||||
services:
|
||||
opensearch-node:
|
||||
image: opensearchproject/opensearch:2.19.4
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- cluster.name=opensearch-cluster
|
||||
- node.name=opensearch-node
|
||||
- discovery.type=single-node
|
||||
- bootstrap.memory_lock=true
|
||||
- 'OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m'
|
||||
- plugins.security.disabled=true
|
||||
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=UserFeedback123!@#
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
nofile:
|
||||
soft: 65536
|
||||
hard: 65536
|
||||
volumes:
|
||||
- opensearch-data:/usr/share/opensearch/data
|
||||
ports:
|
||||
- '9201:9200'
|
||||
- '9601:9600'
|
||||
|
||||
opensearch-dashboards:
|
||||
image: opensearchproject/opensearch-dashboards:2.19.4
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- '5602:5601'
|
||||
environment:
|
||||
- 'OPENSEARCH_HOSTS=["http://opensearch-node:9200"]'
|
||||
- 'DISABLE_SECURITY_DASHBOARDS_PLUGIN=true'
|
||||
depends_on:
|
||||
- opensearch-node
|
||||
|
||||
vector:
|
||||
image: timberio/vector:latest-alpine
|
||||
command: ['--config', '/etc/vector/vector.yml']
|
||||
volumes:
|
||||
- ./vector.yml:/etc/vector/vector.yml:ro
|
||||
ports:
|
||||
- '4319:4319' # OTLP HTTP
|
||||
- '4317:4317' # OTLP gRPC
|
||||
depends_on:
|
||||
- opensearch-node
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
opensearch-data:
|
||||
@@ -0,0 +1,4 @@
|
||||
services:
|
||||
smtp4dev:
|
||||
ports:
|
||||
- 5080:80
|
||||
@@ -0,0 +1,132 @@
|
||||
name: abc-user-feedback
|
||||
services:
|
||||
web:
|
||||
image: line/abc-user-feedback-web:latest
|
||||
environment:
|
||||
- NEXT_PUBLIC_API_BASE_URL=http://localhost:4000
|
||||
- SUPPORT_API_BASE_URL=http://secretary-api:8010
|
||||
ports:
|
||||
- 3002:3000
|
||||
depends_on:
|
||||
- api
|
||||
- secretary-api
|
||||
restart: unless-stopped
|
||||
|
||||
api:
|
||||
image: line/abc-user-feedback-api:latest
|
||||
environment:
|
||||
- JWT_SECRET=jwtsecretjwtsecretjwtsecret
|
||||
- MYSQL_PRIMARY_URL=mysql://userfeedback:userfeedback@mysql:3306/userfeedback
|
||||
- SMTP_HOST=smtp4dev
|
||||
- SMTP_PORT=25
|
||||
- SMTP_SENDER=user@feedback.com
|
||||
# - OPENSEARCH_USE=true
|
||||
# - OPENSEARCH_NODE=http://opensearch-node:9200
|
||||
ports:
|
||||
- 4000:4000
|
||||
depends_on:
|
||||
- mysql
|
||||
restart: unless-stopped
|
||||
|
||||
secretary-api:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/secretary-api.dockerfile
|
||||
environment:
|
||||
- APP_NAME=secretary-api
|
||||
- APP_ENV=local
|
||||
- APP_HOST=0.0.0.0
|
||||
- APP_PORT=8010
|
||||
- DATABASE_URL=mysql+pymysql://baron_support:baron_support@mysql-secretary:3306/baron_support
|
||||
- ABC_API_BASE_URL=http://api:4000
|
||||
- ABC_API_KEY=3B1B08761D2DD0B9C021
|
||||
- ABC_PROJECT_ID=1
|
||||
- ABC_CHANNEL_ID=1
|
||||
- UPLOAD_ROOT_DIR=/app/uploads
|
||||
ports:
|
||||
- 8010:8010
|
||||
depends_on:
|
||||
- api
|
||||
- mysql-secretary
|
||||
volumes:
|
||||
- ../uploads:/app/uploads
|
||||
restart: unless-stopped
|
||||
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
command:
|
||||
[
|
||||
'--default-authentication-plugin=mysql_native_password',
|
||||
'--collation-server=utf8mb4_bin',
|
||||
]
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: userfeedback
|
||||
MYSQL_DATABASE: userfeedback
|
||||
MYSQL_USER: userfeedback
|
||||
MYSQL_PASSWORD: userfeedback
|
||||
TZ: UTC
|
||||
ports:
|
||||
- 13306:3306
|
||||
volumes:
|
||||
- mysql:/var/lib/mysql
|
||||
restart: unless-stopped
|
||||
|
||||
mysql-secretary:
|
||||
hostname: mysql-secretary
|
||||
image: mysql:8.0
|
||||
command:
|
||||
[
|
||||
'--default-authentication-plugin=mysql_native_password',
|
||||
'--collation-server=utf8mb4_bin',
|
||||
]
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: baron_support
|
||||
MYSQL_DATABASE: baron_support
|
||||
MYSQL_USER: baron_support
|
||||
MYSQL_PASSWORD: baron_support
|
||||
TZ: UTC
|
||||
ports:
|
||||
- 13308:3306
|
||||
volumes:
|
||||
- mysql-secretary:/var/lib/mysql
|
||||
restart: unless-stopped
|
||||
|
||||
smtp4dev:
|
||||
image: rnwood/smtp4dev:v3
|
||||
ports:
|
||||
- 5080:80
|
||||
- 25:25
|
||||
- 143:143
|
||||
volumes:
|
||||
- smtp4dev:/smtp4dev
|
||||
restart: unless-stopped
|
||||
|
||||
# opensearch-node:
|
||||
# image: opensearchproject/opensearch:2.16.0
|
||||
# restart: unless-stopped
|
||||
# environment:
|
||||
# - cluster.name=opensearch-cluster
|
||||
# - node.name=opensearch-node
|
||||
# - discovery.type=single-node
|
||||
# - bootstrap.memory_lock=true
|
||||
# - 'OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m'
|
||||
# - plugins.security.disabled=true
|
||||
# - OPENSEARCH_INITIAL_ADMIN_PASSWORD=UserFeedback123!@#
|
||||
# ulimits:
|
||||
# memlock:
|
||||
# soft: -1
|
||||
# hard: -1
|
||||
# nofile:
|
||||
# soft: 65536
|
||||
# hard: 65536
|
||||
# volumes:
|
||||
# - opensearch:/usr/share/opensearch/data
|
||||
# ports:
|
||||
# - 9200:9200
|
||||
# - 9600:9600
|
||||
|
||||
volumes:
|
||||
mysql:
|
||||
mysql-secretary:
|
||||
smtp4dev:
|
||||
# opensearch:
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
FROM node:24.14.1-alpine AS base
|
||||
|
||||
# ---- Builder Stage ----
|
||||
FROM base AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN npm install -g turbo
|
||||
|
||||
COPY . .
|
||||
|
||||
# Only isolate needed parts for docs
|
||||
RUN turbo prune --scope=docs --docker
|
||||
|
||||
# ---- Installer Stage ----
|
||||
FROM base AS installer
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
# Copy pruned workspace
|
||||
COPY --from=builder /app/out/json/ .
|
||||
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
|
||||
|
||||
# Install only necessary dependencies
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Copy full source for build
|
||||
COPY --from=builder /app/out/full/ .
|
||||
COPY turbo.json ./
|
||||
COPY .turbo/ ./.turbo/
|
||||
COPY .git/ ./.git/
|
||||
|
||||
# Build Docusaurus
|
||||
RUN pnpm dlx turbo run build --filter=docs...
|
||||
|
||||
|
||||
# ---- Runner Stage ----
|
||||
FROM installer AS runner
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
WORKDIR /app/apps/docs
|
||||
CMD ["pnpm", "start", "--host", "0.0.0.0", "--no-open"]
|
||||
@@ -0,0 +1,21 @@
|
||||
FROM python:3.12-slim
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1
|
||||
|
||||
WORKDIR /app/apps/secretary-api
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends build-essential default-libmysqlclient-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY apps/secretary-api/pyproject.toml ./pyproject.toml
|
||||
COPY apps/secretary-api/README.md ./README.md
|
||||
COPY apps/secretary-api/alembic.ini ./alembic.ini
|
||||
COPY apps/secretary-api/alembic ./alembic
|
||||
COPY apps/secretary-api/app ./app
|
||||
|
||||
RUN pip install --no-cache-dir --upgrade pip \
|
||||
&& pip install --no-cache-dir .
|
||||
|
||||
CMD ["sh", "-c", "alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port 8010"]
|
||||
@@ -0,0 +1,121 @@
|
||||
# ────────────────────────────────────────────────
|
||||
# Vector Pipeline: OTLP Logs → OpenSearch
|
||||
# ────────────────────────────────────────────────
|
||||
|
||||
api:
|
||||
enabled: true
|
||||
address: '0.0.0.0:8686'
|
||||
|
||||
sources:
|
||||
otlp_logs:
|
||||
type: opentelemetry
|
||||
grpc:
|
||||
address: '0.0.0.0:4317'
|
||||
http:
|
||||
address: '0.0.0.0:4319'
|
||||
|
||||
transforms:
|
||||
build_message:
|
||||
type: remap
|
||||
inputs:
|
||||
- otlp_logs.logs
|
||||
source: |
|
||||
# time
|
||||
if exists(.timestamp) && .timestamp != null {
|
||||
._time_str = format_timestamp!(.timestamp, "%H:%M:%S%.3f")
|
||||
} else { ._time_str = "" }
|
||||
|
||||
# level
|
||||
if exists(.severity_text) && .severity_text != null {
|
||||
._level = upcase(string!(.severity_text))
|
||||
} else { ._level = "INFO" }
|
||||
|
||||
# pid
|
||||
if exists(.resources."process.pid") && .resources."process.pid" != null {
|
||||
._pid_str = to_string!(.resources."process.pid")
|
||||
} else { ._pid_str = "" }
|
||||
|
||||
# message
|
||||
._orig_msg = ""
|
||||
if exists(.message) && .message != null {
|
||||
._orig_msg = string!(.message)
|
||||
}
|
||||
|
||||
# attrs json
|
||||
._json_str = ""
|
||||
if exists(.attributes) && .attributes != null {
|
||||
._json_str = encode_json(.attributes)
|
||||
}
|
||||
|
||||
# build
|
||||
if ._pid_str != "" {
|
||||
.message = "[" + ._time_str + "] " + ._level + " (" + ._pid_str + "): " + ._orig_msg
|
||||
} else {
|
||||
.message = "[" + ._time_str + "] " + ._level + ": " + ._orig_msg
|
||||
}
|
||||
|
||||
if ._json_str != "" && ._json_str != "{}" {
|
||||
.message = .message + " " + ._json_str
|
||||
}
|
||||
|
||||
# cleanup
|
||||
del(._time_str)
|
||||
del(._level)
|
||||
del(._pid_str)
|
||||
del(._orig_msg)
|
||||
del(._json_str)
|
||||
|
||||
if exists(.attributes) { del(.attributes) }
|
||||
|
||||
if exists(.resources."service.name") {
|
||||
.service.name = .resources."service.name"
|
||||
}
|
||||
if exists(.resources."service.version") {
|
||||
.service.version = .resources."service.version"
|
||||
}
|
||||
if exists(.resources) { del(.resources) }
|
||||
|
||||
sinks:
|
||||
opensearch:
|
||||
type: elasticsearch
|
||||
inputs:
|
||||
- build_message
|
||||
endpoints:
|
||||
- '${OPENSEARCH_ENDPOINT:-http://opensearch-node:9200}'
|
||||
auth:
|
||||
strategy: basic
|
||||
user: '${OPENSEARCH_USERNAME:-}'
|
||||
password: '${OPENSEARCH_PASSWORD:-}'
|
||||
tls:
|
||||
verify_certificate: ${OPENSEARCH_TLS_VERIFY:-false}
|
||||
api_version: v8
|
||||
opensearch_service_type: managed
|
||||
bulk:
|
||||
index: '${OPENSEARCH_INDEX_PREFIX:-logs}-%Y.%m.%d'
|
||||
action: index
|
||||
batch:
|
||||
max_bytes: 10485760 # 10MB
|
||||
timeout_secs: 5
|
||||
buffer:
|
||||
type: memory
|
||||
max_events: 10000
|
||||
when_full: block
|
||||
|
||||
console_out:
|
||||
type: console
|
||||
inputs:
|
||||
- build_message
|
||||
encoding:
|
||||
codec: json
|
||||
|
||||
drop_metrics:
|
||||
type: blackhole
|
||||
inputs:
|
||||
- otlp_logs.metrics
|
||||
print_interval_secs: 0
|
||||
|
||||
drop_traces:
|
||||
type: blackhole
|
||||
inputs:
|
||||
- otlp_logs.traces
|
||||
print_interval_secs: 0
|
||||
@@ -0,0 +1,68 @@
|
||||
# This Dockerfile is copy-pasted into our main docs at /docs/handbook/deploying-with-docker.
|
||||
# Make sure you update both files!
|
||||
FROM node:24.14.1-alpine AS base
|
||||
|
||||
FROM base AS builder
|
||||
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||
RUN apk add --no-cache libc6-compat
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
RUN npm install -g turbo
|
||||
COPY . .
|
||||
RUN turbo prune --scope=web --docker
|
||||
|
||||
# Add lockfile and package.json's of isolated subworkspace
|
||||
FROM base AS installer
|
||||
|
||||
RUN apk add --no-cache libc6-compat
|
||||
RUN apk --no-cache add --virtual .builds-deps build-base python3
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN npm install -g node-gyp corepack@latest
|
||||
RUN corepack enable
|
||||
|
||||
# First install the dependencies (as they change less often)
|
||||
COPY --from=builder /app/out/json/ .
|
||||
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Build the project
|
||||
COPY --from=builder /app/out/full/ .
|
||||
COPY turbo.json ./
|
||||
COPY .turbo/ ./.turbo/
|
||||
|
||||
|
||||
COPY --from=builder /app/apps/web/.env.build /app/apps/web/.env.production
|
||||
RUN SKIP_ENV_VALIDATION=true pnpm dlx turbo run build --filter=web...
|
||||
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
# install usermod and change node user to 1001
|
||||
RUN echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories
|
||||
RUN apk --no-cache add shadow
|
||||
RUN groupmod -g 1001 node \
|
||||
&& usermod -u 1001 -g 1001 node
|
||||
|
||||
# Don't run production as root
|
||||
RUN addgroup --system --gid 3000 nodejs
|
||||
RUN adduser --system -G nodejs --uid 1000 nextjs -D
|
||||
USER nextjs
|
||||
|
||||
COPY --from=installer /app/apps/web/next-i18next.config.js .
|
||||
COPY --from=installer /app/apps/web/next.config.js .
|
||||
COPY --from=installer /app/apps/web/package.json .
|
||||
COPY --from=installer /app/apps/web/.env.production ./apps/web/.env.production
|
||||
|
||||
# Automatically leverage output traces to reduce image size
|
||||
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
|
||||
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/entrypoint.sh ./apps/web/entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["apps/web/entrypoint.sh"]
|
||||
|
||||
CMD ["node", "apps/web/server.js"]
|
||||
Reference in New Issue
Block a user