docker를 이용한 mlflow tracking server 설치

1. 설치 항목

  • (1) MLflow Tracking Server

MLflow Tracking 관련 기능 REST API 제공 및 UI 제공

  • (2) Backend Store(PostgreSQL)

MLflow의 메타데이터를 저장하는 Backend DB

  • (3) Artifact Store(RustFS)

훈련된 모델 파일과 실행의 결과물 등을 저장하는 Artifact Store

2. 사전 준비

  • Git
  • Docker Engine과 Docker Compose Plugin
  • OS : docker 실행이 가능한 linux 계열 또는 docker desktop

3. Docker-Compose 준비

(1) 표준 docker compose 파일 준비

(2) docker compose의 서비스 목록

  • 서비스
서비스 역할 설명
postgres backend store MLflow Tracking Server의 백엔드 스토어. 메타데이터 저장.
기본 이미지는 PostgreSQL의 15버전
storage artifact store MLflow Tracking Server의 아티팩트 스토어. 훈련된 모델 파일 등 저장.
기본 이미지는 RustFS:1.0.0
create-bucket artifact store init 아티팩트 스토어의 초기화 작업 컨테이너. 완료 후 종료됨.
기본 이미지는 amazon/aws-cli
mlflow mlflow tracking server Tracking Server의 API 및 UI 제공.
기본 이미지는 ghcr.io/mlflow/mlflow
  • 도커 볼륨
볼륨 역할 설명
pgdata backend store mount 백엔드 스토어를 호스트에 마운트한 볼륨
storage-data artifact store mount 아티팩트 스토어를 호스트에 마운트한 볼륨

4. 환경 설정

(1) 주요 항목

  • 주요 항목은 .env.dev.example 파일에서 확인할 수 있다.
항목 설명 예시값
POSTGRES_USER Backend Store 계정이름 mlflow
POSTGRES_PASSWORD Backend Store 비밀번호 mlflow
POSTGRES_DB Backend Store DB명 mlflow
AWS_ACCESS_KEY_ID S3호환 아티팩트 서버 KEY ID s3admin
AWS_SECRET_ACCESS_KEY S3호환 아티팩트 서버 키 s3admin
AWS_DEFAULT_REGION S3호환 아티팩트 서버 리전값 us-east-1
RUSTFS_CONSOLE_ENABLE 아티팩트스토어 CLI 사용 여부 true
S3_BUCKET 아티팩트스토어 버킷 이름 mlflow
MLFLOW_VERSION 사용할 MLflow Tracking Server 버전 3.10.1-full
MLFLOW_HOST MLflow Tracking Server 접근 0.0.0.0
MLFLOW_PORT MLflow Tracking Server 포트 5000
MLFLOW_BACKEND_STORE_URI MLflow Tracking Server에서 바라볼 백엔드 스토어 경로 postgresql://..(하단 참조)
MLFLOW_ARTIFACTS_DESTINATION MLflow Tracking Server에서 바라볼 아티팩트 스토어 경로 s3://${S3_BUCKET}
MLFLOW_S3_ENDPOINT_URL MLflow Tracking Server에서 바라볼 아티팩트 스토어 포트 http://storage:9000

(2) docker compose 파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
volumes:
  mlflow-pgdata:
  mlflow-storage-data:

