# 앱 및 버전

버전 관리와 애플리케이션에 대해 알아보세요 - 더 깊이 이해하기 위한 개념과 모범 사례입니다.

## 📦 애플리케이션

애플리케이션은 서버 프로젝트를 캡슐화합니다. 이러한 문맥 분리는 다음과 같은 경우 특히 유용합니다:

* 여러 게임이나 비게임 프로젝트를 작업할 때(통합 청구),
* 외부 프로젝트를 공동 개발자로 작업할 때(나중에 소유권 이전),
* 서로 다른 확장 패턴이나 요구 사항을 가진 여러 개의 느슨하게 결합된 서버 유형에 의존할 때.

플러그인, [대시보드](https://app.edgegap.com/application-management/applications/list)또는 API를 사용하여 Edgegap에서 애플리케이션을 관리할 수 있습니다.

{% hint style="success" %}
다음을 살펴보세요 [애플리케이션 API 참조](https://docs.edgegap.com/api/#tag/Applications)또는 다음에 대해 더 읽어보세요 [관리 API](https://docs.edgegap.com/api/).
{% endhint %}

## 🏷️ 앱 버전

애플리케이션을 개발하고 새로운 빌드를 계속 생성함에 따라, 각 빌드를 별도의 버전으로 저장해야 합니다. 그 이유는 다음과 같습니다:

* **호환성 유지** 클라이언트와 서버 간의
* 여러 측면을 비교하기 위해 **점진적 릴리스** (성능, 사용자 반응),
* 테스트하고 **여러 앱 버전을 동시에** (개발, 품질 보증, 스테이징, 베타).

{% hint style="info" %}
각 앱 버전은 선택한 하나의 빌드 아티팩트를 가리킵니다. 여러 버전이 같은 빌드를 가리킬 수도 있습니다.
{% endhint %}

플러그인, [대시보드](https://app.edgegap.com/application-management/applications/list)또는 API를 사용하여 Edgegap에서 애플리케이션을 관리할 수 있습니다.

{% hint style="success" %}
다음을 살펴보세요 [앱 버전 API 참조](https://docs.edgegap.com/api/#tag/Applications/operation/app-version-post)를 사용하여 Edgegap에서 앱 버전을 관리할 수 있으며, 또는 다음에 대해 더 읽어보세요 [API](https://docs.edgegap.com/api/).
{% endhint %}

각 버전은 부모 애플리케이션 내에서 다음에 의해 고유하게 식별됩니다 **앱 버전 이름**. 원하는 명명 규칙을 자유롭게 정할 수 있습니다. 선택에 영감을 줄 몇 가지 인기 있는 예시는 다음과 같습니다:

* `2024.01.30-16.23.00-UTC` - 타임스탬프는 과거 버전을 많이 보관할 때 명확합니다,
* `1.1.0` - [의미적 버전 관리](https://semver.org/) 는 변경 범위를 전달하는 데 좋은 선택입니다,
* `dev` , `staging`, `qa`, `prod` - 환경별로 최신 버전만 유지하는 것은 매우 쉽습니다,
* `blue`, `green` - 버전은 롤링 업데이트 릴리스 전략의 별칭으로 사용할 수 있습니다.

{% hint style="success" %}
클라이언트/서버 호환성을 유지하는 한, 언제든지 접근 방식을 변경할 수 있습니다.
{% endhint %}

{% hint style="info" %}
다음에서 모든 앱 또는 버전을 비활성화할 수 있습니다 [대시보드](https://app.edgegap.com/application-management/applications/list) 를 사용하여 **사람(개발자)의 실수로부터 보호**.
{% endhint %}

{% hint style="info" %}
무료 요금제는 애플리케이션 2개, 버전 2개, 그리고 컨테이너 레지스트리 저장공간 5GB로 제한됩니다.
{% endhint %}

### 버전 관리 전략 결합

대개 가장 좋은 해결책은 버전 관리 전략을 혼합하는 것입니다. 예를 들면:

* 더 세밀한 추적을 위해 개발 빌드에 타임스탬프나 의미적 버전 관리를 사용하는 것;
* 보관하기 `staging`, `qa` 및 `prod` 환경별 매개변수가 있는 버전;
* 번갈아 사용하는 `blue` 및 `green` 버전을 다음의 별칭으로 [매치메이킹 다운타임이 없는 업데이트](https://docs.edgegap.com/docs/gen2-matchmaker#rolling-updates-ab-tests).

## 🧱 필수 매개변수

이러한 기본 매개변수는 항상 정의되어야 합니다.

### 리소스 요구 사항

다음 외에도 **버전 이름**, 새 버전을 만들려면 여러 매개변수가 필요합니다:

* **vCPU** - 앱을 실행하는 데 필요한 가상 CPU 단위 수입니다(1024 단위 = 1 vCPU),
  * **허용되는 최소 vCPU 수는 0.25 vCPU(256 단위)입니다,**
  * 이 설정은 기존 앱 버전에서 수정할 수 없으며, 새 버전을 만들어야 합니다.
* **메모리** - 앱을 실행하는 데 필요한 RAM 메가바이트 수입니다(1024MB = 1GB),
  * 이 설정은 기존 앱 버전에서 수정할 수 없으며, 새 버전을 만들어야 합니다.
* **GPU** - 앱을 실행하는 데 필요한 그래픽 처리 장치 수입니다,
  * 이 기능은 아직 사용할 수 없습니다. 관심이 있으시면 문의해 주세요.

{% hint style="success" %}
버전에는 RAM-vCPU 비율 2:1로 RAM이 자동으로 포함되며, **0.25 vCPU당 최대 512MB의 RAM을 허용합니다**.
{% endhint %}

{% hint style="info" %}
저희 서버 머신은 위치에 따라 다르지만 2.4 - 3.2 GHz 클럭 속도의 AMD/Intel CPU를 사용합니다. 서버에 충분한 리소스가 있는지 확인하려면 다음에서 문의해 주세요 [커뮤니티 디스코드](https://discord.gg/MmJf8fWjnt).
{% endhint %}

### 이미지 세부 정보

이러한 매개변수는 시스템이 나중에 어떤 서버 빌드를 시작해야 하는지 결정하는 데 도움이 됩니다:

* **레지스트리** - `registry.edgegap.com` 저희 [컨테이너 레지스트리](https://docs.edgegap.com/docs/container/edgegap-container-registry),
  * 를 사용하는 경우, 서드파티 레지스트리를 사용하려면 해당 서드파티 레지스트리의 Docker 자격 증명을 입력하세요,
  * 레지스트리는 귀하와 다른 사용자의 저장소를 위한 공유 저장 서비스 역할을 합니다.
* **이미지 저장소** - 애플리케이션 전용 저장소를 의미합니다,
  * 모든 저장소는 다음에서 찾을 수 있습니다 [대시보드의 컨테이너 레지스트리 페이지](https://app.edgegap.com/registry-management/repositories/list),
  * 각 저장소에는 서버 이미지의 여러 태그가 포함될 수 있습니다.
* **태그** - 서버 이미지의 특정 빌드 아티팩트(버전)를 의미합니다,
  * 저희 플러그인은 기본적으로 앱 버전 이름에서 태그 값을 복사합니다,
  * Docker Desktop Images 또는 docker CLI를 사용하여 로컬에 저장된 태그를 볼 수 있습니다.

{% hint style="danger" %}
:x: **하지 마세요 - 기존 태그를 덮어쓰거나 `latest` 태그를 사용하지 마세요** 오래된(캐시된) 빌포를 배포하는 일을 피하기 위해서입니다.\
:white\_check\_mark: **해야 합니다 - 버전 태그를 항상 증가시키세요** 의도한 빌드를 배포하고 릴리스 문제를 방지하기 위해서입니다.
{% endhint %}

* **비공개 레지스트리** - 저장소 접근이 보호되는 경우(비공개 저장소), 다음도 필요합니다:
  * **사용자 이름 토큰** - 레지스트리의 프로그램적 접근용 사용자 이름,
  * **비밀번호 토큰** - 레지스트리의 프로그램적 접근용 비밀번호,
  * Edgegap의 경우 [컨테이너 레지스트리](https://docs.edgegap.com/docs/container/edgegap-container-registry), 다음을 할 수 있습니다 [대시보드에서 이 값을 복사](https://app.edgegap.com/registry-management/repositories/list),
  * 이 항목들은 공개 저장소에는 필요하지 않습니다.

<details>

<summary>문제 해결 및 FAQ</summary>

오류가 발생했습니다 `401 Unauthorized` 를 서버 이미지 푸시할 때 받았습니다.

* 이는 컨테이너 레지스트리에 로그인하지 않았음을 의미합니다. 다음을 참조하세요 [Edgegap 컨테이너 레지스트리 안내](https://docs.edgegap.com/docs/container/edgegap-container-registry#getting-your-credentials)또는 귀하의 레지스트리 제공업체에 해당하는 안내를 확인하세요. 마지막 작업을 반복해도 오류는 해결되지 않습니다.

***

오류가 발생했습니다 `403 Forbidden` 를 서버 이미지 푸시할 때 받았습니다.

* 이는 현재 로그인한 레지스트리 사용자의 권한이 충분하지 않거나(보통 새 이미지를 푸시할 권한), 잘못된 레지스트리 제공업체에 로그인했음을 의미합니다. 로그아웃한 뒤 적절한 권한을 가진 올바른 제공업체와 사용자로 다시 로그인해 보세요. 마지막 작업을 반복해도 오류는 해결되지 않습니다.

***

레지스트리, 저장소, 프로젝트의 차이점은 무엇인가요?

* 레지스트리를 저장 시설, 저장소를 보관함, 프로젝트를 보관함 번호라고 생각하면 됩니다. 각 레지스트리에는 보통 많은 저장소가 있으며, 일부는 공개이고 일부는 조직과 사용자에게 비공개입니다.
* 예시 레지스트리: `registry.edgegap.com` .
* 예시 저장소: `registry.edgegap.com/my-edgegap-org/my-game-server`.
* 예시 프로젝트 이름: `my-game-server` .

***

새 이미지 태그 / 빌드를 푸시할 때 변경 사항이 제대로 다시 로드되지 않습니다.

* 매번 다시 빌드할 때 새 이미지 태그로 푸시하는지 확인하세요. Edgegap의 내부 캐싱 시스템은 태그 이름을 사용하며, 태그 값을 덮어쓰는 경우(예: `latest`) 새 빌드를 인식하지 못합니다.

***

같은 빌드 아티팩트에 여러 번 태그를 붙일 수 있나요?

* 네, 같은 아티팩트에 여러 번 문제 없이 태그를 붙일 수 있으며, 동일한 빌드에 대한 여러 별칭으로 작동합니다. 나중에 태그를 제거하는 방법을 알아보려면 계속 읽어보세요.

***

태그를 삭제하면 어떻게 되나요? 해시를 사용해 특정 아티팩트를 삭제할 수 없는 이유는 무엇인가요?

* 태그를 삭제하면, 삭제 시점에 해당 아티팩트와 연결된 다른 태그가 없다면 관련 빌드 아티팩트도 삭제됩니다 [API 요청](https://docs.edgegap.com/api/#tag/Container-Registry/operation/image-tag-delete).
* Docker API 표준과 최상의 사용자 경험을 보장하기 위해, 저희는 태그 삭제용 인터페이스만 제공합니다. 빌드 아티팩트 삭제에 관한 위의 설명을 참고하세요.

</details>

## ⚙️ 선택적 매개변수

이러한 매개변수는 배포를 더 세밀하게 사용자 지정하기 위해 구성할 수 있습니다.

### 주입된 변수

사용자 지정 환경 변수가 이 버전의 모든 배포에 주입됩니다:

* 일반적인 예: 엔진 인수, 서드파티 비밀 정보 및 엔드포인트,
* 참조 [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#injected-environment-variables) 배포 문맥에 따라 환경 변수가 주입될 수 있는 다양한 방법을 이해하려면, 앱 버전 변수 외에도
* 각 환경 변수는 최대 4KB(킬로바이트)의 문자열 데이터를 포함할 수 있습니다.

{% hint style="warning" %}
다음을 꼭 하세요 **민감한 변수(비밀, 토큰)는 숨김으로 설정하여** 보안을 강화하세요!
{% endhint %}

### 활성 캐싱

:star2: [**종량제 요금제로 업그레이드하세요**](https://app.edgegap.com/user-settings?tab=memberships) **전 세계 0.5초 배포 시간을 해제하려면!**

**배포를 더 빠르게 하고 몇 초 안에 서버를 시작하세요. 대기 서버가 필요 없습니다.** 이 앱 버전에 연결된 서버 이미지는 전 세계 모든 지역에 자동으로 미리 로드됩니다.

캐싱은 앱 버전의 캐싱 수준이 🟢 좋음에 도달하면 완전히 적용됩니다.

{% hint style="success" %}
여러 앱 버전이 같은 이미지 태그를 재사용할 수 있습니다. **한 버전에서 캐시를 활성화하면 동일한 이미지 태그에 연결된 모든 버전에도 자동으로 활성화되어**매개변수화된 배포를 쉽게 만듭니다.
{% endhint %}

{% hint style="info" %}
이미지는 배포 시 수동으로도 캐시되며, 배포된 호스트 머신에서만 캐시됩니다.
{% endhint %}

{% hint style="warning" %}
**이미지는 72시간 연속으로 배포되지 않으면 캐시에서 제거됩니다.**
{% endhint %}

### 포트 매핑

모든 서버는 들어오는 클라이언트 연결을 받기 위해 최소 하나의 포트가 필요합니다:

* **포트** 값은 다음을 의미합니다 **내부 포트** 값으로, 일반적으로 네트코드 통합에서 가져옵니다,
* **프로토콜** 네트코드 통합 전송 방식에 따라 달라집니다,
* **이름** 은 사용자의 필요를 위한 사람이 읽을 수 있는 식별자이며, 포트와 같을 수도 있습니다,
* **검증** 를 활성화하여 컨테이너가 READY로 표시되기 전에 초기화되었는지 확인할 수 있습니다.

{% hint style="success" %}
대부분의 게임은 포트에 대해 단일 UDP 포트 매핑만 추가하면 됩니다 `7777`.
{% endhint %}

서버 프로세스의 내부 포트는 앱 버전의 일부로 정의되지만, **외부 포트는 배포가 생성되면 무작위로 할당됩니다**그래서 잠재적 악의자(해커)가 피해를 주기 전에 속도가 늦춰지고 탐지됩니다.

<figure><img src="/files/4ba971ec5dc2edf09fe8eb3467658441fa65db04" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
서버가 여러 프로토콜로 통신하는 경우 포트 매핑에 더 많은 포트를 추가하세요.
{% endhint %}

### 안전 가드레일

이러한 매개변수는 다양한 예외 상황과 일반적인 서버 문제 해결에 도움이 됩니다:

* **시간 제한** - 이러한 기능은 배포의 리소스 수명 주기를 관리하는 데 도움이 됩니다:
  * **게임 최대 지속 시간** 은 지정된 기간 후 서버를 정상적으로 종료하도록 설정하거나 `-1`  을 [앱 버전 API 생성/편집](/docs.edgegap.com-ko/docs/api/versioning.md#post-v1-app-app_name-version) 으로 설정할 수 있습니다 [지속성](/docs.edgegap.com-ko/learn/orchestration/persistence.md) 을 [프라이빗 플릿](/docs.edgegap.com-ko/learn/orchestration/private-fleets.md).
  * **배포에 걸리는 최대 시간** 을 사용하면 시작하는 데 너무 오래 걸리는 배포를 정리할 수 있습니다.
* **프로세스 재시작 정책** - 서버 프로세스가 중지될 때의 배포 동작을 제어합니다.
  * 항상 재시작(기본값) - 성공 종료 코드(0)와 모든 오류 종료에서 재시작합니다.
  * 재시작 안 함(권장) - 성공 및 오류 종료 코드에서 배포가 중지됩니다.
  * 충돌 시 재시작 - 오류 종료 코드에서만 재시작하며, 지속형 서버에 유용합니다.
* **컨테이너 로그 저장소** - 배포가 중지된 후 서버 로그를 내보내려면, 사전 구성된 S3 호환 버킷을 지정하여 컨테이너 로그를 내보내세요,
  * 참조 [엔드포인트 저장소](https://docs.edgegap.com/docs/deployment/endpoint-storage) 구성 및 사용에 대한 자세한 내용은

{% hint style="warning" %}
외부 저장소가 없는 버전의 로그는 배포 종료 시 삭제됩니다.
{% endhint %}

{% hint style="info" %}
무료 요금제는 애플리케이션 2개, 버전 2개, 그리고 컨테이너 레지스트리 저장공간 5GB로 제한됩니다.
{% endhint %}

## ⏩ 업데이트 일관성

새 앱 버전을 만들 때 모든 매개변수가 변경되지 않도록 하려면, 저희 [대시보드](https://app.edgegap.com/application-management/applications/list)를 통해, 다음을 사용하는 것을 권장합니다 **복제** 이전 앱 버전의 대시보드 페이지 오른쪽 상단에 있는 기능입니다. 복제할 때 저장하기 전에 모든 매개변수를 편집할 수 있습니다.

{% hint style="success" %}
**앱 버전을 복제하거나 편집해도 서버 이미지를 다시 빌드할 필요가 없습니다.**
{% endhint %}

{% hint style="info" %}
를 참조하여 [매치메이커 롤링 업데이트](https://docs.edgegap.com/docs/gen2-matchmaker#rolling-updates-ab-tests) 추가 **릴리스 자동화**.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.edgegap.com/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
