· Nacho Coll · Tutorials  · 18 분 소요

2026년 IPFS에 파일을 업로드하는 방법 — 완벽 가이드

대시보드, REST API, JavaScript 또는 Python을 사용하여 JSON, 이미지, PDF 및 모든 파일을 IPFS에 업로드하는 방법을 배웁니다. 코드 예제가 포함된 단계별 가이드.

대시보드, REST API, JavaScript 또는 Python을 사용하여 JSON, 이미지, PDF 및 모든 파일을 IPFS에 업로드하는 방법을 배웁니다. 코드 예제가 포함된 단계별 가이드.

2026년 IPFS에 파일을 업로드하는 방법 — 완벽 가이드

단일 회사가 통제하지 않고, 누구나 검증할 수 있으며, 검열에 저항할 수 있는 방식으로 파일을 저장하고 싶었다면, InterPlanetary File System(IPFS)이 답입니다. 이 가이드는 간단한 드래그 앤 드롭 대시보드부터 JavaScript와 Python의 프로덕션 준비된 코드에 이르기까지 IPFS에 파일을 업로드하는 모든 실용적인 방법을 안내합니다.

드래그 앤 드롭 파일 업로드가 포함된 IPFS Ninja 업로드 페이지

IPFS란 무엇이며 왜 사용해야 합니까?

IPFS는 파일을 저장하고 공유하기 위한 피어 투 피어 프로토콜입니다. 콘텐츠가 어디에 있는지(특정 서버의 URL)로 콘텐츠를 주소 지정하는 대신, IPFS는 콘텐츠가 무엇인지로 주소 지정합니다. 모든 파일은 콘텐츠의 암호학적 해시에서 파생된 고유한 **콘텐츠 식별자(CID)**를 받습니다. 이 설계는 기존 호스팅이 따라올 수 없는 세 가지 속성을 제공합니다.

  • 콘텐츠 주소 지정. CID는 수신한 데이터가 업로드된 데이터와 정확히 일치함을 보장합니다. 1바이트가 변경되면 CID가 변경됩니다. 누구도 주소를 무효화하지 않고 파일을 변조할 수 없습니다.
  • 영속성. 네트워크의 적어도 하나의 노드가 파일을 핀(pin)하는 한, 파일은 계속 사용할 수 있습니다. IPFS Ninja와 같은 핀 서비스는 자체 인프라를 운영하지 않고도 파일을 온라인 상태로 유지합니다. 핀이 왜 중요한지 그리고 가비지 컬렉션이 어떻게 작동하는지 이해하려면 IPFS 피닝이란 무엇인가?를 참조하세요.
  • 검열 저항성. IPFS의 파일은 단일 도메인이나 서버에 묶이지 않습니다. 정부나 기업이 종료할 수 있는 단일 장애 지점이 없습니다.

일반적인 사용 사례에는 NFT 메타데이터 및 미디어, 탈중앙화 애플리케이션 자산, 과학 데이터 세트, 공공 기록 및 데이터 무결성이 중요한 모든 시나리오가 포함됩니다.

사전 요구 사항

무엇이든 업로드하기 전에 두 가지가 필요합니다.

  1. IPFS Ninja 계정. https://ipfs.ninja/signup에서 무료로 가입하세요. 무료 플랜은 500개 파일과 1GB 저장 공간을 제공합니다 — 시작하기에 충분합니다.

  2. API 키. 로그인 후 대시보드의 API Keys 섹션으로 이동하여 새 키를 생성합니다. bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6와 같이 보일 것입니다(접두사 bws_a1b2c3d4는 식별을 위해 대시보드에 표시됩니다). 이 키를 비밀로 유지하세요. 모든 API 요청과 함께 X-Api-Key 헤더에 전달합니다.

웹 대시보드만 사용하려면 API 키 단계를 건너뛸 수 있지만, API 키가 있으면 자체 애플리케이션에서 프로그래밍 방식으로 업로드할 수 있습니다.

방법 1: 웹 대시보드(드래그 앤 드롭)

파일을 업로드하는 가장 빠른 방법은 IPFS Ninja 대시보드를 통하는 것입니다.

  1. https://ipfs.ninja/upload로 이동하여 로그인합니다.
  2. JSON, PNG, JPEG, PDF, SVG 또는 기타 유형의 파일을 업로드 영역에 드래그 앤 드롭하거나 클릭하여 파일 시스템을 찾아봅니다.
  3. 선택적으로 나중에 파일을 정리하는 데 도움이 되는 설명메타데이터(키-값 쌍)를 추가합니다.
  4. 업로드를 클릭합니다. 몇 초 안에 파일이 IPFS에 핀되고 CID와 게이트웨이 URL을 받게 됩니다.