services:
  mlflow-postgres:
    image: postgres:15
    container_name: mlflow-postgres
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - mlflow-pgdata:/var/lib/postgresql/data
    ports:
      - "${POSTGRES_PORT}:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 5s
      timeout: 3s
      retries: 10

  mlflow-storage:
    image: rustfs/rustfs:1.0.0-alpha.83
    container_name: mlflow-storage
    environment:
      RUSTFS_ADDRESS: :9000
      RUSTFS_SERVER_DOMAINS: mlflow-storage:9000
      RUSTFS_REGION: ${AWS_DEFAULT_REGION:-us-east-1}
      RUSTFS_ACCESS_KEY: ${AWS_ACCESS_KEY_ID:-s3admin}
      RUSTFS_SECRET_KEY: ${AWS_SECRET_ACCESS_KEY:-s3admin}
      RUSTFS_CONSOLE_ENABLE: ${RUSTFS_CONSOLE_ENABLE:-true}
    ports:
      - "${RUSTFS_ENDPOINT_PORT}:9000"
      - "${RUSTFS_MANAGING_PORT}:9001"
    volumes:
      - mlflow-storage-data:/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", 'curl -s http://127.0.0.1:9000/health | grep -q ''"status":"ok"''']
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s

  create-bucket:
    image: amazon/aws-cli:2.33.25
    container_name: mlflow-create-bucket
    depends_on:
      mlflow-storage:
        condition: service_healthy
    entrypoint: >
      /bin/sh -c "
        set -e;
        echo 'Waiting for S3 gateway getting ready...';
        if aws --endpoint-url=${MLFLOW_S3_ENDPOINT_URL} s3api head-bucket --bucket ${S3_BUCKET} 2>/dev/null; then
          echo 'Bucket ${S3_BUCKET} already exists. Skipping creation.';
        else
          echo 'Creating bucket ${S3_BUCKET}...';
          aws --endpoint-url=${MLFLOW_S3_ENDPOINT_URL} s3api create-bucket --bucket ${S3_BUCKET} --region ${AWS_DEFAULT_REGION};
        fi
      "
    environment:
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
      AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
      AWS_S3_ADDRESSING_STYLE: path
      MLFLOW_S3_ENDPOINT_URL: ${MLFLOW_S3_ENDPOINT_URL}
      S3_BUCKET: ${S3_BUCKET}
    restart: "no"

  mlflow:
    image: ghcr.io/mlflow/mlflow:${MLFLOW_VERSION}
    container_name: mlflow-server
    depends_on:
      mlflow-postgres:
        condition: service_healthy
      mlflow-storage:
        condition: service_healthy
      create-bucket:
        condition: service_completed_successfully
    environment:
      # Backend store URI built from vars
      MLFLOW_BACKEND_STORE_URI: ${MLFLOW_BACKEND_STORE_URI}

      # S3/RustFS settings
      MLFLOW_S3_ENDPOINT_URL: ${MLFLOW_S3_ENDPOINT_URL}
      MLFLOW_ARTIFACTS_DESTINATION: ${MLFLOW_ARTIFACTS_DESTINATION}
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
      AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
      MLFLOW_S3_IGNORE_TLS: "true"

      # Server host/port
      MLFLOW_HOST: ${MLFLOW_HOST}
      MLFLOW_PORT: ${MLFLOW_PORT}
    command:
      - /bin/bash
      - -c
      - |
        pip install --no-cache-dir psycopg2-binary boto3
        mlflow server \
          --backend-store-uri "${MLFLOW_BACKEND_STORE_URI}" \
          --artifacts-destination "${MLFLOW_ARTIFACTS_DESTINATION}" \
          --serve-artifacts \
          --host "${MLFLOW_HOST}" \
          --port "${MLFLOW_PORT}"
    ports:
      - "${MLFLOW_PORT}:${MLFLOW_PORT}"
    healthcheck:
      test:
        [
          "CMD",
          "python",
          "-c",
          "import urllib.request; urllib.request.urlopen('http://localhost:${MLFLOW_PORT}/health')",
        ]
      interval: 10s
      timeout: 5s
      retries: 30

networks:
  default:
    name: mlflow-network

(3) env 파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# .env 파일

# PostgreSQL
POSTGRES_USER=mlflow
POSTGRES_PASSWORD=mlflow
POSTGRES_DB=mlflow
POSTGRES_PORT=5432

# S3 Credentials
AWS_ACCESS_KEY_ID=mlflow
AWS_SECRET_ACCESS_KEY=mlflow
AWS_DEFAULT_REGION=us-east-1

# RustFS
RUSTFS_CONSOLE_ENABLE=true
S3_BUCKET=mlflow
RUSTFS_ENDPOINT_PORT=9000
RUSTFS_MANAGING_PORT=9001

# MLflow
MLFLOW_VERSION=v3.10.1-full
MLFLOW_HOST=0.0.0.0
MLFLOW_PORT=5000

MLFLOW_BACKEND_STORE_URI=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@mlflow-postgres:5432/${POSTGRES_DB}
MLFLOW_ARTIFACTS_DESTINATION=s3://${S3_BUCKET}
MLFLOW_S3_ENDPOINT_URL=http://mlflow-storage:${RUSTFS_ENDPOINT_PORT}

5. 설치 및 실행

  • docker compose up 명령어로 서비스들(컨테이너들)을 실행한다.
1
docker compose up
  • 브라우저를 통해 각 서비스에 접속해본다.
  • 가장 먼저 mlflow tracking server는 http://localhost:5000 로 UI 접근이 가능하다.

    서버 실행하는 위치에 따라 localhost를 서버가 띄워진 IP로 변경해주면 된다.


  • 아티팩트 스토어인 RustFS는 http://localhost:9001 로 UI 접근이 가능하다.

    서버 실행하는 위치에 따라 localhost를 서버가 띄워진 IP로 변경해주면 된다.

  • 계정은 env 파일에 설정한 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY에 해당한다.
  • 로그인을 하면 아래와 같은 화면을 볼 수 있다.

Reference

https://github.com/mlflow/mlflow/tree/master/docker-compose
https://github.com/mlflow/mlflow/pkgs/container/mlflow

Comments