스토리지 서비스 추가 및 기존 MinIO 서비스 전환, 배포 및 설정 파일 개선

main
bjkim 2 months ago
parent 0f48a0d01e
commit cae77e2a12

@ -1,3 +1,3 @@
NODE_ENV = "prod"
VITE_APP_API_SERVER_URL = "http://cuuva.com:2481/autoflow-server-mgmt"
VITE_APP_API_SERVER_URL = "/autoflow-server-mgmt"
VITE_ROOT_PATH = "/autoflow"

@ -1,9 +0,0 @@
FROM nginx:stable-alpine
RUN apk --no-cache add tzdata && cp /usr/share/zoneinfo/Asia/Seoul /etc/localtime
COPY default.conf /etc/nginx/conf.d/default.conf
COPY dist/. /usr/share/nginx/html/autoflow
EXPOSE 80
ENTRYPOINT ["nginx", "-g", "daemon off;"]

@ -0,0 +1,38 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: autoflow-web
namespace: autoflow
spec:
replicas: 1
selector:
matchLabels:
app: autoflow-web
template:
metadata:
labels:
app: autoflow-web
spec:
containers:
- name: autoflow-web
# [수정] 외부 레지스트리 주소를 제거하고 로컬 태그만 사용
image: autoflow-web:latest
# [추가] 외부에서 이미지를 다운로드하지 않고 로컬 이미지를 사용하도록 강제
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: autoflow-web-svc
namespace: autoflow
spec:
# Outpost EKS 환경에 따라 LoadBalancer 또는 NodePort를 선택하세요.
type: LoadBalancer
selector:
app: autoflow-web
ports:
- protocol: TCP
port: 80
targetPort: 80

127
package-lock.json generated

@ -873,59 +873,12 @@
"url": "https://github.com/sponsors/nzakas"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.12",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
"integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.10",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz",
"integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.29",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
"integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@jsdevtools/ono": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
@ -1321,17 +1274,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "24.0.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.12.tgz",
"integrity": "sha512-LtOrbvDf5ndC9Xi+4QZjVL0woFymF/xSTKZKPgrrl7H7XoeDvnD+E2IclKVDyaK9UM756W/3BXqSU+JEHopA9g==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"undici-types": "~7.8.0"
}
},
"node_modules/@types/normalize-package-data": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
@ -2082,7 +2024,7 @@
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"devOptional": true,
"dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@ -2327,14 +2269,6 @@
"devOptional": true,
"license": "MIT/X11"
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"license": "MIT",
"optional": true,
"peer": true
},
"node_modules/builtin-modules": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz",
@ -2535,14 +2469,6 @@
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"license": "MIT",
"optional": true,
"peer": true
},
"node_modules/comment-parser": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
@ -5540,17 +5466,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"license": "BSD-3-Clause",
"optional": true,
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@ -5560,18 +5475,6 @@
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/spdx-correct": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
@ -5742,26 +5645,6 @@
"url": "https://opencollective.com/synckit"
}
},
"node_modules/terser": {
"version": "5.43.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz",
"integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==",
"license": "BSD-2-Clause",
"optional": true,
"peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.14.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"engines": {
"node": ">=10"
}
},
"node_modules/tinyexec": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
@ -5890,14 +5773,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/undici-types": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
"license": "MIT",
"optional": true,
"peer": true
},
"node_modules/unicorn-magic": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",

@ -3,13 +3,13 @@ import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { ExternalAuthControllerService } from "@/components/service/management/ExternalAuthControllerService";
import {
AddFileParamsSwagger,
AddMinioParamsSwagger,
AddStorageParamsSwagger,
EdgePkgInfoVOModel,
} from "@/components/models/management/ExternalAuthController";
type PackageOption = { label: string; value: string; raw: any };
type MinioRegisterModel = EdgePkgInfoVOModel & {
type StorageRegisterModel = EdgePkgInfoVOModel & {
objectName: string;
type: "type1" | "type2";
localPath: string;
@ -227,7 +227,7 @@ const toInt = (v: unknown, fallback = 1) => {
const n = parseInt(String(v ?? "").trim(), 10);
return Number.isFinite(n) ? n : fallback;
};
const minioType = ref<"type1" | "type2">("type2");
const storageType = ref<"type1" | "type2">("type2");
async function submit() {
errorMsg.value = "";
@ -291,10 +291,10 @@ async function submit() {
const params: AddMinioParamsSwagger = {
...common,
objectName: props.artifactPath || "",
type: minioType.value,
type: storageType.value,
localPath: (form.value.install_location || "").trim(),
};
res = await ExternalAuthControllerService.addMinio(params);
res = await ExternalAuthControllerService.addStorage(params);
}
const ok =

@ -28,7 +28,7 @@ export type AddFileParamsSwagger = {
creation_datetime: string;
};
export type AddMinioParamsSwagger = AddFileParamsSwagger & {
export type AddStorageParamsSwagger = AddFileParamsSwagger & {
objectName: string;
type: "type1" | "type2";
localPath: string;

@ -1,6 +1,6 @@
import {
AddFileParamsSwagger,
AddMinioParamsSwagger,
AddStorageParamsSwagger,
} from "@/components/models/management/ExternalAuthController";
import { request } from "@/components/service/index";
@ -20,7 +20,7 @@ export const ExternalAuthControllerService = {
});
},
addMinio: (params: AddMinioParamsSwagger) => {
addStorage: (params: AddStorageParamsSwagger) => {
return request.postWithConfig(
"/api/external-auth/register-with-minio-file",
{},

@ -0,0 +1,22 @@
import { request } from "@/components/service/index";
import { saveBlob, filenameFromContentDisposition } from "@/utils/download";
/**
* (MinIO, S3, FileSystem )
*/
export const StorageService = {
async download(objectName: string) {
const res = await request.getFile("/api/minio/download", {
objectName,
type: "type2", // Mlflow artifacts 등 대용량 다운로드용
});
const blob: Blob = res.data;
const cd = res.headers?.["content-disposition"];
const fallback = objectName.split("/").pop() || "download.bin";
const filename = filenameFromContentDisposition(cd, fallback);
saveBlob(blob, filename);
},
};

@ -13,7 +13,7 @@ import {
import Plotly from "plotly.js-dist-min";
import CompareRunsDialog from "@/components/atoms/organisms/CompareRunDialog.vue";
import DeploymentDialog from "@/components/atoms/organisms/DeploymentDialog.vue";
import { MinioService } from "@/components/service/management/MinioService";
import { StorageService } from "@/components/service/management/StorageService";
import IconDownloadBtn from "@/components/atoms/button/IconDownloadBtn.vue";
import IconDeployBtn from "@/components/atoms/button/IconDeployBtn.vue";
@ -293,7 +293,7 @@ async function onClickArtifact(fullPath: string) {
const objectName = buildArtifactUri(fullPath);
try {
artifactsLoading.value = true;
await MinioService.download(objectName);
await StorageService.download(objectName);
} finally {
artifactsLoading.value = false;
}

Loading…
Cancel
Save