Directory 구조를 잡아보자(feat. MinIO)

물뮤 프로젝트의 디렉토리 구조 설계하기 🏗️

안녕하세요! 오늘은 제가 진행 중인 물뮤(MoolMeow) 프로젝트의 디렉토리 구조를 어떻게 설계했는지 공유해보려고 해요. 🐱 특히 온프레미스 쿠버네티스 환경에서 어떻게 파일 시스템을 구성하고 VM에 마운트했는지 소상히 설명해드릴게요!

첫 고민, 디렉토리 구조를 어떻게 가져갈까? 🤔

물뮤 프로젝트는 수영(Mool, 물)과 고양이(Meow, 야옹)를 테마로 한 통합 커뮤니티 서비스예요. Mac Mini에서 쿠버네티스를 활용해 운영할 계획인데, 처음부터 디렉토리 구조를 체계적으로 잡아야 나중에 관리하기 편하더라고요.

특히 고려해야 했던 사항들은:

  • 다양한 환경(개발, 스테이징, 프로덕션) 분리
  • 여러 서비스(Jenkins, Docker Registry, MinIO)의 데이터 관리
  • 이미지 저장소 구성(게시물, 마켓, 프로필 이미지)
  • 백업과 로그 관리

이런 요소들을 고려하여 점진적으로 디렉토리 구조를 발전시켜 나갔습니다.

최종 디렉토리 구조 📂

여러 번의 고민 끝에 아래와 같은 디렉토리 구조로 최종 결정했어요!

/moolmeow
├── services/
│   ├── jenkins/               → Jenkins 데이터 및 설정
│   ├── registry/              → Docker 레지스트리 데이터
│   └── minio/                 → MinIO 서비스 데이터
│
├── storage/
│   ├── development/           → 개발 환경 스토리지
│   │   ├── images/
│   │   │   ├── post/         → 게시물 이미지
│   │   │   ├── market/       → 마켓 이미지
│   │   │   └── profile/      → 프로필 이미지
│   │   └── uploads/          → 기타 사용자 업로드
│   │
│   ├── staging/              → 스테이징 환경 스토리지 (개발과 동일 구조)
│   │   ├── images/
│   │   │   ├── post/
│   │   │   ├── market/
│   │   │   └── profile/
│   │   └── uploads/
│   │
│   └── production/           → 프로덕션 환경 스토리지 (개발과 동일 구조)
│       ├── images/
│       │   ├── post/
│       │   ├── market/
│       │   └── profile/
│       └── uploads/
│
├── shared/                    → 환경 간 공유 리소스
│   ├── certificates/          → SSL/TLS 인증서
│   ├── secrets/               → 민감한 설정 파일, 키 등
│   └── assets/                → 공통 에셋 (로고, 아이콘 등)
│
├── configs/                   → 모든 서비스 설정 파일
│   ├── kubernetes/
│   ├── jenkins/
│   ├── registry/
│   └── minio/
│
├── databases/                 → 데이터베이스 데이터 파일
│   ├── mysql/
│   └── redis/
│
├── backups/                   → 시스템 백업
│   ├── databases/
│   ├── configs/
│   └── storage/
│
└── logs/                      → 로그 파일
    ├── kubernetes/
    ├── jenkins/
    ├── registry/
    └── applications/

왜 이런 구조를 선택했나요? 🧩

1. 서비스별 분리 ⚙️

처음에는 서비스별로 데이터를 분리하려고 했어요. Jenkins, Docker Registry, MinIO 등의 서비스들은 각각의 데이터 특성이 다르고 별도로 관리되어야 했기 때문이죠. /services 디렉토리 아래에 각 서비스별 폴더를 만든 이유입니다.

2. 환경별 분리 🌍

개발부터 프로덕션까지 데이터 격리는 정말 중요해요! 실수로 개발 환경에서 프로덕션 데이터를 덮어쓴다면…? 😱 생각만 해도 끔찍하죠! 그래서 /storage 아래 환경별로 디렉토리를 구분했습니다.

3. 이미지 타입별 분리 🖼️

처음엔 이미지를 한 곳에 모두 저장하려고 했지만, 관리와 백업 측면에서 용도별로 구분하는 게 더 효율적이라고 판단했어요. 게시물 이미지는 /post, 마켓 이미지는 /market, 프로필 이미지는 /profile로 분리했습니다.

4. 공유 리소스 관리 🤝

환경에 상관없이 공통으로 사용하는 자원들은 /shared 디렉토리로 분리했어요. 특히 인증서나 민감한 시크릿 정보는 별도 관리가 필요했죠!

