제품 — FluxFiles

기능

현대적인 파일 매니저에 필요한 모든 것

유연성이 필요한 개발자를 위해 구축.

멀티 스토리지

로컬, AWS S3, Cloudflare R2, SFTP — Flysystem v3. 설정만으로 전환.

어디든 임베드

iframe + postMessage SDK. 독립 UI는 Alpine.js(빌드 없음). 모든 프레임워크와 호환.

JWT 인증 + 스코핑

사용자별 경로 접두사, 권한, 디스크 화이트리스트, owner-only 모드 — 또는 viewer/editor/admin 역할 프리셋으로 시작.

ACL 역할 프리셋

viewer/editor/admin/superadmin 프리셋으로 토큰 발급 — 매개변수 하나로 올바른 권한·디스크·범위 클레임이 자동으로 구성되어 수동 조합이 필요 없습니다.

AI 자동 태그

Claude / OpenAI vision — alt 텍스트, 제목, 태그 자동 생성.

이미지 자르기

종횡비 프리셋이 있는 인라인 자르기 도구.

이미지 최적화

WebP 변형 자동 생성 — 썸네일, 중간, 대형.

사전 서명 업로드

브라우저에서 S3/R2로 직접 업로드 — 서버 대역폭 제로.

청크 업로드

10MB 초과 파일용 S3 멀티파트.

전체 텍스트 검색

이름, 제목, 태그 인덱스 검색 — 기본은 파일 기반, 선택적으로 자체 SQL 데이터베이스를 백엔드로 사용 가능.

DB 기반 메타데이터

선택적 FLUXFILES_STORAGE_BACKEND=db 모드 — 메타데이터, 검색/폴더 인덱스, 감사 로그가 JSON 사이드카 대신 자체 MySQL/PostgreSQL/SQLite에 저장됩니다. 파일 바이트는 두 경우 모두 스토리지에 그대로 남습니다.

일괄 작업

다중 선택 이동, 복사, 삭제, 다운로드.

크로스 디스크 전송

로컬 ↔ S3 ↔ R2 간 복사/이동.

휴지통

복구 가능한 삭제, 자동 정리.

SEO 메타데이터

제목, alt, 캡션, 태그 — 클라우드는 S3 객체 메타데이터, 로컬은 sidecar JSON. 전체 텍스트 검색.

다크 모드

UI 및 SDK에서 라이트/다크/자동.

16개 언어

기본 영어. SDK, URL (?locale=), FLUXFILES_LOCALE로 설정. 아랍어 RTL.

감사 로그

모든 쓰기 작업 기록.

속도 제한

사용자별 토큰 버킷 API 보호.

저장소 할당량

JWT 클레임을 통한 사용자별 제한.

BYOB 버킷

사용자 자체 S3/R2 — JWT 내 자격 증명 암호화(AES-256-GCM).

중복 감지

SHA-256 일치 시 강제 덮어쓰기 전까지 중복 업로드 건너뜀.

SDK 토큰 갱신

401 시 onTokenRefresh — 갱신 병합, 재시도, updateToken()으로 사전 갱신.

버킷 닥터

모든 S3/R2 디스크를 진단 — 자격 증명, 읽기/쓰기/삭제, 프리사인, CORS, 멀티파트 — 붙여넣기만 하면 되는 IAM·CORS 수정안 포함. BYOB 버킷을 몇 분 만에 온보딩.

SFTP 디스크

S3/R2에 이은 세 번째 드라이버 — VPS·공유 호스트를 파일 관리자로.

코드 / 설정 편집기

텍스트·설정 파일(wp-config.php, .env, nginx.conf)을 브라우저에서 편집.

압축 & 해제

선택 항목을 zip으로 받거나 제자리에서 해제 — zip-slip·폭탄 방어.

워터마크

미리보기 보호를 위해 텍스트·로고 워터마크를 즉시 적용 — 원본은 그대로.

온디맨드 WebP + AVIF

하나의 URL로 모든 크기 이미지를 캐시된 AVIF/WebP로 제공(Accept 협상), 반응형 srcset 포함.

SFTP 권한

cPanel 스타일 대화상자로 SFTP 디스크의 유닉스 권한(chmod) 변경.

SSH 터미널

SFTP 디스크 위에서 동작하는 무상태 명령 실행 터미널 — cPanel 스타일 관리 도구를 무료로 내장 (완전한 PTY가 필요하면 자체 ttyd를 임베드 가능).

원클릭 Git 배포

파일 관리자에서 바로 SFTP 서버의 Git 저장소를 pull·reset — 고정된 형태이며 임의 셸이 아니고, hooks는 기본적으로 꺼져 있습니다.

사용량 대시보드

스토리지를 한눈에 — 할당량과 유형별·폴더별 분석.

미디어 미리보기

