# Unreal Engine - 시작하기

실습을 통해 배우고 Edgegap에서 첫 전용 서버를 배포해 보세요. 이 가이드가 끝날 때쯤이면 비용 없이 Edgegap으로 전용 서버를 배포하게 됩니다.

Docker Desktop으로 빌드하는 것이 시작하기에 가장 빠르고 쉽고 가장 신뢰할 수 있는 방법입니다.

{% embed url="<https://youtu.be/q7ljcr9rAWE>" %}

## ✔️ 준비

<details>

<summary><a href="https://open.docker.com/extensions/marketplace?extensionId=edgegap/docker-extension">Edgegap Quickstart Docker 확장 설치</a></summary>

* Docker Desktop / Extensions / Browse에서 설치하거나 [링크를 사용하여](https://open.docker.com/extensions/marketplace?extensionId=edgegap/docker-extension).

<figure><img src="/files/17d13f47476dc4dcaf81956beb14da18abe1adc0" alt=""><figcaption></figcaption></figure>

</details>

{% hint style="info" %}
**서버 빌드에 자신이 있으신가요?** 다음으로 건너뛰기 [#customize-server-image](#customize-server-image "mention") 및 [고급 기능](/docs.edgegap.com-ko/learn/advanced-features.md).
{% endhint %}

## ⚙️ 1. 프로젝트 구성 <a href="#id-1-configure-project" id="id-1-configure-project"></a>

{% hint style="info" %}
이 방법은 Unreal Engine 소스 코드를 다운로드하거나 소스에서 빌드할 필요가 없습니다!
{% endhint %}

☑️ 먼저 **Unreal Engine 버전을 확인하세요** - 프로젝트 파일의 값으로 미리 채워집니다.

☑️ **GitHub 사용자 이름과** [**PAT**](#user-content-fn-1)[^1] 을 [#preparation](#preparation "mention")에서 입력하여 GitHub에서 종속성을 다운로드합니다.

## 🔧 2. 게임 서버 빌드 <a href="#id-2-build-game-server" id="id-2-build-game-server"></a>

이제 프로젝트를 빌드하고 쿠킹한 뒤, 쉽게 재사용할 수 있는 Docker 이미지로 패키징합니다.

☑️ 다음 옵션을 구성할 수 있습니다(또는 기본값 유지):

* **이미지 이름** 은 선택한 고유 식별자로, 배포 전에 서버 빌드를 표시합니다.
  * 보통 게임 이름이 포함됩니다. 예: “my-game-server”.
* **이미지 태그** 는 이미지의 특정 버전을 가리키는 식별자입니다.
  * “빌드 아티팩트”라는 용어는 특정 버전의 이미지를 지칭하는 데 때때로 사용됩니다.
  * 타임스탬프는 태그로 사용하기에 좋은 옵션입니다. 예: `2024.01.30-16.23.00-UTC`  (기본값).

☑️ **프로젝트 빌드** 구성이 만족스러우면 실행하세요. 이 단계를 완료하면 Linux 게임 서버 실행 파일이 포함된 새 이미지가 로컬 Docker 클라이언트에 추가됩니다.

✅ 이제 다음 단계로 진행할 수 있습니다.

## 🧪 3. 로컬에서 서버 테스트 <a href="#id-3-test-server-locally" id="id-3-test-server-locally"></a>

☑️ **로컬에서 실행할 이미지 태그를 선택하세요** (원격 이미지는 다운로드됩니다). 선택적으로 추가 [docker run 인자](https://docs.docker.com/reference/cli/docker/image/build/#options) 를 제공하여 로컬 테스트를 사용자 지정할 수 있습니다:

* `-p 7777:7777/udp` - 이것은 로컬 컨테이너의 [포트 매핑입니다](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#port-mapping),
* `-e ARBITRIUM_PORT_GAMEPORT_INTERNAL=7777`  은 [환경 변수](#environment-variables) 로, 실제 Edgegap 배포를 모방하여 게임 서버에 플레이어 연결을 수신할 내부 포트를 알려줍니다.

☑️ 구성이 만족스러우면 **로컬 서버 시작**을 누르세요. 이 단계를 완료하면 **새 컨테이너가 시작됩니다** 개발 머신에서.

☑️ 이제 Unreal Engine Editor(PIE) 게임 클라이언트를 로컬 서버 컨테이너에 연결할 차례입니다. Unreal PIE 콘솔을 `~`  (틸드)로 열고 다음으로 연결하세요 `open <ip>:<port>`:

* `ip`  = `localhost`  또는 `127.0.0.1`  (대부분의 경우 동일),
* `port`  = Docker GUI의 컨테이너 외부 포트 무작위 값.

✅ 이제 다음 단계로 진행할 수 있습니다.

<details>

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

클라이언트를 서버에 연결할 수 없음 - `요청 시간 초과.` , `请求超时` , `ConnectionFailed` 또는 `포트 확인 실패`

* 먼저 컨테이너가 실행 중인지, 그리고 로그에 런타임 오류가 없는지 확인하세요.
* 다음의 포트 값이 `docker run` 명령에서 일치하는지 확인하세요.
* 게임 클라이언트가 **외부 포트** 에 연결하고 있는지 확인하세요. 이 값은 보안상의 이유로 항상 무작위로 지정됩니다.
* 대상 파일 이름을 변경하고 게임 빌드를 1단계에서 설명한 대로 구성했는지 확인하세요. [#id-1-configure-project](#id-1-configure-project "mention").

***

컨테이너는 올라왔지만 그 후 몇 분 동안 연결할 수 없습니다.

* 컨테이너가 시작되면 게임 엔진 초기화가 시작됩니다. 이 과정은 수초에서 수분까지 걸릴 수 있으며, 이 기간 동안 서버는 플레이어 연결을 허용하지 않습니다.
* 이 시간을 줄이기 위해 서버 초기화를 최적화하는 것을 고려하세요.
* 게임 클라이언트는 제한된 시간 동안(초기화 지속 시간에 따라) 1초 간격으로 연결을 재시도한 뒤, 매치메이킹으로 돌아가야 합니다.
* 로딩 씬을 추가하여 서버가 클라이언트와 동시에 초기화(그리고 Unreal Engine의 경우 이동)할 수 있게 하고, 두 상태를 동기화하는 것을 고려하세요.

***

`경고: 바인드 주소에 대한 소켓을 만들 수 없음`

* Fab 에셋 스토어를 통해 Epic의 Steam Subsystem 플러그인을 설치하세요.
* GitHub에서 다운로드한 SteamCore 소스 버전과 함께 Edgegap Integration Kit(EGIK)를 사용할 경우, Epic Games의 플러그인 배포 정책으로 인해 Epic의 Steam Subsystem 플러그인은 포함되지 않습니다.

***

연결했는데 화면이 완전히 검게 나옵니다.

* 올바른 **Game Default Map** 이 **Edit / Project Settings / Maps & Modes**.

</details>

## ☁️ 4. Edgegap에 게시 <a href="#id-4-publish-to-edgegap" id="id-4-publish-to-edgegap"></a>

☑️ **애플리케이션 이름을 선택하세요** Edgegap에서 유사한 이미지를 레이블링하고 그룹화하기 위해 사용합니다.

☑️ **게시할 이미지 태그를 선택하세요** 및 **이미지 업로드**. 이 단계를 완료하면 서버 이미지가 Edgegap Registry에 업로드되고 새 [애플리케이션 버전이 생성됩니다](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md) 웹 브라우저에서. **프롬프트가 표시되면** [**포트 매핑입니다**](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#port-mapping) **다음을 생성하세요** 기본값으&#xB85C;**.**

{% hint style="success" %}
버그를 발견해서 다시 빌드/게시해야 하나요? **소스에서 다시 빌드** 를 사용하여 [#id-2.-build-game-server](#id-2.-build-game-server "mention") 및 [#id-4.-publish-to-edgegap](#id-4.-publish-to-edgegap "mention") **현재 확장 입력 값으로 빠르게 수행하세요.**
{% endhint %}

✅ 이제 다음 단계로 진행할 수 있습니다.

## 🚀 5. 클라우드에 배포 <a href="#id-5-deploy-to-cloud" id="id-5-deploy-to-cloud"></a>

☑️ 이제 최종 테스트를 수행하고 **Unreal Engine Editor를 클라우드 배포에 연결합니다**. 서버 IP 대신 **배포의 호스트** 를 가져오고 배포의 **외부 포트**을 사용한 뒤, 게임 클라이언트에서 Unreal 콘솔을 열고(틸드 `~`) 다음을 입력하세요 `open {host}:{port}` .

<details>

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

클라이언트를 서버에 연결할 수 없음 - `요청 시간 초과.` , `请求超时` , `ConnectionFailed` 또는 `포트 확인 실패`

* 먼저 배포가 Ready 상태인지, 배포 로그에 런타임 예외나 오류가 없는지 확인하세요. 배포가 중지되었다면, [대시보드](https://app.edgegap.com/deployment-management/deployments/list).
* 에서 로그를 확인하세요. 서버 빌드의 넷코드 설정에 있는 포트 설정이 [앱 버전](https://app.edgegap.com/application-management/applications/list)의 내부 포트와 일치하는지 확인하세요. 플러그인 빌드의 경우 포트는 자동으로 설정됩니다.  [앱 버전](https://app.edgegap.com/application-management/applications/list) 를 편집하여 재빌드 없이 포트 매핑을 변경할 수 있습니다. 넷코드 통합에서 프로토콜을 찾으세요.
* 게임 클라이언트가 **외부 포트** 배포 세부 정보 페이지에 표시되는 이 값은 보안상의 이유로 항상 무작위로 지정됩니다.
* 대상 파일 이름을 변경하고 게임 빌드를 1단계에서 설명한 대로 구성했는지 확인하세요. [#id-1.-configure-project](#id-1.-configure-project "mention").
* 중국에 있고 [스마트 플릿](https://docs.edgegap.com/docs/deployment/session/fleet-manager/fleet)을 사용 중인가요? Great Firewall 때문에 연결이 차단될 수 있습니다. 플릿에 중국에 위치한 서버를 추가하거나 VPN을 사용하여 연결하는 것을 고려하세요.

***

배포는 준비되었지만 그 후 몇 분 동안 연결할 수 없습니다.

* 배포가 Ready 상태가 되면 게임 엔진 초기화가 시작됩니다. 이 과정은 수초에서 수분까지 걸릴 수 있으며, 이 기간 동안 서버는 플레이어 연결을 허용하지 않습니다.
* 이 시간을 줄이기 위해 서버 초기화를 최적화하는 것을 고려하세요.
* 게임 클라이언트는 제한된 시간 동안(초기화 지속 시간에 따라) 1초 간격으로 연결을 재시도한 뒤, 매치메이킹으로 돌아가야 합니다.
* 로딩 씬을 추가하여 서버가 클라이언트와 동시에 초기화(그리고 Unreal Engine의 경우 이동)할 수 있게 하고, 두 상태를 동기화하는 것을 고려하세요.

***

`경고: 바인드 주소에 대한 소켓을 만들 수 없음`

* Fab 에셋 스토어를 통해 Epic의 Steam Subsystem 플러그인을 설치하세요.
* GitHub에서 다운로드한 SteamCore Integration Kit(SIK) 소스 버전과 함께 Edgegap Integration Kit(EGIK)를 사용할 경우, Epic Games의 플러그인 배포 정책으로 인해 Epic의 Steam Subsystem 플러그인은 포함되지 않습니다.

***

연결했는데 화면이 완전히 검게 나옵니다.

* 올바른 **Game Default Map** 이 **Edit / Project Settings / Maps & Modes**.
* 다음 항목이 [Unreal Engine 버전 호환성 검사가 비활성화되었는지](#id-2.-configure-game-server-builds) 에서 `DefaultEngine.ini`.

***

배포가 중지/재시작되었고 이제 로그에 접근할 수 없습니다.

* 예외로 인해 서버 프로세스가 충돌하는 경우, 시스템이 서버를 자동으로 재시작하려고 시도합니다. 근본 원인을 찾기 위해 서버를 로컬에서 테스트해 보세요.
* 로그는 배포가 유지되는 동안만 보관됩니다. 배포 중지 후 로그를 확인하려면 [타사 로그 저장소를 통합하세요](https://docs.edgegap.com/docs/deployment/endpoint-storage).
* 를 참조하여 [/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped](https://docs.edgegap.com/docs.edgegap.com-ko/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped "mention") 배포가 중지된 모든 원인을 확인하세요.

***

내 배포가 X분 후 자동으로 중지되었습니다.

* 무료 요금제 배포에는 60분 제한이 있으므로 계정 업그레이드를 고려하세요.
* 모든 배포는 서버 정리 정책, 인프라 유지보수, 그리고 배포가 제대로 종료되지 않았을 때 예상치 못한 비용이 누적되는 것을 방지하기 위해 실행 24시간 후 종료됩니다. 장시간 실행되는 서버의 경우 [프라이빗 플릿](/docs.edgegap.com-ko/learn/orchestration/private-fleets.md) 을 [지속성](/docs.edgegap.com-ko/learn/orchestration/persistence.md).
* 를 참조하여 [/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped](https://docs.edgegap.com/docs.edgegap.com-ko/pages/1e75126474c80b6c476cbd5e97b171fce5779d47#id-5.-deployment-stopped "mention") 배포가 중지된 모든 원인을 확인하세요.

***

플레이어가 내 배포를 떠나면 어떻게 되나요?

* 기본적으로 서버는 플레이어 연결을 거부하지 않습니다. 플레이어 인증은 개발자의 몫입니다. 여러 가지 방법과 플레이어 인증 제공자를 사용할 수 있기 때문입니다.
* 게임 클라이언트는 예기치 않은 충돌 시 재연결을 시도하기 위해 연결 정보를 로컬에 저장할 수 있습니다.
* 플레이어가 진행 중인 게임에 참여할 수 있도록 하려면 [심층 살펴보기](/docs.edgegap.com-ko/learn/matchmaking/matchmaker-in-depth.md#backfill) 또는 [세션](https://docs.edgegap.com/docs/deployment/session).

***

서버가 준비된 후 CPU 사용률이 100%로 표시됩니다.

* 게임 엔진은 서버 초기화 중 CPU 집약적인 작업을 수행하는 경향이 있으므로 문제가 아닐 수 있습니다. 배포 시작 후 2\~3분이 지나도 CPU 사용률이 떨어지지 않으면 서버를 최적화하거나 앱 버전 리소스를 늘려야 할 수 있습니다.
* 틱 속도를 줄이면 더 적은 메시지를 처리하므로 CPU 사용량을 제어하는 데 도움이 됩니다.
* 무료 요금제에서는 1.5 vCPU와 3GB 메모리(RAM)로 제한됩니다.
* 새 앱 버전을 만들 때 할당 리소스를 늘릴 수 있습니다. 대시보드에서 앱 버전을 복제하고 서버나 이미지를 다시 빌드하지 않고도 필요에 따라 이 값을 조정할 수 있습니다.

***

배포가 반복적으로 재시작되고 오류가 표시됩니다 `OOM kill`

* 할당된 메모리 양을 초과해서 발생합니다. 오브젝트 풀링, 압축 또는 씬에서 불필요한 오브젝트 제거를 통해 메모리 사용을 최적화하는 것을 고려하세요.
* 무료 요금제에서는 1.5 vCPU와 3GB 메모리(RAM)로 제한됩니다.
* 새 앱 버전을 만들 때 할당 리소스를 늘릴 수 있습니다. 대시보드에서 앱 버전을 복제하고 서버나 이미지를 다시 빌드하지 않고도 필요에 따라 이 값을 조정할 수 있습니다.

***

때때로 서버의 메모리(RAM) 사용량이 높은 값으로 급증하는데, 문제가 있나요?

* 할당된 앱 버전 메모리 양 이내인 한, 이는 문제가 아닙니다.
* 할당된 앱 버전 메모리 양을 초과하면 `OOM kill` 이 발생합니다(위 참조).

***

같은 머신에서 실행 중인 다른 서버 때문에 내 서버 성능이 영향을 받나요?

* 아니요. 당사 플랫폼은 할당된 리소스가 다른 스튜디오나 공유 인프라의 다른 서버에 의해 사용되지 않도록 보장합니다. Edgegap에서는 시끄러운 이웃 문제가 없습니다.

</details>

## 👉 다음 단계

### 배포 중지

매치가 끝나거나 플레이어가 떠나면 비용 절감을 위해 배포를 중지할 수 있습니다. [비어 있거나 일부만 채워진 상태로 계속 실행하면 비용이 불필요하게 증가할 수 있습니다!](https://edgegap.com/blog/how-session-fill-rate-affects-your-multiplayer-hosting-costs)

이 가이드를 따라 Docker 확장으로 빌드했다면, 다음 메서드를 간단히 호출할 수 있습니다 `FGenericPlatformMisc::RequestExit` . 패키지된 이미지에 서버 프로세스를 관리하는 스크립트를 추가했으며, 이를 통해 자동으로 정상적인 배포 종료가 수행됩니다.

서버 수명 주기 관리를 사용자 지정하려면 [예제 `StartServer.sh`](https://github.com/edgegap/edgegap-unreal-buildutils/blob/main/StartServer.sh)  스크립트를 수정하세요.

{% hint style="info" %}
Unreal에서 수명 주기를 관리하고 싶으신가요? [개발자 도구](/docs.edgegap.com-ko/unreal-engine/developer-tools.md#integration-kit) 에서 자체 중지 API 블루프린트를 확인하세요.
{% endhint %}

### 주입된 변수

주입된 환경 변수에 접근하여 배포 ID, 서버 IP 주소, 서버 위치 등의 유용한 정보를 읽을 수 있습니다. 각 배포에는 자동으로 다음이 포함됩니다:

* [배포 변수](/docs.edgegap.com-ko/learn/orchestration/deployments.md#injected-environment-variables) - Edgegap에서 자동으로 제공됨,
* [매치메이킹 변수](/docs.edgegap.com-ko/learn/matchmaking/matchmaker-in-depth.md#injected-environment-variables) - 사용할 때 Edgegap에서 자동으로 제공됨 [매치메이킹](/docs.edgegap.com-ko/learn/matchmaking.md),
* [앱 버전 변수](/docs.edgegap.com-ko/learn/orchestration/application-and-versions.md#injected-variables) - 사용자가 구성할 수 있는 사용자 정의 키-값 쌍.

{% hint style="success" %}
우리의 [개발자 도구](/docs.edgegap.com-ko/unreal-engine/developer-tools.md#integration-kit) 를 사용하여 **Blueprint를 사용하여 형식이 지정된 변수를 쉽게 읽을 수 있습니다**.
{% endhint %}

### 서버 프로파일링

Edgegap에서 서버 성능 문제를 이해하고 최적화하려면 [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#container-logs), [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#container-metrics)및 기타 [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#dashboard-monitoring) 도구를 활용하세요.

또한 Edgegap과 함께 기존 Unreal Engine 프로파일링 도구를 사용할 수 있습니다:

* [Unreal Engine 서버에서 트레이싱 구성](https://dev.epicgames.com/documentation/en-us/unreal-engine/developer-guide-to-tracing-in-unreal-engine) (기본 및 사용자 지정 이벤트):
  * 서버 디스크에 트레이스를 저장하려면 `-tracefile`을 사용하고, 타사 저장소에 업로드하여 오프라인으로 분석하거나,
  * 또는 다음으로 트레이스 데이터를 스트리밍하세요 [배포](/docs.edgegap.com-ko/learn/orchestration/deployments.md#port-mapping) 내부 포트용 `1981` UDP 프로토콜을 통해.
* 분석 [메모리 인사이트](https://dev.epicgames.com/documentation/en-us/unreal-engine/memory-insights-in-unreal-engine) 및 [네트워킹 인사이트](https://dev.epicgames.com/documentation/en-us/unreal-engine/networking-insights-in-unreal-engine) 및 [#optimize-server-builds](#optimize-server-builds "mention").

### 세션 자동화

### 빌드 최적화

**클라이언트 전용 에셋을 서버 에셋과 분리하도록 에셋 청킹을 구성하세요.**

* 탐색 [에픽의 에셋 청킹 기법 및 권장 사항](https://dev.epicgames.com/documentation/en-us/unreal-engine/preparing-assets-for-chunking-in-unreal-engine) 을 확인하세요.

**클라이언트 전용이며 서버 실행에 필요하지 않은 에셋과 플러그인을 제외하세요.**

* 다음 내용을 알아보세요 [빌드 시간 에셋 및 플러그인 제외](https://dev.epicgames.com/community/learning/tutorials/Kp1k/unreal-engine-build-time-asset-and-plugin-exclusion).

**콘텐츠 쿠킹 전략을 검토하세요.**

* 다음을 고려하세요 [Cooking on the Fly (COTF)](https://dev.epicgames.com/documentation/en-us/unreal-engine/build-operations-cooking-packaging-deploying-and-running-projects-in-unreal-engine#cookonthefly) 클라이언트 에셋 쿠킹을 지연시켜 서버 빌드 속도를 높이세요.

**런타임 메모리 부담을 줄이기 위해 레벨 스트리밍을 구현하세요.**

* 설계상 플레이어가 대부분 같은 맵 영역에 함께 있게 된다면, [레벨 스트리밍은 서버의 메모리 사용량을](https://dev.epicgames.com/documentation/en-us/unreal-engine/level-streaming-in-unreal-engine) 60% 이상 줄이고, 클라이언트 성능도 향상시킬 수 있습니다!

**서버 실행에 절대적으로 필요한 것만 포함하세요.**

* 사용하지 않는 파일을 이미지에 복사하면 이미지 비대화, 업로드 시간 증가, 캐싱 속도 저하, 전반적인 서버 시작 속도 저하가 발생합니다. [Docker 이미지 최적화 제안을 검토하세요](https://docs.docker.com/build-cloud/optimization/#dockerignore-files).

<details>

<summary>예시 <code>.dockerignore</code> 파일로 추가 파일을 제거하세요.</summary>

```docker
# 컴파일된 오브젝트 파일
*.slo
*.lo
*.o
*.obj

# 사전 컴파일된 헤더
*.gch
*.pch

# 컴파일된 동적 라이브러리
*.so
*.dylib
*.dll

# Fortran 모듈 파일
*.mod

# 컴파일된 정적 라이브러리
*.lai
*.la
*.a
*.lib

# 실행 파일
*.exe
*.out
*.app
*.ipa

# 이러한 프로젝트 파일은 엔진에서 생성될 수 있습니다
*.xcodeproj
*.xcworkspace
*.sln
*.suo
*.opensdf
*.sdf
*.VC.db
*.VC.opendb

# 사전 컴파일된 에셋
**/SourceArt/**/*.png
**/SourceArt/**/*.tga

# 빌드
**/Build/*

# PakBlacklist-<BuildConfiguration>.txt 파일 허용 목록
!**/Build/*/
**/Build/*/**
!**/Build/*/PakBlacklist*.txt

# Build의 아이콘 파일은 무시하지 않음
!**/Build/**/*.ico

# 에디터에서 생성된 구성 파일
**/Saved/*
**/Intermediate/*
**/DerivedDataCache/*
**/Binaries/*
**/Build/*
**/Releases/*
**/Packaged/*
```

</details>

**다음을 사용하는 것을 고려하세요** [**멀티 스테이지 Docker 빌드(링크)**](https://docs.docker.com/build/building/multi-stage/)**.**

* 대용량 서버 종속성을 별도의 이미지로 분리하여 멀티 스테이지 빌드에서 재사용하세요. Docker는 각 레이어를 캐시하고 이전 버전을 단순히 재사용하며, 별도 지시가 없는 한 이 부분의 업로드를 건너뛰므로 대역폭과 업로드 완료 대기 시간을 절약할 수 있습니다.
* Dockerfile 명령 중 하나가 오류를 발생시키는 이유를 모르겠다면, 로컬에서 디버깅해 보세요. 문제가 발생하기 직전에 새 스테이지를 만들고(두 번째 `FROM` 명령을 추가), `--target` 을 사용하여 빌드 프로세스가 문제의 스테이지에서 멈추도록 지시한 다음 `docker exec -it {container} /bin/bash` 를 사용해 컨테이너 내부의 대화형 터미널로 들어가세요. 그다음 베이스 이미지의 셸 명령을 사용해 추가로 조사할 수 있습니다(예: `top` 우분투에서).

### 이미지 사용자 지정

또한 빌드 크기 최적화, 불필요한 종속성, 더 복잡한 시작 프로세스 때문에 이미지에 더 많은 제어가 필요한 사용자들을 위해 자체 Dockerfile 추가도 지원합니다. 이제 몇 가지 “직접 해보기” 팁과 모범 사례를 공유하겠습니다.

[^1]: Personal Access Token


---

# 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/unreal-engine.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.