5. 설정 파일 중앙화 ⚙️

모든 설정을 /configs에 중앙 집중식으로 관리하기로 했어요. 이렇게 하면 설정 변경 이력 관리나 백업이 훨씬 편해져요.

6. 백업과 로그 관리 📊

백업과 로그는 시스템 운영에 있어 핵심이죠! /backups/logs 디렉토리를 통해 체계적으로 관리하기로 했습니다.

Vagrant에서의 마운트 설정 🔄

디렉토리 구조를 결정한 후, Vagrant 파일에 다음과 같이 마운트 설정을 추가했어요:

# 주요 카테고리별 마운트
node_config.vm.synced_folder "#{base_path}/services", "/mnt/services", create: true
node_config.vm.synced_folder "#{base_path}/storage", "/mnt/storage", create: true
node_config.vm.synced_folder "#{base_path}/shared", "/mnt/shared", create: true
node_config.vm.synced_folder "#{base_path}/configs", "/mnt/configs", create: true
node_config.vm.synced_folder "#{base_path}/databases", "/mnt/databases", create: true
node_config.vm.synced_folder "#{base_path}/backups", "/mnt/backups", create: true
node_config.vm.synced_folder "#{base_path}/logs", "/mnt/logs", create: true

처음에는 더 세분화해서 마운트할까 고민했는데, 마운트 포인트가 많아지면 VirtualBox shared folder의 성능 이슈가 있을 수 있어서 주요 카테고리별로만 마운트하기로 했어요.

디렉토리 생성 스크립트 🛠️

모든 디렉토리를 수동으로 만들기는 번거롭죠. 아래 스크립트를 통해 한 번에 모든 디렉토리를 생성할 수 있어요:

#!/bin/bash

# 기본 경로 설정
BASE_PATH="$HOME/Desktop/moolmeow"

# 메인 디렉토리 생성
mkdir -p "$BASE_PATH"

# 서비스 디렉토리 생성
mkdir -p "$BASE_PATH/services/jenkins"
mkdir -p "$BASE_PATH/services/registry"
mkdir -p "$BASE_PATH/services/minio"

# 환경별 스토리지 생성
for ENV in development staging production; do
  mkdir -p "$BASE_PATH/storage/$ENV/images/post"
  mkdir -p "$BASE_PATH/storage/$ENV/images/market"
  mkdir -p "$BASE_PATH/storage/$ENV/images/profile"
  mkdir -p "$BASE_PATH/storage/$ENV/uploads"
done

# 공유 리소스 디렉토리 생성
mkdir -p "$BASE_PATH/shared/certificates"
mkdir -p "$BASE_PATH/shared/secrets"
mkdir -p "$BASE_PATH/shared/assets"

# 설정 디렉토리 생성
mkdir -p "$BASE_PATH/configs/kubernetes/base"
mkdir -p "$BASE_PATH/configs/kubernetes/development"
mkdir -p "$BASE_PATH/configs/kubernetes/staging"
mkdir -p "$BASE_PATH/configs/kubernetes/production"
mkdir -p "$BASE_PATH/configs/jenkins"
mkdir -p "$BASE_PATH/configs/registry"
mkdir -p "$BASE_PATH/configs/minio"

# 데이터베이스 디렉토리 생성
mkdir -p "$BASE_PATH/databases/mysql"
mkdir -p "$BASE_PATH/databases/redis"

# 백업 디렉토리 생성
mkdir -p "$BASE_PATH/backups/databases"
mkdir -p "$BASE_PATH/backups/configs"
mkdir -p "$BASE_PATH/backups/storage"

# 로그 디렉토리 생성
mkdir -p "$BASE_PATH/logs/kubernetes"
mkdir -p "$BASE_PATH/logs/jenkins"
mkdir -p "$BASE_PATH/logs/registry"
mkdir -p "$BASE_PATH/logs/applications"

# 적절한 권한 설정
find "$BASE_PATH" -type d -exec chmod 755 {} \;

echo "물뮤 프로젝트 디렉토리 구조가 $BASE_PATH에 생성되었습니다."

MinIO와 객체 스토리지 💾

처음에는 물리적인 디렉토리 구조에 파일을 직접 저장하려고 했지만, S3 호환 객체 스토리지인 MinIO를 도입하기로 했어요. MinIO에서는 다음과 같은 버킷 구조를 사용할 예정이에요:

  • 개발 환경

    • dev-post-images
    • dev-market-images
    • dev-profile-images
  • 스테이징 환경

    • stage-post-images
    • stage-market-images
    • stage-profile-images
  • 프로덕션 환경

    • prod-post-images
    • prod-market-images
    • prod-profile-images

