From cc5edc3bc900575caa8502f2ac536a3462d35dc1 Mon Sep 17 00:00:00 2001 From: KoungQ Date: Tue, 5 May 2026 12:04:17 +0900 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=EC=BB=A8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=84=88=20JFR/JMC=20=EA=B8=B0=EB=A1=9D=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 4 ++++ .gitignore | 8 +++++++- docker-compose.yml | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index 10321c48..dad317c2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,6 +3,10 @@ .gradle build out +logs +*.jfr +*.hprof +gc.log* *.iml .idea **/.DS_Store diff --git a/.gitignore b/.gitignore index a311993f..12b265ae 100644 --- a/.gitignore +++ b/.gitignore @@ -55,7 +55,13 @@ pinpoint-agent/tools/ .env /analysis/ +### JVM profiling artifacts ### +logs/ +*.jfr +*.hprof +gc.log* + # macOS artefacts .DS_Store -docs/ \ No newline at end of file +docs/ diff --git a/docker-compose.yml b/docker-compose.yml index bf88b1fe..1dbec3db 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,8 +46,11 @@ services: - PINPOINT_APPLICATION_NAME=dorumdorum - PINPOINT_AGENT_ID=${PINPOINT_AGENT_ID:-dorumdorum-backend-${HOSTNAME}} - PINPOINT_AGENT_NAME=${PINPOINT_AGENT_NAME:-dorumdorum-be} + - JFR_RUN_ID=${JFR_RUN_ID:-cloud-load-test} + - JAVA_OPTS=${JAVA_OPTS:--XX:StartFlightRecording=name=dorumdorum,settings=profile,disk=true,dumponexit=true,filename=/app/logs/jfr/dorumdorum-${JFR_RUN_ID:-cloud-load-test}.jfr,maxage=30m,maxsize=512m} volumes: - ./firebase-service-account.json:/app/firebase-service-account.json:ro + - ./logs/jfr:/app/logs/jfr depends_on: postgres: condition: service_healthy From 6cfefb100942a360b45687d09f75e67d26caeeed Mon Sep 17 00:00:00 2001 From: KoungQ Date: Tue, 5 May 2026 12:41:02 +0900 Subject: [PATCH 02/11] =?UTF-8?q?chore:=20=EC=8B=9C=ED=81=AC=EB=A6=BF=20?= =?UTF-8?q?=EC=84=9C=EB=B8=8C=EB=AA=A8=EB=93=88=20=EA=B8=B0=EB=B0=98=20?= =?UTF-8?q?=EB=B0=B0=ED=8F=AC=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 2 ++ .gitmodules | 3 +++ docker-compose.yml | 4 ++-- secrets | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .gitmodules create mode 160000 secrets diff --git a/.dockerignore b/.dockerignore index dad317c2..a5364460 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,8 @@ .git .github .gradle +.env +secrets build out logs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..392a0f4e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "secrets"] + path = secrets + url = https://github.com/DorumDorum/secrets diff --git a/docker-compose.yml b/docker-compose.yml index 1dbec3db..f6e8d00c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -38,7 +38,7 @@ services: - "8080:8080" stop_grace_period: 45s env_file: - - .env + - ./secrets/.env environment: - REDIS_HOST=redis - REDIS_PORT=6379 @@ -49,7 +49,7 @@ services: - JFR_RUN_ID=${JFR_RUN_ID:-cloud-load-test} - JAVA_OPTS=${JAVA_OPTS:--XX:StartFlightRecording=name=dorumdorum,settings=profile,disk=true,dumponexit=true,filename=/app/logs/jfr/dorumdorum-${JFR_RUN_ID:-cloud-load-test}.jfr,maxage=30m,maxsize=512m} volumes: - - ./firebase-service-account.json:/app/firebase-service-account.json:ro + - ./secrets/firebase-service-account.json:/app/firebase-service-account.json:ro - ./logs/jfr:/app/logs/jfr depends_on: postgres: diff --git a/secrets b/secrets new file mode 160000 index 00000000..5d9f67fa --- /dev/null +++ b/secrets @@ -0,0 +1 @@ +Subproject commit 5d9f67fa14d9368c18ca68365c765fc7314ba555 From 672b1bb992c3003b28c578fbaea8551c3e1611e1 Mon Sep 17 00:00:00 2001 From: KoungQ Date: Tue, 5 May 2026 13:11:42 +0900 Subject: [PATCH 03/11] =?UTF-8?q?feat:=20=EC=BB=A8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=84=88=20JFR/JMC=20=EA=B8=B0=EB=A1=9D=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- Dockerfile.pinpoint | 4 ++-- docker-compose.yml | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 83d51c1e..0b6e5462 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,4 +17,4 @@ COPY --from=builder /app/build/libs/*.jar app.jar EXPOSE 8080 -ENTRYPOINT ["sh", "-c", "exec java ${JAVA_OPTS} -Dspring.profiles.active=${SPRING_PROFILES_ACTIVE:-prod} -jar /app/app.jar"] +ENTRYPOINT ["sh", "-c", "DEFAULT_JAVA_OPTS=\"-XX:StartFlightRecording=name=dorumdorum,settings=${JFR_SETTINGS:-profile},disk=true,dumponexit=true,filename=/app/logs/jfr/dorumdorum-${JFR_RUN_ID:-cloud-load-test}.jfr,maxage=${JFR_MAX_AGE:-30m},maxsize=${JFR_MAX_SIZE:-512m}\"; EFFECTIVE_JAVA_OPTS=\"${JAVA_OPTS:-$DEFAULT_JAVA_OPTS}\"; exec java ${EFFECTIVE_JAVA_OPTS} -Dspring.profiles.active=${SPRING_PROFILES_ACTIVE:-prod} -jar /app/app.jar"] diff --git a/Dockerfile.pinpoint b/Dockerfile.pinpoint index ccbffc8e..9bcca926 100644 --- a/Dockerfile.pinpoint +++ b/Dockerfile.pinpoint @@ -38,12 +38,12 @@ EXPOSE 8080 # pinpoint-root.config에서 Collector IP 오버라이드 (profiler.transport.grpc.collector.ip) # -D 옵션으로 전달 -ENTRYPOINT ["sh", "-c", "java \ +ENTRYPOINT ["sh", "-c", "DEFAULT_JAVA_OPTS=\"-XX:StartFlightRecording=name=dorumdorum,settings=${JFR_SETTINGS:-profile},disk=true,dumponexit=true,filename=/app/logs/jfr/dorumdorum-${JFR_RUN_ID:-cloud-load-test}.jfr,maxage=${JFR_MAX_AGE:-30m},maxsize=${JFR_MAX_SIZE:-512m}\"; EFFECTIVE_JAVA_OPTS=\"${JAVA_OPTS:-$DEFAULT_JAVA_OPTS}\"; java \ -javaagent:/app/pinpoint-agent/pinpoint-bootstrap-${PINPOINT_VERSION}.jar \ -Dpinpoint.agentId=${PINPOINT_AGENT_ID} \ -Dpinpoint.applicationName=${PINPOINT_APPLICATION_NAME} \ -Dprofiler.transport.grpc.collector.ip=${PINPOINT_COLLECTOR_IP} \ -Dpinpoint.container=true \ - ${JAVA_OPTS} \ + ${EFFECTIVE_JAVA_OPTS} \ -Dspring.profiles.active=${SPRING_PROFILES_ACTIVE:-prod} \ -jar /app/app.jar"] diff --git a/docker-compose.yml b/docker-compose.yml index f6e8d00c..7ca60a9c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,8 +46,6 @@ services: - PINPOINT_APPLICATION_NAME=dorumdorum - PINPOINT_AGENT_ID=${PINPOINT_AGENT_ID:-dorumdorum-backend-${HOSTNAME}} - PINPOINT_AGENT_NAME=${PINPOINT_AGENT_NAME:-dorumdorum-be} - - JFR_RUN_ID=${JFR_RUN_ID:-cloud-load-test} - - JAVA_OPTS=${JAVA_OPTS:--XX:StartFlightRecording=name=dorumdorum,settings=profile,disk=true,dumponexit=true,filename=/app/logs/jfr/dorumdorum-${JFR_RUN_ID:-cloud-load-test}.jfr,maxage=30m,maxsize=512m} volumes: - ./secrets/firebase-service-account.json:/app/firebase-service-account.json:ro - ./logs/jfr:/app/logs/jfr @@ -125,7 +123,7 @@ services: image: pinpointdocker/pinpoint-web:2.5.4 container_name: pinpoint-web env_file: - - .env + - ./secrets/.env depends_on: - pinpoint-hbase networks: From 88d39d2267fd802c63f0747238cf1997373255d1 Mon Sep 17 00:00:00 2001 From: KoungQ Date: Tue, 5 May 2026 13:12:12 +0900 Subject: [PATCH 04/11] =?UTF-8?q?refactor:=20CD=20=ED=8C=8C=EC=9D=B4?= =?UTF-8?q?=ED=94=84=EB=9D=BC=EC=9D=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cicd.yml | 116 +++++++++++++------------------------ 1 file changed, 41 insertions(+), 75 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 620ddb46..229eaf7d 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -1,4 +1,7 @@ # CI/CD에 필요한 GitHub Secrets (Repo Settings > Secrets and variables > Actions) +# - Docker Hub: DOCKERHUB_USERNAME, DOCKERHUB_TOKEN +# - Server: SERVER_HOST, SERVER_USER, SERVER_SSH_KEY, SERVER_SSH_PORT +# - GitHub repo/submodule access: GITHUB_TOKEN name: cicd @@ -118,18 +121,6 @@ jobs: IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/dorumdorum-be:pinpoint DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - FIREBASE_SERVICE_ACCOUNT_B64: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_B64 }} - RDB_USERNAME: ${{ secrets.RDB_USERNAME }} - RDB_URL: ${{ secrets.RDB_URL }} - RDB_PASSWORD: ${{ secrets.RDB_PASSWORD }} - MYSQL_ROOT_PASSWORD: ${{ secrets.MYSQL_ROOT_PASSWORD }} - MYSQL_DATABASE: ${{ secrets.MYSQL_DATABASE }} - JWT_KEY: ${{ secrets.JWT_KEY }} - JWT_ACCESS_EXPIRATION: ${{ secrets.JWT_ACCESS_EXPIRATION }} - JWT_REFRESH_EXPIRATION: ${{ secrets.JWT_REFRESH_EXPIRATION }} - SMTP_USERNAME: ${{ secrets.SMTP_USERNAME }} - SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }} - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} CONTAINER_NAME: dorumdorum-be GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPO_FULL_NAME: ${{ github.repository }} @@ -138,56 +129,11 @@ jobs: username: ${{ secrets.SERVER_USER }} key: ${{ secrets.SERVER_SSH_KEY }} port: ${{ secrets.SERVER_SSH_PORT }} - envs: IMAGE,DOCKERHUB_USERNAME,DOCKERHUB_TOKEN,FIREBASE_SERVICE_ACCOUNT_B64,RDB_USERNAME,RDB_URL,RDB_PASSWORD,MYSQL_ROOT_PASSWORD,MYSQL_DATABASE,JWT_KEY,JWT_ACCESS_EXPIRATION,JWT_REFRESH_EXPIRATION,SMTP_USERNAME,SMTP_PASSWORD,CONTAINER_NAME,GITHUB_TOKEN,REPO_FULL_NAME,DISCORD_WEBHOOK + envs: IMAGE,DOCKERHUB_USERNAME,DOCKERHUB_TOKEN,CONTAINER_NAME,GITHUB_TOKEN,REPO_FULL_NAME script_stop: true script: | set -e - echo ">>> [Deploy] SSH 연결됨, 환경 변수 정규화 중..." - - RDB_USERNAME="$(printf '%s' "$RDB_USERNAME" | tr -d '\r\n')" - RDB_URL="$(printf '%s' "$RDB_URL" | tr -d '\r\n')" - RDB_PASSWORD="$(printf '%s' "$RDB_PASSWORD" | tr -d '\r\n')" - MYSQL_ROOT_PASSWORD="$(printf '%s' "$MYSQL_ROOT_PASSWORD" | tr -d '\r\n')" - MYSQL_DATABASE="$(printf '%s' "$MYSQL_DATABASE" | tr -d '\r\n')" - JWT_KEY="$(printf '%s' "$JWT_KEY" | tr -d '\r\n')" - JWT_ACCESS_EXPIRATION="$(printf '%s' "$JWT_ACCESS_EXPIRATION" | tr -d '\r\n')" - JWT_REFRESH_EXPIRATION="$(printf '%s' "$JWT_REFRESH_EXPIRATION" | tr -d '\r\n')" - SMTP_USERNAME="$(printf '%s' "$SMTP_USERNAME" | tr -d '\r\n')" - SMTP_PASSWORD="$(printf '%s' "$SMTP_PASSWORD" | tr -d '\r\n')" - - DEPLOY_PATH="${HOME}/dorumdorum" - mkdir -p "$DEPLOY_PATH" - cd "$DEPLOY_PATH" - echo ">>> [Deploy] DEPLOY_PATH=$DEPLOY_PATH" - - # 1) Firebase 서비스 계정 파일 생성 (VM에 저장) - printf '%s' "$FIREBASE_SERVICE_ACCOUNT_B64" | base64 -d > firebase-service-account.json - chmod 600 firebase-service-account.json - - # 2) 컨테이너에서 참조할 경로를 env로 고정 - FIREBASE_SERVICE_ACCOUNT_PATH="/app/firebase-service-account.json" - - # 3) .env 생성 - # Pinpoint Web reads Spring datasource keys directly. - printf '%s\n' \ - "SPRING_PROFILES_ACTIVE=prod" \ - "RDB_USERNAME=$RDB_USERNAME" \ - "RDB_URL=$RDB_URL" \ - "RDB_PASSWORD=$RDB_PASSWORD" \ - "MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD" \ - "MYSQL_DATABASE=$MYSQL_DATABASE" \ - "SPRING_DATASOURCE_URL=$RDB_URL" \ - "SPRING_DATASOURCE_USERNAME=$RDB_USERNAME" \ - "SPRING_DATASOURCE_PASSWORD=$RDB_PASSWORD" \ - "JWT_KEY=$JWT_KEY" \ - "JWT_ACCESS_EXPIRATION=$JWT_ACCESS_EXPIRATION" \ - "JWT_REFRESH_EXPIRATION=$JWT_REFRESH_EXPIRATION" \ - "SMTP_USERNAME=$SMTP_USERNAME" \ - "SMTP_PASSWORD=$SMTP_PASSWORD" \ - "DISCORD_WEBHOOK=$DISCORD_WEBHOOK" \ - "FIREBASE_SERVICE_ACCOUNT_PATH=$FIREBASE_SERVICE_ACCOUNT_PATH" > .env - chmod 600 .env - echo ">>> [Deploy] .env, firebase-service-account.json 생성 완료" + echo ">>> [Deploy] SSH 연결됨" docker info >/dev/null 2>&1 || { echo "Docker socket permission denied for current deploy user." @@ -198,8 +144,8 @@ jobs: echo "$DOCKERHUB_TOKEN" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin echo ">>> [Deploy] Docker Hub 로그인 완료" - echo ">>> [Deploy] MySQL 이미지 pull 중..." - docker pull mysql:8.0 + echo ">>> [Deploy] PostgreSQL 이미지 pull 중..." + docker pull postgres:16-alpine echo ">>> [Deploy] Redis 이미지 pull 중..." docker pull redis:7-alpine echo ">>> [Deploy] Backend 이미지 pull 중..." @@ -215,9 +161,14 @@ jobs: echo ">>> [Deploy] COMPOSE_PATH=$COMPOSE_PATH, Git clone 중..." rm -rf temp_repo - # Git에서 production 브랜치로 docker-compose.yml, monitoring 가져오기 + # Git에서 production 브랜치로 docker-compose.yml, monitoring, secrets submodule 가져오기 git clone --depth 1 -b production "https://x-access-token:${GITHUB_TOKEN}@github.com/${REPO_FULL_NAME}.git" temp_repo - echo ">>> [Deploy] Clone 완료, docker-compose.yml · monitoring 복사 중..." + ( + cd temp_repo + git -c url."https://x-access-token:${GITHUB_TOKEN}@github.com/".insteadOf="https://github.com/" \ + submodule update --init --recursive --depth 1 + ) + echo ">>> [Deploy] Clone 완료, docker-compose.yml · monitoring · secrets 복사 중..." if [ -f "temp_repo/BE/docker-compose.yml" ]; then cp temp_repo/BE/docker-compose.yml . @@ -248,6 +199,19 @@ jobs: mkdir -p monitoring/prometheus monitoring/grafana/provisioning/dashboards/json monitoring/grafana/provisioning/datasources fi + rm -rf secrets + if [ -d "temp_repo/BE/secrets" ]; then + cp -R temp_repo/BE/secrets . + echo ">>> [Deploy] BE/secrets 복사 완료" + elif [ -d "temp_repo/secrets" ]; then + cp -R temp_repo/secrets . + echo ">>> [Deploy] secrets 복사 완료" + else + echo "ERROR: secrets submodule directory not found in temp_repo/" + exit 1 + fi + chmod 600 secrets/.env secrets/firebase-service-account.json + rm -rf temp_repo echo ">>> [Deploy] temp_repo 삭제, compose 파일 확인 중..." @@ -257,21 +221,23 @@ jobs: ls -la exit 1 fi - - # .env 파일과 firebase-service-account.json 복사 - cp "$DEPLOY_PATH/.env" . - cp "$DEPLOY_PATH/firebase-service-account.json" . - echo ">>> [Deploy] .env, firebase-service-account.json 복사 완료" + + if [ ! -f "secrets/.env" ] || [ ! -f "secrets/firebase-service-account.json" ]; then + echo "ERROR: required secret files are missing" + ls -la secrets || true + exit 1 + fi # docker-compose로 모든 서비스 실행 export BACKEND_IMAGE="$IMAGE" export CONTAINER_NAME="$CONTAINER_NAME" + COMPOSE="docker compose --env-file secrets/.env -f docker-compose.yml" echo ">>> [Deploy] 기존 컨테이너 정리 (down + 이름으로 강제 제거)..." - docker compose -f docker-compose.yml down --remove-orphans >/dev/null 2>&1 || true + $COMPOSE down --remove-orphans >/dev/null 2>&1 || true docker rm -f dorumdorum-redis dorumdorum-be dorumdorum-prometheus dorumdorum-grafana zoo1 pinpoint-hbase pinpoint-collector pinpoint-web 2>/dev/null || true echo ">>> [Deploy] [1/6] ZooKeeper 기동..." - docker compose -f docker-compose.yml up -d zoo1 + $COMPOSE up -d zoo1 for i in $(seq 1 30); do if docker ps --format '{{.Names}}' | grep -q '^zoo1$'; then echo ">>> [Deploy] ZooKeeper up" @@ -281,7 +247,7 @@ jobs: done echo ">>> [Deploy] [2/6] HBase 기동..." - docker compose -f docker-compose.yml up -d pinpoint-hbase + $COMPOSE up -d pinpoint-hbase echo ">>> [Deploy] HBase 초기화 대기..." HBASE_READY=0 for i in $(seq 1 300); do @@ -305,7 +271,7 @@ jobs: fi echo ">>> [Deploy] [3/6] Pinpoint Collector 기동..." - docker compose -f docker-compose.yml up -d pinpoint-collector + $COMPOSE up -d pinpoint-collector COLLECTOR_READY=0 for i in $(seq 1 60); do if docker logs pinpoint-collector 2>&1 | grep -Eq "Started .*CollectorApp|Started CollectorApp"; then @@ -322,7 +288,7 @@ jobs: fi echo ">>> [Deploy] [4/6] Pinpoint Web 기동..." - docker compose -f docker-compose.yml up -d pinpoint-web + $COMPOSE up -d pinpoint-web WEB_READY=0 for i in $(seq 1 60); do if docker logs pinpoint-web 2>&1 | grep -Eq "Started .*WebApp|Started WebApp|Started .*PinpointWebApplication"; then @@ -339,10 +305,10 @@ jobs: fi echo ">>> [Deploy] [5/6] Backend 기동..." - docker compose -f docker-compose.yml up -d backend + $COMPOSE up -d backend echo ">>> [Deploy] [6/6] Redis/Monitoring 기동..." - docker compose -f docker-compose.yml up -d redis prometheus grafana + $COMPOSE up -d redis prometheus grafana echo ">>> [Deploy] 오래된 이미지 정리 중..." docker image prune -af --filter "until=168h" From 4ca6234fa95bcf417d0554c70614b5a050a391af Mon Sep 17 00:00:00 2001 From: KoungQ Date: Sun, 10 May 2026 13:29:54 +0900 Subject: [PATCH 05/11] =?UTF-8?q?chore:=20JVM=20GC=20=ED=8A=9C=EB=8B=9D?= =?UTF-8?q?=EC=9A=A9=20k6=20=EB=B6=80=ED=95=98=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=ED=99=98=EA=B2=BD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + docker-compose.yml | 44 +- load-testing/README.md | 16 + load-testing/k6/.gitkeep | 1 + .../dashboards/json/k6-jvm-gc-load-test.json | 776 ++++++++++++++++++ 5 files changed, 834 insertions(+), 6 deletions(-) create mode 100644 load-testing/README.md create mode 100644 load-testing/k6/.gitkeep create mode 100644 monitoring/grafana/provisioning/dashboards/json/k6-jvm-gc-load-test.json diff --git a/.gitignore b/.gitignore index 12b265ae..7534d640 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,9 @@ logs/ *.hprof gc.log* +### k6 load test artifacts ### +load-testing/results/ + # macOS artefacts .DS_Store diff --git a/docker-compose.yml b/docker-compose.yml index 7ca60a9c..4e4c978c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,15 +40,19 @@ services: env_file: - ./secrets/.env environment: - - REDIS_HOST=redis - - REDIS_PORT=6379 - - PINPOINT_COLLECTOR_IP=pinpoint-collector - - PINPOINT_APPLICATION_NAME=dorumdorum - - PINPOINT_AGENT_ID=${PINPOINT_AGENT_ID:-dorumdorum-backend-${HOSTNAME}} - - PINPOINT_AGENT_NAME=${PINPOINT_AGENT_NAME:-dorumdorum-be} + REDIS_HOST: redis + REDIS_PORT: 6379 + PINPOINT_COLLECTOR_IP: pinpoint-collector + PINPOINT_APPLICATION_NAME: dorumdorum + PINPOINT_AGENT_ID: ${PINPOINT_AGENT_ID:-dorumdorum-backend-local} + PINPOINT_AGENT_NAME: ${PINPOINT_AGENT_NAME:-dorumdorum-be} + JAVA_TOOL_OPTIONS: >- + ${JAVA_TOOL_OPTIONS:--XX:+UseG1GC -XX:InitialRAMPercentage=50.0 -XX:MaxRAMPercentage=75.0 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/logs/heapdump -XX:+ExitOnOutOfMemoryError -Xlog:gc*,safepoint:file=/app/logs/gc/gc.log:time,uptime,level,tags:filecount=10,filesize=50m} volumes: - ./secrets/firebase-service-account.json:/app/firebase-service-account.json:ro - ./logs/jfr:/app/logs/jfr + - ./logs/gc:/app/logs/gc + - ./logs/heapdump:/app/logs/heapdump depends_on: postgres: condition: service_healthy @@ -56,6 +60,8 @@ services: condition: service_started pinpoint-collector: condition: service_started + cpus: ${BACKEND_CPU_LIMIT:-4.0} + mem_limit: ${BACKEND_MEMORY_LIMIT:-16g} deploy: resources: limits: @@ -153,12 +159,38 @@ services: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.path=/prometheus" - "--web.enable-lifecycle" + - "--web.enable-remote-write-receiver" extra_hosts: - "host.docker.internal:host-gateway" restart: unless-stopped networks: - dorumdorum-net + k6: + image: ${K6_IMAGE:-grafana/k6:latest} + container_name: dorumdorum-k6 + profiles: + - loadtest + environment: + BASE_URL: ${K6_BASE_URL:-http://backend:8080} + K6_OUT: ${K6_OUT:-experimental-prometheus-rw} + K6_PROMETHEUS_RW_SERVER_URL: ${K6_PROMETHEUS_RW_SERVER_URL:-http://prometheus:9090/api/v1/write} + K6_PROMETHEUS_RW_PUSH_INTERVAL: ${K6_PROMETHEUS_RW_PUSH_INTERVAL:-5s} + K6_PROMETHEUS_RW_TREND_STATS: ${K6_PROMETHEUS_RW_TREND_STATS:-p(90),p(95),p(99),min,max,avg} + K6_PROMETHEUS_RW_STALE_MARKERS: ${K6_PROMETHEUS_RW_STALE_MARKERS:-true} + K6_WEB_DASHBOARD: ${K6_WEB_DASHBOARD:-true} + K6_WEB_DASHBOARD_EXPORT: ${K6_WEB_DASHBOARD_EXPORT:-/results/k6-report.html} + volumes: + - ./load-testing/k6:/scripts:ro + - ./load-testing/results:/results + working_dir: /scripts + entrypoint: ["k6"] + depends_on: + - backend + - prometheus + networks: + - dorumdorum-net + grafana: image: grafana/grafana:11.2.0 container_name: dorumdorum-grafana diff --git a/load-testing/README.md b/load-testing/README.md new file mode 100644 index 00000000..026fd456 --- /dev/null +++ b/load-testing/README.md @@ -0,0 +1,16 @@ +# k6 Load Testing + +This directory is reserved for k6 load-test assets. Test scripts are intentionally not included. + +Place scripts under `load-testing/k6/` when needed, then run: + +```sh +docker compose --profile loadtest run --rm k6 run --tag testid=gc-baseline /scripts/