이 방법은 모든 파일 형식을 지원하며 코드가 필요 없습니다. 일회성 업로드, 빠른 테스트 또는 콘텐츠를 핀해야 하는 비기술 팀 구성원에게 이상적입니다.

방법 2: curl을 사용한 REST API

자동화 및 스크립팅의 경우 REST API가 가장 직접적인 접근 방식입니다. 엔드포인트는 다음과 같습니다.

POST https://api.ipfs.ninja/upload/new

모든 요청에는 X-Api-Key 헤더와 content 필드가 있는 JSON 본문이 필요합니다.

JSON 업로드

JSON 객체를 업로드하려면 content의 값으로 직접 전달합니다.

curl -X POST https://api.ipfs.ninja/upload/new \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6" \
  -d '{
    "content": {
      "name": "Astro Cat #42",
      "description": "A fearless cat exploring the cosmos.",
      "image": "ipfs://bafkreigh2akiscaildc7lqnpfuh3sksq4ogrtz7tpk2aulid5fhqotmqm",
      "attributes": [
        { "trait_type": "Background", "value": "Nebula" },
        { "trait_type": "Helmet", "value": "Gold" }
      ]
    },
    "description": "NFT metadata for Astro Cat #42",
    "metadata": { "collection": "astro-cats", "tokenId": "42" }
  }'

descriptionmetadata 필드는 선택 사항입니다. 이들은 IPFS Ninja 대시보드와 API 응답에서 파일과 함께 저장되어 나중에 업로드를 식별하고 필터링하는 데 도움이 됩니다. IPFS에 핀된 콘텐츠에는 포함되지 않습니다.

이미지(이진 파일) 업로드

이미지나 PDF와 같은 이진 파일의 경우 파일을 base64로 인코딩하고 인코딩된 문자열을 content로 전달합니다.

curl -X POST https://api.ipfs.ninja/upload/new \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6" \
  -d "{
    \"content\": \"$(base64 -w 0 photo.png)\",
    \"description\": \"Product photo for landing page\",
    \"metadata\": { \"project\": \"website-redesign\" }
  }"

API는 콘텐츠 유형을 자동으로 감지합니다. JSON, 이미지, PDF 중 무엇을 업로드하는지 지정할 필요가 없습니다 — 서비스가 이를 처리합니다.

방법 3: JavaScript / Node.js

내장된 fetch API(Node.js 18+ 또는 모든 최신 브라우저)를 사용하면 IPFS 업로드가 몇 줄로 가능합니다.

JSON 업로드

const API_KEY = "bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6";

const metadata = {
  name: "Astro Cat #42",
  description: "A fearless cat exploring the cosmos.",
  image: "ipfs://bafkreigh2akiscaildc7lqnpfuh3sksq4ogrtz7tpk2aulid5fhqotmqm",
  attributes: [
    { trait_type: "Background", value: "Nebula" },
    { trait_type: "Helmet", value: "Gold" },
  ],
};

const response = await fetch("https://api.ipfs.ninja/upload/new", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Api-Key": API_KEY,
  },
  body: JSON.stringify({
    content: metadata,
    description: "NFT metadata for Astro Cat #42",
  }),
});

const result = await response.json();
console.log("CID:", result.cid);
console.log("Gateway URL:", result.uris.url);

이진 파일 업로드

import { readFileSync } from "node:fs";

const API_KEY = "bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6";
const fileBuffer = readFileSync("photo.png");
const base64Content = fileBuffer.toString("base64");

const response = await fetch("https://api.ipfs.ninja/upload/new", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Api-Key": API_KEY,
  },
  body: JSON.stringify({
    content: base64Content,
    description: "Product photo",
    metadata: { project: "website-redesign" },
  }),
});

const result = await response.json();
console.log("CID:", result.cid);
console.log("IPFS URI:", result.uris.ipfs);
console.log("Gateway URL:", result.uris.url);

오류 처리가 포함된 일괄 업로드

프로덕션에서는 많은 파일을 업로드해야 하는 경우가 많습니다. 다음은 재시도 기능이 있는 재사용 가능한 도우미입니다.

import { readFileSync } from "node:fs";

const API_KEY = "bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6";
const API_URL = "https://api.ipfs.ninja/upload/new";

async function uploadToIPFS(content, options = {}) {
  const body = { content };
  if (options.description) body.description = options.description;
  if (options.metadata) body.metadata = options.metadata;

  const response = await fetch(API_URL, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Api-Key": API_KEY,
    },
    body: JSON.stringify(body),
  });

  if (!response.ok) {
    const error = await response.text();
    throw new Error(`Upload failed (${response.status}): ${error}`);
  }

  return response.json();
}

// Upload JSON
const jsonResult = await uploadToIPFS(
  { name: "My Data", values: [1, 2, 3] },
  { description: "Sample dataset" }
);