이렇게 하면 S3 API를 통해 일관된 방식으로 이미지에 접근할 수 있어요!

구조 설계에서 배운 점 🎓

이번 디렉토리 구조 설계를 통해 배운 몇 가지 교훈을 공유하자면:

  1. 처음부터 완벽하지 않아도 돼요 – 처음에는 간단하게 시작해서 필요에 따라 발전시켜 나가는 게 좋아요.
  2. 확장성을 고려하세요 – 나중에 서비스가 커져도 구조가 혼란스러워지지 않도록 설계해야 해요.
  3. 환경 분리는 필수! – 개발, 스테이징, 프로덕션 환경은 명확히 분리하는 게 중요해요.
  4. 백업 전략도 함께 고려하세요 – 디렉토리 구조가 백업과 복구 전략과도 일치해야 해요.

마무리 🎉

이렇게 물뮤 프로젝트의 디렉토리 구조 설계 과정을 공유해봤어요. 여러분의 프로젝트에도 참고가 되었으면 좋겠네요! 질문이나 의견이 있으시면 언제든지 댓글로 남겨주세요~ 😊

Designing Directory Structure for the MoolMeow Project 🏗️

Hello everyone! Today I’d like to share how I designed the directory structure for my MoolMeow project. 🐱 I’ll explain in detail how I configured the file system and mounted it to VMs in an on-premises Kubernetes environment!

Initial Consideration: How to Structure the Directories? 🤔

The MoolMeow project is an integrated community service themed around swimming (Mool, 물) and cats (Meow, 야옹). I’m planning to run it on Kubernetes using a Mac Mini, and I realized that establishing a systematic directory structure from the beginning would make management much easier later on.

Key considerations included:

  • Separation of different environments (development, staging, production)
  • Managing data for various services (Jenkins, Docker Registry, MinIO)
  • Organizing image repositories (post, market, profile images)
  • Backup and log management

I progressively developed the directory structure with these factors in mind.

Final Directory Structure 📂

After careful consideration, I decided on the following directory structure:

/moolmeow
├── services/
│   ├── jenkins/               → Jenkins data and settings
│   ├── registry/              → Docker Registry data
│   └── minio/                 → MinIO service data
│
├── storage/
│   ├── development/           → Development environment storage
│   │   ├── images/
│   │   │   ├── post/         → Post images
│   │   │   ├── market/       → Market images
│   │   │   └── profile/      → Profile images
│   │   └── uploads/          → Other user uploads
│   │
│   ├── staging/              → Staging environment storage (same structure as dev)
│   │   ├── images/
│   │   │   ├── post/
│   │   │   ├── market/
│   │   │   └── profile/
│   │   └── uploads/
│   │
│   └── production/           → Production environment storage (same structure as dev)
│       ├── images/
│       │   ├── post/
│       │   ├── market/
│       │   └── profile/
│       └── uploads/
│
├── shared/                    → Resources shared between environments
│   ├── certificates/          → SSL/TLS certificates
│   ├── secrets/               → Sensitive config files, keys, etc.
│   └── assets/                → Common assets (logos, icons, etc.)
│
├── configs/                   → All service configuration files
│   ├── kubernetes/
│   ├── jenkins/
│   ├── registry/
│   └── minio/
│
├── databases/                 → Database data files
│   ├── mysql/
│   └── redis/
│
├── backups/                   → System backups
│   ├── databases/
│   ├── configs/
│   └── storage/
│
└── logs/                      → Log files
    ├── kubernetes/
    ├── jenkins/
    ├── registry/
    └── applications/

Why Did I Choose This Structure? 🧩

1. Service Separation ⚙️

Initially, I wanted to separate data by service. Services like Jenkins, Docker Registry, and MinIO have different data characteristics and need to be managed separately. That’s why I created folders for each service under the /services directory.

2. Environment Separation 🌍

Data isolation from development to production is crucial! What if you accidentally overwrite production data in a development environment? 😱 Terrifying, right? That’s why I separated directories by environment under /storage.

3. Image Type Separation 🖼️

At first, I thought about storing all images in one place, but decided it would be more efficient to separate them by purpose for management and backup. Post images go to /post, market images to /market, and profile images to /profile.

4. Shared Resource Management 🤝

Resources used across all environments were separated into the /shared directory. Certificates and sensitive secret information especially needed separate management!