이미지·동영상·오디오·PDF 인라인 미리보기; 비공개 로컬 미디어 안전 스트리밍.

빠른 설치

2분 만에 시작

composer require fluxfiles/fluxfiles
cp .env.example .env

# .env
FLUXFILES_SECRET=your-random-32-char-secret
FLUXFILES_ALLOWED_ORIGINS=https://yourapp.com

require_once 'vendor/autoload.php';

$token = fluxfiles_token(
    userId: 'user-123',
    perms: ['read', 'write', 'delete'],
    disks: ['local', 's3', 'r2'],
    prefix: 'user-123/',
    maxUploadMb: 10,
    allowedExt: null,
    ttl: 3600
);
composer require fluxfiles/laravel
php artisan vendor:publish --tag=fluxfiles-config

# .env — point the adapter at your FluxFiles server
FLUXFILES_ENDPOINT=https://fm.yourdomain.com
FLUXFILES_SECRET=your-secret-min-32-chars

# Optional: match CORS on the FluxFiles host
# FLUXFILES_ALLOWED_ORIGINS=https://yourapp.com

# Config: config/fluxfiles.php
npm install @fluxfiles/node

// Express / Next.js route — mint a token from your JS backend (no PHP)
import { createToken } from '@fluxfiles/node';

app.get('/fluxfiles-token', (req, res) => {
    const token = createToken({
        secret: process.env.FLUXFILES_SECRET, // >= 32 bytes
        userId: req.user.id,
        perms: ['read', 'write', 'delete'],
        prefix: `users/${req.user.id}`,
        ttl: 3600,
    });
    res.json({ token });
});
pip install fluxfiles-token

# FastAPI / Django / Flask route — mint a token from your Python backend (no PHP)
from fluxfiles_token import create_token

@app.get("/fluxfiles-token")
def fluxfiles_token(user=Depends(current_user)):
    token = create_token(
        secret=os.environ["FLUXFILES_SECRET"],  # >= 32 bytes
        user_id=user.id,
        perms=["read", "write", "delete"],
        prefix=f"users/{user.id}",
        ttl=3600,
    )
    return {"token": token}
<!-- Demo: unpkg. In production, serve fluxfiles.js from your FluxFiles host -->
<script src="https://unpkg.com/fluxfiles@latest/fluxfiles.js"></script>

<script>
FluxFiles.open({
    endpoint: 'https://your-api.com',
    token: 'eyJhbGci...',
    disk: 'local',
    mode: 'picker',
    container: '#file-picker',
    onSelect: function(file) {
        console.log('Selected:', file.url);
    },
    async onTokenRefresh() {
        const r = await fetch('/api/auth/refresh-fluxfiles-token');
        const { token } = await r.json();
        return token;
    }
});
</script>
npm install @fluxfiles/react

import { FluxFilesModal } from '@fluxfiles/react';

<FluxFilesModal
    open={open}
    endpoint="https://your-api.com"
    token={token}
    onSelect={(file) => console.log(file)}
    onClose={() => setOpen(false)}
/>
npm install @fluxfiles/vue

<script setup>
import { FluxFilesModal } from '@fluxfiles/vue';
</script>

<FluxFilesModal
    v-model:open="open"
    endpoint="https://your-api.com"
    :token="token"
    @select="onSelect"
    @close="open = false"
/>
git clone https://github.com/thai-pc/fluxfiles.git
docker build -f fluxfiles/docker/Dockerfile.prod -t fluxfiles fluxfiles

docker run -p 8080:80 \\
  -e FLUXFILES_SECRET=your-random-32-char-secret \\
  fluxfiles

# UI: http://localhost:8080/public/index.html
git clone https://github.com/thai-pc/fluxfiles.git
cd fluxfiles
composer install -d packages/core
cp .env.example .env

cd packages/core
php -S localhost:8080 router.php

# UI:  http://localhost:8080/public/index.html
# API: http://localhost:8080/api/fm/list?disk=local&path=

호환 프레임워크

Laravel WordPress React / Next.js Vue / Nuxt CKEditor 4 TinyMCE Summernote Any framework

통합

당신의 스택을 위한 드롭인 어댑터

공식 어댑터로 이미 사용 중인 프레임워크와 에디터에 FluxFiles를 네이티브로 임베드하세요.

Laravel
PHP
WordPress
Plugin
React
Component
Vue / Nuxt
Component
CKEditor 4
Plugin
TinyMCE
Plugin
Summernote
Plugin

임베드

몇 줄이면 임베드 완료

fluxfiles.js를 로드하고 서버에서 발급한 JWT를 전달하면, 완전한 파일 관리자(또는 파일 선택 모달)를 어떤 페이지에든 넣을 수 있습니다.

<script src="https://fm.example.com/fluxfiles.js"></script>