// Upload image
const imageBase64 = readFileSync("banner.jpg").toString("base64");
const imageResult = await uploadToIPFS(imageBase64, {
  description: "Banner image",
  metadata: { format: "jpg", width: "1200" },
});

console.log("JSON CID:", jsonResult.cid);
console.log("Image CID:", imageResult.cid);

방법 4: Python

Python의 requests 라이브러리는 IPFS 업로드를 간단하게 만듭니다.

JSON 업로드

import requests

API_KEY = "bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
API_URL = "https://api.ipfs.ninja/upload/new"

headers = {
    "Content-Type": "application/json",
    "X-Api-Key": API_KEY,
}

payload = {
    "content": {
        "name": "Astro Cat #42",
        "description": "A fearless cat exploring the cosmos.",
        "image": "ipfs://bafkreigh2akiscaildc7lqnpfuh3sksq4ogrtz7tpk2aulid5fhqotmqm",
        "attributes": [
            {"trait_type": "Background", "value": "Nebula"},
            {"trait_type": "Helmet", "value": "Gold"},
        ],
    },
    "description": "NFT metadata for Astro Cat #42",
    "metadata": {"collection": "astro-cats", "tokenId": "42"},
}

response = requests.post(API_URL, json=payload, headers=headers)
result = response.json()

print(f"CID: {result['cid']}")
print(f"Gateway URL: {result['uris']['url']}")

이진 파일 업로드

import base64
import requests

API_KEY = "bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
API_URL = "https://api.ipfs.ninja/upload/new"

headers = {
    "Content-Type": "application/json",
    "X-Api-Key": API_KEY,
}

with open("photo.png", "rb") as f:
    encoded = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "content": encoded,
    "description": "Product photo",
    "metadata": {"project": "website-redesign"},
}

response = requests.post(API_URL, json=payload, headers=headers)
result = response.json()

print(f"CID: {result['cid']}")
print(f"Size: {result['sizeMB']} MB")
print(f"IPFS URI: {result['uris']['ipfs']}")
print(f"Gateway URL: {result['uris']['url']}")

일괄 업로드

import base64
from pathlib import Path
import requests

API_KEY = "bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
API_URL = "https://api.ipfs.ninja/upload/new"
HEADERS = {"Content-Type": "application/json", "X-Api-Key": API_KEY}


def upload_file(file_path, description=None, metadata=None):
    with open(file_path, "rb") as f:
        encoded = base64.b64encode(f.read()).decode("utf-8")

    payload = {"content": encoded}
    if description:
        payload["description"] = description
    if metadata:
        payload["metadata"] = metadata

    response = requests.post(API_URL, json=payload, headers=HEADERS)
    response.raise_for_status()
    return response.json()


# Upload all PNGs in a directory
for png in Path("./images").glob("*.png"):
    result = upload_file(png, description=f"Image: {png.name}")
    print(f"{png.name} -> {result['cid']}")

응답 이해하기

성공적인 모든 업로드는 다음 필드가 있는 JSON 객체를 반환합니다.