5. Centralized Configuration Files ⚙️

I decided to centrally manage all configurations in /configs. This makes change history management and backups much easier.

6. Backup and Log Management 📊

Backups and logs are essential for system operations! I chose to manage them systematically through the /backups and /logs directories.

Mount Configuration in Vagrant 🔄

After deciding on the directory structure, I added the following mount settings to my Vagrant file:

# Mount by main category
node_config.vm.synced_folder "#{base_path}/services", "/mnt/services", create: true
node_config.vm.synced_folder "#{base_path}/storage", "/mnt/storage", create: true
node_config.vm.synced_folder "#{base_path}/shared", "/mnt/shared", create: true
node_config.vm.synced_folder "#{base_path}/configs", "/mnt/configs", create: true
node_config.vm.synced_folder "#{base_path}/databases", "/mnt/databases", create: true
node_config.vm.synced_folder "#{base_path}/backups", "/mnt/backups", create: true
node_config.vm.synced_folder "#{base_path}/logs", "/mnt/logs", create: true

Initially, I considered more granular mounting, but decided to mount only by main category since having too many mount points could cause performance issues with VirtualBox shared folders.

Directory Creation Script 🛠️

Creating all these directories manually would be tedious. Here’s a script to create all directories at once:

#!/bin/bash

# Set base path
BASE_PATH="$HOME/Desktop/moolmeow"

# Create main directory
mkdir -p "$BASE_PATH"

# Create service directories
mkdir -p "$BASE_PATH/services/jenkins"
mkdir -p "$BASE_PATH/services/registry"
mkdir -p "$BASE_PATH/services/minio"

# Create environment-specific storage
for ENV in development staging production; do
  mkdir -p "$BASE_PATH/storage/$ENV/images/post"
  mkdir -p "$BASE_PATH/storage/$ENV/images/market"
  mkdir -p "$BASE_PATH/storage/$ENV/images/profile"
  mkdir -p "$BASE_PATH/storage/$ENV/uploads"
done

# Create shared resource directories
mkdir -p "$BASE_PATH/shared/certificates"
mkdir -p "$BASE_PATH/shared/secrets"
mkdir -p "$BASE_PATH/shared/assets"

# Create config directories
mkdir -p "$BASE_PATH/configs/kubernetes/base"
mkdir -p "$BASE_PATH/configs/kubernetes/development"
mkdir -p "$BASE_PATH/configs/kubernetes/staging"
mkdir -p "$BASE_PATH/configs/kubernetes/production"
mkdir -p "$BASE_PATH/configs/jenkins"
mkdir -p "$BASE_PATH/configs/registry"
mkdir -p "$BASE_PATH/configs/minio"

# Create database directories
mkdir -p "$BASE_PATH/databases/mysql"
mkdir -p "$BASE_PATH/databases/redis"

# Create backup directories
mkdir -p "$BASE_PATH/backups/databases"
mkdir -p "$BASE_PATH/backups/configs"
mkdir -p "$BASE_PATH/backups/storage"

# Create log directories
mkdir -p "$BASE_PATH/logs/kubernetes"
mkdir -p "$BASE_PATH/logs/jenkins"
mkdir -p "$BASE_PATH/logs/registry"
mkdir -p "$BASE_PATH/logs/applications"

# Set appropriate permissions
find "$BASE_PATH" -type d -exec chmod 755 {} \;

echo "MoolMeow project directory structure has been created at $BASE_PATH."

MinIO and Object Storage 💾

Initially, I planned to store files directly in the physical directory structure, but decided to adopt MinIO, an S3-compatible object storage. In MinIO, I plan to use the following bucket structure:

  • Development Environment

    • dev-post-images
    • dev-market-images
    • dev-profile-images
  • Staging Environment

    • stage-post-images
    • stage-market-images
    • stage-profile-images
  • Production Environment

    • prod-post-images
    • prod-market-images
    • prod-profile-images

This allows consistent access to images through the S3 API!

Lessons Learned from Structure Design 🎓

Here are a few lessons I learned through this directory structure design:

  1. It doesn’t have to be perfect from the start – It’s good to start simple and evolve as needed.
  2. Consider scalability – Design in a way that won’t become chaotic when your service grows.
  3. Environment separation is essential! – It’s important to clearly separate development, staging, and production environments.
  4. Consider backup strategy together – Directory structure should align with backup and recovery strategies.

Conclusion 🎉

That’s how I designed the directory structure for the MoolMeow project. I hope this helps with your own projects! Feel free to leave any questions or comments below~ 😊

답글 남기기