FluxFiles.open({
  endpoint: 'https://fm.example.com',
  token: 'eyJhbGci...',   // JWT from your backend
  disk: 'local',
  mode: 'picker',         // select & close
  theme: 'auto',
  onSelect(file) {
    // { url, key, name, size, disk, meta, variants }
    document.querySelector("#img").src = file.url;
  },
});
<div id="fm" style="height:600px"></div>

FluxFiles.open({
  endpoint: 'https://fm.example.com',
  token: 'eyJhbGci...',
  mode: 'browser',          // full manager, stays open
  container: '#fm',         // omit for a modal overlay
  disks: ['local', 's3', 'r2'],
});

FluxFiles.on('FM_EVENT', (e) => console.log(e.event));
FluxFiles.navigate('/photos/2024');
import { FluxFilesModal } from '@fluxfiles/react';

function Picker({ open, setOpen, token }) {
  return (
    <FluxFilesModal
      open={open}
      endpoint="https://fm.example.com"
      token={token}
      onSelect={(file) => console.log(file.url)}
      onClose={() => setOpen(false)}
    />
  );
}

토큰은 서버에서 발급합니다 — 시크릿을 절대 브라우저로 보내지 마세요.

왜 FluxFiles인가

다른 도구가 잊은 것을 구축

스와이프하여 비교
기능 FluxFiles elFinder Laravel-FM RichFilemanager Responsive FM
S3 + R2 + Local + SFTP
모든 프레임워크에 임베드
JWT 인증 + 스코핑
SEO 메타데이터
AI 자동 태그
이미지 자르기
청크 업로드
전체 텍스트 검색
다크 모드
16개 언어
PHP ≥ 8.1
활발히 유지보수 중
현대적 UI
기능 FluxFiles Filestack Uploadcare Cloudinary Supabase Storage
셀프 호스팅(자체 인프라에서 실행)
BYOB — 각 고객의 자체 버킷
임베드 가능한 파일 관리자 UI
오픈 소스(MIT)
스토리지/업로드별 SaaS 요금 없음
멀티 스토리지(S3 / R2 / 로컬)
테넌트별 토큰 범위 기본 제공

비교는 일반적인 기본 제공 기능을 반영합니다. 각 제품은 고유 영역에서 뛰어납니다. FluxFiles의 틈새는 임베드 가능·셀프 호스팅·자체 버킷의 조합입니다.

September 2026 기준 비교이며, 비공식 자료입니다 — 수정이 필요하면 GitHub 저장소에 알려주세요.

FAQ

자주 묻는 질문

인증은 어떻게 동작하나요?
무상태 JWT(HS256)입니다. 권한·디스크·경로 범위·한도 같은 세분화된 클레임으로 서버에서 토큰을 발급하므로, 각 사용자는 허용된 것만 볼 수 있습니다.
사용자에게 FluxFiles 계정이 필요한가요?
아니요. FluxFiles는 당신의 앱이 발급한 JWT를 신뢰하므로 기존 인증에 바로 연결됩니다 — 별도의 사용자 시스템이 필요 없습니다.
실행하려면 무엇이 필요한가요?
PHP 8.1+와 몇 가지 일반 확장, 그리고 Composer입니다. 디스크를 지정하고 시크릿과 허용 오리진을 설정한 뒤 실행하면 됩니다 — 작은 VPS에서도 잘 돌아갑니다.
사용자마다 다른 권한을 줄 수 있나요?
네. 세밀한 클레임(읽기/쓰기/삭제, 디스크, 경로 접두사, 업로드 한도, 허용 확장자, owner-only)으로 토큰을 발급하거나, viewer, editor, admin, superadmin 네 가지 내장 역할 프리셋 중 하나를 사용해 클레임을 일일이 나열하지 않고 한 줄로 토큰 범위를 지정할 수 있습니다.
데이터베이스를 직접 운영해야 하나요?
아니요. 기본적으로 모든 메타데이터(파일 정보, 검색 인덱스, 감사 로그)는 파일 옆에 JSON 사이드카 형태로 저장됩니다 — 별도로 준비하거나 백업할 것이 없습니다. 이 관리 정보를 직접 운영하는 MySQL, PostgreSQL, SQLite에 두고 싶다면, 선택적인 FLUXFILES_STORAGE_BACKEND=db 모드로 그쪽으로 옮길 수 있습니다. 어느 쪽이든 파일 바이트 자체는 항상 여러분의 스토리지에 남습니다.
사용량 제한이 있나요?
코어 자체에는 인위적인 제한이 없습니다 — 월간 활성 사용자 상한도, 강제 업그레이드 유도도 없습니다. 사용자별 저장 공간 할당량, 업로드 크기/확장자 제한, 내장 속도 제한기(기본값 분당 읽기 60회/쓰기 10회, 설정 가능)까지 모든 제한은 JWT 클레임으로 직접 설정합니다.