{
  "cid": "bafkreigh2akiscaildc7lqnpfuh3sksq4ogrtz7tpk2aulid5fhqotmqm",
  "sizeMB": 0.024,
  "uris": {
    "ipfs": "ipfs://bafkreigh2akiscaildc7lqnpfuh3sksq4ogrtz7tpk2aulid5fhqotmqm",
    "url": "https://ipfs.ninja/ipfs/bafkreigh2akiscaildc7lqnpfuh3sksq4ogrtz7tpk2aulid5fhqotmqm"
  }
}
필드설명
cid콘텐츠 식별자 — 파일 내용의 고유한 해시. 이것은 IPFS에서 파일의 영구 주소입니다.
sizeMB업로드된 파일의 크기(메가바이트 단위).
uris.ipfsIPFS 네이티브 URI(ipfs://CID). 스마트 컨트랙트, NFT 메타데이터 또는 기타 IPFS 인식 애플리케이션에서 파일을 참조할 때 이를 사용합니다.
uris.url모든 브라우저에서 열 수 있는 직접 HTTPS 게이트웨이 URL. 공유, 웹사이트에 임베드 또는 빠른 확인에 이상적입니다.

파일 액세스

파일이 핀되면 검색하는 두 가지 주요 방법이 있습니다.

전용 게이트웨이

모든 IPFS Ninja 계정에는 사용자 정의 슬러그가 있는 전용 게이트웨이가 포함됩니다.

https://your-slug.gw.ipfs.ninja/ipfs/{CID}

전용 게이트웨이는 IPFS Ninja 핀 인프라에 직접 연결되기 때문에 공개 게이트웨이보다 빠르고 신뢰할 수 있습니다. 업로드 응답의 CID를 사용하여 전용 게이트웨이를 통해 파일에 액세스할 수 있습니다.

공개 IPFS 게이트웨이

모든 IPFS 게이트웨이는 CID를 사용하여 콘텐츠를 제공할 수 있습니다.

https://ipfs.ninja/ipfs/{CID}     ← 전용 게이트웨이
https://dweb.link/ipfs/{CID}       ← 공개 게이트웨이
https://w3s.link/ipfs/{CID}        ← 공개 게이트웨이

공개 게이트웨이는 IPFS Ninja 네트워크 외부에서 콘텐츠에 도달할 수 있는지 확인하려는 경우에 유용합니다. 전용 게이트웨이에 비해 느리거나 속도 제한이 있을 수 있다는 점을 명심하세요.

스마트 컨트랙트 및 dApp에서

체인 상에 참조를 저장할 때(예: ERC-721 토큰 URI에서) ipfs:// URI를 사용하세요.

ipfs://bafkreigh2akiscaildc7lqnpfuh3sksq4ogrtz7tpk2aulid5fhqotmqm

지갑, 마켓플레이스 및 기타 IPFS 인식 애플리케이션은 사용 가능한 모든 게이트웨이를 통해 이 URI를 해결하는 방법을 알고 있습니다.

모범 사례

개별 파일을 100MB 미만으로 유지하세요. API는 더 큰 업로드를 허용하지만, 더 작은 파일은 더 빨리 핀되고 IPFS 네트워크에서 더 효율적으로 복제됩니다. 대규모 데이터 세트를 다루는 경우 더 작은 청크로 분할하세요.

설명적인 메타데이터를 사용하세요. descriptionmetadata 필드는 무료이며 나중에 업로드를 관리하는 것이 훨씬 쉬워집니다. 프로젝트 이름, 버전 번호 또는 검색 및 필터링에 도움이 되는 식별자를 포함하세요.

자체 데이터베이스에 CID를 저장하세요. IPFS Ninja가 업로드 기록을 저장하더라도, CID와 애플리케이션 수준 식별자(사용자 ID, 주문 번호, 토큰 ID) 간의 자체 매핑을 유지하면 통합이 더 탄력적이 됩니다.

체인 상 참조에 IPFS URI를 사용하세요. 스마트 컨트랙트나 불변 레코드에는 HTTPS 게이트웨이 URL보다는 항상 ipfs://CID를 저장하세요. 게이트웨이 URL은 변경될 수 있지만 CID는 변경될 수 없습니다.

구조화된 데이터에는 JSON 콘텐츠를 선호하세요. 데이터가 구조화되어 있는 경우(메타데이터, 구성, 레코드) 문자열로 인코딩하기보다는 JSON 객체로 전달하세요. API는 이를 더 효율적으로 저장하며, 결과 IPFS 콘텐츠는 사람이 읽을 수 있습니다.

오류를 우아하게 처리하세요. HTTP 상태 코드를 확인하고 5xx 응답에 대해 지수 백오프로 재시도를 구현하세요. API는 4xx 응답(잘못된 API 키, 누락된 콘텐츠, 충분하지 않은 크레딧)에 대해 명확한 오류 메시지를 반환하며 이를 사용자에게 표시해야 합니다.

결론

IPFS에 파일을 업로드하는 것이 이렇게 간단했던 적이 없습니다. 시각적 대시보드, 빠른 curl 명령 또는 JavaScript나 Python의 프로덕션급 통합을 선호하든, IPFS Ninja는 모든 콘텐츠 유형에서 단일 엔드포인트와 일관된 경험을 제공합니다.

무료 Dharma 플랜에는 50개 파일, 1GB 저장 공간, 월 2GB 대역폭이 포함되어 있어 통합을 엔드 투 엔드로 구축하고 테스트하기에 충분합니다. 확장할 준비가 되면, 월 $5의 Bodhi 플랜, 월 $19의 Karma 플랜, 월 $59의 Nirvana 플랜에서 더 높은 한도, 전용 게이트웨이 및 (Nirvana에서는) 우선 지원을 제공합니다.

무료 계정을 만들고 1분 이내에 IPFS에 파일을 업로드하기 시작하세요.

서명된 토큰 및 클라이언트 측 업로드에 대한 자세한 API 둘러보기는 IPFS Upload API 튜토리얼을 참조하세요. 파일 나열, API 키 관리 및 게이트웨이 구성을 포함한 전체 API 참조는 문서를 방문하세요.

블로그로 돌아가기
IPFS Upload API — 완전한 개발자 튜토리얼

IPFS Upload API — 완전한 개발자 튜토리얼

REST API를 통해 IPFS에 파일을 업로드하는 방법을 배웁니다. JavaScript, Node.js 및 curl의 완전한 코드 예제. JSON, 이미지 업로드, 클라이언트 측 업로드용 서명된 토큰 사용.