<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Image Archives - 어제와 내일의 나 그 사이의 이야기</title>
	<atom:link href="https://lycos7560.com/tag/image/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>생각의 흐름을 타고 다니며 만드는 블로그</description>
	<lastBuildDate>Sat, 02 Aug 2025 23:35:58 +0000</lastBuildDate>
	<language>ko-KR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://lycos7560.com/wp-content/uploads/2022/11/cropped-cropped-cropped-log-1-150x150-1-80x80.png</url>
	<title>Image Archives - 어제와 내일의 나 그 사이의 이야기</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Docker 백그라운드 실행 명령어</title>
		<link>https://lycos7560.com/docker/docker-%eb%b0%b1%ea%b7%b8%eb%9d%bc%ec%9a%b4%eb%93%9c-%ec%8b%a4%ed%96%89-%eb%aa%85%eb%a0%b9%ec%96%b4/40219/</link>
					<comments>https://lycos7560.com/docker/docker-%eb%b0%b1%ea%b7%b8%eb%9d%bc%ec%9a%b4%eb%93%9c-%ec%8b%a4%ed%96%89-%eb%aa%85%eb%a0%b9%ec%96%b4/40219/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Thu, 31 Jul 2025 18:54:54 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[Auto Scaling]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Base Image]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Cloud Native]]></category>
		<category><![CDATA[Cloud Provider]]></category>
		<category><![CDATA[Compliance]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Container as a Service]]></category>
		<category><![CDATA[Container Registry]]></category>
		<category><![CDATA[Container Runtime]]></category>
		<category><![CDATA[Containerization]]></category>
		<category><![CDATA[Continuous Deployment]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[Docker Compose]]></category>
		<category><![CDATA[Docker Desktop]]></category>
		<category><![CDATA[Docker Engine]]></category>
		<category><![CDATA[Docker Hub]]></category>
		<category><![CDATA[Dockerfile]]></category>
		<category><![CDATA[Enterprise]]></category>
		<category><![CDATA[Environment Variables]]></category>
		<category><![CDATA[GitOps]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Guest OS]]></category>
		<category><![CDATA[Health Check]]></category>
		<category><![CDATA[Host OS]]></category>
		<category><![CDATA[Hypervisor]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Image Optimization]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Isolation]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Layer]]></category>
		<category><![CDATA[Legacy System]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Modernization]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Multi-stage Build]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Orchestration]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[pipeline]]></category>
		<category><![CDATA[Port Mapping]]></category>
		<category><![CDATA[Portability]]></category>
		<category><![CDATA[Production]]></category>
		<category><![CDATA[Pull]]></category>
		<category><![CDATA[Push]]></category>
		<category><![CDATA[Registry]]></category>
		<category><![CDATA[Resource Efficiency]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Security Scanning]]></category>
		<category><![CDATA[Service Mesh]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Staging]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Swarm]]></category>
		<category><![CDATA[Tag]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[vm]]></category>
		<category><![CDATA[Volume]]></category>
		<category><![CDATA[Vulnerability]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[가상머신]]></category>
		<category><![CDATA[개발]]></category>
		<category><![CDATA[게스트 OS]]></category>
		<category><![CDATA[격리]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[구글 클라우드]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[깃옵스]]></category>
		<category><![CDATA[네트워크]]></category>
		<category><![CDATA[데브옵스]]></category>
		<category><![CDATA[도커]]></category>
		<category><![CDATA[도커 데스크톱]]></category>
		<category><![CDATA[도커 엔진]]></category>
		<category><![CDATA[도커 컴포즈]]></category>
		<category><![CDATA[도커 허브]]></category>
		<category><![CDATA[도커파일]]></category>
		<category><![CDATA[레거시 시스템]]></category>
		<category><![CDATA[레이어]]></category>
		<category><![CDATA[레지스트리]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[로드 밸런싱]]></category>
		<category><![CDATA[리눅스]]></category>
		<category><![CDATA[리소스 효율성]]></category>
		<category><![CDATA[마이그레이션]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[멀티 스테이지 빌드]]></category>
		<category><![CDATA[모니터링]]></category>
		<category><![CDATA[모범 사례]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[백업]]></category>
		<category><![CDATA[베이스 이미지]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[보안 스캔]]></category>
		<category><![CDATA[볼륨]]></category>
		<category><![CDATA[빌드]]></category>
		<category><![CDATA[서비스 메시]]></category>
		<category><![CDATA[서비스형 컨테이너]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[소프트웨어 개발]]></category>
		<category><![CDATA[스웜]]></category>
		<category><![CDATA[스테이징]]></category>
		<category><![CDATA[실행]]></category>
		<category><![CDATA[아마존 웹 서비스]]></category>
		<category><![CDATA[아이아씨]]></category>
		<category><![CDATA[아키텍처]]></category>
		<category><![CDATA[애저]]></category>
		<category><![CDATA[애플리케이션]]></category>
		<category><![CDATA[엔터프라이즈]]></category>
		<category><![CDATA[오케스트레이션]]></category>
		<category><![CDATA[오픈 소스]]></category>
		<category><![CDATA[윈도우]]></category>
		<category><![CDATA[이미지]]></category>
		<category><![CDATA[이미지 최적화]]></category>
		<category><![CDATA[이식성]]></category>
		<category><![CDATA[인프라스트럭처]]></category>
		<category><![CDATA[자동 확장]]></category>
		<category><![CDATA[자동화]]></category>
		<category><![CDATA[지속적 배포]]></category>
		<category><![CDATA[지속적 통합]]></category>
		<category><![CDATA[취약점]]></category>
		<category><![CDATA[컨테이너]]></category>
		<category><![CDATA[컨테이너 런타임]]></category>
		<category><![CDATA[컨테이너 레지스트리]]></category>
		<category><![CDATA[컨테이너화]]></category>
		<category><![CDATA[컴플라이언스]]></category>
		<category><![CDATA[코드형 인프라]]></category>
		<category><![CDATA[쿠버네티스]]></category>
		<category><![CDATA[클라우드 네이티브]]></category>
		<category><![CDATA[클라우드 제공자]]></category>
		<category><![CDATA[클라우드 컴퓨팅]]></category>
		<category><![CDATA[태그]]></category>
		<category><![CDATA[테스팅]]></category>
		<category><![CDATA[트러블슈팅]]></category>
		<category><![CDATA[파이프라인]]></category>
		<category><![CDATA[포트 매핑]]></category>
		<category><![CDATA[푸시]]></category>
		<category><![CDATA[풀]]></category>
		<category><![CDATA[프로덕션]]></category>
		<category><![CDATA[하이퍼바이저]]></category>
		<category><![CDATA[헬스 체크]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40219</guid>

					<description><![CDATA[<p>1. Docker 백그라운드 실행 명령어 컨테이너를 백그라운드(detached) 모드로 실행하여 터미널을 점유하지 않고 계속해서 동작하게 하는 명령어 2. 실행 중인 컨테이너 확인 명령어 현재 시스템에서 실행 중인 컨테이너를 확인하는 명령어 3. 모든 컨테이너 확인 명령어 (실행 중 + 정지) 실행 중인 컨테이너뿐만 아니라, 이전에 실행되었다가 현재는 정지된 모든 컨테이너를 확인하는 명령어 4. 기타 유용한 명령어</p>
<p>The post <a href="https://lycos7560.com/docker/docker-%eb%b0%b1%ea%b7%b8%eb%9d%bc%ec%9a%b4%eb%93%9c-%ec%8b%a4%ed%96%89-%eb%aa%85%eb%a0%b9%ec%96%b4/40219/">Docker 백그라운드 실행 명령어</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-a09493e2      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-docker-백그라운드-실행-명령어" class="uagb-toc-link__trigger">1. Docker 백그라운드 실행 명령어</a><li class="uagb-toc__list"><a href="#2-실행-중인-컨테이너-확인-명령어" class="uagb-toc-link__trigger">2. 실행 중인 컨테이너 확인 명령어</a><li class="uagb-toc__list"><a href="#3-모든-컨테이너-확인-명령어-실행-중-정지" class="uagb-toc-link__trigger">3. 모든 컨테이너 확인 명령어 (실행 중 + 정지)</a><li class="uagb-toc__list"><a href="#4-기타-유용한-명령어" class="uagb-toc-link__trigger">4. 기타 유용한 명령어</a></ol>					</div>
									</div>
				</div>
			


<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">1. Docker 백그라운드 실행 명령어</h3>



<p>컨테이너를 백그라운드(detached) 모드로 실행하여 터미널을 점유하지 않고 계속해서 동작하게 하는 명령어</p>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// docker run -d [이미지 이름]
// -d 또는 --detach 옵션은 컨테이너를 백그라운드에서 실행하도록 지시
docker run -d -p 8080:80 nginx</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2. 실행 중인 컨테이너 확인 명령어</h3>



<p>현재 시스템에서 실행 중인 컨테이너를 확인하는 명령어</p>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// ps는 "process status"의 약자로, 현재 실행 중인 컨테이너의 목록을 보여줌
docker ps


CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
a1b2c3d4e5f6   nginx     "/docker-entrypoint.sh"  10 seconds ago   Up 8 seconds    0.0.0.0:8080->80/tcp, :::8080->80/tcp   web_server

// CONTAINER ID: 컨테이너의 고유 ID
// IMAGE: 컨테이너를 생성하는 데 사용된 이미지
// COMMAND: 컨테이너가 실행될 때 사용된 명령어
// CREATED: 컨테이너가 생성된 시점
// STATUS: 컨테이너의 현재 상태 (예: Up 5 minutes)
// PORTS: 포트 매핑 정보
// NAMES: 컨테이너에 할당된 이름</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3. 모든 컨테이너 확인 명령어 (실행 중 + 정지)</h3>



<p>실행 중인 컨테이너뿐만 아니라, 이전에 실행되었다가 현재는 정지된 모든 컨테이너를 확인하는 명령어</p>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// -a 또는 --all 옵션은 모든 컨테이너를 표시하도록 지시
docker ps -a

CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS                      PORTS     NAMES
a1b2c3d4e5f6   nginx     "/docker-entrypoint.sh"  2 minutes ago   Up 2 minutes                ...       web_server
e6f5d4c3b2a1   ubuntu    "/bin/bash"              5 hours ago     Exited (0) 4 minutes ago              test_container</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4. 기타 유용한 명령어</h3>



<ul class="wp-block-list">
<li>docker stop</li>



<li>docker start</li>



<li>docker kill</li>



<li>docker logs</li>



<li>docker attach</li>



<li>docker exec</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 컨테이너 중지: docker stop [컨테이너 ID 또는 이름]
// 실행 중인 컨테이너를 정상적으로 종료시킵니다.
docker stop web_server

// 컨테이너 시작: docker start [컨테이너 ID 또는 이름]
// 정지된 컨테이너를 다시 시작합니다.
docker start test_container

// 컨테이너 강제 종료: docker kill [컨테이너 ID 또는 이름]
// 컨테이너를 강제로 즉시 종료시킵니다.
docker kill web_server

// 컨테이너 로그 확인: docker logs [컨테이너 ID 또는 이름]
// 컨테이너의 표준 출력(stdout)과 표준 에러(stderr) 로그를 확인합니다.
docker logs web_server

// 컨테이너 접속: docker attach [컨테이너 ID 또는 이름]
// 백그라운드에서 실행 중인 컨테이너의 터미널에 연결합니다.
docker attach web_server

// 컨테이너 내부에 명령어 실행: docker exec [컨테이너 ID 또는 이름] [명령어]
// 실행 중인 컨테이너 내부에 새로운 프로세스를 실행합니다.
// 예시 : Nginx 컨테이너에서 bash 셸을 실행하여 내부로 접속
docker exec -it web_server /bin/bash</pre>



<ul class="wp-block-list"></ul>



<p></p>
<p>The post <a href="https://lycos7560.com/docker/docker-%eb%b0%b1%ea%b7%b8%eb%9d%bc%ec%9a%b4%eb%93%9c-%ec%8b%a4%ed%96%89-%eb%aa%85%eb%a0%b9%ec%96%b4/40219/">Docker 백그라운드 실행 명령어</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/docker/docker-%eb%b0%b1%ea%b7%b8%eb%9d%bc%ec%9a%b4%eb%93%9c-%ec%8b%a4%ed%96%89-%eb%aa%85%eb%a0%b9%ec%96%b4/40219/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Docker Port Mapping(포트 매핑)</title>
		<link>https://lycos7560.com/docker/docker-port-mapping%ed%8f%ac%ed%8a%b8-%eb%a7%a4%ed%95%91/40217/</link>
					<comments>https://lycos7560.com/docker/docker-port-mapping%ed%8f%ac%ed%8a%b8-%eb%a7%a4%ed%95%91/40217/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Thu, 31 Jul 2025 18:29:11 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[Auto Scaling]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Base Image]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Cloud Native]]></category>
		<category><![CDATA[Cloud Provider]]></category>
		<category><![CDATA[Compliance]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Container as a Service]]></category>
		<category><![CDATA[Container Registry]]></category>
		<category><![CDATA[Container Runtime]]></category>
		<category><![CDATA[Containerization]]></category>
		<category><![CDATA[Continuous Deployment]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[Docker Compose]]></category>
		<category><![CDATA[Docker Desktop]]></category>
		<category><![CDATA[Docker Engine]]></category>
		<category><![CDATA[Docker Hub]]></category>
		<category><![CDATA[Dockerfile]]></category>
		<category><![CDATA[Enterprise]]></category>
		<category><![CDATA[Environment Variables]]></category>
		<category><![CDATA[GitOps]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Guest OS]]></category>
		<category><![CDATA[Health Check]]></category>
		<category><![CDATA[Host OS]]></category>
		<category><![CDATA[Hypervisor]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Image Optimization]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Isolation]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Layer]]></category>
		<category><![CDATA[Legacy System]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Modernization]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Multi-stage Build]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Orchestration]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[pipeline]]></category>
		<category><![CDATA[Port Mapping]]></category>
		<category><![CDATA[Portability]]></category>
		<category><![CDATA[Production]]></category>
		<category><![CDATA[Pull]]></category>
		<category><![CDATA[Push]]></category>
		<category><![CDATA[Registry]]></category>
		<category><![CDATA[Resource Efficiency]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Security Scanning]]></category>
		<category><![CDATA[Service Mesh]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Staging]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Swarm]]></category>
		<category><![CDATA[Tag]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[vm]]></category>
		<category><![CDATA[Volume]]></category>
		<category><![CDATA[Vulnerability]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[가상머신]]></category>
		<category><![CDATA[개발]]></category>
		<category><![CDATA[게스트 OS]]></category>
		<category><![CDATA[격리]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[구글 클라우드]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[깃옵스]]></category>
		<category><![CDATA[네트워크]]></category>
		<category><![CDATA[데브옵스]]></category>
		<category><![CDATA[도커]]></category>
		<category><![CDATA[도커 데스크톱]]></category>
		<category><![CDATA[도커 엔진]]></category>
		<category><![CDATA[도커 컴포즈]]></category>
		<category><![CDATA[도커 허브]]></category>
		<category><![CDATA[도커파일]]></category>
		<category><![CDATA[레거시 시스템]]></category>
		<category><![CDATA[레이어]]></category>
		<category><![CDATA[레지스트리]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[로드 밸런싱]]></category>
		<category><![CDATA[리눅스]]></category>
		<category><![CDATA[리소스 효율성]]></category>
		<category><![CDATA[마이그레이션]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[멀티 스테이지 빌드]]></category>
		<category><![CDATA[모니터링]]></category>
		<category><![CDATA[모범 사례]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[백업]]></category>
		<category><![CDATA[베이스 이미지]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[보안 스캔]]></category>
		<category><![CDATA[볼륨]]></category>
		<category><![CDATA[빌드]]></category>
		<category><![CDATA[서비스 메시]]></category>
		<category><![CDATA[서비스형 컨테이너]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[소프트웨어 개발]]></category>
		<category><![CDATA[스웜]]></category>
		<category><![CDATA[스테이징]]></category>
		<category><![CDATA[실행]]></category>
		<category><![CDATA[아마존 웹 서비스]]></category>
		<category><![CDATA[아이아씨]]></category>
		<category><![CDATA[아키텍처]]></category>
		<category><![CDATA[애저]]></category>
		<category><![CDATA[애플리케이션]]></category>
		<category><![CDATA[엔터프라이즈]]></category>
		<category><![CDATA[오케스트레이션]]></category>
		<category><![CDATA[오픈 소스]]></category>
		<category><![CDATA[윈도우]]></category>
		<category><![CDATA[이미지]]></category>
		<category><![CDATA[이미지 최적화]]></category>
		<category><![CDATA[이식성]]></category>
		<category><![CDATA[인프라스트럭처]]></category>
		<category><![CDATA[자동 확장]]></category>
		<category><![CDATA[자동화]]></category>
		<category><![CDATA[지속적 배포]]></category>
		<category><![CDATA[지속적 통합]]></category>
		<category><![CDATA[취약점]]></category>
		<category><![CDATA[컨테이너]]></category>
		<category><![CDATA[컨테이너 런타임]]></category>
		<category><![CDATA[컨테이너 레지스트리]]></category>
		<category><![CDATA[컨테이너화]]></category>
		<category><![CDATA[컴플라이언스]]></category>
		<category><![CDATA[코드형 인프라]]></category>
		<category><![CDATA[쿠버네티스]]></category>
		<category><![CDATA[클라우드 네이티브]]></category>
		<category><![CDATA[클라우드 제공자]]></category>
		<category><![CDATA[클라우드 컴퓨팅]]></category>
		<category><![CDATA[태그]]></category>
		<category><![CDATA[테스팅]]></category>
		<category><![CDATA[트러블슈팅]]></category>
		<category><![CDATA[파이프라인]]></category>
		<category><![CDATA[포트 매핑]]></category>
		<category><![CDATA[푸시]]></category>
		<category><![CDATA[풀]]></category>
		<category><![CDATA[프로덕션]]></category>
		<category><![CDATA[하이퍼바이저]]></category>
		<category><![CDATA[헬스 체크]]></category>
		<category><![CDATA[현대화]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40217</guid>

					<description><![CDATA[<p>Docker 포트 매핑 (Port Mapping) Docker에서 포트 매핑은 컨테이너 내부에서 실행 중인 서비스의 포트와 호스트 컴퓨터(Docker가 설치된 머신)의 포트를 연결하는 중요한 기능입니다. 포트 매핑 왜 필요한가? Docker 컨테이너는 기본적으로 격리된 환경에서 실행됩니다. 즉, 컨테이너 내부에 웹 서버가 80번 포트에서 동작하더라도, 외부에서는 이 포트에 직접 접근할 수 없습니다. 컨테이너는 자체적인 IP 주소를 가지고 있으며, 호스트 컴퓨터와는 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/docker/docker-port-mapping%ed%8f%ac%ed%8a%b8-%eb%a7%a4%ed%95%91/40217/">Docker Port Mapping(포트 매핑)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-5dd74c8e      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#docker-포트-매핑-port-mapping" class="uagb-toc-link__trigger">Docker 포트 매핑 (Port Mapping)</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#포트-매핑-왜-필요한가" class="uagb-toc-link__trigger">포트 매핑 왜 필요한가?</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#포트-매핑의-역할" class="uagb-toc-link__trigger">포트 매핑의 역할</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#간단한-예시" class="uagb-toc-link__trigger">간단한 예시</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#요약" class="uagb-toc-link__trigger">요약</a></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Docker 포트 매핑 (Port Mapping)</h2>



<p>Docker에서 <strong>포트 매핑</strong>은 컨테이너 내부에서 실행 중인 서비스의 포트와 호스트 컴퓨터(Docker가 설치된 머신)의 포트를 연결하는 중요한 기능입니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">포트 매핑 <strong>왜 필요한가?</strong></h3>



<p>Docker 컨테이너는 기본적으로 격리된 환경에서 실행됩니다. </p>



<p>즉, 컨테이너 내부에 웹 서버가 80번 포트에서 동작하더라도, 외부에서는 이 포트에 직접 접근할 수 없습니다. </p>



<p><strong>컨테이너</strong>는 <strong>자체적인 IP 주소</strong>를 가지고 있으며, 호스트 컴퓨터와는 다른 네트워크 환경에 있습니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>포트 매핑의 역할</strong></h3>



<p>포트 매핑은 <strong>컨테이너의 특정 포트</strong>를 <strong>호스트 컴퓨터의 특정 포트</strong>로 터널링(tunneling)하는 역할을 합니다. </p>



<p>이를 통해 외부 사용자는 호스트 컴퓨터의 포트를 통해 컨테이너 내부의 서비스에 접근할 수 있게 됩니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">간단한 <strong>예시</strong></h3>



<p>Nginx 웹 서버를 실행하는 컨테이너를 생각해봅시다. </p>



<p>Nginx는 기본적으로 80번 포트에서 동작합니다. </p>



<p>이 컨테이너에<strong> 외부에서 접근</strong>할 수 있도록 하려면 다음과 같이 <strong>포트 매핑</strong>을 설정할 수 있습니다.</p>



<p>Bash</p>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker run -p 8080:80 nginx
</pre>



<ul class="wp-block-list">
<li><strong><code>-p</code></strong>: <br>포트 매핑 옵션</li>



<li><strong><code>8080</code></strong>: <br><strong>호스트 컴퓨터의 포트</strong>로 외부에서 <code>http://[호스트 IP]:8080</code>으로 접속</li>



<li><strong><code>80</code></strong>: <br><strong>컨테이너 내부의 포트</strong>로 Nginx가 이 포트에서 대기</li>



<li><strong><code>nginx</code></strong>: <br>사용할 Docker 이미지 이름</li>
</ul>



<p>호스트 컴퓨터의 8080번 포트로 들어오는 모든 네트워크 요청은 Docker에 의해 컨테이너의 80번 포트로 전달됩니다. </p>



<p>이로써 외부 사용자는 <code>http://localhost:8080</code> (만약 로컬에서 실행했다면)으로 접속하여 컨테이너 내부의 Nginx 웹 서버에 접근할 수 있게 됩니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><strong>요약</strong></h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td>개념</td><td>설명</td></tr><tr><td>컨테이너 포트</td><td>컨테이너 내부에서 서비스가 실제로 사용하고 있는 포트 (예: Nginx의 80번 포트)</td></tr><tr><td>호스트 포트</td><td>컨테이너에 접근하기 위해 외부에서 사용하는, 호스트 컴퓨터의 포트</td></tr><tr><td>포트 매핑</td><td>[호스트 포트]:[컨테이너 포트] 형태로 두 포트를 연결하는 과정</td></tr></tbody></table></figure>
<p>The post <a href="https://lycos7560.com/docker/docker-port-mapping%ed%8f%ac%ed%8a%b8-%eb%a7%a4%ed%95%91/40217/">Docker Port Mapping(포트 매핑)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/docker/docker-port-mapping%ed%8f%ac%ed%8a%b8-%eb%a7%a4%ed%95%91/40217/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Docker에서 HTML 페이지 배포</title>
		<link>https://lycos7560.com/docker/docker%ec%97%90%ec%84%9c-html-%ed%8e%98%ec%9d%b4%ec%a7%80-%eb%b0%b0%ed%8f%ac/40200/</link>
					<comments>https://lycos7560.com/docker/docker%ec%97%90%ec%84%9c-html-%ed%8e%98%ec%9d%b4%ec%a7%80-%eb%b0%b0%ed%8f%ac/40200/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Thu, 31 Jul 2025 17:13:30 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[Auto Scaling]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Base Image]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Cloud Native]]></category>
		<category><![CDATA[Cloud Provider]]></category>
		<category><![CDATA[Compliance]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Container as a Service]]></category>
		<category><![CDATA[Container Registry]]></category>
		<category><![CDATA[Container Runtime]]></category>
		<category><![CDATA[Containerization]]></category>
		<category><![CDATA[Continuous Deployment]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[Docker Compose]]></category>
		<category><![CDATA[Docker Desktop]]></category>
		<category><![CDATA[Docker Engine]]></category>
		<category><![CDATA[Docker Hub]]></category>
		<category><![CDATA[Dockerfile]]></category>
		<category><![CDATA[Enterprise]]></category>
		<category><![CDATA[Environment Variables]]></category>
		<category><![CDATA[GitOps]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Guest OS]]></category>
		<category><![CDATA[Health Check]]></category>
		<category><![CDATA[Host OS]]></category>
		<category><![CDATA[Hypervisor]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Image Optimization]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Isolation]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Layer]]></category>
		<category><![CDATA[Legacy System]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Modernization]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Multi-stage Build]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Orchestration]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[pipeline]]></category>
		<category><![CDATA[Port Mapping]]></category>
		<category><![CDATA[Portability]]></category>
		<category><![CDATA[Production]]></category>
		<category><![CDATA[Pull]]></category>
		<category><![CDATA[Push]]></category>
		<category><![CDATA[Registry]]></category>
		<category><![CDATA[Resource Efficiency]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Security Scanning]]></category>
		<category><![CDATA[Service Mesh]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Staging]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Swarm]]></category>
		<category><![CDATA[Tag]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[vm]]></category>
		<category><![CDATA[Volume]]></category>
		<category><![CDATA[Vulnerability]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[가상머신]]></category>
		<category><![CDATA[개발]]></category>
		<category><![CDATA[게스트 OS]]></category>
		<category><![CDATA[격리]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[구글 클라우드]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[깃옵스]]></category>
		<category><![CDATA[네트워크]]></category>
		<category><![CDATA[데브옵스]]></category>
		<category><![CDATA[도커]]></category>
		<category><![CDATA[도커 데스크톱]]></category>
		<category><![CDATA[도커 엔진]]></category>
		<category><![CDATA[도커 컴포즈]]></category>
		<category><![CDATA[도커 허브]]></category>
		<category><![CDATA[도커파일]]></category>
		<category><![CDATA[레거시 시스템]]></category>
		<category><![CDATA[레이어]]></category>
		<category><![CDATA[레지스트리]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[로드 밸런싱]]></category>
		<category><![CDATA[리눅스]]></category>
		<category><![CDATA[리소스 효율성]]></category>
		<category><![CDATA[마이그레이션]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[멀티 스테이지 빌드]]></category>
		<category><![CDATA[모니터링]]></category>
		<category><![CDATA[모범 사례]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[백업]]></category>
		<category><![CDATA[베이스 이미지]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[보안 스캔]]></category>
		<category><![CDATA[볼륨]]></category>
		<category><![CDATA[빌드]]></category>
		<category><![CDATA[서비스 메시]]></category>
		<category><![CDATA[서비스형 컨테이너]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[소프트웨어 개발]]></category>
		<category><![CDATA[스웜]]></category>
		<category><![CDATA[스테이징]]></category>
		<category><![CDATA[실행]]></category>
		<category><![CDATA[아마존 웹 서비스]]></category>
		<category><![CDATA[아이아씨]]></category>
		<category><![CDATA[아키텍처]]></category>
		<category><![CDATA[애저]]></category>
		<category><![CDATA[애플리케이션]]></category>
		<category><![CDATA[엔터프라이즈]]></category>
		<category><![CDATA[오케스트레이션]]></category>
		<category><![CDATA[오픈 소스]]></category>
		<category><![CDATA[윈도우]]></category>
		<category><![CDATA[이미지]]></category>
		<category><![CDATA[이미지 최적화]]></category>
		<category><![CDATA[이식성]]></category>
		<category><![CDATA[인프라스트럭처]]></category>
		<category><![CDATA[자동 확장]]></category>
		<category><![CDATA[자동화]]></category>
		<category><![CDATA[지속적 배포]]></category>
		<category><![CDATA[지속적 통합]]></category>
		<category><![CDATA[취약점]]></category>
		<category><![CDATA[컨테이너]]></category>
		<category><![CDATA[컨테이너 런타임]]></category>
		<category><![CDATA[컨테이너 레지스트리]]></category>
		<category><![CDATA[컨테이너화]]></category>
		<category><![CDATA[컴플라이언스]]></category>
		<category><![CDATA[코드형 인프라]]></category>
		<category><![CDATA[쿠버네티스]]></category>
		<category><![CDATA[클라우드 네이티브]]></category>
		<category><![CDATA[클라우드 제공자]]></category>
		<category><![CDATA[클라우드 컴퓨팅]]></category>
		<category><![CDATA[태그]]></category>
		<category><![CDATA[테스팅]]></category>
		<category><![CDATA[트러블슈팅]]></category>
		<category><![CDATA[파이프라인]]></category>
		<category><![CDATA[포트 매핑]]></category>
		<category><![CDATA[푸시]]></category>
		<category><![CDATA[풀]]></category>
		<category><![CDATA[프로덕션]]></category>
		<category><![CDATA[하이퍼바이저]]></category>
		<category><![CDATA[헬스 체크]]></category>
		<category><![CDATA[현대화]]></category>
		<category><![CDATA[호스트 OS]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40200</guid>

					<description><![CDATA[<p>Docker에서 HTML 페이지 배포 기본적으로 웹 서버로 이동하여 HTML 페이지를 렌더링 웹 서버 nginx 이미지 가져오기 index.html 파일을 준비 nginx 이미지를 사용하여 Docker 컨테이너에 로드 Dockerfile 생성 도커파일은 확장자가 없음 Dockerfile 이미지 생성 도커파일은 확장자가 없음 컨테이너를 생성 및 실행</p>
<p>The post <a href="https://lycos7560.com/docker/docker%ec%97%90%ec%84%9c-html-%ed%8e%98%ec%9d%b4%ec%a7%80-%eb%b0%b0%ed%8f%ac/40200/">Docker에서 HTML 페이지 배포</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-df0e6530      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#docker에서-html-페이지-배포" class="uagb-toc-link__trigger">Docker에서 HTML 페이지 배포</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#웹-서버-nginx-이미지-가져오기" class="uagb-toc-link__trigger">웹 서버 nginx 이미지 가져오기</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#indexhtml-파일을-준비" class="uagb-toc-link__trigger">index.html 파일을 준비</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#nginx-이미지를-사용하여-docker-컨테이너에-로드" class="uagb-toc-link__trigger">nginx 이미지를 사용하여 Docker 컨테이너에 로드</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#dockerfile-생성" class="uagb-toc-link__trigger">Dockerfile 생성</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#dockerfile-이미지-생성" class="uagb-toc-link__trigger">Dockerfile 이미지 생성</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#컨테이너를-생성-및-실행" class="uagb-toc-link__trigger">컨테이너를 생성 및 실행</a></ul></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Docker에서 HTML 페이지 배포</h2>



<p>기본적으로 웹 서버로 이동하여 HTML 페이지를 렌더링</p>



<h3 class="wp-block-heading">웹 서버 nginx 이미지 가져오기</h3>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="1874" height="867" src="https://lycos7560.com/wp-content/uploads/2025/08/image.png" alt="" class="wp-image-40201" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image.png 1874w, https://lycos7560.com/wp-content/uploads/2025/08/image-300x139.png 300w, https://lycos7560.com/wp-content/uploads/2025/08/image-768x355.png 768w, https://lycos7560.com/wp-content/uploads/2025/08/image-1536x711.png 1536w" sizes="(max-width: 1874px) 100vw, 1874px" /></figure>



<figure class="wp-block-image size-full"><img decoding="async" width="664" height="250" src="https://lycos7560.com/wp-content/uploads/2025/08/image-1.png" alt="" class="wp-image-40202" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-1.png 664w, https://lycos7560.com/wp-content/uploads/2025/08/image-1-300x113.png 300w" sizes="(max-width: 664px) 100vw, 664px" /></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker pull nginx</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="1761" height="476" src="https://lycos7560.com/wp-content/uploads/2025/08/image-2.png" alt="" class="wp-image-40203" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-2.png 1761w, https://lycos7560.com/wp-content/uploads/2025/08/image-2-300x81.png 300w, https://lycos7560.com/wp-content/uploads/2025/08/image-2-768x208.png 768w, https://lycos7560.com/wp-content/uploads/2025/08/image-2-1536x415.png 1536w" sizes="(max-width: 1761px) 100vw, 1761px" /></figure>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">index.html 파일을 준비</h3>



<figure class="wp-block-image size-full"><img decoding="async" width="801" height="342" src="https://lycos7560.com/wp-content/uploads/2025/08/image-3.png" alt="" class="wp-image-40204" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-3.png 801w, https://lycos7560.com/wp-content/uploads/2025/08/image-3-300x128.png 300w, https://lycos7560.com/wp-content/uploads/2025/08/image-3-768x328.png 768w" sizes="(max-width: 801px) 100vw, 801px" /></figure>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="html" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;!DOCTYPE html>
&lt;html lang="ko">
&lt;head>
  &lt;meta charset="UTF-8">
  &lt;title>테스트 페이지&lt;/title>
  &lt;style>
    body {
      font-family: Arial, sans-serif;
      background-color: #f0f0f0;
      text-align: center;
      padding: 50px;
    }
    h1 {
      color: #333;
    }
    button {
      padding: 10px 20px;
      font-size: 16px;
    }
  &lt;/style>
&lt;/head>
&lt;body>
  &lt;h1>HTML 테스트 페이지&lt;/h1>
  &lt;p>이 페이지는 테스트용으로 생성되었습니다.&lt;/p>
  &lt;button onclick="alert('버튼이 클릭되었습니다!')">클릭해보세요&lt;/button>
&lt;/body>
&lt;/html></pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">nginx 이미지를 사용하여 Docker 컨테이너에 로드</h3>



<h4 class="wp-block-heading">Dockerfile 생성</h4>



<p>도커파일은 확장자가 없음</p>



<figure class="wp-block-image size-full"><img decoding="async" width="631" height="251" src="https://lycos7560.com/wp-content/uploads/2025/08/image-5.png" alt="" class="wp-image-40208" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-5.png 631w, https://lycos7560.com/wp-content/uploads/2025/08/image-5-300x119.png 300w" sizes="(max-width: 631px) 100vw, 631px" /></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">FROM nginx
COPY ./SampleWebApp/ /usr/share/nginx/html</pre>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="1233" height="922" src="https://lycos7560.com/wp-content/uploads/2025/08/image-4.png" alt="" class="wp-image-40207" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-4.png 1233w, https://lycos7560.com/wp-content/uploads/2025/08/image-4-300x224.png 300w, https://lycos7560.com/wp-content/uploads/2025/08/image-4-768x574.png 768w" sizes="(max-width: 1233px) 100vw, 1233px" /></figure>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Dockerfile 이미지 생성</h4>



<p>도커파일은 확장자가 없음</p>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cd C:\Users\IKHO\Desktop\Docker 
// dockerfile 위치로 이동

ls 
// 파일 목록 확인

docker build -t sample_web_app:1.0.0 .
// docker build: 현재 디렉터리에 있는 Dockerfile을 기반으로 Docker 이미지를 만들라는 명령입니다.
// -t sample_web_app:1.0.0: 생성될 이미지의 이름과 태그를 지정합니다.
// sample_web_app이 이미지 이름
// 1.0.0은 버전 또는 태그 (나중에 버전별로 관리할 때 유용)
</pre>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="1328" height="605" src="https://lycos7560.com/wp-content/uploads/2025/08/image-6.png" alt="" class="wp-image-40209" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-6.png 1328w, https://lycos7560.com/wp-content/uploads/2025/08/image-6-300x137.png 300w, https://lycos7560.com/wp-content/uploads/2025/08/image-6-768x350.png 768w" sizes="(max-width: 1328px) 100vw, 1328px" /></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-uagb-container uagb-block-87046324 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-fa3865a3">
<figure class="wp-block-image size-full"><img decoding="async" width="1758" height="484" src="https://lycos7560.com/wp-content/uploads/2025/08/image-7.png" alt="" class="wp-image-40210" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-7.png 1758w, https://lycos7560.com/wp-content/uploads/2025/08/image-7-300x83.png 300w, https://lycos7560.com/wp-content/uploads/2025/08/image-7-768x211.png 768w, https://lycos7560.com/wp-content/uploads/2025/08/image-7-1536x423.png 1536w" sizes="(max-width: 1758px) 100vw, 1758px" /></figure>
</div>



<div class="wp-block-uagb-container uagb-block-91139572">
<figure class="wp-block-image size-full"><img decoding="async" width="539" height="119" src="https://lycos7560.com/wp-content/uploads/2025/08/image-8.png" alt="" class="wp-image-40211" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-8.png 539w, https://lycos7560.com/wp-content/uploads/2025/08/image-8-300x66.png 300w" sizes="(max-width: 539px) 100vw, 539px" /></figure>
</div>
</div></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">컨테이너를 생성 및 실행</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="bash" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker run --name sample_web_app-container -p 9000:80 sample_web_app:1.0.0
// docker run   : 새로운 컨테이너를 생성하고 실행합니다
// --name sample_web_app-container   : 컨테이너의 이름을 sample_web_app-container로 설정합니다
// -p 9000:80   : 포트 매핑: 호스트의 9000 포트를 컨테이너의 80 포트에 연결합니다 (외부에서 localhost:9000으로 접근 가능)
// sample_web_app:1.0.0   : sample_web_app라는 이름과 1.0.0 태그가 붙은 이미지를 기반으로 컨테이너를 생성합니다



http://127.0.0.1:9000/</pre>



<figure class="wp-block-image size-full"><img decoding="async" width="1333" height="641" src="https://lycos7560.com/wp-content/uploads/2025/08/image-9.png" alt="" class="wp-image-40213" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-9.png 1333w, https://lycos7560.com/wp-content/uploads/2025/08/image-9-300x144.png 300w, https://lycos7560.com/wp-content/uploads/2025/08/image-9-768x369.png 768w" sizes="(max-width: 1333px) 100vw, 1333px" /></figure>



<figure class="wp-block-image size-full"><img decoding="async" width="2230" height="933" src="https://lycos7560.com/wp-content/uploads/2025/08/image-11.png" alt="" class="wp-image-40215" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-11.png 2230w, https://lycos7560.com/wp-content/uploads/2025/08/image-11-300x126.png 300w, https://lycos7560.com/wp-content/uploads/2025/08/image-11-768x321.png 768w, https://lycos7560.com/wp-content/uploads/2025/08/image-11-1536x643.png 1536w, https://lycos7560.com/wp-content/uploads/2025/08/image-11-2048x857.png 2048w" sizes="(max-width: 2230px) 100vw, 2230px" /></figure>



<figure class="wp-block-image size-full"><img decoding="async" width="1754" height="491" src="https://lycos7560.com/wp-content/uploads/2025/08/image-10.png" alt="" class="wp-image-40214" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-10.png 1754w, https://lycos7560.com/wp-content/uploads/2025/08/image-10-300x84.png 300w, https://lycos7560.com/wp-content/uploads/2025/08/image-10-768x215.png 768w, https://lycos7560.com/wp-content/uploads/2025/08/image-10-1536x430.png 1536w" sizes="(max-width: 1754px) 100vw, 1754px" /></figure>
<p>The post <a href="https://lycos7560.com/docker/docker%ec%97%90%ec%84%9c-html-%ed%8e%98%ec%9d%b4%ec%a7%80-%eb%b0%b0%ed%8f%ac/40200/">Docker에서 HTML 페이지 배포</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/docker/docker%ec%97%90%ec%84%9c-html-%ed%8e%98%ec%9d%b4%ec%a7%80-%eb%b0%b0%ed%8f%ac/40200/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>기본적인 Docker 명령어 연습</title>
		<link>https://lycos7560.com/docker/%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-docker-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%97%b0%ec%8a%b5/40181/</link>
					<comments>https://lycos7560.com/docker/%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-docker-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%97%b0%ec%8a%b5/40181/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Wed, 30 Jul 2025 14:02:17 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[Auto Scaling]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Base Image]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Cloud Native]]></category>
		<category><![CDATA[Cloud Provider]]></category>
		<category><![CDATA[Compliance]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Container as a Service]]></category>
		<category><![CDATA[Container Registry]]></category>
		<category><![CDATA[Container Runtime]]></category>
		<category><![CDATA[Containerization]]></category>
		<category><![CDATA[Continuous Deployment]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[Docker Compose]]></category>
		<category><![CDATA[Docker Desktop]]></category>
		<category><![CDATA[Docker Engine]]></category>
		<category><![CDATA[Docker Hub]]></category>
		<category><![CDATA[Dockerfile]]></category>
		<category><![CDATA[Enterprise]]></category>
		<category><![CDATA[Environment Variables]]></category>
		<category><![CDATA[GitOps]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Guest OS]]></category>
		<category><![CDATA[Health Check]]></category>
		<category><![CDATA[Host OS]]></category>
		<category><![CDATA[Hypervisor]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Image Optimization]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Isolation]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Layer]]></category>
		<category><![CDATA[Legacy System]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Modernization]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Multi-stage Build]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Orchestration]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[pipeline]]></category>
		<category><![CDATA[Port Mapping]]></category>
		<category><![CDATA[Portability]]></category>
		<category><![CDATA[Production]]></category>
		<category><![CDATA[Pull]]></category>
		<category><![CDATA[Push]]></category>
		<category><![CDATA[Registry]]></category>
		<category><![CDATA[Resource Efficiency]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Security Scanning]]></category>
		<category><![CDATA[Service Mesh]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Staging]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Swarm]]></category>
		<category><![CDATA[Tag]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[vm]]></category>
		<category><![CDATA[Volume]]></category>
		<category><![CDATA[Vulnerability]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[가상머신]]></category>
		<category><![CDATA[개발]]></category>
		<category><![CDATA[게스트 OS]]></category>
		<category><![CDATA[격리]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[구글 클라우드]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[깃옵스]]></category>
		<category><![CDATA[네트워크]]></category>
		<category><![CDATA[데브옵스]]></category>
		<category><![CDATA[도커]]></category>
		<category><![CDATA[도커 데스크톱]]></category>
		<category><![CDATA[도커 엔진]]></category>
		<category><![CDATA[도커 컴포즈]]></category>
		<category><![CDATA[도커 허브]]></category>
		<category><![CDATA[도커파일]]></category>
		<category><![CDATA[레거시 시스템]]></category>
		<category><![CDATA[레이어]]></category>
		<category><![CDATA[레지스트리]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[로드 밸런싱]]></category>
		<category><![CDATA[리눅스]]></category>
		<category><![CDATA[리소스 효율성]]></category>
		<category><![CDATA[마이그레이션]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[멀티 스테이지 빌드]]></category>
		<category><![CDATA[모니터링]]></category>
		<category><![CDATA[모범 사례]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[백업]]></category>
		<category><![CDATA[베이스 이미지]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[보안 스캔]]></category>
		<category><![CDATA[볼륨]]></category>
		<category><![CDATA[빌드]]></category>
		<category><![CDATA[서비스 메시]]></category>
		<category><![CDATA[서비스형 컨테이너]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[소프트웨어 개발]]></category>
		<category><![CDATA[스웜]]></category>
		<category><![CDATA[스테이징]]></category>
		<category><![CDATA[실행]]></category>
		<category><![CDATA[아마존 웹 서비스]]></category>
		<category><![CDATA[아이아씨]]></category>
		<category><![CDATA[아키텍처]]></category>
		<category><![CDATA[애저]]></category>
		<category><![CDATA[애플리케이션]]></category>
		<category><![CDATA[엔터프라이즈]]></category>
		<category><![CDATA[오케스트레이션]]></category>
		<category><![CDATA[오픈 소스]]></category>
		<category><![CDATA[윈도우]]></category>
		<category><![CDATA[이미지]]></category>
		<category><![CDATA[이미지 최적화]]></category>
		<category><![CDATA[이식성]]></category>
		<category><![CDATA[인프라스트럭처]]></category>
		<category><![CDATA[자동 확장]]></category>
		<category><![CDATA[자동화]]></category>
		<category><![CDATA[지속적 배포]]></category>
		<category><![CDATA[지속적 통합]]></category>
		<category><![CDATA[취약점]]></category>
		<category><![CDATA[컨테이너]]></category>
		<category><![CDATA[컨테이너 런타임]]></category>
		<category><![CDATA[컨테이너 레지스트리]]></category>
		<category><![CDATA[컨테이너화]]></category>
		<category><![CDATA[컴플라이언스]]></category>
		<category><![CDATA[코드형 인프라]]></category>
		<category><![CDATA[쿠버네티스]]></category>
		<category><![CDATA[클라우드 네이티브]]></category>
		<category><![CDATA[클라우드 제공자]]></category>
		<category><![CDATA[클라우드 컴퓨팅]]></category>
		<category><![CDATA[태그]]></category>
		<category><![CDATA[테스팅]]></category>
		<category><![CDATA[트러블슈팅]]></category>
		<category><![CDATA[파이프라인]]></category>
		<category><![CDATA[포트 매핑]]></category>
		<category><![CDATA[푸시]]></category>
		<category><![CDATA[풀]]></category>
		<category><![CDATA[프로덕션]]></category>
		<category><![CDATA[하이퍼바이저]]></category>
		<category><![CDATA[헬스 체크]]></category>
		<category><![CDATA[현대화]]></category>
		<category><![CDATA[호스트 OS]]></category>
		<category><![CDATA[확장성]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40181</guid>

					<description><![CDATA[<p>기본적인 Docker 명령어 항목 의미 docker run 새로운 컨테이너를 생성하고 실행 -d Detached mode → 백그라운드에서 실행 ubuntu 사용할 이미지 이름 (없으면 자동으로 Docker Hub에서 pull함) sleep 10 컨테이너 내부에서 실행할 명령어 (10초 동안 대기) .NET Image 추가 두 항목의 IMAGE ID가 동일REPOSITORY: mcr.microsoft.com/dotnet/sdkTAG: 9.0 → IMAGE ID: 08fe223b9022TAG: latest → IMAGE ID: 08fe223b9022이유: latest [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/docker/%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-docker-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%97%b0%ec%8a%b5/40181/">기본적인 Docker 명령어 연습</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-05d805a4      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#기본적인-docker-명령어" class="uagb-toc-link__trigger">기본적인 Docker 명령어</a><li class="uagb-toc__list"><a href="#net-image-추가" class="uagb-toc-link__trigger">.NET Image 추가</a></ol>					</div>
									</div>
				</div>
			


<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--40);margin-bottom:var(--wp--preset--spacing--40)"/>



<h2 class="wp-block-heading">기본적인 Docker 명령어</h2>



<div class="wp-block-uagb-container uagb-block-8ea15a0c alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-78e1b8eb">
<figure class="wp-block-image size-full"><img decoding="async" width="694" height="521" src="https://lycos7560.com/wp-content/uploads/2025/07/image-24.png" alt="" class="wp-image-40182" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-24.png 694w, https://lycos7560.com/wp-content/uploads/2025/07/image-24-300x225.png 300w" sizes="(max-width: 694px) 100vw, 694px" /></figure>
</div>



<div class="wp-block-uagb-container uagb-block-b5e6ec6e">
<figure class="wp-block-image size-full"><img decoding="async" width="1876" height="938" src="https://lycos7560.com/wp-content/uploads/2025/07/image-25.png" alt="" class="wp-image-40183" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-25.png 1876w, https://lycos7560.com/wp-content/uploads/2025/07/image-25-300x150.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-25-768x384.png 768w, https://lycos7560.com/wp-content/uploads/2025/07/image-25-1536x768.png 1536w" sizes="(max-width: 1876px) 100vw, 1876px" /></figure>
</div>
</div></div>



<div class="wp-block-uagb-container uagb-block-1d798c28 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-c832cc9d">
<figure class="wp-block-image size-full"><img decoding="async" width="969" height="505" src="https://lycos7560.com/wp-content/uploads/2025/07/image-26.png" alt="" class="wp-image-40184" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-26.png 969w, https://lycos7560.com/wp-content/uploads/2025/07/image-26-300x156.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-26-768x400.png 768w" sizes="(max-width: 969px) 100vw, 969px" /><figcaption class="wp-element-caption">PowerShell 에서 Docker 버전 확인</figcaption></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker --version</pre>
</div>



<div class="wp-block-uagb-container uagb-block-7b55c5ea">
<figure class="wp-block-image size-full"><img decoding="async" width="549" height="472" src="https://lycos7560.com/wp-content/uploads/2025/07/image-27.png" alt="" class="wp-image-40186" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-27.png 549w, https://lycos7560.com/wp-content/uploads/2025/07/image-27-300x258.png 300w" sizes="(max-width: 549px) 100vw, 549px" /></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Docker Hub에서 hello-world 이미지를 다운로드하는 명령어
docker pull hello-world</pre>



<figure class="wp-block-image size-full"><img decoding="async" width="901" height="241" src="https://lycos7560.com/wp-content/uploads/2025/07/image-28.png" alt="" class="wp-image-40187" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-28.png 901w, https://lycos7560.com/wp-content/uploads/2025/07/image-28-300x80.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-28-768x205.png 768w" sizes="(max-width: 901px) 100vw, 901px" /><figcaption class="wp-element-caption">처음에는 docker를 잠시 멈추어 놓아서 실패</figcaption></figure>
</div>
</div></div>



<div class="wp-block-uagb-container uagb-block-498467b0 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-13b563ab">
<figure class="wp-block-image size-full"><img decoding="async" width="887" height="297" src="https://lycos7560.com/wp-content/uploads/2025/07/image-29.png" alt="" class="wp-image-40188" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-29.png 887w, https://lycos7560.com/wp-content/uploads/2025/07/image-29-300x100.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-29-768x257.png 768w" sizes="(max-width: 887px) 100vw, 887px" /><figcaption class="wp-element-caption">다운로드 완료 후 이미지 확인</figcaption></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker images</pre>
</div>



<div class="wp-block-uagb-container uagb-block-10c0d61c">
<figure class="wp-block-image size-full"><img decoding="async" width="1380" height="490" src="https://lycos7560.com/wp-content/uploads/2025/07/image-30.png" alt="" class="wp-image-40189" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-30.png 1380w, https://lycos7560.com/wp-content/uploads/2025/07/image-30-300x107.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-30-768x273.png 768w" sizes="(max-width: 1380px) 100vw, 1380px" /><figcaption class="wp-element-caption">Desktop에서도 확인이 가능하</figcaption></figure>
</div>
</div></div>



<div class="wp-block-uagb-container uagb-block-5f7b883f alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-f890a406">
<figure class="wp-block-image size-full"><img decoding="async" width="668" height="440" src="https://lycos7560.com/wp-content/uploads/2025/07/image-31.png" alt="" class="wp-image-40190" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-31.png 668w, https://lycos7560.com/wp-content/uploads/2025/07/image-31-300x198.png 300w" sizes="(max-width: 668px) 100vw, 668px" /><figcaption class="wp-element-caption">hello-world 이미지 실행</figcaption></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker run hello-world</pre>
</div>



<div class="wp-block-uagb-container uagb-block-17c9d70c">
<figure class="wp-block-image size-full"><img decoding="async" width="1181" height="230" src="https://lycos7560.com/wp-content/uploads/2025/07/image-32.png" alt="" class="wp-image-40191" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-32.png 1181w, https://lycos7560.com/wp-content/uploads/2025/07/image-32-300x58.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-32-768x150.png 768w" sizes="(max-width: 1181px) 100vw, 1181px" /></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 실행 중인 컨테이너 목록만 출력
docker ps

모든 컨테이너 목록 출력
// 중지된, 종료된, 에러 난 컨테이너도 포함해서 모두 보여줌
docker ps -a</pre>
</div>
</div></div>



<div class="wp-block-uagb-container uagb-block-e9226391 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-83c0597d">
<figure class="wp-block-image size-full"><img decoding="async" width="1105" height="477" src="https://lycos7560.com/wp-content/uploads/2025/07/image-33.png" alt="" class="wp-image-40192" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-33.png 1105w, https://lycos7560.com/wp-content/uploads/2025/07/image-33-300x130.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-33-768x332.png 768w" sizes="(max-width: 1105px) 100vw, 1105px" /><figcaption class="wp-element-caption">이미지를 제거하려면 실행중인 container를 모두 제거해야한다.</figcaption></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker ps // 컨테이너 확인
docker ps -a // 모든 컨테이너 확인
docker rm 5fea
docker rm 6c465
docker rm 0fe
docker rm 1957
docker ps -a // 모든 컨테이너 확인
docker images // 이미지 검색
docker rmi ec1538 // 이미지 제거</pre>
</div>



<div class="wp-block-uagb-container uagb-block-0047b3d5">
<figure class="wp-block-image size-full"><img decoding="async" width="1309" height="525" src="https://lycos7560.com/wp-content/uploads/2025/07/image-34.png" alt="" class="wp-image-40193" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-34.png 1309w, https://lycos7560.com/wp-content/uploads/2025/07/image-34-300x120.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-34-768x308.png 768w" sizes="(max-width: 1309px) 100vw, 1309px" /><figcaption class="wp-element-caption">이미지 제거 적용됨</figcaption></figure>
</div>
</div></div>



<div class="wp-block-uagb-container uagb-block-97073334 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-8a80809e">
<figure class="wp-block-image size-full"><img decoding="async" width="1590" height="702" src="https://lycos7560.com/wp-content/uploads/2025/07/image-35.png" alt="" class="wp-image-40194" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-35.png 1590w, https://lycos7560.com/wp-content/uploads/2025/07/image-35-300x132.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-35-768x339.png 768w, https://lycos7560.com/wp-content/uploads/2025/07/image-35-1536x678.png 1536w" sizes="(max-width: 1590px) 100vw, 1590px" /></figure>
</div>



<div class="wp-block-uagb-container uagb-block-d6288adb">
<figure class="wp-block-image size-full"><img decoding="async" width="982" height="256" src="https://lycos7560.com/wp-content/uploads/2025/07/image-36.png" alt="" class="wp-image-40195" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-36.png 982w, https://lycos7560.com/wp-content/uploads/2025/07/image-36-300x78.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-36-768x200.png 768w" sizes="(max-width: 982px) 100vw, 982px" /></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker run -d ubuntu sleep 10</pre>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>항목</th><th>의미</th></tr></thead><tbody><tr><td><code>docker run</code></td><td>새로운 컨테이너를 생성하고 실행</td></tr><tr><td><code>-d</code></td><td><strong>Detached mode</strong> → 백그라운드에서 실행</td></tr><tr><td><code>ubuntu</code></td><td>사용할 이미지 이름 (없으면 자동으로 Docker Hub에서 pull함)</td></tr><tr><td><code>sleep 10</code></td><td>컨테이너 내부에서 실행할 명령어 (10초 동안 대기)</td></tr></tbody></table></figure>
</div>
</div></div>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--40);margin-bottom:var(--wp--preset--spacing--40)"/>



<h2 class="wp-block-heading">.NET Image 추가</h2>



<div class="wp-block-uagb-container uagb-block-cf968062 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-deb4736b">
<figure class="wp-block-image size-full"><img decoding="async" width="1824" height="1016" src="https://lycos7560.com/wp-content/uploads/2025/07/image-37.png" alt="" class="wp-image-40196" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-37.png 1824w, https://lycos7560.com/wp-content/uploads/2025/07/image-37-300x167.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-37-768x428.png 768w, https://lycos7560.com/wp-content/uploads/2025/07/image-37-1536x856.png 1536w" sizes="(max-width: 1824px) 100vw, 1824px" /><figcaption class="wp-element-caption"><a href="https://hub.docker.com/r/microsoft/dotnet-sdk" target="_blank" rel="noreferrer noopener">https://hub.docker.com/r/microsoft/dotnet-sdk</a></figcaption></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">docker pull mcr.microsoft.com/dotnet/sdk:8.0
docker images</pre>
</div>



<div class="wp-block-uagb-container uagb-block-1095baf6">
<figure class="wp-block-image size-full"><img decoding="async" width="645" height="304" src="https://lycos7560.com/wp-content/uploads/2025/07/image-38.png" alt="" class="wp-image-40197" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-38.png 645w, https://lycos7560.com/wp-content/uploads/2025/07/image-38-300x141.png 300w" sizes="(max-width: 645px) 100vw, 645px" /></figure>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="763" height="165" src="https://lycos7560.com/wp-content/uploads/2025/07/image-39.png" alt="" class="wp-image-40198" style="width:763px;height:auto" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-39.png 763w, https://lycos7560.com/wp-content/uploads/2025/07/image-39-300x65.png 300w" sizes="(max-width: 763px) 100vw, 763px" /></figure>



<p>두 항목의 <strong><code>IMAGE ID</code>가 동일</strong><br>REPOSITORY: mcr.microsoft.com/dotnet/sdk<br>TAG: 9.0 → IMAGE ID: 08fe223b9022<br>TAG: latest → IMAGE ID: 08fe223b9022<br>이유: <code>latest</code> 태그는 <strong>별칭(alias)</strong> 이기 때문이다<br>도커에서 태그(<code>TAG</code>)는 특정 이미지 버전을 <strong>지칭하는 이름</strong>일 뿐이며, <strong>동일한 이미지에 여러 개의 태그를 붙일 수 있습니다.</strong><br>=> <code>9.0</code> 버전의 이미지에 <code>latest</code>라는 이름을 <strong>추가로 붙여 놓은 것</strong></p>
</div>
</div></div>



<p></p>
<p>The post <a href="https://lycos7560.com/docker/%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-docker-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%97%b0%ec%8a%b5/40181/">기본적인 Docker 명령어 연습</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/docker/%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-docker-%eb%aa%85%eb%a0%b9%ec%96%b4-%ec%97%b0%ec%8a%b5/40181/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Docker / Virtual Machine 차이점</title>
		<link>https://lycos7560.com/docker/docker-virtual-machine-%ec%b0%a8%ec%9d%b4%ec%a0%90/40173/</link>
					<comments>https://lycos7560.com/docker/docker-virtual-machine-%ec%b0%a8%ec%9d%b4%ec%a0%90/40173/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Wed, 30 Jul 2025 12:57:01 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[Auto Scaling]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Base Image]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Cloud Native]]></category>
		<category><![CDATA[Cloud Provider]]></category>
		<category><![CDATA[Compliance]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Container as a Service]]></category>
		<category><![CDATA[Container Registry]]></category>
		<category><![CDATA[Container Runtime]]></category>
		<category><![CDATA[Containerization]]></category>
		<category><![CDATA[Continuous Deployment]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[Docker Compose]]></category>
		<category><![CDATA[Docker Desktop]]></category>
		<category><![CDATA[Docker Engine]]></category>
		<category><![CDATA[Docker Hub]]></category>
		<category><![CDATA[Dockerfile]]></category>
		<category><![CDATA[Enterprise]]></category>
		<category><![CDATA[Environment Variables]]></category>
		<category><![CDATA[GitOps]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Guest OS]]></category>
		<category><![CDATA[Health Check]]></category>
		<category><![CDATA[Host OS]]></category>
		<category><![CDATA[Hypervisor]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Image Optimization]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Isolation]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Layer]]></category>
		<category><![CDATA[Legacy System]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Modernization]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[Multi-stage Build]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Orchestration]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[pipeline]]></category>
		<category><![CDATA[Port Mapping]]></category>
		<category><![CDATA[Portability]]></category>
		<category><![CDATA[Production]]></category>
		<category><![CDATA[Pull]]></category>
		<category><![CDATA[Push]]></category>
		<category><![CDATA[Registry]]></category>
		<category><![CDATA[Resource Efficiency]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Security Scanning]]></category>
		<category><![CDATA[Service Mesh]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Staging]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Swarm]]></category>
		<category><![CDATA[Tag]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[vm]]></category>
		<category><![CDATA[Volume]]></category>
		<category><![CDATA[Vulnerability]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[가상머신]]></category>
		<category><![CDATA[개발]]></category>
		<category><![CDATA[게스트 OS]]></category>
		<category><![CDATA[격리]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[구글 클라우드]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[깃옵스]]></category>
		<category><![CDATA[네트워크]]></category>
		<category><![CDATA[데브옵스]]></category>
		<category><![CDATA[도커]]></category>
		<category><![CDATA[도커 데스크톱]]></category>
		<category><![CDATA[도커 엔진]]></category>
		<category><![CDATA[도커 컴포즈]]></category>
		<category><![CDATA[도커 허브]]></category>
		<category><![CDATA[도커파일]]></category>
		<category><![CDATA[레거시 시스템]]></category>
		<category><![CDATA[레이어]]></category>
		<category><![CDATA[레지스트리]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[로드 밸런싱]]></category>
		<category><![CDATA[리눅스]]></category>
		<category><![CDATA[리소스 효율성]]></category>
		<category><![CDATA[마이그레이션]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[멀티 스테이지 빌드]]></category>
		<category><![CDATA[모니터링]]></category>
		<category><![CDATA[모범 사례]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[백업]]></category>
		<category><![CDATA[베이스 이미지]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[보안 스캔]]></category>
		<category><![CDATA[볼륨]]></category>
		<category><![CDATA[빌드]]></category>
		<category><![CDATA[서비스 메시]]></category>
		<category><![CDATA[서비스형 컨테이너]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[소프트웨어 개발]]></category>
		<category><![CDATA[스웜]]></category>
		<category><![CDATA[스테이징]]></category>
		<category><![CDATA[실행]]></category>
		<category><![CDATA[아마존 웹 서비스]]></category>
		<category><![CDATA[아이아씨]]></category>
		<category><![CDATA[아키텍처]]></category>
		<category><![CDATA[애저]]></category>
		<category><![CDATA[애플리케이션]]></category>
		<category><![CDATA[엔터프라이즈]]></category>
		<category><![CDATA[오케스트레이션]]></category>
		<category><![CDATA[오픈 소스]]></category>
		<category><![CDATA[윈도우]]></category>
		<category><![CDATA[이미지]]></category>
		<category><![CDATA[이미지 최적화]]></category>
		<category><![CDATA[이식성]]></category>
		<category><![CDATA[인프라스트럭처]]></category>
		<category><![CDATA[자동 확장]]></category>
		<category><![CDATA[자동화]]></category>
		<category><![CDATA[지속적 배포]]></category>
		<category><![CDATA[지속적 통합]]></category>
		<category><![CDATA[취약점]]></category>
		<category><![CDATA[컨테이너]]></category>
		<category><![CDATA[컨테이너 런타임]]></category>
		<category><![CDATA[컨테이너 레지스트리]]></category>
		<category><![CDATA[컨테이너화]]></category>
		<category><![CDATA[컴플라이언스]]></category>
		<category><![CDATA[코드형 인프라]]></category>
		<category><![CDATA[쿠버네티스]]></category>
		<category><![CDATA[클라우드 네이티브]]></category>
		<category><![CDATA[클라우드 제공자]]></category>
		<category><![CDATA[클라우드 컴퓨팅]]></category>
		<category><![CDATA[태그]]></category>
		<category><![CDATA[테스팅]]></category>
		<category><![CDATA[트러블슈팅]]></category>
		<category><![CDATA[파이프라인]]></category>
		<category><![CDATA[포트 매핑]]></category>
		<category><![CDATA[푸시]]></category>
		<category><![CDATA[풀]]></category>
		<category><![CDATA[프로덕션]]></category>
		<category><![CDATA[하이퍼바이저]]></category>
		<category><![CDATA[헬스 체크]]></category>
		<category><![CDATA[현대화]]></category>
		<category><![CDATA[호스트 OS]]></category>
		<category><![CDATA[확장성]]></category>
		<category><![CDATA[환경 변수]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40173</guid>

					<description><![CDATA[<p>현대 소프트웨어 개발에서 가상화 기술은 필수적인 요소입니다. 전통적인 가상머신(Virtual Machine)과 Docker 컨테이너 기술의 차이점을 알아봅니다. 1. 아키텍처 비교 1.1 Virtual Machine 아키텍처 Virtual Machine은 다음과 같은 계층 구조를 가집니다: 특징: 1.2 Docker 아키텍처 Docker는 다음과 같은 경량화된 구조를 가집니다: 특징: 2. 핵심 차이점 분석 2.1 운영체제 레이어 구분 Virtual Machine Docker Guest OS 필수 불필요 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/docker/docker-virtual-machine-%ec%b0%a8%ec%9d%b4%ec%a0%90/40173/">Docker / Virtual Machine 차이점</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-a0bc8ff7      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-아키텍처-비교" class="uagb-toc-link__trigger">1. 아키텍처 비교</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#11-virtual-machine-아키텍처" class="uagb-toc-link__trigger">1.1 Virtual Machine 아키텍처</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#12-docker-아키텍처" class="uagb-toc-link__trigger">1.2 Docker 아키텍처</a></li></ul></li><li class="uagb-toc__list"><a href="#2-핵심-차이점-분석" class="uagb-toc-link__trigger">2. 핵심 차이점 분석</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#21-운영체제-레이어" class="uagb-toc-link__trigger">2.1 운영체제 레이어</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#22-리소스-사용량" class="uagb-toc-link__trigger">2.2 리소스 사용량</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#virtual-machine" class="uagb-toc-link__trigger">Virtual Machine</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#docker" class="uagb-toc-link__trigger">Docker</a></li></ul><li class="uagb-toc__list"><a href="#23-성능-비교" class="uagb-toc-link__trigger">2.3 성능 비교</a></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#3-장단점-비교" class="uagb-toc-link__trigger">3. 장단점 비교</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#31-virtual-machine" class="uagb-toc-link__trigger">3.1 Virtual Machine</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#장점" class="uagb-toc-link__trigger">장점</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#단점" class="uagb-toc-link__trigger">단점</a></li></ul><li class="uagb-toc__list"><a href="#32-docker" class="uagb-toc-link__trigger">3.2 Docker</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#장점" class="uagb-toc-link__trigger">장점</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#단점" class="uagb-toc-link__trigger">단점</a></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#4-사용-사례별-권장사항" class="uagb-toc-link__trigger">4. 사용 사례별 권장사항</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#41-virtual-machine이-적합한-경우" class="uagb-toc-link__trigger">4.1 Virtual Machine이 적합한 경우</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#42-docker가-적합한-경우" class="uagb-toc-link__trigger">4.2 Docker가 적합한 경우</a></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#5-하이브리드-접근법" class="uagb-toc-link__trigger">5. 하이브리드 접근법</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#51-vm-위의-docker" class="uagb-toc-link__trigger">5.1 VM 위의 Docker</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#52-클라우드-환경" class="uagb-toc-link__trigger">5.2 클라우드 환경</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#6-결론" class="uagb-toc-link__trigger">6. 결론</a></ul></ul></ul></ul></ul></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p>현대 소프트웨어 개발에서 가상화 기술은 필수적인 요소입니다.</p>



<p>전통적인 가상머신(Virtual Machine)과 Docker 컨테이너 기술의 차이점을 알아봅니다.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="1668" height="710" src="https://lycos7560.com/wp-content/uploads/2025/07/image-20.png" alt="" class="wp-image-40174" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-20.png 1668w, https://lycos7560.com/wp-content/uploads/2025/07/image-20-300x128.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-20-768x327.png 768w, https://lycos7560.com/wp-content/uploads/2025/07/image-20-1536x654.png 1536w" sizes="(max-width: 1668px) 100vw, 1668px" /></figure>



<ul class="wp-block-list">
<li><strong>Infrastructure</strong> (물리적 하드웨어) </li>



<li><strong>Host OS</strong> (호스트 운영체제) </li>



<li><strong>Hypervisor</strong> (가상화 관리자) </li>



<li><strong>Guest OS</strong> (각 가상머신마다 독립된 운영체제) </li>



<li><strong>bins/lib</strong> (각 VM마다 독립된 바이너리/라이브러리) </li>



<li><strong>App 1, 2, 3</strong> (애플리케이션들)</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">1. 아키텍처 비교</h2>



<h3 class="wp-block-heading">1.1 Virtual Machine 아키텍처</h3>



<p>Virtual Machine은 다음과 같은 계층 구조를 가집니다:</p>



<figure class="wp-block-image size-full"><img decoding="async" width="765" height="723" src="https://lycos7560.com/wp-content/uploads/2025/07/image-21.png" alt="" class="wp-image-40175" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-21.png 765w, https://lycos7560.com/wp-content/uploads/2025/07/image-21-300x284.png 300w" sizes="(max-width: 765px) 100vw, 765px" /></figure>



<p><strong>특징:</strong></p>



<ul class="wp-block-list">
<li>각 가상머신은 독립된 Guest OS를 보유</li>



<li>하드웨어 가상화를 통한 완전한 격리</li>



<li>Hypervisor가 하드웨어 리소스 관리</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">1.2 Docker 아키텍처</h3>



<p>Docker는 다음과 같은 경량화된 구조를 가집니다:</p>



<figure class="wp-block-image size-full"><img decoding="async" width="746" height="692" src="https://lycos7560.com/wp-content/uploads/2025/07/image-22.png" alt="" class="wp-image-40176" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-22.png 746w, https://lycos7560.com/wp-content/uploads/2025/07/image-22-300x278.png 300w" sizes="(max-width: 746px) 100vw, 746px" /></figure>



<p><strong>특징:</strong></p>



<ul class="wp-block-list">
<li>Guest OS 레이어 제거</li>



<li>Host OS 커널 공유</li>



<li>컨테이너 단위의 프로세스 격리</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">2. 핵심 차이점 분석</h2>



<h3 class="wp-block-heading">2.1 운영체제 레이어</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>구분</th><th>Virtual Machine</th><th>Docker</th></tr></thead><tbody><tr><td>Guest OS</td><td>필수</td><td>불필요</td></tr><tr><td>커널</td><td>각 VM마다 독립</td><td>Host OS 커널 공유</td></tr><tr><td>부팅 과정</td><td>OS 전체 부팅</td><td>프로세스 시작</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">2.2 리소스 사용량</h3>



<h4 class="wp-block-heading">Virtual Machine</h4>



<ul class="wp-block-list">
<li><strong>메모리</strong>: GB 단위 (OS + 애플리케이션)</li>



<li><strong>디스크</strong>: 수 GB ~ 수십 GB</li>



<li><strong>CPU</strong>: OS 오버헤드 포함</li>



<li><strong>네트워크</strong>: 가상 네트워크 스택</li>
</ul>



<h4 class="wp-block-heading">Docker</h4>



<ul class="wp-block-list">
<li><strong>메모리</strong>: MB 단위 (애플리케이션만)</li>



<li><strong>디스크</strong>: MB ~ GB 단위</li>



<li><strong>CPU</strong>: 최소한의 오버헤드</li>



<li><strong>네트워크</strong>: Host 네트워크 스택 공유</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2.3 성능 비교</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>항목</th><th>Virtual Machine</th><th>Docker</th></tr></thead><tbody><tr><td>시작 시간</td><td>1-5분</td><td>1-10초</td></tr><tr><td>메모리 오버헤드</td><td>높음 (OS 포함)</td><td>낮음 (애플리케이션만)</td></tr><tr><td>I/O 성능</td><td>가상화 오버헤드</td><td>네이티브에 근접</td></tr><tr><td>밀도</td><td>낮음 (서버당 수십 개)</td><td>높음 (서버당 수백-수천 개)</td></tr></tbody></table></figure>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">3. 장단점 비교</h2>



<h3 class="wp-block-heading">3.1 Virtual Machine</h3>



<h4 class="wp-block-heading">장점</h4>



<ul class="wp-block-list">
<li><strong>완전한 격리</strong>: 하드웨어 레벨의 보안 격리</li>



<li><strong>OS 다양성</strong>: 다양한 운영체제 동시 실행 가능</li>



<li><strong>성숙한 기술</strong>: 오랜 기간 검증된 안정성</li>



<li><strong>강력한 보안</strong>: 하이퍼바이저 레벨 보안</li>
</ul>



<h4 class="wp-block-heading">단점</h4>



<ul class="wp-block-list">
<li><strong>높은 리소스 사용량</strong>: OS 오버헤드</li>



<li><strong>느린 시작</strong>: 부팅 시간 필요</li>



<li><strong>관리 복잡성</strong>: 각 VM의 OS 관리 필요</li>



<li><strong>낮은 밀도</strong>: 제한적인 VM 수</li>
</ul>



<h3 class="wp-block-heading">3.2 Docker</h3>



<h4 class="wp-block-heading">장점</h4>



<ul class="wp-block-list">
<li><strong>경량성</strong>: 최소한의 리소스 사용</li>



<li><strong>빠른 시작</strong>: 초 단위 컨테이너 시작</li>



<li><strong>높은 밀도</strong>: 단일 호스트에 많은 컨테이너</li>



<li><strong>일관성</strong>: &#8220;한 번 빌드, 어디서든 실행&#8221;</li>



<li><strong>DevOps 친화적</strong>: CI/CD 파이프라인 최적화</li>
</ul>



<h4 class="wp-block-heading">단점</h4>



<ul class="wp-block-list">
<li><strong>보안 취약점</strong>: 커널 공유로 인한 잠재적 위험</li>



<li><strong>OS 제약</strong>: Linux 컨테이너는 Linux에서만</li>



<li><strong>복잡한 네트워킹</strong>: 컨테이너 간 통신 설정</li>



<li><strong>데이터 지속성</strong>: 컨테이너 재시작 시 데이터 손실 위험</li>
</ul>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">4. 사용 사례별 권장사항</h2>



<h3 class="wp-block-heading">4.1 Virtual Machine이 적합한 경우</h3>



<p><strong>기업 환경</strong></p>



<ul class="wp-block-list">
<li>레거시 애플리케이션 운영</li>



<li>서로 다른 OS가 필요한 환경</li>



<li>강력한 보안 격리가 필요한 경우</li>



<li>규제 준수가 중요한 산업</li>
</ul>



<p><strong>기술적 요구사항</strong></p>



<ul class="wp-block-list">
<li>Windows와 Linux 애플리케이션 동시 운영</li>



<li>커널 수준의 소프트웨어 개발</li>



<li>완전한 네트워크 격리 필요</li>



<li>다양한 OS 버전 테스트</li>
</ul>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4.2 Docker가 적합한 경우</h3>



<p><strong>현대적 애플리케이션 개발</strong></p>



<ul class="wp-block-list">
<li>마이크로서비스 아키텍처</li>



<li>클라우드 네이티브 애플리케이션</li>



<li>지속적 통합/배포 (CI/CD)</li>



<li>개발 환경 표준화</li>
</ul>



<p><strong>운영 효율성</strong></p>



<ul class="wp-block-list">
<li>빠른 스케일링이 필요한 서비스</li>



<li>리소스 효율성이 중요한 환경</li>



<li>개발팀 간 환경 일관성</li>



<li>컨테이너 오케스트레이션 (Kubernetes)</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">5. 하이브리드 접근법</h2>



<p>많은 조직에서는 두 기술을 함께 사용합니다:</p>



<h3 class="wp-block-heading">5.1 VM 위의 Docker</h3>



<ul class="wp-block-list">
<li>VM으로 기본 격리 제공</li>



<li>VM 내에서 Docker로 애플리케이션 컨테이너화</li>



<li>보안과 효율성의 균형</li>
</ul>



<h3 class="wp-block-heading">5.2 클라우드 환경</h3>



<ul class="wp-block-list">
<li>AWS ECS, Google Cloud Run 등</li>



<li>관리형 컨테이너 서비스</li>



<li>인프라 추상화</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">6. 결론</h2>



<p>Virtual Machine과 Docker는 각각 고유한 장점과 적용 영역을 가지고 있습니다.</p>



<p><strong>Virtual Machine</strong>은 강력한 격리와 다양한 OS 지원이 필요한 전통적인 엔터프라이즈 환경에 적합하며, </p>



<p><strong>Docker</strong>는 현대적인 클라우드 네이티브 애플리케이션 개발과 운영에 최적화되어 있습니다.</p>



<p>성공적인 시스템 설계를 위해서는 각 기술의 특성을 정확히 이해하고, 프로젝트의 요구사항에 맞는 적절한 선택을 하는 것이 중요합니다. </p>



<p>많은 경우 두 기술을 적절히 조합하여 사용하는 하이브리드 접근법이 최적의 결과를 제공할 수 있습니다.</p>
<p>The post <a href="https://lycos7560.com/docker/docker-virtual-machine-%ec%b0%a8%ec%9d%b4%ec%a0%90/40173/">Docker / Virtual Machine 차이점</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/docker/docker-virtual-machine-%ec%b0%a8%ec%9d%b4%ec%a0%90/40173/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ASP.NET Core &#8211; UseStaticFiles</title>
		<link>https://lycos7560.com/c/asp-net/asp-net-core-usestaticfiles/40147/</link>
					<comments>https://lycos7560.com/c/asp-net/asp-net-core-usestaticfiles/40147/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Sun, 13 Jul 2025 04:33:03 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET Development]]></category>
		<category><![CDATA[.NET 개발]]></category>
		<category><![CDATA[404 Not Found]]></category>
		<category><![CDATA[app.UseStaticFiles()]]></category>
		<category><![CDATA[Application Root]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[ASP.NET Core Fundamentals]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Browser Cache]]></category>
		<category><![CDATA[Cache Invalidation]]></category>
		<category><![CDATA[Cache-Control]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[Caching Strategy]]></category>
		<category><![CDATA[Configure 메서드]]></category>
		<category><![CDATA[Content Delivery]]></category>
		<category><![CDATA[Content Type]]></category>
		<category><![CDATA[Content-Type]]></category>
		<category><![CDATA[ContentRootPath]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[Development Purpose]]></category>
		<category><![CDATA[Directory Browse]]></category>
		<category><![CDATA[Endpoint Routing]]></category>
		<category><![CDATA[Environment]]></category>
		<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[File Access]]></category>
		<category><![CDATA[File Extension]]></category>
		<category><![CDATA[file management]]></category>
		<category><![CDATA[File Path]]></category>
		<category><![CDATA[File Serving]]></category>
		<category><![CDATA[File System]]></category>
		<category><![CDATA[FileProvider]]></category>
		<category><![CDATA[Font]]></category>
		<category><![CDATA[Frontend]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTTP Headers]]></category>
		<category><![CDATA[HTTP Request]]></category>
		<category><![CDATA[HTTP Response]]></category>
		<category><![CDATA[HTTP 요청]]></category>
		<category><![CDATA[HTTP 응답]]></category>
		<category><![CDATA[HTTP 헤더]]></category>
		<category><![CDATA[HttpRequest]]></category>
		<category><![CDATA[HttpResponse]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Kestrel]]></category>
		<category><![CDATA[Middleware]]></category>
		<category><![CDATA[Middleware Order]]></category>
		<category><![CDATA[Middleware Pipeline]]></category>
		<category><![CDATA[MIME Type]]></category>
		<category><![CDATA[MIME 타입]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Option Configuration]]></category>
		<category><![CDATA[Path Mapping]]></category>
		<category><![CDATA[Path.Combine]]></category>
		<category><![CDATA[Performance Optimization]]></category>
		<category><![CDATA[Performance Tuning]]></category>
		<category><![CDATA[Permissions]]></category>
		<category><![CDATA[Physical File]]></category>
		<category><![CDATA[PhysicalFileProvider]]></category>
		<category><![CDATA[Production Environment]]></category>
		<category><![CDATA[Program.cs]]></category>
		<category><![CDATA[Request Processing Flow]]></category>
		<category><![CDATA[RequestPath]]></category>
		<category><![CDATA[resource management]]></category>
		<category><![CDATA[Response Headers]]></category>
		<category><![CDATA[Root Folder]]></category>
		<category><![CDATA[Routing Configuration]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Security Vulnerability]]></category>
		<category><![CDATA[Server Configuration]]></category>
		<category><![CDATA[Server Resources]]></category>
		<category><![CDATA[Startup.cs]]></category>
		<category><![CDATA[Static Content]]></category>
		<category><![CDATA[Static File]]></category>
		<category><![CDATA[Static File Hosting]]></category>
		<category><![CDATA[StaticFileOptions]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[URL Mapping]]></category>
		<category><![CDATA[URL Path]]></category>
		<category><![CDATA[URL Redirection]]></category>
		<category><![CDATA[URL 경로]]></category>
		<category><![CDATA[URL 리디렉션]]></category>
		<category><![CDATA[URL 매핑]]></category>
		<category><![CDATA[UseDirectoryBrowser]]></category>
		<category><![CDATA[UseRouting]]></category>
		<category><![CDATA[UseStaticFiles]]></category>
		<category><![CDATA[Virtual Path]]></category>
		<category><![CDATA[Web Application]]></category>
		<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[Web Cache]]></category>
		<category><![CDATA[Web Content]]></category>
		<category><![CDATA[Web Deployment]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Page]]></category>
		<category><![CDATA[Web Project]]></category>
		<category><![CDATA[Web Publishing]]></category>
		<category><![CDATA[Web Resource]]></category>
		<category><![CDATA[Web Root]]></category>
		<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Web Server]]></category>
		<category><![CDATA[Web Server Configuration]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[WebApplication]]></category>
		<category><![CDATA[WebApplicationBuilder]]></category>
		<category><![CDATA[wwwroot]]></category>
		<category><![CDATA[가상 경로]]></category>
		<category><![CDATA[개발 목적]]></category>
		<category><![CDATA[개발 환경]]></category>
		<category><![CDATA[경로 매핑]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[권한]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[디렉터리 브라우징]]></category>
		<category><![CDATA[디버깅]]></category>
		<category><![CDATA[라우팅 구성]]></category>
		<category><![CDATA[루트 폴더]]></category>
		<category><![CDATA[물리적 파일]]></category>
		<category><![CDATA[미들웨어]]></category>
		<category><![CDATA[미들웨어 순서]]></category>
		<category><![CDATA[미들웨어 파이프라인]]></category>
		<category><![CDATA[백엔드]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[보안 취약점]]></category>
		<category><![CDATA[브라우저 캐시]]></category>
		<category><![CDATA[서버 리소스]]></category>
		<category><![CDATA[서버 설정]]></category>
		<category><![CDATA[성능 최적화]]></category>
		<category><![CDATA[성능 튜닝]]></category>
		<category><![CDATA[애플리케이션 루트]]></category>
		<category><![CDATA[엔드포인트 라우팅]]></category>
		<category><![CDATA[오류 처리]]></category>
		<category><![CDATA[옵션 설정]]></category>
		<category><![CDATA[요청 처리 흐름]]></category>
		<category><![CDATA[운영 환경]]></category>
		<category><![CDATA[웹 개발]]></category>
		<category><![CDATA[웹 루트]]></category>
		<category><![CDATA[웹 리소스]]></category>
		<category><![CDATA[웹 배포]]></category>
		<category><![CDATA[웹 보안]]></category>
		<category><![CDATA[웹 서버]]></category>
		<category><![CDATA[웹 서버 구성]]></category>
		<category><![CDATA[웹 서비스]]></category>
		<category><![CDATA[웹 애플리케이션]]></category>
		<category><![CDATA[웹 애플리케이션 개발]]></category>
		<category><![CDATA[웹 캐시]]></category>
		<category><![CDATA[웹 콘텐츠]]></category>
		<category><![CDATA[웹 퍼블리싱]]></category>
		<category><![CDATA[웹 페이지]]></category>
		<category><![CDATA[웹 표준]]></category>
		<category><![CDATA[웹 프로젝트]]></category>
		<category><![CDATA[응답 헤더]]></category>
		<category><![CDATA[이미지]]></category>
		<category><![CDATA[자원 관리]]></category>
		<category><![CDATA[정적 콘텐츠]]></category>
		<category><![CDATA[정적 파일]]></category>
		<category><![CDATA[정적 파일 호스팅]]></category>
		<category><![CDATA[최적화]]></category>
		<category><![CDATA[캐시 무효화]]></category>
		<category><![CDATA[캐싱]]></category>
		<category><![CDATA[캐싱 전략]]></category>
		<category><![CDATA[콘텐츠 전달]]></category>
		<category><![CDATA[콘텐츠 타입]]></category>
		<category><![CDATA[파일 경로]]></category>
		<category><![CDATA[파일 관리]]></category>
		<category><![CDATA[파일 서빙]]></category>
		<category><![CDATA[파일 시스템]]></category>
		<category><![CDATA[파일 접근]]></category>
		<category><![CDATA[파일 확장자]]></category>
		<category><![CDATA[폰트]]></category>
		<category><![CDATA[프론트엔드]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40147</guid>

					<description><![CDATA[<p>🔥 UseStaticFiles https://learn.microsoft.com/ko-kr/aspnet/core/fundamentals/static-files?view=aspnetcore-8.0 UseStaticFiles는 ASP.NET Core 애플리케이션에서 정적 파일(Static Files)을 제공하기 위해 사용되는 미들웨어입니다. 정적 파일이란 웹 서버가 클라이언트에 그대로 전달하는 파일들로, 웹 페이지를 구성하는 데 필요한 이미지, CSS 파일, JavaScript 파일, 폰트 등을 의미합니다. 1️⃣ UseStaticFiles 미들웨어의 개념 ASP.NET Core는 기본적으로 보안을 위해 웹 루트(wwwroot 폴더) 외부의 파일에 대한 직접적인 웹 접근을 허용하지 않습니다. [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/asp-net/asp-net-core-usestaticfiles/40147/">ASP.NET Core &#8211; UseStaticFiles</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-39abf3bb      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#usestaticfiles" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> UseStaticFiles</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-usestaticfiles-미들웨어의-개념" class="uagb-toc-link__trigger">1&#x20e3; UseStaticFiles 미들웨어의 개념</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-usestaticfiles의-주요-역할" class="uagb-toc-link__trigger">2&#x20e3; UseStaticFiles의 주요 역할</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-usestaticfiles-사용-방법" class="uagb-toc-link__trigger">3&#x20e3; UseStaticFiles 사용 방법</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#기본-사용법-wwwroot-폴더" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 기본 사용법 (wwwroot 폴더)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#다른-폴더의-정적-파일-제공" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 다른 폴더의 정적 파일 제공</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#디렉터리-브라우징-활성화-권장하지-않음" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 디렉터리 브라우징 활성화 (권장하지 않음)</a></li></ul><li class="uagb-toc__list"><a href="#4-usestaticfiles-미들웨어의-위치" class="uagb-toc-link__trigger">4&#x20e3; UseStaticFiles 미들웨어의 위치</a></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> UseStaticFiles</h2>



<p><a href="https://learn.microsoft.com/ko-kr/aspnet/core/fundamentals/static-files?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/aspnet/core/fundamentals/static-files?view=aspnetcore-8.0</a></p>



<p><code>UseStaticFiles</code>는 ASP.NET Core 애플리케이션에서 <strong>정적 파일(Static Files)을 제공하기 위해 사용되는 미들웨어</strong>입니다. </p>



<p>정적 파일이란 웹 서버가 클라이언트에 그대로 전달하는 파일들로, 웹 페이지를 구성하는 데 필요한 이미지, CSS 파일, JavaScript 파일, 폰트 등을 의미합니다.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">1&#x20e3; UseStaticFiles 미들웨어의 개념</h3>



<p>ASP.NET Core는 기본적으로 보안을 위해 웹 루트(<code>wwwroot</code> 폴더) 외부의 파일에 대한 직접적인 웹 접근을 허용하지 않습니다. </p>



<p><code>UseStaticFiles</code> 미들웨어는 이러한 제한을 해제하고, 웹 서버가 특정 디렉토리(기본값은 <code>wwwroot</code>)에 있는 정적 파일 요청을 처리할 수 있도록 파이프라인에 기능을 추가합니다.</p>



<p>이 미들웨어가 없으면, 브라우저가 <code>/css/site.css</code>나 <code>/images/logo.png</code> 같은 경로로 정적 파일을 요청했을 때, 서버는 해당 파일을 찾지 못하고 404 Not Found 오류를 반환하게 됩니다. </p>



<p><code>UseStaticFiles</code>를 추가함으로써, ASP.NET Core 애플리케이션은 이러한 요청을 가로채어 지정된 위치에서 파일을 찾아 클라이언트에게 응답할 수 있게 됩니다.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2&#x20e3; UseStaticFiles의 주요 역할</h3>



<ul class="wp-block-list">
<li><strong>정적 파일 서빙 활성화</strong>: <br>웹 루트(<code>wwwroot</code>)에 있는 HTML, CSS, JavaScript, 이미지 등 정적 파일을 웹 브라우저가 요청할 수 있도록 허용합니다.</li>



<li><strong>파일 경로 매핑</strong>: <br>들어오는 URL 요청을 서버의 실제 파일 시스템 경로에 매핑합니다.</li>



<li><strong>캐싱 헤더 추가</strong>: <br>효율적인 캐싱을 위해 <code>Cache-Control</code> 같은 HTTP 응답 헤더를 자동으로 추가하여 브라우저가 정적 파일을 효율적으로 캐싱하고, 다음 요청 시 서버에 다시 요청하는 대신 로컬 캐시를 사용하도록 돕습니다.</li>



<li><strong>MIME 타입 추론</strong>: <br>파일 확장자를 기반으로 올바른 MIME 타입(<code>Content-Type</code> 헤더)을 응답에 포함하여 브라우저가 파일을 올바르게 해석하도록 합니다.</li>



<li><strong>디렉터리 브라우징 방지</strong>: <br>기본적으로 보안을 위해 디렉터리 목록을 보여주지 않습니다. (이를 허용하려면 추가 설정 필요)</li>
</ul>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3&#x20e3; UseStaticFiles 사용 방법</h3>



<p><code>UseStaticFiles</code> 미들웨어는 보통 <code>Program.cs</code> 파일의 <code>Configure</code> 메서드에서 다른 미들웨어들과 함께 구성됩니다.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 기본 사용법 (wwwroot 폴더)</h4>



<p>가장 기본적인 사용법은 웹 루트(<code>wwwroot</code>) 폴더에 있는 정적 파일을 제공하는 것입니다. </p>



<p>이 경우, <code>UseStaticFiles()</code> 메서드를 인자 없이 호출하면 됩니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages(); // 또는 AddControllersWithViews 등

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

// UseStaticFiles 미들웨어를 추가합니다.
// 이는 wwwroot 폴더의 정적 파일을 제공합니다.
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages(); // 또는 app.MapControllerRoute 등

app.Run();</pre>



<ul class="wp-block-list">
<li>위 코드에서 <code>UseStaticFiles()</code>를 호출하면, ASP.NET Core 프로젝트 템플릿에 기본으로 생성되는 <code>wwwroot</code> 폴더의 내용이 웹에 노출됩니다.</li>



<li>예를 들어, <code>wwwroot/css/site.css</code> 파일이 있다면, 브라우저에서 <code>http://localhost:포트번호/css/site.css</code>로 접근할 수 있게 됩니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 다른 폴더의 정적 파일 제공</h4>



<p><code>wwwroot</code> 외의 다른 폴더에 있는 정적 파일을 제공하고 싶을 때는 <code>StaticFileOptions</code>를 구성하여 경로를 지정할 수 있습니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Program.cs

var builder = WebApplication.CreateBuilder(args);

// ... 서비스 설정 ...

var app = builder.Build();

// ... 기타 미들웨어 설정 ...

// wwwroot 외의 'MyStaticFiles' 폴더에 있는 정적 파일을 제공합니다.
// URL 경로는 `/MyFiles`로 시작합니다.
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
    RequestPath = "/MyFiles" // URL 프리픽스
});

// 기존 wwwroot 폴더도 계속 사용하려면 이 줄도 유지합니다.
app.UseStaticFiles();

app.UseRouting();

// ... 나머지 미들웨어 및 엔드포인트 설정 ...

app.Run();</pre>



<ul class="wp-block-list">
<li><code>FileProvider</code>: <code>PhysicalFileProvider</code>를 사용하여 서버의 실제 파일 시스템 경로를 지정합니다. <br><code>ContentRootPath</code>는 애플리케이션의 기본 디렉토리를 나타냅니다.</li>



<li><code>RequestPath</code>: 이 <code>StaticFileOptions</code> 인스턴스에 의해 제공되는 파일에 접근하기 위한 URL 프리픽스를 정의합니다. <br>위 예시에서는 <code>MyStaticFiles</code> 폴더에 있는 <code>image.png</code> 파일을 <code>http://localhost:포트번호/MyFiles/image.png</code>로 접근할 수 있습니다.</li>



<li><code>UseStaticFiles()</code>를 여러 번 호출하여 여러 정적 파일 소스를 구성할 수 있습니다.</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 디렉터리 브라우징 활성화 (권장하지 않음)</h4>



<p>보안상의 이유로 기본적으로 비활성화되어 있지만, 개발 목적으로 디렉터리 목록을 웹에 노출해야 하는 경우 <code>UseDirectoryBrowser</code> 미들웨어를 함께 사용할 수 있습니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Program.cs

var builder = WebApplication.CreateBuilder(args);

// 서비스에 디렉터리 브라우징 추가
builder.Services.AddDirectoryBrowser();

var app = builder.Build();

// ... 기타 미들웨어 설정 ...

// 'MyDirectory' 폴더를 웹에 노출하고, 해당 폴더의 내용을 `/MyFolder` URL로 브라우징할 수 있도록 합니다.
app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(app.Environment.ContentRootPath, "MyDirectory")),
    RequestPath = "/MyFolder"
});

// 'MyDirectory' 폴더의 정적 파일도 제공합니다.
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(app.Environment.ContentRootPath, "MyDirectory")),
    RequestPath = "/MyFolder"
});

// ... 나머지 미들웨어 및 엔드포인트 설정 ...

app.Run();</pre>



<ul class="wp-block-list">
<li><strong>경고</strong>: <code>UseDirectoryBrowser</code>는 <strong>보안 취약점</strong>이 될 수 있으므로, <strong>운영 환경에서는 절대 사용해서는 안 됩니다.</strong> <br>오직 개발/디버깅 목적으로만 제한적으로 사용해야 합니다.</li>
</ul>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4&#x20e3; <code>UseStaticFiles</code> 미들웨어의 위치</h3>



<p>미들웨어 파이프라인에서 <code>UseStaticFiles</code>의 위치는 중요합니다.</p>



<ul class="wp-block-list">
<li>일반적으로 <code>UseStaticFiles</code>는 <code>UseRouting</code> 미들웨어 <strong>앞</strong>에 위치하는 것이 좋습니다. <br>이렇게 하면 라우팅 시스템이 복잡한 컨트롤러/엔드포인트 매칭 로직을 시작하기 전에, 정적 파일 요청을 먼저 빠르게 처리하고 응답할 수 있어 성능에 유리합니다.</li>



<li>만약 <code>UseStaticFiles</code>가 <code>UseRouting</code> 뒤에 오면, 정적 파일 요청도 라우팅 시스템의 대상이 되어 불필요한 처리 오버헤드가 발생할 수 있습니다.</li>



<li>하지만, 특정 미들웨어(예: 인증/인가 미들웨어)를 통해 정적 파일 접근을 제어하고 싶다면, 해당 미들웨어 뒤에 <code>UseStaticFiles</code>를 배치할 수도 있습니다. <br>이 경우 정적 파일 요청도 인증/인가 절차를 거치게 됩니다.</li>
</ul>



<p><code>UseStaticFiles</code> 미들웨어는 <strong>ASP.NET Core 웹 애플리케이션에서 정적인 웹 리소스를 효율적이고 안전하게 제공하는 데 필수적인 구성 요소</strong>입니다.</p>



<p></p>
<p>The post <a href="https://lycos7560.com/c/asp-net/asp-net-core-usestaticfiles/40147/">ASP.NET Core &#8211; UseStaticFiles</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/asp-net/asp-net-core-usestaticfiles/40147/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ASP.NET Core 파일 처리: FileResult 및 인터페이스</title>
		<link>https://lycos7560.com/c/asp-net/asp-net-core-%ed%8c%8c%ec%9d%bc-%ec%b2%98%eb%a6%ac-fileresult-%eb%b0%8f-%ec%9d%b8%ed%84%b0%ed%8e%98%ec%9d%b4%ec%8a%a4/40149/</link>
					<comments>https://lycos7560.com/c/asp-net/asp-net-core-%ed%8c%8c%ec%9d%bc-%ec%b2%98%eb%a6%ac-fileresult-%eb%b0%8f-%ec%9d%b8%ed%84%b0%ed%8e%98%ec%9d%b4%ec%8a%a4/40149/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Mon, 07 Jul 2025 07:59:28 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[AntivirusScan]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[AWS S3]]></category>
		<category><![CDATA[AzureBlob]]></category>
		<category><![CDATA[base64]]></category>
		<category><![CDATA[BinaryData]]></category>
		<category><![CDATA[BinaryFile]]></category>
		<category><![CDATA[BlobStorage]]></category>
		<category><![CDATA[ChunkedUpload]]></category>
		<category><![CDATA[ContentType]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[FileAccess]]></category>
		<category><![CDATA[FileAccessMode]]></category>
		<category><![CDATA[FileAnalytics]]></category>
		<category><![CDATA[FileApproval]]></category>
		<category><![CDATA[FileArchive]]></category>
		<category><![CDATA[FileAttributes]]></category>
		<category><![CDATA[FileBackup]]></category>
		<category><![CDATA[FileBuffering]]></category>
		<category><![CDATA[FileCache]]></category>
		<category><![CDATA[FileCDN]]></category>
		<category><![CDATA[FileChecksum]]></category>
		<category><![CDATA[FileCleanup]]></category>
		<category><![CDATA[FileCollaboration]]></category>
		<category><![CDATA[FileCompression]]></category>
		<category><![CDATA[FileConcurrency]]></category>
		<category><![CDATA[FileContentResult]]></category>
		<category><![CDATA[FileController]]></category>
		<category><![CDATA[FileConversion]]></category>
		<category><![CDATA[FileConversionAPI]]></category>
		<category><![CDATA[FileDatabase]]></category>
		<category><![CDATA[FileDirectory]]></category>
		<category><![CDATA[FileDistribution]]></category>
		<category><![CDATA[FileDownload]]></category>
		<category><![CDATA[FileEncryption]]></category>
		<category><![CDATA[FileExpiration]]></category>
		<category><![CDATA[FileExtension]]></category>
		<category><![CDATA[FileExtraction]]></category>
		<category><![CDATA[FileFormat]]></category>
		<category><![CDATA[FileHandler]]></category>
		<category><![CDATA[FileHash]]></category>
		<category><![CDATA[FileHosting]]></category>
		<category><![CDATA[FileIntegrity]]></category>
		<category><![CDATA[FileLocking]]></category>
		<category><![CDATA[FileLogging]]></category>
		<category><![CDATA[FileManagement]]></category>
		<category><![CDATA[FileMetadata]]></category>
		<category><![CDATA[FileMiddleware]]></category>
		<category><![CDATA[FileMode]]></category>
		<category><![CDATA[FileMonitoring]]></category>
		<category><![CDATA[FileNaming]]></category>
		<category><![CDATA[FileOCR]]></category>
		<category><![CDATA[FileOperations]]></category>
		<category><![CDATA[FileOptimization]]></category>
		<category><![CDATA[FileOptions]]></category>
		<category><![CDATA[FilePath]]></category>
		<category><![CDATA[FilePermissions]]></category>
		<category><![CDATA[FilePersistence]]></category>
		<category><![CDATA[FilePreview]]></category>
		<category><![CDATA[FileProgress]]></category>
		<category><![CDATA[FileRepository]]></category>
		<category><![CDATA[FileRequest]]></category>
		<category><![CDATA[FileResizing]]></category>
		<category><![CDATA[FileResponse]]></category>
		<category><![CDATA[FileResult]]></category>
		<category><![CDATA[FileResumeUpload]]></category>
		<category><![CDATA[FileSearch]]></category>
		<category><![CDATA[FileSecurity]]></category>
		<category><![CDATA[FileService]]></category>
		<category><![CDATA[FileShareMode]]></category>
		<category><![CDATA[FileSharing]]></category>
		<category><![CDATA[FileSharingLink]]></category>
		<category><![CDATA[FileSignature]]></category>
		<category><![CDATA[FileSizeLimit]]></category>
		<category><![CDATA[FileStorage]]></category>
		<category><![CDATA[Filestream]]></category>
		<category><![CDATA[FileStreamResult]]></category>
		<category><![CDATA[FileSync]]></category>
		<category><![CDATA[FileSystem]]></category>
		<category><![CDATA[FileTemporaryStorage]]></category>
		<category><![CDATA[FileThumbnail]]></category>
		<category><![CDATA[FileTracking]]></category>
		<category><![CDATA[FileUpload]]></category>
		<category><![CDATA[FileUploadLimit]]></category>
		<category><![CDATA[FileValidation]]></category>
		<category><![CDATA[FileVersioning]]></category>
		<category><![CDATA[FileVirusCheck]]></category>
		<category><![CDATA[FileWatcher]]></category>
		<category><![CDATA[FileWatermark]]></category>
		<category><![CDATA[FileWorkflow]]></category>
		<category><![CDATA[FormFile]]></category>
		<category><![CDATA[GoogleCloudStorage]]></category>
		<category><![CDATA[IDirectoryContents]]></category>
		<category><![CDATA[IFileInfo]]></category>
		<category><![CDATA[IFileProvider]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[MemoryStream]]></category>
		<category><![CDATA[MIME]]></category>
		<category><![CDATA[MultipartFormData]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[PhysicalFileResult]]></category>
		<category><![CDATA[Streaming]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[TextFile]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[VirtualFileResult]]></category>
		<category><![CDATA[Word]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[ZipFile]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[기초]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40149</guid>

					<description><![CDATA[<p>🔥 ASP.NET Core 파일 처리: FileResult 및 인터페이스 ASP.NET Core 애플리케이션에서 파일은 핵심적인 요소입니다. 클라이언트로부터 파일을 업로드 받거나(Upload), 서버에 있는 파일을 클라이언트에게 제공(Download/Serve)하는 등 다양한 시나리오에서 파일을 효율적이고 안전하게 다루는 것이 중요합니다. 파일을 클라이언트에게 전송하는 주요 FileResult 유형(FileContentResult, VirtualFileResult, PhysicalFileResult)의 차이점과 파일 업로드, 파일 시스템 접근, 환경 정보 제공 등 파일 관련하여 알아야 할 핵심 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/asp-net/asp-net-core-%ed%8c%8c%ec%9d%bc-%ec%b2%98%eb%a6%ac-fileresult-%eb%b0%8f-%ec%9d%b8%ed%84%b0%ed%8e%98%ec%9d%b4%ec%8a%a4/40149/">ASP.NET Core 파일 처리: FileResult 및 인터페이스</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-090fc3df      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#aspnet-core-파일-처리-fileresult-및-인터페이스" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ASP.NET Core 파일 처리: FileResult 및 인터페이스</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-file-download-및-serving을-위한-fileresult-유형" class="uagb-toc-link__trigger">1&#x20e3; File Download 및 Serving을 위한 FileResult 유형</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#filecontentresult" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> FileContentResult</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#virtualfileresult" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> VirtualFileResult</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#physicalfileresult" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> PhysicalFileResult</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#filestreamresult-스트림-기반-파일-serving" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> FileStreamResult (스트림 기반 파일 Serving)</a></li></ul><li class="uagb-toc__list"><a href="#2-파일-처리-관련-기타-핵심-인터페이스-및-개념" class="uagb-toc-link__trigger">2&#x20e3; 파일 처리 관련 기타 핵심 인터페이스 및 개념</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#iformfile-및-iformfilecollection-파일-업로드" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> IFormFile 및 IFormFileCollection (파일 업로드)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#iwebhostenvironment-및-ihostenvironment-환경-정보-및-경로" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> IWebHostEnvironment 및 IHostEnvironment (환경 정보 및 경로)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#ifileprovider-추상화된-파일-시스템-접근" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> IFileProvider (추상화된 파일 시스템 접근)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#ifileinfo-및-idirectorycontents-파일디렉토리-메타데이터" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> IFileInfo 및 IDirectoryContents (파일/디렉토리 메타데이터)</a></li></ul><li class="uagb-toc__list"><a href="#3-고급-파일-처리-기능" class="uagb-toc-link__trigger">3&#x20e3; 고급 파일 처리 기능</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#파일-업로드-보안-강화" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 파일 업로드 보안 강화</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#파일-시그니처-검증" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 파일 시그니처 검증</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#커스텀-파일-검증-어트리뷰트" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 커스텀 파일 검증 어트리뷰트</a></li></ul><li class="uagb-toc__list"><a href="#대용량-파일-처리-최적화" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 대용량 파일 처리 최적화</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#스트리밍-업로드" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 스트리밍 업로드</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#range-request-지원-부분-콘텐츠-전송" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Range Request 지원 (부분 콘텐츠 전송)</a></li></ul><li class="uagb-toc__list"><a href="#임시-파일-관리-및-정리" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 임시 파일 관리 및 정리</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#임시-파일-자동-정리-서비스" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 임시 파일 자동 정리 서비스</a></li></ul><li class="uagb-toc__list"><a href="#파일-압축-및-최적화" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 파일 압축 및 최적화</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#이미지-자동-리사이징" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 이미지 자동 리사이징</a></li></ul><li class="uagb-toc__list"><a href="#파일-메타데이터-및-추적" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 파일 메타데이터 및 추적</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#파일-메타데이터-모델" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 파일 메타데이터 모델</a></li></ul><li class="uagb-toc__list"><a href="#에러-처리-및-로깅" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 에러 처리 및 로깅</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#포괄적인-파일-에러-처리" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 포괄적인 파일 에러 처리</a></li></ul></li></ul><li class="uagb-toc__list"><a href="#4-파일-처리-시-보안-및-성능-고려사항" class="uagb-toc-link__trigger">4&#x20e3; 파일 처리 시 보안 및 성능 고려사항</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#보안-고려사항" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 보안 고려사항</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#성능-고려사항" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 성능 고려사항</a></li></ul><li class="uagb-toc__list"><a href="#5-프로덕션-환경-설정" class="uagb-toc-link__trigger">5&#x20e3; 프로덕션 환경 설정</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#programcs-설정-예시" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Program.cs 설정 예시</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#로깅-설정-appsettingsjson" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 로깅 설정 (appsettings.json)</a></li></ul><li class="uagb-toc__list"><a href="#6-결론" class="uagb-toc-link__trigger">6&#x20e3; 결론</a></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-embed is-type-wp-embed"><div class="wp-block-embed__wrapper">
<blockquote class="wp-embedded-content" data-secret="cjGpApKd9k"><a href="https://lycos7560.com/c/asp-net/%eb%a6%ac%ed%94%8c%eb%a0%89%ec%85%98reflection%ec%9d%84-%ec%82%ac%ec%9a%a9%ed%95%9c-actionresult%eb%a5%bc-%ec%83%81%ec%86%8d%eb%b0%9b%eb%8a%94-%eb%aa%a8%eb%93%a0-%ed%81%b4%eb%9e%98%ec%8a%a4/40153/">리플렉션(Reflection)을 사용한 ActionResult를 상속받는 모든 클래스 찾기</a></blockquote><iframe loading="lazy" class="wp-embedded-content" sandbox="allow-scripts" security="restricted"  title="&#8220;리플렉션(Reflection)을 사용한 ActionResult를 상속받는 모든 클래스 찾기&#8221; &#8212; 어제와 내일의 나 그 사이의 이야기" src="https://lycos7560.com/c/asp-net/%eb%a6%ac%ed%94%8c%eb%a0%89%ec%85%98reflection%ec%9d%84-%ec%82%ac%ec%9a%a9%ed%95%9c-actionresult%eb%a5%bc-%ec%83%81%ec%86%8d%eb%b0%9b%eb%8a%94-%eb%aa%a8%eb%93%a0-%ed%81%b4%eb%9e%98%ec%8a%a4/40153/embed/#?secret=tEHT3JgDc3#?secret=cjGpApKd9k" data-secret="cjGpApKd9k" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
</div></figure>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h1 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ASP.NET Core 파일 처리: FileResult 및 인터페이스</h1>



<p>ASP.NET Core 애플리케이션에서 파일은 핵심적인 요소입니다. </p>



<p>클라이언트로부터 파일을 업로드 받거나(Upload), 서버에 있는 파일을 클라이언트에게 제공(Download/Serve)하는 등 다양한 시나리오에서 파일을 효율적이고 안전하게 다루는 것이 중요합니다. </p>



<p>파일을 클라이언트에게 전송하는 주요 <strong>FileResult 유형(FileContentResult, VirtualFileResult, PhysicalFileResult)의 차이점</strong>과</p>



<p>파일 업로드, 파일 시스템 접근, 환경 정보 제공 등 파일 관련하여 알아야 할 핵심 인터페이스와 개념들을 정리합니다.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">1&#x20e3; File Download 및 Serving을 위한 FileResult 유형</h2>



<p>ASP.NET Core MVC/API에서 컨트롤러 액션 메서드가 파일을 HTTP 응답으로 스트리밍할 때 사용하는 IActionResult의 파생 클래스들입니다. </p>



<p>파일 데이터를 가져오는 방식과 경로를 해석하는 방식에 따라 구분됩니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> FileContentResult</h3>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.mvc.filecontentresult?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.mvc.filecontentresult?view=aspnetcore-8.0</a></p>



<p>파일의 내용이 이미 byte[] 배열 형태로 메모리에 로드되어 있을 때 사용됩니다. </p>



<p>웹 서버는 이 바이트 배열을 그대로 클라이언트에게 스트리밍합니다.</p>



<ul class="wp-block-list">
<li><strong>정의</strong>: <br>Microsoft.AspNetCore.Mvc.FileContentResult</li>



<li><strong>데이터 원본</strong>: <br>byte[] (메모리)</li>



<li><strong>메모리 사용</strong>: <br>높음. 파일의 모든 내용이 메모리에 로드되므로, <strong>큰 파일을 처리할 경우 메모리 부족 문제가 발생</strong>할 수 있습니다.</li>



<li><strong>성능</strong>: <br>작은 파일이나 동적으로 생성된 파일에 적합합니다. 대용량 파일에는 비효율적입니다.</li>
</ul>



<p><strong>주요 사용처</strong>:</p>



<ul class="wp-block-list">
<li>동적으로 생성된 파일: <br>이미지 생성 라이브러리(예: System.Drawing.Common, ImageSharp)로 런타임에 생성된 이미지.</li>



<li>데이터베이스에 저장된 파일: <br>파일 데이터가 BLOB(Binary Large Object) 형태로 데이터베이스에 저장되어 있으며, 이를 byte[]로 읽어와야 하는 경우.</li>



<li>작은 파일: <br>메모리 오버헤드가 무시할 만한 수준의 작은 파일.</li>
</ul>



<p><strong>생성자 매개변수</strong>:</p>



<ul class="wp-block-list">
<li><code>byte[] fileContents</code>: 전송할 파일의 바이트 배열 데이터.</li>



<li><code>string contentType</code>: 파일의 MIME 타입 (예: &#8220;image/png&#8221;, &#8220;application/pdf&#8221;, &#8220;text/plain&#8221;).</li>



<li><code>string? fileDownloadName</code> (선택 사항): 브라우저가 파일을 다운로드할 때 제안할 파일 이름. <br>이 매개변수를 지정하면 Content-Disposition 헤더가 attachment로 설정되어 브라우저가 파일을 인라인으로 표시하는 대신 다운로드하도록 유도합니다.</li>
</ul>



<p><strong>예시</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Mvc;
using System.Text;

public class DynamicFileController : Controller
{
    // GET: /DynamicFile/GenerateText
    public IActionResult GenerateText()
    {
        var content = "이것은 동적으로 생성된 텍스트 파일입니다. " +
                      "현재 시간: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        byte[] fileBytes = Encoding.UTF8.GetBytes(content);

        return File(fileBytes, "text/plain", "generated_text.txt");
    }

    // GET: /DynamicFile/GetImageFromDatabase
    public IActionResult GetImageFromDatabase()
    {
        // 실제 시나리오에서는 DB에서 byte[]를 읽어옵니다.
        // 여기서는 예시를 위해 더미 바이트 배열을 사용합니다.
        byte[] imageBytes = new byte[] { /* ... PNG 이미지 바이트 데이터 ... */ };

        return File(imageBytes, "image/png", "db_image.png");
    }
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> VirtualFileResult</h3>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.mvc.virtualfileresult?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.mvc.virtualfileresult?view=aspnetcore-8.0</a></p>



<p><strong>웹 애플리케이션의 가상 경로(Virtual Path)</strong>를 사용하여 파일을 제공할 때 사용됩니다. </p>



<p>ASP.NET Core는 이 가상 경로를 실제 파일 시스템 경로로 변환하여 파일을 찾아 클라이언트에 스트리밍합니다.</p>



<ul class="wp-block-list">
<li><strong>정의</strong>: <br>Microsoft.AspNetCore.Mvc.VirtualFileResult</li>



<li><strong>데이터 원본</strong>: <br>웹 루트(wwwroot)를 기준으로 한 가상 경로</li>



<li><strong>메모리 사용</strong>: <br>낮음. 파일의 내용이 메모리에 한 번에 로드되지 않고, 스트림 방식으로 전송되므로 대용량 파일에도 적합합니다.</li>



<li><strong>성능</strong>: <br>효율적입니다.</li>
</ul>



<p><strong>주요 사용처</strong>:</p>



<ul class="wp-block-list">
<li>wwwroot 내의 정적 파일: 애플리케이션의 wwwroot 폴더 내에 있는 CSS, JavaScript, 이미지 등 정적 파일을 컨트롤러 액션 메서드에서 직접 제공해야 할 때 (예: 특정 인증/권한이 필요한 정적 파일).</li>



<li>StaticFileOptions로 구성된 가상 경로: UseStaticFiles 미들웨어 구성 시 RequestPath를 지정하여 만든 가상 경로에 있는 파일.</li>
</ul>



<p><strong>생성자 매개변수</strong>:</p>



<ul class="wp-block-list">
<li><code>string virtualPath</code>: 웹 루트를 기준으로 한 가상 경로 (예: ~/images/logo.png, /css/site.css).</li>



<li><code>string contentType</code>: 파일의 MIME 타입.</li>



<li><code>string? fileDownloadName</code> (선택 사항): 다운로드 시 파일 이름.</li>
</ul>



<p><strong>예시</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Mvc;

public class StaticAssetController : Controller
{
    // GET: /StaticAsset/GetAppStyle
    public IActionResult GetAppStyle()
    {
        // wwwroot/css/app.css 파일을 제공합니다.
        return File("~/css/app.css", "text/css");
    }

    // GET: /StaticAsset/DownloadSampleDocument
    public IActionResult DownloadSampleDocument()
    {
        // wwwroot/downloads/sample.pdf 파일을 다운로드합니다.
        return File("/downloads/sample.pdf", "application/pdf", "SampleDocument.pdf");
    }
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> PhysicalFileResult</h3>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.mvc.physicalfileresult?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.mvc.physicalfileresult?view=aspnetcore-8.0</a></p>



<p><strong>서버의 실제 파일 시스템 경로(Physical Path)</strong>를 사용하여 파일을 제공할 때 사용됩니다. </p>



<p>웹 애플리케이션의 <strong>루트 디렉토리를 벗어나 서버의 임의의 경로에 있는 파일을 제공해야 할 때 가장 유용</strong>합니다.</p>



<ul class="wp-block-list">
<li><strong>정의</strong>: <br>Microsoft.AspNetCore.Mvc.PhysicalFileResult</li>



<li><strong>데이터 원본</strong>: <br>서버의 실제 파일 시스템 경로 (절대 경로 또는 콘텐츠 루트 기준 상대 경로)</li>



<li><strong>메모리 사용</strong>: <br>낮음. VirtualFileResult와 마찬가지로 스트림 방식으로 전송되어 메모리 효율적입니다.</li>



<li><strong>성능</strong>: <br>효율적입니다.</li>
</ul>



<p><strong>주요 사용처</strong>:</p>



<ul class="wp-block-list">
<li>웹 루트 외부 파일: <strong>사용자가 업로드한 파일, 백업 파일, 또는 보안상의 이유로 wwwroot에 직접 노출되지 않는 폴더에 저장된 파일.</strong></li>



<li>서버의 특정 위치에 있는 파일: 애플리케이션과 독립적으로 관리되는 파일 저장소의 파일.</li>
</ul>



<p><strong>생성자 매개변수</strong>:</p>



<ul class="wp-block-list">
<li><code>string physicalPath</code>: 파일의 절대 경로 (예: &#8220;C:\Uploads\document.pdf&#8221;) 또는 애플리케이션의 콘텐츠 루트에 대한 상대 경로.</li>



<li><code>string contentType</code>: 파일의 MIME 타입.</li>



<li><code>string? fileDownloadName</code> (선택 사항): 다운로드 시 파일 이름.</li>
</ul>



<p><strong>주의사항: 사용자가 physicalPath를 직접 제어할 수 있는 경우 보안 취약점이 될 수 있습니다. 경로 유효성 검사 및 인가 처리가 필수적입니다.</strong></p>



<p><strong>예시</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Hosting; // IWebHostEnvironment를 사용하기 위해 필요

public class UploadedFileController : Controller
{
    private readonly IWebHostEnvironment _env;

    public UploadedFileController(IWebHostEnvironment env)
    {
        _env = env;
    }

    // GET: /UploadedFile/Download/{fileName}
    public IActionResult Download(string fileName)
    {
        // 업로드된 파일이 ContentRootPath/UserUploads 폴더에 저장되어 있다고 가정합니다.
        var filePath = Path.Combine(_env.ContentRootPath, "UserUploads", fileName);

        if (!System.IO.File.Exists(filePath))
        {
            return NotFound();
        }

        // 파일 확장자를 기반으로 MIME 타입 결정 (실제로는 더 견고한 로직 필요)
        string contentType;
        var ext = Path.GetExtension(fileName).ToLowerInvariant();
        if (ext == ".pdf") contentType = "application/pdf";
        else if (ext == ".jpg" || ext == ".jpeg") contentType = "image/jpeg";
        else contentType = "application/octet-stream"; // 기본값: 알 수 없는 파일

        return PhysicalFile(filePath, contentType, fileName);
    }
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> FileStreamResult (스트림 기반 파일 Serving)</h3>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.mvc.filestreamresult?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.mvc.filestreamresult?view=aspnetcore-8.0</a></p>



<p>FileStreamResult는 Stream 객체로부터 직접 파일을 제공할 때 사용됩니다.</p>



<p>이는 PhysicalFileResult나 VirtualFileResult와 마찬가지로 메모리 효율적이며, </p>



<p>파일이 이미 스트림 형태로 열려 있거나 외부 소스에서 스트림으로 직접 데이터를 읽어올 때 유용합니다.</p>



<ul class="wp-block-list">
<li><strong>정의</strong>: <br>Microsoft.AspNetCore.Mvc.FileStreamResult</li>



<li><strong>데이터 원본</strong>: <br>System.IO.Stream</li>



<li><strong>메모리 사용</strong>: <br>낮음. 파일 내용을 한 번에 메모리에 로드하지 않고 스트림에서 직접 읽어 전송합니다.</li>



<li><strong>성능</strong>: <br>효율적입니다.</li>
</ul>



<p><strong>주요 사용처</strong>:</p>



<ul class="wp-block-list">
<li>네트워크 스트림에서 직접 읽어온 데이터.</li>



<li>압축 파일 내부의 특정 파일을 스트림으로 추출하여 제공할 때.</li>



<li>데이터베이스에서 BLOB 데이터를 Stream으로 직접 가져올 때.</li>



<li>외부 API에서 스트림 형태로 응답을 받을 때.</li>
</ul>



<p><strong>생성자 매개변수</strong>:</p>



<ul class="wp-block-list">
<li><code>Stream fileStream</code>: 전송할 파일의 내용을 담고 있는 스트림.</li>



<li><code>string contentType</code>: 파일의 MIME 타입.</li>



<li><code>string? fileDownloadName</code> (선택 사항): 다운로드 시 파일 이름.</li>
</ul>



<p><strong>예시</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Mvc;
using System.IO;

public class StreamFileController : Controller
{
    // GET: /StreamFile/GetLogFile
    public IActionResult GetLogFile()
    {
        var logFilePath = Path.Combine(AppContext.BaseDirectory, "Logs", "application.log");
        if (!System.IO.File.Exists(logFilePath))
        {
            return NotFound();
        }
        // FileStream을 직접 열어 FileStreamResult로 반환
        var stream = new FileStream(logFilePath, FileMode.Open, FileAccess.Read);
        return File(stream, "text/plain", "application.log");
    }
}
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">2&#x20e3; 파일 처리 관련 기타 핵심 인터페이스 및 개념</h2>



<p>FileResult 유형 외에도 ASP.NET Core에서 파일을 효율적이고 안전하게 다루기 위해 알아야 할 중요한 인터페이스와 개념들이 있습니다.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> IFormFile 및 IFormFileCollection (파일 업로드)</h3>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.http.iformfile?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.http.iformfile?view=aspnetcore-8.0</a></p>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.http.iformfilecollection?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.http.iformfilecollection?view=aspnetcore-8.0</a></p>



<p>클라이언트(브라우저)에서 서버로 파일을 전송할 때 사용하는 인터페이스입니다.</p>



<ul class="wp-block-list">
<li><strong>IFormFile</strong>: 단일 업로드 파일을 나타냅니다.
<ul class="wp-block-list">
<li><strong>정의</strong>: Microsoft.AspNetCore.Http.IFormFile</li>



<li><strong>주요 속성</strong>: FileName, ContentType, Length.</li>



<li><strong>주요 메서드</strong>: CopyToAsync(Stream), OpenReadStream().</li>
</ul>
</li>



<li><strong>IFormFileCollection</strong>: 여러 개의 업로드 파일을 나타내는 IFormFile 객체의 컬렉션입니다.
<ul class="wp-block-list">
<li><strong>정의</strong>: Microsoft.AspNetCore.Http.IFormFileCollection</li>



<li><strong>사용 예시</strong>: <code>&lt;input type="file" multiple&gt;</code> 폼 요소로 여러 파일을 받을 때 컨트롤러 액션의 매개변수로 사용됩니다.</li>
</ul>
</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> IWebHostEnvironment 및 IHostEnvironment (환경 정보 및 경로)</h3>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.hosting.iwebhostenvironment?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.hosting.iwebhostenvironment?view=aspnetcore-8.0</a></p>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.components.routing.ihostenvironmentnavigationmanager?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.components.routing.ihostenvironmentnavigationmanager?view=aspnetcore-8.0</a></p>



<p>애플리케이션의 호스팅 환경에 대한 정보를 제공하여, 파일 경로를 구성하고 접근할 때 매우 유용합니다. 이들은 DI 컨테이너에 등록되어 있어 생성자를 통해 쉽게 주입받을 수 있습니다.</p>



<ul class="wp-block-list">
<li><strong>IWebHostEnvironment</strong>: 웹 호스팅 환경에 특화된 정보를 제공합니다.
<ul class="wp-block-list">
<li><strong>정의</strong>: Microsoft.AspNetCore.Hosting.IWebHostEnvironment</li>



<li><strong>주요 속성</strong>:
<ul class="wp-block-list">
<li><code>WebRootPath</code>: 웹 루트(wwwroot) 폴더의 물리적 경로. 정적 파일이 위치하는 곳입니다.</li>



<li><code>WebRootFileProvider</code>: WebRootPath에 대한 IFileProvider 인스턴스.</li>
</ul>
</li>



<li><strong>주요 사용처</strong>: 정적 파일 저장 경로, 웹에 노출될 리소스 경로 구성.</li>
</ul>
</li>



<li><strong>IHostEnvironment</strong>: 일반적인 호스팅 환경 정보를 제공합니다. IWebHostEnvironment는 IHostEnvironment를 상속합니다.
<ul class="wp-block-list">
<li><strong>정의</strong>: Microsoft.Extensions.Hosting.IHostEnvironment</li>



<li><strong>주요 속성</strong>:
<ul class="wp-block-list">
<li><code>ContentRootPath</code>: 애플리케이션의 콘텐츠 루트 폴더(프로젝트 파일이 있는 기본 디렉토리)의 물리적 경로.</li>



<li><code>ContentRootFileProvider</code>: ContentRootPath에 대한 IFileProvider 인스턴스.</li>



<li><code>EnvironmentName</code>: 현재 실행 중인 환경의 이름 (예: &#8220;Development&#8221;, &#8220;Production&#8221;, &#8220;Staging&#8221;).</li>
</ul>
</li>



<li><strong>주요 사용처</strong>: 로그 파일, 설정 파일 등 애플리케이션이 사용하는 비-웹 관련 파일 경로 구성.</li>
</ul>
</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> IFileProvider (추상화된 파일 시스템 접근)</h3>



<p>파일 시스템 접근을 추상화하는 핵심 인터페이스입니다. </p>



<p>물리적인 디스크, 메모리, 압축 파일 등 다양한 소스에서 파일을 일관된 방식으로 다룰 수 있게 해줍니다.</p>



<ul class="wp-block-list">
<li><strong>정의</strong>: Microsoft.Extensions.FileProviders.IFileProvider</li>



<li><strong>주요 역할</strong>: 파일 존재 여부 확인, 디렉토리 내용 열거, 파일 내용 스트림 생성 등 파일 시스템 작업을 수행합니다. UseStaticFiles 미들웨어, Razor Pages 등에서 내부적으로 사용됩니다.</li>



<li><strong>주요 메서드</strong>:
<ul class="wp-block-list">
<li><code>GetFileInfo(string subpath)</code>: 지정된 하위 경로의 파일 또는 디렉토리에 대한 IFileInfo 객체를 반환합니다.</li>



<li><code>GetDirectoryContents(string subpath)</code>: 지정된 하위 경로의 디렉토리 콘텐츠(IDirectoryContents)를 반환합니다.</li>



<li><code>Watch(string filter)</code>: 지정된 필터와 일치하는 파일 또는 디렉토리의 변경 사항을 감시합니다 (예: 파일 변경 시 캐시 무효화).</li>
</ul>
</li>



<li><strong>주요 구현체</strong>:
<ul class="wp-block-list">
<li><code>PhysicalFileProvider</code>: 실제 파일 시스템 경로에서 파일을 제공합니다.</li>



<li><code>CompositeFileProvider</code>: 여러 IFileProvider를 결합하여 여러 위치에서 파일을 찾을 수 있게 합니다.</li>
</ul>
</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> IFileInfo 및 IDirectoryContents (파일/디렉토리 메타데이터)</h3>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.mvc.razor.runtimecompilation.fileproviderrazorprojectitem.fileinfo?view=aspnetcore-8.0#microsoft-aspnetcore-mvc-razor-runtimecompilation-fileproviderrazorprojectitem-fileinfo" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/microsoft.aspnetcore.mvc.razor.runtimecompilation.fileproviderrazorprojectitem.fileinfo?view=aspnetcore-8.0#microsoft-aspnetcore-mvc-razor-runtimecompilation-fileproviderrazorprojectitem-fileinfo</a></p>



<p>IFileProvider와 함께 사용되어 파일 시스템 항목의 상세 정보를 제공합니다.</p>



<ul class="wp-block-list">
<li><strong>IFileInfo</strong>: 단일 파일 또는 디렉토리에 대한 메타데이터 (이름, 크기, 수정 시간, 존재 여부 등)를 제공합니다. IFileProvider.GetFileInfo()가 반환합니다.</li>



<li><strong>IDirectoryContents</strong>: 디렉토리 내의 파일 및 서브디렉토리 목록을 나타냅니다. IFileProvider.GetDirectoryContents()가 반환하며, IEnumerable&lt;IFileInfo&gt;를 구현합니다.</li>
</ul>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">3&#x20e3; 고급 파일 처리 기능</h2>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 파일 업로드 보안 강화</h3>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 파일 시그니처 검증</h4>



<p>파일 확장자만으로는 안전하지 않으며, 파일 시그니처(매직 바이트) 검증이 필요합니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">public static class FileSignatureValidator
{
    private static readonly Dictionary&lt;string, byte[][]> FileSignatures = new()
    {
        { ".jpg", new[] { new byte[] { 0xFF, 0xD8, 0xFF } } },
        { ".jpeg", new[] { new byte[] { 0xFF, 0xD8, 0xFF } } },
        { ".png", new[] { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } } },
        { ".pdf", new[] { new byte[] { 0x25, 0x50, 0x44, 0x46 } } },
        { ".gif", new[] { new byte[] { 0x47, 0x49, 0x46, 0x38 } } }
    };

    public static bool IsValidFileSignature(IFormFile file, string[] allowedExtensions)
    {
        if (file.Length == 0) return false;

        var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
        if (!allowedExtensions.Contains(ext) || !FileSignatures.ContainsKey(ext))
            return false;

        using var reader = new BinaryReader(file.OpenReadStream());
        var signatures = FileSignatures[ext];
        var headerBytes = reader.ReadBytes(signatures.Max(s => s.Length));

        return signatures.Any(signature => 
            headerBytes.Take(signature.Length).SequenceEqual(signature));
    }
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 커스텀 파일 검증 어트리뷰트</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">public class AllowedExtensionsAttribute : ValidationAttribute
{
    private readonly string[] _extensions;

    public AllowedExtensionsAttribute(params string[] extensions)
    {
        _extensions = extensions;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value is IFormFile file)
        {
            if (!FileSignatureValidator.IsValidFileSignature(file, _extensions))
            {
                return new ValidationResult("허용되지 않는 파일 형식입니다.");
            }
        }
        return ValidationResult.Success;
    }
}

public class MaxFileSizeAttribute : ValidationAttribute
{
    private readonly int _maxFileSize;

    public MaxFileSizeAttribute(int maxFileSize)
    {
        _maxFileSize = maxFileSize;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value is IFormFile file &amp;&amp; file.Length > _maxFileSize)
        {
            return new ValidationResult($"파일 크기는 {_maxFileSize / (1024 * 1024)}MB를 초과할 수 없습니다.");
        }
        return ValidationResult.Success;
    }
}

// 사용 예시
public class FileUploadModel
{
    [AllowedExtensions(".jpg", ".jpeg", ".png", ".pdf")]
    [MaxFileSize(5 * 1024 * 1024)] // 5MB
    public IFormFile UploadedFile { get; set; }
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 대용량 파일 처리 최적화</h3>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 스트리밍 업로드</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[HttpPost]
[DisableFormValueModelBinding]
public async Task&lt;IActionResult> UploadLargeFile()
{
    if (!IsMultipartContentType(Request.ContentType))
        return BadRequest("지원하지 않는 미디어 타입입니다.");

    var boundary = GetBoundary(Request.ContentType);
    var reader = new MultipartReader(boundary, HttpContext.Request.Body);
    var section = await reader.ReadNextSectionAsync();

    while (section != null)
    {
        if (ContentDispositionHeaderValue.TryParse(section.ContentDisposition, 
            out var contentDisposition))
        {
            if (HasFileContentDisposition(contentDisposition))
            {
                var fileName = contentDisposition.FileName.Value;
                var filePath = Path.Combine("uploads", fileName);
                
                using var targetStream = new FileStream(filePath, FileMode.Create);
                await section.Body.CopyToAsync(targetStream);
            }
        }
        section = await reader.ReadNextSectionAsync();
    }

    return Ok("파일 업로드 완료");
}

private static bool IsMultipartContentType(string contentType)
{
    return !string.IsNullOrEmpty(contentType) 
           &amp;&amp; contentType.IndexOf("multipart/", StringComparison.OrdinalIgnoreCase) >= 0;
}

private static string GetBoundary(string contentType)
{
    var elements = contentType.Split(' ');
    var element = elements.Where(entry => entry.StartsWith("boundary=")).First();
    var boundary = element.Substring("boundary=".Length);
    return HeaderUtilities.RemoveQuotes(boundary).Value;
}

private static bool HasFileContentDisposition(ContentDispositionHeaderValue contentDisposition)
{
    return contentDisposition != null
           &amp;&amp; contentDisposition.DispositionType.Equals("form-data")
           &amp;&amp; (!StringSegment.IsNullOrEmpty(contentDisposition.FileName)
               || !StringSegment.IsNullOrEmpty(contentDisposition.FileNameStar));
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Range Request 지원 (부분 콘텐츠 전송)</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">public IActionResult DownloadWithRangeSupport(string fileName)
{
    var filePath = Path.Combine("uploads", fileName);
    if (!System.IO.File.Exists(filePath))
        return NotFound();

    var fileInfo = new FileInfo(filePath);
    var rangeHeader = Request.Headers["Range"].ToString();

    if (!string.IsNullOrEmpty(rangeHeader))
    {
        // Range 요청 처리
        var range = ParseRangeHeader(rangeHeader, fileInfo.Length);
        if (range.HasValue)
        {
            var (start, end) = range.Value;
            var contentLength = end - start + 1;

            Response.StatusCode = 206; // Partial Content
            Response.Headers.Add("Content-Range", $"bytes {start}-{end}/{fileInfo.Length}");
            Response.Headers.Add("Content-Length", contentLength.ToString());

            var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            stream.Seek(start, SeekOrigin.Begin);
            
            return File(stream, "application/octet-stream", fileName, enableRangeProcessing: true);
        }
    }

    return PhysicalFile(filePath, "application/octet-stream", fileName);
}

private (long start, long end)? ParseRangeHeader(string rangeHeader, long fileLength)
{
    if (!rangeHeader.StartsWith("bytes="))
        return null;

    var range = rangeHeader.Substring(6);
    var parts = range.Split('-');
    
    if (parts.Length != 2)
        return null;

    long start = 0, end = fileLength - 1;

    if (!string.IsNullOrEmpty(parts[0]))
        start = long.Parse(parts[0]);

    if (!string.IsNullOrEmpty(parts[1]))
        end = long.Parse(parts[1]);

    if (start > end || start >= fileLength)
        return null;

    return (start, Math.Min(end, fileLength - 1));
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 임시 파일 관리 및 정리</h3>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 임시 파일 자동 정리 서비스</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">public class TempFileCleanupService : BackgroundService
{
    private readonly ILogger&lt;TempFileCleanupService> _logger;
    private readonly string _tempDirectory;

    public TempFileCleanupService(ILogger&lt;TempFileCleanupService> logger, IWebHostEnvironment env)
    {
        _logger = logger;
        _tempDirectory = Path.Combine(env.ContentRootPath, "temp");
        
        // 임시 디렉토리가 존재하지 않으면 생성
        if (!Directory.Exists(_tempDirectory))
        {
            Directory.CreateDirectory(_tempDirectory);
        }
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                CleanupOldTempFiles();
                await Task.Delay(TimeSpan.FromHours(1), stoppingToken);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "임시 파일 삭제 실패: {FilePath}", file);
            }
        }
    }
}

// Program.cs에서 서비스 등록
builder.Services.AddHostedService&lt;TempFileCleanupService>();
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 파일 압축 및 최적화</h3>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 이미지 자동 리사이징</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Formats.Jpeg;

public class ImageProcessingResult : FileStreamResult
{
    public ImageProcessingResult(Stream imageStream, string contentType, int maxWidth = 800, int maxHeight = 600)
        : base(ProcessImage(imageStream, maxWidth, maxHeight), contentType)
    {
    }

    private static Stream ProcessImage(Stream originalStream, int maxWidth, int maxHeight)
    {
        using var image = Image.Load(originalStream);
        
        if (image.Width > maxWidth || image.Height > maxHeight)
        {
            image.Mutate(x => x.Resize(new ResizeOptions
            {
                Size = new Size(maxWidth, maxHeight),
                Mode = ResizeMode.Max
            }));
        }

        var outputStream = new MemoryStream();
        image.SaveAsJpeg(outputStream, new JpegEncoder { Quality = 85 });
        outputStream.Position = 0;
        
        return outputStream;
    }
}

// 사용 예시
public IActionResult GetOptimizedImage(string fileName)
{
    var filePath = Path.Combine("images", fileName);
    if (!System.IO.File.Exists(filePath))
        return NotFound();
        
    var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
    
    return new ImageProcessingResult(stream, "image/jpeg");
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 파일 메타데이터 및 추적</h3>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 파일 메타데이터 모델</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">public class FileMetadata
{
    public string Id { get; set; } = Guid.NewGuid().ToString();
    public string OriginalName { get; set; }
    public string StoredName { get; set; }
    public string ContentType { get; set; }
    public long Size { get; set; }
    public string Hash { get; set; } // SHA256 해시
    public DateTime UploadedAt { get; set; } = DateTime.UtcNow;
    public string UploadedBy { get; set; }
    public int DownloadCount { get; set; }
    public DateTime? LastAccessedAt { get; set; }
}

public class SecureFileService
{
    private readonly ILogger&lt;SecureFileService> _logger;
    private readonly string _uploadDirectory;
    private readonly Dictionary&lt;string, FileMetadata> _fileMetadata = new();

    public SecureFileService(ILogger&lt;SecureFileService> logger, IWebHostEnvironment env)
    {
        _logger = logger;
        _uploadDirectory = Path.Combine(env.ContentRootPath, "SecureUploads");
        
        if (!Directory.Exists(_uploadDirectory))
        {
            Directory.CreateDirectory(_uploadDirectory);
        }
    }

    public async Task&lt;FileMetadata> SaveFileAsync(IFormFile file, string userId)
    {
        // 파일 시그니처 검증
        var allowedExtensions = new[] { ".jpg", ".jpeg", ".png", ".pdf", ".docx", ".xlsx" };
        if (!FileSignatureValidator.IsValidFileSignature(file, allowedExtensions))
        {
            throw new InvalidOperationException("허용되지 않는 파일 형식입니다.");
        }

        var metadata = new FileMetadata
        {
            OriginalName = file.FileName,
            StoredName = $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}",
            ContentType = file.ContentType,
            Size = file.Length,
            UploadedBy = userId
        };

        var filePath = Path.Combine(_uploadDirectory, metadata.StoredName);
        
        // 파일 저장
        using (var stream = new FileStream(filePath, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }

        // 파일 해시 계산
        metadata.Hash = await ComputeFileHashAsync(filePath);
        
        // 메타데이터 저장
        _fileMetadata[metadata.Id] = metadata;
        
        _logger.LogInformation("파일 저장 완료: {FileName} ({FileId})", 
            metadata.OriginalName, metadata.Id);
        
        return metadata;
    }

    public async Task&lt;(Stream stream, FileMetadata metadata)> GetFileAsync(string fileId)
    {
        if (!_fileMetadata.TryGetValue(fileId, out var metadata))
        {
            throw new FileNotFoundException("파일을 찾을 수 없습니다.");
        }

        var filePath = Path.Combine(_uploadDirectory, metadata.StoredName);
        if (!System.IO.File.Exists(filePath))
        {
            throw new FileNotFoundException("물리적 파일이 존재하지 않습니다.");
        }

        // 다운로드 통계 업데이트
        metadata.DownloadCount++;
        metadata.LastAccessedAt = DateTime.UtcNow;

        var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        return (stream, metadata);
    }

    private async Task&lt;string> ComputeFileHashAsync(string filePath)
    {
        using var sha256 = SHA256.Create();
        using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        var hash = await sha256.ComputeHashAsync(stream);
        return Convert.ToBase64String(hash);
    }

    public bool DeleteFile(string fileId, string userId)
    {
        if (!_fileMetadata.TryGetValue(fileId, out var metadata))
        {
            return false;
        }

        // 권한 확인
        if (metadata.UploadedBy != userId)
        {
            throw new UnauthorizedAccessException("파일 삭제 권한이 없습니다.");
        }

        var filePath = Path.Combine(_uploadDirectory, metadata.StoredName);
        
        try
        {
            if (System.IO.File.Exists(filePath))
            {
                System.IO.File.Delete(filePath);
            }
            
            _fileMetadata.Remove(fileId);
            
            _logger.LogInformation("파일 삭제 완료: {FileName} ({FileId})", 
                metadata.OriginalName, fileId);
            
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "파일 삭제 실패: {FileName} ({FileId})", 
                metadata.OriginalName, fileId);
            return false;
        }
    }
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 에러 처리 및 로깅</h3>



<h4 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 포괄적인 파일 에러 처리</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">public class FileController : Controller
{
    private readonly ILogger&lt;FileController> _logger;
    private readonly SecureFileService _fileService;

    public FileController(ILogger&lt;FileController> logger, SecureFileService fileService)
    {
        _logger = logger;
        _fileService = fileService;
    }

    [HttpPost]
    public async Task&lt;IActionResult> Upload(IFormFile file)
    {
        try
        {
            if (file == null || file.Length == 0)
                return BadRequest(new { error = "파일이 선택되지 않았습니다." });

            if (file.Length > 10 * 1024 * 1024) // 10MB
                return BadRequest(new { error = "파일 크기가 10MB를 초과합니다." });

            // 파일명 검증 (경로 조작 공격 방지)
            var fileName = Path.GetFileName(file.FileName);
            if (string.IsNullOrEmpty(fileName) || fileName.Contains(".."))
                return BadRequest(new { error = "유효하지 않은 파일명입니다." });

            var result = await _fileService.SaveFileAsync(file, User.Identity.Name);
            
            _logger.LogInformation("파일 업로드 성공: {FileName}, 사용자: {User}, 파일ID: {FileId}", 
                file.FileName, User.Identity.Name, result.Id);

            return Ok(new { 
                fileId = result.Id, 
                fileName = result.OriginalName,
                size = result.Size,
                message = "파일 업로드 완료" 
            });
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("파일 업로드 유효성 검사 실패: {FileName}, 오류: {Error}", 
                file?.FileName, ex.Message);
            return BadRequest(new { error = ex.Message });
        }
        catch (IOException ex)
        {
            _logger.LogError(ex, "파일 I/O 오류: {FileName}", file?.FileName);
            return StatusCode(500, new { error = "파일 저장 중 오류가 발생했습니다." });
        }
        catch (UnauthorizedAccessException ex)
        {
            _logger.LogError(ex, "파일 접근 권한 오류: {FileName}", file?.FileName);
            return StatusCode(500, new { error = "파일 접근 권한이 없습니다." });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "예상치 못한 오류: {FileName}", file?.FileName);
            return StatusCode(500, new { error = "파일 처리 중 오류가 발생했습니다." });
        }
    }

    [HttpGet("{fileId}")]
    public async Task&lt;IActionResult> Download(string fileId)
    {
        try
        {
            var (stream, metadata) = await _fileService.GetFileAsync(fileId);
            
            _logger.LogInformation("파일 다운로드: {FileName} ({FileId}), 사용자: {User}", 
                metadata.OriginalName, fileId, User.Identity.Name);

            return File(stream, metadata.ContentType, metadata.OriginalName);
        }
        catch (FileNotFoundException ex)
        {
            _logger.LogWarning("파일 다운로드 실패 - 파일 없음: {FileId}, 사용자: {User}", 
                fileId, User.Identity.Name);
            return NotFound(new { error = "파일을 찾을 수 없습니다." });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "파일 다운로드 오류: {FileId}", fileId);
            return StatusCode(500, new { error = "파일 다운로드 중 오류가 발생했습니다." });
        }
    }

    [HttpDelete("{fileId}")]
    public IActionResult Delete(string fileId)
    {
        try
        {
            var success = _fileService.DeleteFile(fileId, User.Identity.Name);
            
            if (!success)
                return NotFound(new { error = "파일을 찾을 수 없습니다." });

            return Ok(new { message = "파일이 삭제되었습니다." });
        }
        catch (UnauthorizedAccessException ex)
        {
            _logger.LogWarning("파일 삭제 권한 없음: {FileId}, 사용자: {User}", 
                fileId, User.Identity.Name);
            return Forbid("파일 삭제 권한이 없습니다.");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "파일 삭제 오류: {FileId}", fileId);
            return StatusCode(500, new { error = "파일 삭제 중 오류가 발생했습니다." });
        }
    }
}
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">4&#x20e3; 파일 처리 시 보안 및 성능 고려사항</h2>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 보안 고려사항</h3>



<ol class="wp-block-list">
<li><strong>경로 유효성 검사</strong>: <br>PhysicalFileResult나 파일 업로드 시 사용자가 제공한 파일 이름/경로에 대해 경로 조작(Path Traversal) 공격을 방지하기 위해 철저한 유효성 검사를 수행해야 합니다. <br><code>Path.GetFullPath()</code>, <code>Path.GetFileName()</code> 등을 사용하여 안전한 경로를 구성하고, 허용된 디렉토리 내에만 파일을 저장하도록 제한해야 합니다.</li>



<li><strong>MIME 타입</strong>: <br>올바른 Content-Type을 지정하여 브라우저가 파일을 올바르게 해석하고, 잠재적인 스크립트 실행 공격을 방지합니다. <br><code>FileExtensionContentTypeProvider</code>와 같은 클래스를 사용하여 MIME 타입을 자동으로 추론하는 것이 좋습니다.</li>



<li><strong>파일 시그니처 검증</strong>: <br>파일 확장자만으로는 안전하지 않으므로, 파일의 매직 바이트(시그니처)를 검증하여 실제 파일 형식을 확인해야 합니다.</li>



<li><strong>파일 크기 제한</strong>: <br>서비스 거부 공격을 방지하기 위해 업로드 파일 크기를 제한해야 합니다.</li>



<li><strong>바이러스 스캔</strong>: <br>중요한 시스템에서는 업로드된 파일에 대한 바이러스 검사를 수행해야 합니다.</li>
</ol>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 성능 고려사항</h3>



<ol class="wp-block-list">
<li><strong>대용량 파일</strong>: <br>큰 파일은 <code>byte[]</code>로 메모리에 로드하는 <code>FileContentResult</code> 대신, 스트림 기반의 <code>VirtualFileResult</code>, <code>PhysicalFileResult</code>, <code>FileStreamResult</code>를 사용하여 메모리 사용량을 최소화해야 합니다.</li>



<li><strong>캐싱</strong>: <br><code>UseStaticFiles</code> 미들웨어의 <code>StaticFileOptions.OnPrepareResponse</code>를 사용하여 Cache-Control 헤더를 설정하거나, <code>ResponseCaching</code> 미들웨어를 사용하여 캐싱 전략을 최적화할 수 있습니다.</li>



<li><strong>응답 압축</strong>: <br><code>UseResponseCompression</code> 미들웨어를 사용하여 정적 파일 및 동적 응답을 gzip, brotli 등으로 압축하여 네트워크 대역폭 사용을 줄이고 로딩 속도를 향상시킬 수 있습니다.</li>



<li><strong>스트리밍 처리</strong>: <br>대용량 파일 업로드/다운로드 시 전체 파일을 메모리에 로드하지 않고 스트림으로 처리하여 메모리 효율성을 높입니다.</li>



<li><strong>비동기 처리</strong>: <br>파일 I/O 작업은 항상 비동기 메서드(<code>CopyToAsync</code>, <code>ReadAsync</code> 등)를 사용하여 스레드 풀을 효율적으로 활용합니다.</li>
</ol>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">5&#x20e3; 프로덕션 환경 설정</h2>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Program.cs 설정 예시</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var builder = WebApplication.CreateBuilder(args);

// 서비스 등록
builder.Services.AddControllers();
builder.Services.AddScoped&lt;SecureFileService>();
builder.Services.AddHostedService&lt;TempFileCleanupService>();

// 파일 업로드 설정
builder.Services.Configure&lt;FormOptions>(options =>
{
    options.MultipartBodyLengthLimit = 100 * 1024 * 1024; // 100MB
    options.ValueLengthLimit = int.MaxValue;
    options.ValueCountLimit = int.MaxValue;
    options.KeyLengthLimit = int.MaxValue;
});

// 응답 압축 설정
builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add&lt;BrotliCompressionProvider>();
    options.Providers.Add&lt;GzipCompressionProvider>();
});

var app = builder.Build();

// 미들웨어 파이프라인
app.UseResponseCompression();
app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        // 정적 파일 캐싱 설정
        ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=31536000");
    }
});

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

app.Run();
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 로깅 설정 (appsettings.json)</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="json" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "FileController": "Information",
      "SecureFileService": "Information",
      "TempFileCleanupService": "Information"
    }
  }
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">6&#x20e3; 결론</h2>



<p>ASP.NET Core의 이러한 다양한 파일 처리 도구와 개념을 이해하고 적절히 활용하는 것은 견고하고 효율적인 웹 애플리케이션을 구축하는 데 필수적입니다. </p>



<p>특히 보안, 성능, 사용자 경험을 모두 고려한 파일 처리 시스템을 구축하기 위해서는:</p>



<ol class="wp-block-list">
<li><strong>적절한 FileResult 선택</strong>: 파일의 특성과 사용 목적에 따라 최적의 FileResult 유형을 선택</li>



<li><strong>강력한 보안 검증</strong>: 파일 시그니처 검증, 경로 조작 방지, 크기 제한 등 다층적 보안 적용</li>



<li><strong>성능 최적화</strong>: 스트리밍 처리, 캐싱, 압축 등을 통한 성능 향상</li>



<li><strong>포괄적인 에러 처리</strong>: 예상 가능한 모든 오류 상황에 대한 적절한 처리와 로깅</li>



<li><strong>사용자 경험 고려</strong>: Range Request 지원, 진행률 표시, 적절한 피드백 제공</li>
</ol>



<p>이러한 원칙들을 따라 구현하면 안전하고 효율적이며 사용자 친화적인 파일 처리 시스템을 구축할 수 있습니다.</p>
<p>The post <a href="https://lycos7560.com/c/asp-net/asp-net-core-%ed%8c%8c%ec%9d%bc-%ec%b2%98%eb%a6%ac-fileresult-%eb%b0%8f-%ec%9d%b8%ed%84%b0%ed%8e%98%ec%9d%b4%ec%8a%a4/40149/">ASP.NET Core 파일 처리: FileResult 및 인터페이스</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/asp-net/asp-net-core-%ed%8c%8c%ec%9d%bc-%ec%b2%98%eb%a6%ac-fileresult-%eb%b0%8f-%ec%9d%b8%ed%84%b0%ed%8e%98%ec%9d%b4%ec%8a%a4/40149/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Dependency Inversion Principle(DIP, 의존성 역전 원리)</title>
		<link>https://lycos7560.com/c/dependency-inversion-principledip-%ec%9d%98%ec%a1%b4%ec%84%b1-%ec%97%ad%ec%a0%84-%ec%9b%90%eb%a6%ac/38731/</link>
					<comments>https://lycos7560.com/c/dependency-inversion-principledip-%ec%9d%98%ec%a1%b4%ec%84%b1-%ec%97%ad%ec%a0%84-%ec%9b%90%eb%a6%ac/38731/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Sun, 03 Nov 2024 07:48:04 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Blazor]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[.Net Core]]></category>
		<category><![CDATA[AddModelError]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Consuming]]></category>
		<category><![CDATA[Controller]]></category>
		<category><![CDATA[Create]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Data access logic]]></category>
		<category><![CDATA[DataBase]]></category>
		<category><![CDATA[DbContext]]></category>
		<category><![CDATA[DbSet]]></category>
		<category><![CDATA[DELETE]]></category>
		<category><![CDATA[Dependency]]></category>
		<category><![CDATA[Dependency Inversion]]></category>
		<category><![CDATA[Deploying]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[DIP]]></category>
		<category><![CDATA[Domain]]></category>
		<category><![CDATA[Domain Model]]></category>
		<category><![CDATA[File]]></category>
		<category><![CDATA[FileDescription]]></category>
		<category><![CDATA[Filestream]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[IFormFile]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Image Controller]]></category>
		<category><![CDATA[IsValid]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[ModelState]]></category>
		<category><![CDATA[pepe]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[program]]></category>
		<category><![CDATA[Program.cs]]></category>
		<category><![CDATA[PUT]]></category>
		<category><![CDATA[Repository]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[REST Web API]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Upload]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[web API]]></category>
		<category><![CDATA[wpf]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[의존성]]></category>
		<category><![CDATA[의존성 역전]]></category>
		<category><![CDATA[의존성 역전 원리]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=38731</guid>

					<description><![CDATA[<p>Dependency Inversion Principle(DIP, 의존성 역전 원리) https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/architectural-principles#dependency-inversion The direction of dependency within the application should be in the direction of abstraction, not implementation details.애플리케이션 내의 종속성 방향은 구현 세부 사항이 아닌 추상화 방향이어야 합니다. Most applications are written such that compile-time dependency flows in the direction of runtime execution, producing a direct dependency graph.대부분의 애플리케이션은 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/dependency-inversion-principledip-%ec%9d%98%ec%a1%b4%ec%84%b1-%ec%97%ad%ec%a0%84-%ec%9b%90%eb%a6%ac/38731/">Dependency Inversion Principle(DIP, 의존성 역전 원리)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="dependency-inversion">Dependency Inversion Principle(DIP, 의존성 역전 원리)</h2>



<p><a href="https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/architectural-principles#dependency-inversion" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/architectural-principles#dependency-inversion</a></p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p>The direction of dependency within the application should be in the direction of abstraction, not implementation details.<br>애플리케이션 내의 종속성 방향은 구현 세부 사항이 아닌 추상화 방향이어야 합니다. <br>Most applications are written such that compile-time dependency flows in the direction of runtime execution, producing a direct dependency graph.<br>대부분의 애플리케이션은 컴파일 타임 종속성이 런타임 실행 방향으로 흐르도록 작성되어 직접적인 종속성 그래프를 생성합니다.</p>



<p>That is, if class A calls a method of class B and class B calls a method of class C, then at compile time class A will depend on class B, and class B will depend on class C.<br>즉, class A가 class B의 메서드를 호출하고 class B가 class C의 메서드를 호출하는 경우 컴파일 타임에 class A는 class B에 종속되고 class B는 class C에 종속됩니다.</p>



<p>코드 구조에서 세부 구현 내용에 의존하지 말고, 더 추상적이고 일반적인 개념에 의존해야 한다는 뜻<br>이렇게 하면 코드가 더 유연해지고, 변경하기 쉽고, 재사용하기도 쉬워진다.<br>예를 들어, 어떤 기능을 <strong>직접 호출하는 것보다 그 기능을 일반적으로 설명하는 인터페이스를 사용하는 것이 더 좋다는 의미</strong>)</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="669" height="556" src="https://lycos7560.com/wp-content/uploads/2024/11/image-73.png" alt="" class="wp-image-38735" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-73.png 669w, https://lycos7560.com/wp-content/uploads/2024/11/image-73-300x249.png 300w" sizes="(max-width: 669px) 100vw, 669px" /><figcaption class="wp-element-caption">Direct dependency graph.</figcaption></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Applying the dependency inversion principle allows A to call methods on an abstraction that B implements, making it possible for A to call B at run time, but for B to depend on an interface controlled by A at compile time (thus,&nbsp;<em>inverting</em>&nbsp;the typical compile-time dependency).<br>종속성 반전 원칙을 적용하면 A가 B가 구현하는 추상화에 대한 메서드를 호출할 수 있으므로 A가 런타임에 B를 호출할 수 있지만 B는 컴파일 타임에 A에 의해 제어되는 인터페이스에 의존할 수 있습니다<br>(따라서 일반적인 컴파일 타임 종속성을&nbsp;<em>반전시킵니다</em>).&nbsp;</p>



<p>At run time, the flow of program execution remains unchanged, but the introduction of interfaces means that different implementations of these interfaces can easily be plugged in.<br>런타임에 프로그램 실행의 흐름은 변경되지 않지만 인터페이스의 도입은 이러한 인터페이스의 다른 구현을 쉽게 연결할 수 있음을 의미합니다.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="838" height="455" src="https://lycos7560.com/wp-content/uploads/2024/11/image-74.png" alt="" class="wp-image-38736" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-74.png 838w, https://lycos7560.com/wp-content/uploads/2024/11/image-74-300x163.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-74-768x417.png 768w" sizes="(max-width: 838px) 100vw, 838px" /><figcaption class="wp-element-caption">Inverted dependency graph.</figcaption></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Dependency inversion</strong>&nbsp;is a key part of building loosely coupled applications, since implementation details can be written to depend on and implement higher-level abstractions, rather than the other way around.<br><strong>종속성 반전</strong>은 느슨하게 결합된 애플리케이션을 구축하는 데 있어 중요한 부분인데, 그 이유는 구현 세부 정보를 작성하여 더 높은 수준의 추상화에 의존하고 구현하도록 할 수 있기 때문입니다.</p>



<p>The resulting applications are more testable, modular, and maintainable as a result.<br>그 결과 응용 프로그램은 더 쉽게 테스트할 수 있고, 모듈화되며, 유지 관리가 더 용이합니다.&nbsp;</p>



<p>The practice of&nbsp;<em>dependency injection</em>&nbsp;is made possible by following the dependency inversion principle.<br><em>종속성 주입</em>의 연습은 종속성 반전 원칙을 따름으로써 가능합니다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--20);margin-bottom:var(--wp--preset--spacing--20)"/>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p>애플리케이션의 의존성을 구체적인 구현이 아니라 추상화된 개념에 맞추는 것</p>



<p>대부분의 애플리케이션은 A 클래스가 B 클래스를, B 클래스가 C 클래스를 호출하는 형태로 작성됩니다. </p>



<p>이는 A가 B에, B가 C에 의존하게 만든다는 뜻입니다. 종속성 반전 원칙을 적용하면 A는 B의 구체적인 구현이 아니라 B가 구현하는 추상 개념에 의존하게 됩니다. </p>



<p>이렇게 하면 코드를 더 쉽게 테스트할 수 있고, 변경 및 유지보수가 용이해집니다. </p>



<p>간단히 말해, 코드를 유연하고 재사용 가능하게 만들어줍니다.</p>



<div style="height:102px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>종속성 반전 적용 전</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 엔진 클래스
public class Engine
{
    public void Start()
    {
        Console.WriteLine("Engine starts.");
    }
}

// 자동차 클래스
public class Car
{
    private Engine _engine = new Engine();

    public void Start()
    {
        _engine.Start();
        Console.WriteLine("Car starts.");
    }
}

// 메인 프로그램
public class Program
{
    public static void Main(string[] args)
    {
        Car car = new Car();
        car.Start();
    }
}
</pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>종속성 반전 적용 후</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 인터페이스 정의
public interface IEngine
{
    void Start();
}

// 엔진 클래스
public class Engine : IEngine
{
    public void Start()
    {
        Console.WriteLine("Engine starts.");
    }
}

// 전기 엔진 클래스
public class ElectricEngine : IEngine
{
    public void Start()
    {
        Console.WriteLine("Electric engine starts.");
    }
}

// 자동차 클래스
public class Car
{
    private IEngine _engine;

    public Car(IEngine engine)
    {
        _engine = engine;
    }

    public void Start()
    {
        _engine.Start();
        Console.WriteLine("Car starts.");
    }
}

// 메인 프로그램
public class Program
{
    public static void Main(string[] args)
    {
        IEngine engine = new Engine();
        Car car = new Car(engine);
        car.Start();
        
        IEngine electricEngine = new ElectricEngine();
        Car electricCar = new Car(electricEngine);
        electricCar.Start();
    }
}
</pre>



<p></p>
<p>The post <a href="https://lycos7560.com/c/dependency-inversion-principledip-%ec%9d%98%ec%a1%b4%ec%84%b1-%ec%97%ad%ec%a0%84-%ec%9b%90%eb%a6%ac/38731/">Dependency Inversion Principle(DIP, 의존성 역전 원리)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/dependency-inversion-principledip-%ec%9d%98%ec%a1%b4%ec%84%b1-%ec%97%ad%ec%a0%84-%ec%9b%90%eb%a6%ac/38731/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Deploying ASP.NET Web API To Azure</title>
		<link>https://lycos7560.com/c/deploying-asp-net-web-api-to-azure/38646/</link>
					<comments>https://lycos7560.com/c/deploying-asp-net-web-api-to-azure/38646/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Fri, 01 Nov 2024 08:08:45 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[.Net Core]]></category>
		<category><![CDATA[AddModelError]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Consuming]]></category>
		<category><![CDATA[Controller]]></category>
		<category><![CDATA[Create]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Data access logic]]></category>
		<category><![CDATA[DataBase]]></category>
		<category><![CDATA[DbContext]]></category>
		<category><![CDATA[DbSet]]></category>
		<category><![CDATA[DELETE]]></category>
		<category><![CDATA[Deploying]]></category>
		<category><![CDATA[Domain]]></category>
		<category><![CDATA[Domain Model]]></category>
		<category><![CDATA[File]]></category>
		<category><![CDATA[FileDescription]]></category>
		<category><![CDATA[Filestream]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[IFormFile]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Image Controller]]></category>
		<category><![CDATA[IsValid]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[ModelState]]></category>
		<category><![CDATA[pepe]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[program]]></category>
		<category><![CDATA[Program.cs]]></category>
		<category><![CDATA[PUT]]></category>
		<category><![CDATA[Repository]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[REST Web API]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Upload]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[web API]]></category>
		<category><![CDATA[wpf]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[배포]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=38646</guid>

					<description><![CDATA[<p>Deploying ASP.NET Web API To Azure https://azure.microsoft.com/ko-kr</p>
<p>The post <a href="https://lycos7560.com/c/deploying-asp-net-web-api-to-azure/38646/">Deploying ASP.NET Web API To Azure</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Deploying ASP.NET Web API To Azure</h2>



<p><a href="https://azure.microsoft.com/ko-kr" target="_blank" rel="noreferrer noopener">https://azure.microsoft.com/ko-kr</a></p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1462" height="565" src="https://lycos7560.com/wp-content/uploads/2024/11/image.png" alt="" class="wp-image-38647" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image.png 1462w, https://lycos7560.com/wp-content/uploads/2024/11/image-300x116.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-768x297.png 768w" sizes="(max-width: 1462px) 100vw, 1462px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1242" height="801" src="https://lycos7560.com/wp-content/uploads/2024/11/image-1.png" alt="" class="wp-image-38650" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-1.png 1242w, https://lycos7560.com/wp-content/uploads/2024/11/image-1-300x193.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-1-768x495.png 768w" sizes="(max-width: 1242px) 100vw, 1242px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1019" height="525" src="https://lycos7560.com/wp-content/uploads/2024/11/image-2.png" alt="" class="wp-image-38651" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-2.png 1019w, https://lycos7560.com/wp-content/uploads/2024/11/image-2-300x155.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-2-768x396.png 768w" sizes="(max-width: 1019px) 100vw, 1019px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="745" height="541" src="https://lycos7560.com/wp-content/uploads/2024/11/image-3.png" alt="" class="wp-image-38652" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-3.png 745w, https://lycos7560.com/wp-content/uploads/2024/11/image-3-300x218.png 300w" sizes="(max-width: 745px) 100vw, 745px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1242" height="801" src="https://lycos7560.com/wp-content/uploads/2024/11/image-4.png" alt="" class="wp-image-38653" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-4.png 1242w, https://lycos7560.com/wp-content/uploads/2024/11/image-4-300x193.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-4-768x495.png 768w" sizes="(max-width: 1242px) 100vw, 1242px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1242" height="801" src="https://lycos7560.com/wp-content/uploads/2024/11/image-10.png" alt="" class="wp-image-38659" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-10.png 1242w, https://lycos7560.com/wp-content/uploads/2024/11/image-10-300x193.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-10-768x495.png 768w" sizes="(max-width: 1242px) 100vw, 1242px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1456" height="399" src="https://lycos7560.com/wp-content/uploads/2024/11/image-11.png" alt="" class="wp-image-38661" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-11.png 1456w, https://lycos7560.com/wp-content/uploads/2024/11/image-11-300x82.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-11-768x210.png 768w" sizes="(max-width: 1456px) 100vw, 1456px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="936" height="769" src="https://lycos7560.com/wp-content/uploads/2024/11/image-12.png" alt="" class="wp-image-38662" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-12.png 936w, https://lycos7560.com/wp-content/uploads/2024/11/image-12-300x246.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-12-768x631.png 768w" sizes="(max-width: 936px) 100vw, 936px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1176" height="457" src="https://lycos7560.com/wp-content/uploads/2024/11/image-13.png" alt="" class="wp-image-38663" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-13.png 1176w, https://lycos7560.com/wp-content/uploads/2024/11/image-13-300x117.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-13-768x298.png 768w" sizes="(max-width: 1176px) 100vw, 1176px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1510" height="801" src="https://lycos7560.com/wp-content/uploads/2024/11/image-14.png" alt="" class="wp-image-38664" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-14.png 1510w, https://lycos7560.com/wp-content/uploads/2024/11/image-14-300x159.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-14-768x407.png 768w" sizes="(max-width: 1510px) 100vw, 1510px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image"><img decoding="async" width="1146" height="521" src="https://lycos7560.com/wp-content/uploads/2024/11/image-15.png" alt="" class="wp-image-38665" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-15.png 1146w, https://lycos7560.com/wp-content/uploads/2024/11/image-15-300x136.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-15-768x349.png 768w" sizes="(max-width: 1146px) 100vw, 1146px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="845" height="518" src="https://lycos7560.com/wp-content/uploads/2024/11/image-16.png" alt="" class="wp-image-38666" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-16.png 845w, https://lycos7560.com/wp-content/uploads/2024/11/image-16-300x184.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-16-768x471.png 768w" sizes="(max-width: 845px) 100vw, 845px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="662" height="978" src="https://lycos7560.com/wp-content/uploads/2024/11/image-17.png" alt="" class="wp-image-38668" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-17.png 662w, https://lycos7560.com/wp-content/uploads/2024/11/image-17-203x300.png 203w" sizes="(max-width: 662px) 100vw, 662px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="661" height="820" src="https://lycos7560.com/wp-content/uploads/2024/11/image-18.png" alt="" class="wp-image-38670" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-18.png 661w, https://lycos7560.com/wp-content/uploads/2024/11/image-18-242x300.png 242w" sizes="(max-width: 661px) 100vw, 661px" /></figure>
</div>
</div>



<figure class="wp-block-image size-full"><img decoding="async" width="1726" height="984" src="https://lycos7560.com/wp-content/uploads/2024/11/image-20.png" alt="" class="wp-image-38672" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-20.png 1726w, https://lycos7560.com/wp-content/uploads/2024/11/image-20-300x171.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-20-768x438.png 768w, https://lycos7560.com/wp-content/uploads/2024/11/image-20-1536x876.png 1536w" sizes="(max-width: 1726px) 100vw, 1726px" /></figure>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="895" height="295" src="https://lycos7560.com/wp-content/uploads/2024/11/image-21.png" alt="" class="wp-image-38673" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-21.png 895w, https://lycos7560.com/wp-content/uploads/2024/11/image-21-300x99.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-21-768x253.png 768w" sizes="(max-width: 895px) 100vw, 895px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="688" height="328" src="https://lycos7560.com/wp-content/uploads/2024/11/image-25.png" alt="" class="wp-image-38677" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-25.png 688w, https://lycos7560.com/wp-content/uploads/2024/11/image-25-300x143.png 300w" sizes="(max-width: 688px) 100vw, 688px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="645" height="987" src="https://lycos7560.com/wp-content/uploads/2024/11/image-27.png" alt="" class="wp-image-38679" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-27.png 645w, https://lycos7560.com/wp-content/uploads/2024/11/image-27-196x300.png 196w" sizes="(max-width: 645px) 100vw, 645px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="696" height="1020" src="https://lycos7560.com/wp-content/uploads/2024/11/image-26.png" alt="" class="wp-image-38678" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-26.png 696w, https://lycos7560.com/wp-content/uploads/2024/11/image-26-205x300.png 205w" sizes="(max-width: 696px) 100vw, 696px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="824" height="415" src="https://lycos7560.com/wp-content/uploads/2024/11/image-28.png" alt="" class="wp-image-38680" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-28.png 824w, https://lycos7560.com/wp-content/uploads/2024/11/image-28-300x151.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-28-768x387.png 768w" sizes="(max-width: 824px) 100vw, 824px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="826" height="330" src="https://lycos7560.com/wp-content/uploads/2024/11/image-29.png" alt="" class="wp-image-38681" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-29.png 826w, https://lycos7560.com/wp-content/uploads/2024/11/image-29-300x120.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-29-768x307.png 768w" sizes="(max-width: 826px) 100vw, 826px" /></figure>
</div>
</div>



<figure class="wp-block-image size-full"><img decoding="async" width="1404" height="1005" src="https://lycos7560.com/wp-content/uploads/2024/11/image-30.png" alt="" class="wp-image-38682" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-30.png 1404w, https://lycos7560.com/wp-content/uploads/2024/11/image-30-300x215.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-30-768x550.png 768w" sizes="(max-width: 1404px) 100vw, 1404px" /></figure>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-image size-full"><img decoding="async" width="714" height="604" src="https://lycos7560.com/wp-content/uploads/2024/11/image-31.png" alt="" class="wp-image-38683" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-31.png 714w, https://lycos7560.com/wp-content/uploads/2024/11/image-31-300x254.png 300w" sizes="(max-width: 714px) 100vw, 714px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-image size-full"><img decoding="async" width="618" height="372" src="https://lycos7560.com/wp-content/uploads/2024/11/image-32.png" alt="" class="wp-image-38684" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-32.png 618w, https://lycos7560.com/wp-content/uploads/2024/11/image-32-300x181.png 300w" sizes="(max-width: 618px) 100vw, 618px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-full"><img decoding="async" width="473" height="496" src="https://lycos7560.com/wp-content/uploads/2024/11/image-33.png" alt="" class="wp-image-38685" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-33.png 473w, https://lycos7560.com/wp-content/uploads/2024/11/image-33-286x300.png 286w" sizes="(max-width: 473px) 100vw, 473px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-image size-full"><img decoding="async" width="762" height="475" src="https://lycos7560.com/wp-content/uploads/2024/11/image-34.png" alt="" class="wp-image-38686" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-34.png 762w, https://lycos7560.com/wp-content/uploads/2024/11/image-34-300x187.png 300w" sizes="(max-width: 762px) 100vw, 762px" /><figcaption class="wp-element-caption">Azure 계정확인</figcaption></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-image size-full"><img decoding="async" width="596" height="362" src="https://lycos7560.com/wp-content/uploads/2024/11/image-35.png" alt="" class="wp-image-38687" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-35.png 596w, https://lycos7560.com/wp-content/uploads/2024/11/image-35-300x182.png 300w" sizes="(max-width: 596px) 100vw, 596px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-full"><img decoding="async" width="781" height="549" src="https://lycos7560.com/wp-content/uploads/2024/11/image-36.png" alt="" class="wp-image-38688" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-36.png 781w, https://lycos7560.com/wp-content/uploads/2024/11/image-36-300x211.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-36-768x540.png 768w" sizes="(max-width: 781px) 100vw, 781px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-image size-full"><img decoding="async" width="787" height="541" src="https://lycos7560.com/wp-content/uploads/2024/11/image-38.png" alt="" class="wp-image-38690" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-38.png 787w, https://lycos7560.com/wp-content/uploads/2024/11/image-38-300x206.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-38-768x528.png 768w" sizes="(max-width: 787px) 100vw, 787px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-image size-full"><img decoding="async" width="779" height="545" src="https://lycos7560.com/wp-content/uploads/2024/11/image-39.png" alt="" class="wp-image-38691" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-39.png 779w, https://lycos7560.com/wp-content/uploads/2024/11/image-39-300x210.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-39-768x537.png 768w" sizes="(max-width: 779px) 100vw, 779px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-full"><img decoding="async" width="764" height="523" src="https://lycos7560.com/wp-content/uploads/2024/11/image-40.png" alt="" class="wp-image-38692" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-40.png 764w, https://lycos7560.com/wp-content/uploads/2024/11/image-40-300x205.png 300w" sizes="(max-width: 764px) 100vw, 764px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50.01%">
<figure class="wp-block-image size-full"><img decoding="async" width="785" height="547" src="https://lycos7560.com/wp-content/uploads/2024/11/image-41.png" alt="" class="wp-image-38693" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-41.png 785w, https://lycos7560.com/wp-content/uploads/2024/11/image-41-300x209.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-41-768x535.png 768w" sizes="(max-width: 785px) 100vw, 785px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:49.99%">
<figure class="wp-block-image size-full"><img decoding="async" width="1133" height="772" src="https://lycos7560.com/wp-content/uploads/2024/11/image-42.png" alt="" class="wp-image-38694" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-42.png 1133w, https://lycos7560.com/wp-content/uploads/2024/11/image-42-300x204.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-42-768x523.png 768w" sizes="(max-width: 1133px) 100vw, 1133px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1074" height="288" src="https://lycos7560.com/wp-content/uploads/2024/11/image-43.png" alt="" class="wp-image-38695" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-43.png 1074w, https://lycos7560.com/wp-content/uploads/2024/11/image-43-300x80.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-43-768x206.png 768w" sizes="(max-width: 1074px) 100vw, 1074px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="786" height="549" src="https://lycos7560.com/wp-content/uploads/2024/11/image-44.png" alt="" class="wp-image-38697" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-44.png 786w, https://lycos7560.com/wp-content/uploads/2024/11/image-44-300x210.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-44-768x536.png 768w" sizes="(max-width: 786px) 100vw, 786px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="777" height="540" src="https://lycos7560.com/wp-content/uploads/2024/11/image-45.png" alt="" class="wp-image-38698" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-45.png 777w, https://lycos7560.com/wp-content/uploads/2024/11/image-45-300x208.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-45-768x534.png 768w" sizes="(max-width: 777px) 100vw, 777px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="775" height="543" src="https://lycos7560.com/wp-content/uploads/2024/11/image-46.png" alt="" class="wp-image-38699" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-46.png 775w, https://lycos7560.com/wp-content/uploads/2024/11/image-46-300x210.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-46-768x538.png 768w" sizes="(max-width: 775px) 100vw, 775px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="788" height="564" src="https://lycos7560.com/wp-content/uploads/2024/11/image-47.png" alt="" class="wp-image-38700" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-47.png 788w, https://lycos7560.com/wp-content/uploads/2024/11/image-47-300x215.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-47-768x550.png 768w" sizes="(max-width: 788px) 100vw, 788px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1059" height="338" src="https://lycos7560.com/wp-content/uploads/2024/11/image-48.png" alt="" class="wp-image-38701" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-48.png 1059w, https://lycos7560.com/wp-content/uploads/2024/11/image-48-300x96.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-48-768x245.png 768w" sizes="(max-width: 1059px) 100vw, 1059px" /><figcaption class="wp-element-caption">위와 같은 작업 반복</figcaption></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="858" height="260" src="https://lycos7560.com/wp-content/uploads/2024/11/image-49.png" alt="" class="wp-image-38702" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-49.png 858w, https://lycos7560.com/wp-content/uploads/2024/11/image-49-300x91.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-49-768x233.png 768w" sizes="(max-width: 858px) 100vw, 858px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1117" height="772" src="https://lycos7560.com/wp-content/uploads/2024/11/image-54.png" alt="" class="wp-image-38708" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-54.png 1117w, https://lycos7560.com/wp-content/uploads/2024/11/image-54-300x207.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-54-768x531.png 768w" sizes="(max-width: 1117px) 100vw, 1117px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1151" height="377" src="https://lycos7560.com/wp-content/uploads/2024/11/image-53.png" alt="" class="wp-image-38711" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-53.png 1151w, https://lycos7560.com/wp-content/uploads/2024/11/image-53-300x98.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-53-768x252.png 768w" sizes="(max-width: 1151px) 100vw, 1151px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="686" height="544" src="https://lycos7560.com/wp-content/uploads/2024/11/image-55.png" alt="" class="wp-image-38712" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-55.png 686w, https://lycos7560.com/wp-content/uploads/2024/11/image-55-300x238.png 300w" sizes="(max-width: 686px) 100vw, 686px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1170" height="123" src="https://lycos7560.com/wp-content/uploads/2024/11/image-50.png" alt="" class="wp-image-38703" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-50.png 1170w, https://lycos7560.com/wp-content/uploads/2024/11/image-50-300x32.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-50-768x81.png 768w" sizes="(max-width: 1170px) 100vw, 1170px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1046" height="319" src="https://lycos7560.com/wp-content/uploads/2024/11/image-56.png" alt="" class="wp-image-38713" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-56.png 1046w, https://lycos7560.com/wp-content/uploads/2024/11/image-56-300x91.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-56-768x234.png 768w" sizes="(max-width: 1046px) 100vw, 1046px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-image size-full"><img decoding="async" width="687" height="537" src="https://lycos7560.com/wp-content/uploads/2024/11/image-57.png" alt="" class="wp-image-38714" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-57.png 687w, https://lycos7560.com/wp-content/uploads/2024/11/image-57-300x234.png 300w" sizes="(max-width: 687px) 100vw, 687px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-full"><img decoding="async" width="319" height="342" src="https://lycos7560.com/wp-content/uploads/2024/11/image-65.png" alt="" class="wp-image-38722" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-65.png 319w, https://lycos7560.com/wp-content/uploads/2024/11/image-65-280x300.png 280w" sizes="(max-width: 319px) 100vw, 319px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-image size-full"><img decoding="async" width="1091" height="731" src="https://lycos7560.com/wp-content/uploads/2024/11/image-58.png" alt="" class="wp-image-38715" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-58.png 1091w, https://lycos7560.com/wp-content/uploads/2024/11/image-58-300x201.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-58-768x515.png 768w" sizes="(max-width: 1091px) 100vw, 1091px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="672" height="599" src="https://lycos7560.com/wp-content/uploads/2024/11/image-59.png" alt="" class="wp-image-38716" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-59.png 672w, https://lycos7560.com/wp-content/uploads/2024/11/image-59-300x267.png 300w" sizes="(max-width: 672px) 100vw, 672px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1066" height="750" src="https://lycos7560.com/wp-content/uploads/2024/11/image-60.png" alt="" class="wp-image-38717" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-60.png 1066w, https://lycos7560.com/wp-content/uploads/2024/11/image-60-300x211.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-60-768x540.png 768w" sizes="(max-width: 1066px) 100vw, 1066px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="304" height="432" src="https://lycos7560.com/wp-content/uploads/2024/11/image-61.png" alt="" class="wp-image-38718" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-61.png 304w, https://lycos7560.com/wp-content/uploads/2024/11/image-61-211x300.png 211w" sizes="(max-width: 304px) 100vw, 304px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="528" height="628" src="https://lycos7560.com/wp-content/uploads/2024/11/image-62.png" alt="" class="wp-image-38719" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-62.png 528w, https://lycos7560.com/wp-content/uploads/2024/11/image-62-252x300.png 252w" sizes="(max-width: 528px) 100vw, 528px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1034" height="568" src="https://lycos7560.com/wp-content/uploads/2024/11/image-63.png" alt="" class="wp-image-38720" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-63.png 1034w, https://lycos7560.com/wp-content/uploads/2024/11/image-63-300x165.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-63-768x422.png 768w" sizes="(max-width: 1034px) 100vw, 1034px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1005" height="434" src="https://lycos7560.com/wp-content/uploads/2024/11/image-64.png" alt="" class="wp-image-38721" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-64.png 1005w, https://lycos7560.com/wp-content/uploads/2024/11/image-64-300x130.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-64-768x332.png 768w" sizes="(max-width: 1005px) 100vw, 1005px" /></figure>
</div>
</div>



<figure class="wp-block-image size-full"><img decoding="async" width="1593" height="225" src="https://lycos7560.com/wp-content/uploads/2024/11/image-66.png" alt="" class="wp-image-38723" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-66.png 1593w, https://lycos7560.com/wp-content/uploads/2024/11/image-66-300x42.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-66-768x108.png 768w, https://lycos7560.com/wp-content/uploads/2024/11/image-66-1536x217.png 1536w" sizes="(max-width: 1593px) 100vw, 1593px" /></figure>



<figure class="wp-block-image size-full"><img decoding="async" width="1359" height="598" src="https://lycos7560.com/wp-content/uploads/2024/11/image-67.png" alt="" class="wp-image-38724" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-67.png 1359w, https://lycos7560.com/wp-content/uploads/2024/11/image-67-300x132.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-67-768x338.png 768w" sizes="(max-width: 1359px) 100vw, 1359px" /></figure>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="940" height="534" src="https://lycos7560.com/wp-content/uploads/2024/11/image-68.png" alt="" class="wp-image-38725" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-68.png 940w, https://lycos7560.com/wp-content/uploads/2024/11/image-68-300x170.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-68-768x436.png 768w" sizes="(max-width: 940px) 100vw, 940px" /><figcaption class="wp-element-caption">계정 생성</figcaption></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1435" height="379" src="https://lycos7560.com/wp-content/uploads/2024/11/image-69.png" alt="" class="wp-image-38726" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-69.png 1435w, https://lycos7560.com/wp-content/uploads/2024/11/image-69-300x79.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-69-768x203.png 768w" sizes="(max-width: 1435px) 100vw, 1435px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-full"><img decoding="async" width="927" height="637" data-id="38727" src="https://lycos7560.com/wp-content/uploads/2024/11/image-70.png" alt="" class="wp-image-38727" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-70.png 927w, https://lycos7560.com/wp-content/uploads/2024/11/image-70-300x206.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-70-768x528.png 768w" sizes="(max-width: 927px) 100vw, 927px" /></figure>
</figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="939" height="447" src="https://lycos7560.com/wp-content/uploads/2024/11/image-71.png" alt="" class="wp-image-38728" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-71.png 939w, https://lycos7560.com/wp-content/uploads/2024/11/image-71-300x143.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-71-768x366.png 768w" sizes="(max-width: 939px) 100vw, 939px" /></figure>
</div>
</div>



<figure class="wp-block-image size-full"><img decoding="async" width="942" height="762" src="https://lycos7560.com/wp-content/uploads/2024/11/image-72.png" alt="" class="wp-image-38729" srcset="https://lycos7560.com/wp-content/uploads/2024/11/image-72.png 942w, https://lycos7560.com/wp-content/uploads/2024/11/image-72-300x243.png 300w, https://lycos7560.com/wp-content/uploads/2024/11/image-72-768x621.png 768w" sizes="(max-width: 942px) 100vw, 942px" /></figure>
<p>The post <a href="https://lycos7560.com/c/deploying-asp-net-web-api-to-azure/38646/">Deploying ASP.NET Web API To Azure</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/deploying-asp-net-web-api-to-azure/38646/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Consuming REST Web APIs</title>
		<link>https://lycos7560.com/c/consuming-rest-web-apis/38585/</link>
					<comments>https://lycos7560.com/c/consuming-rest-web-apis/38585/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Thu, 31 Oct 2024 09:56:32 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[.Net Core]]></category>
		<category><![CDATA[AddModelError]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[Consuming]]></category>
		<category><![CDATA[Controller]]></category>
		<category><![CDATA[Create]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Data access logic]]></category>
		<category><![CDATA[DataBase]]></category>
		<category><![CDATA[DbContext]]></category>
		<category><![CDATA[DbSet]]></category>
		<category><![CDATA[DELETE]]></category>
		<category><![CDATA[Domain]]></category>
		<category><![CDATA[Domain Model]]></category>
		<category><![CDATA[File]]></category>
		<category><![CDATA[FileDescription]]></category>
		<category><![CDATA[Filestream]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[IFormFile]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[Image Controller]]></category>
		<category><![CDATA[IsValid]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[ModelState]]></category>
		<category><![CDATA[pepe]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[program]]></category>
		<category><![CDATA[Program.cs]]></category>
		<category><![CDATA[PUT]]></category>
		<category><![CDATA[Repository]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[REST Web API]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Upload]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[web API]]></category>
		<category><![CDATA[wpf]]></category>
		<category><![CDATA[기초]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=38585</guid>

					<description><![CDATA[<p>Consuming REST Web APIs 1. 프로젝트 생성(MVC UI) ASP.Net Core Web App (MVC) 2. GET Controller 생성 HttpClient 적용 .Net에서 제공하는 HttpClient Class https://learn.microsoft.com/ko-kr/dotnet/api/system.net.http.httpclient?view=net-8.0 HTTP 요청을 보내고 URI로 식별된 리소스에서 HTTP 응답을 수신하기 위한 클래스를 제공합니다. 사용 예제 HttpClient를 사용하려면, Program.cs 파일에 HttpClient Factory를 설정 이를 통해 효율적으로 HttpClient 인스턴스를 관리하고, 특히 성능 문제를 해결할 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/consuming-rest-web-apis/38585/">Consuming REST Web APIs</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Consuming REST Web APIs</h2>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>


				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-b7f87031      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#consuming-rest-web-apis" class="uagb-toc-link__trigger">Consuming REST Web APIs</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-프로젝트-생성mvc-ui" class="uagb-toc-link__trigger">1. 프로젝트 생성(MVC UI)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-get-controller-생성" class="uagb-toc-link__trigger">2. GET Controller 생성</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#httpclient-적용" class="uagb-toc-link__trigger">HttpClient 적용</a></li></ul><li class="uagb-toc__list"><a href="#3-indexcshtml-layoutcshtml-생성-및-수정" class="uagb-toc-link__trigger">3. Index.cshtml , _Layout.cshtml 생성 및 수정</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#4-regiondtocs-생성-및-indexcshtml-적용" class="uagb-toc-link__trigger">4. RegionDto.cs 생성 및 Index.cshtml 적용</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#5-post-method-생성" class="uagb-toc-link__trigger">5. POST Method 생성</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#6-단일-편집-기능" class="uagb-toc-link__trigger">6. 단일 편집 기능</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#7-삭제-기능" class="uagb-toc-link__trigger">7. 삭제 기능</a></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">1. 프로젝트 생성(MVC UI)</h3>



<p>ASP.Net Core Web App (MVC)</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="807" height="611" src="https://lycos7560.com/wp-content/uploads/2024/10/image-154.png" alt="" class="wp-image-38586" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-154.png 807w, https://lycos7560.com/wp-content/uploads/2024/10/image-154-300x227.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-154-768x581.png 768w" sizes="(max-width: 807px) 100vw, 807px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1005" height="626" src="https://lycos7560.com/wp-content/uploads/2024/10/image-155.png" alt="" class="wp-image-38587" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-155.png 1005w, https://lycos7560.com/wp-content/uploads/2024/10/image-155-300x187.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-155-768x478.png 768w" sizes="(max-width: 1005px) 100vw, 1005px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1207" height="800" src="https://lycos7560.com/wp-content/uploads/2024/10/image-156.png" alt="" class="wp-image-38588" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-156.png 1207w, https://lycos7560.com/wp-content/uploads/2024/10/image-156-300x199.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-156-768x509.png 768w" sizes="(max-width: 1207px) 100vw, 1207px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="957" height="805" src="https://lycos7560.com/wp-content/uploads/2024/10/image-157.png" alt="" class="wp-image-38589" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-157.png 957w, https://lycos7560.com/wp-content/uploads/2024/10/image-157-300x252.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-157-768x646.png 768w" sizes="(max-width: 957px) 100vw, 957px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="787" height="539" src="https://lycos7560.com/wp-content/uploads/2024/10/image-158.png" alt="" class="wp-image-38590" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-158.png 787w, https://lycos7560.com/wp-content/uploads/2024/10/image-158-300x205.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-158-768x526.png 768w" sizes="(max-width: 787px) 100vw, 787px" /><figcaption class="wp-element-caption">여러 개의 시작 프로젝트로 변경</figcaption></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1905" height="1023" src="https://lycos7560.com/wp-content/uploads/2024/10/image-159.png" alt="" class="wp-image-38591" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-159.png 1905w, https://lycos7560.com/wp-content/uploads/2024/10/image-159-300x161.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-159-768x412.png 768w, https://lycos7560.com/wp-content/uploads/2024/10/image-159-1536x825.png 1536w" sizes="(max-width: 1905px) 100vw, 1905px" /><figcaption class="wp-element-caption">MVC UI와 API(Swagger)</figcaption></figure>
</div>
</div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2. GET Controller 생성</h3>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1286" height="394" src="https://lycos7560.com/wp-content/uploads/2024/10/image-160.png" alt="" class="wp-image-38592" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-160.png 1286w, https://lycos7560.com/wp-content/uploads/2024/10/image-160-300x92.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-160-768x235.png 768w" sizes="(max-width: 1286px) 100vw, 1286px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="935" height="406" src="https://lycos7560.com/wp-content/uploads/2024/10/image-161.png" alt="" class="wp-image-38593" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-161.png 935w, https://lycos7560.com/wp-content/uploads/2024/10/image-161-300x130.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-161-768x333.png 768w" sizes="(max-width: 935px) 100vw, 935px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="992" height="431" src="https://lycos7560.com/wp-content/uploads/2024/10/image-162.png" alt="" class="wp-image-38594" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-162.png 992w, https://lycos7560.com/wp-content/uploads/2024/10/image-162-300x130.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-162-768x334.png 768w" sizes="(max-width: 992px) 100vw, 992px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1251" height="440" src="https://lycos7560.com/wp-content/uploads/2024/10/image-171.png" alt="" class="wp-image-38603" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-171.png 1251w, https://lycos7560.com/wp-content/uploads/2024/10/image-171-300x106.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-171-768x270.png 768w" sizes="(max-width: 1251px) 100vw, 1251px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="737" height="619" src="https://lycos7560.com/wp-content/uploads/2024/10/image-172.png" alt="" class="wp-image-38604" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-172.png 737w, https://lycos7560.com/wp-content/uploads/2024/10/image-172-300x252.png 300w" sizes="(max-width: 737px) 100vw, 737px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1032" height="440" src="https://lycos7560.com/wp-content/uploads/2024/10/image-177.png" alt="" class="wp-image-38609" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-177.png 1032w, https://lycos7560.com/wp-content/uploads/2024/10/image-177-300x128.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-177-768x327.png 768w" sizes="(max-width: 1032px) 100vw, 1032px" /></figure>
</div>
</div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">HttpClient 적용</h4>



<p>.Net에서 제공하는 <strong>HttpClient Class</strong></p>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/system.net.http.httpclient?view=net-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/ko-kr/dotnet/api/system.net.http.httpclient?view=net-8.0</a></p>



<p>HTTP 요청을 보내고 URI로 식별된 리소스에서 HTTP 응답을 수신하기 위한 클래스를 제공합니다.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">public class HttpClient : System.Net.Http.HttpMessageInvoker</pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>사용 예제</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// HttpClient는 매번 사용될 때마다 인스턴스화되지 않고, 애플리케이션 전체에서 한 번만 인스턴스화되어야 합니다. 참고 사항을 참조하세요.
static readonly HttpClient client = new HttpClient();

static async Task Main()
{
    // 비동기 네트워크 메서드를 try/catch 블록 내에서 호출하여 예외를 처리합니다.
    try
    {
        // 비동기적으로 GET 요청을 보냅니다.
        using HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/");
        
        // 요청이 성공적으로 완료되었는지 확인합니다.
        response.EnsureSuccessStatusCode();
        
        // 응답 본문을 문자열로 읽어옵니다.
        string responseBody = await response.Content.ReadAsStringAsync();
        
        // 위의 세 줄은 아래 새로운 헬퍼 메서드로 대체할 수 있습니다.
        // string responseBody = await client.GetStringAsync(uri);
        
        // 응답 본문을 콘솔에 출력합니다.
        Console.WriteLine(responseBody);
    }
    catch (HttpRequestException e)
    {
        // 예외가 발생했을 때 예외 메시지를 콘솔에 출력합니다.
        Console.WriteLine("\nException Caught!");
        Console.WriteLine("Message :{0} ", e.Message);
    }
}
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p><a href="https://learn.microsoft.com/ko-kr/dotnet/api/system.net.http.httpclient?view=net-8.0#remarks"></a></p>



<p>HttpClient를 사용하려면, Program.cs 파일에 HttpClient Factory를 설정</p>



<p>이를 통해 효율적으로 <strong>HttpClient 인스턴스를 관리하고, 특히 성능 문제를 해결</strong>할 수 있음</p>



<p>Program.cs</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

// HttpClient 삽입
builder.Services.AddHttpClient();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="920" height="469" src="https://lycos7560.com/wp-content/uploads/2024/10/image-178.png" alt="" class="wp-image-38610" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-178.png 920w, https://lycos7560.com/wp-content/uploads/2024/10/image-178-300x153.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-178-768x392.png 768w" sizes="(max-width: 920px) 100vw, 920px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1077" height="459" src="https://lycos7560.com/wp-content/uploads/2024/10/image-179.png" alt="" class="wp-image-38611" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-179.png 1077w, https://lycos7560.com/wp-content/uploads/2024/10/image-179-300x128.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-179-768x327.png 768w" sizes="(max-width: 1077px) 100vw, 1077px" /><figcaption class="wp-element-caption">NZWalks.API의 launchSettings.json</figcaption></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1306" height="778" src="https://lycos7560.com/wp-content/uploads/2024/10/image-180.png" alt="" class="wp-image-38612" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-180.png 1306w, https://lycos7560.com/wp-content/uploads/2024/10/image-180-300x179.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-180-768x458.png 768w" sizes="(max-width: 1306px) 100vw, 1306px" /><figcaption class="wp-element-caption">RegionsController의 GetAll Api를 사용</figcaption></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="907" height="668" src="https://lycos7560.com/wp-content/uploads/2024/10/image-181.png" alt="" class="wp-image-38613" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-181.png 907w, https://lycos7560.com/wp-content/uploads/2024/10/image-181-300x221.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-181-768x566.png 768w" sizes="(max-width: 907px) 100vw, 907px" /><figcaption class="wp-element-caption">테스트를 위해서 인증 주석</figcaption></figure>
</div>
</div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>RegionsController.cs 수정</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Mvc;

namespace NZWalksUI.Controllers
{
    public class RegionsController : Controller
    {
        private readonly IHttpClientFactory httpClientFactory;

        // Http 클라이언트 팩토리를 삽입하기 위한 생성자를 생성
        public RegionsController(IHttpClientFactory httpClientFactory)
        {
            this.httpClientFactory = httpClientFactory;
        }

        // Index 액션 메서드
        public async Task&lt;IActionResult> Index()
        {
            try
            {
                // Get All Regions From Web API
                // 새로운 Http 클라이언트가 생성
                var client = httpClientFactory.CreateClient();
                
                // Web API로 GET 요청을 보냄
                var httpResponseMessage = await client.GetAsync("https://localhost:7256/api/regions");
                
                // 요청이 성공적으로 완료되었는지 확인
                httpResponseMessage.EnsureSuccessStatusCode();
                
                // 응답 본문을 문자열로 읽어옴
                var stringResponse = await httpResponseMessage.Content.ReadAsStringAsync();
                
                // 응답 내용을 ViewBag에 저장
                ViewBag.Response = stringResponse;
                
                // 응답 메시지를 반환
                return Ok(httpResponseMessage);
            }
            catch (Exception ex)
            {
                // 예외를 로깅 (로그 기록)
            }
            
            // View를 반환
            return View();
        }
    }
}
</pre>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3. Index.cshtml , <strong>_Layout.cshtml </strong>생성 및 수정 </h3>



<p><strong>Index.cshtml</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="html" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@*
    For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}

&lt;h1 class="mt-3">Regions&lt;/h1>

@if (ViewBag.Respose is not null)
{
    &lt;p>ViewBag.Respose&lt;/p>
}</pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>_Layout.cshtml</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="html" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;!DOCTYPE html>
&lt;html lang="en">
&lt;head>
    &lt;meta charset="utf-8" />
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0" />
    &lt;title>@ViewData["Title"] - NZWalksUI&lt;/title>
    &lt;link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    &lt;link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    &lt;link rel="stylesheet" href="~/NZWalksUI.styles.css" asp-append-version="true" />
&lt;/head>
&lt;body>
    &lt;header>
        &lt;nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            &lt;div class="container-fluid">
                &lt;a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">NZWalksUI&lt;/a>
                &lt;button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    &lt;span class="navbar-toggler-icon">&lt;/span>
                &lt;/button>
                &lt;div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    &lt;ul class="navbar-nav flex-grow-1">
                        &lt;li class="nav-item">
                            &lt;a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home&lt;/a>
                        &lt;/li>
                        &lt;li class="nav-item">
                            &lt;a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy&lt;/a>
                        &lt;/li>
                        &lt;li class="nav-item">
                            &lt;a class="nav-link text-dark" asp-area="" asp-controller="Regions" asp-action="Index">Regions&lt;/a>
                        &lt;/li>
                    &lt;/ul>
                &lt;/div>
            &lt;/div>
        &lt;/nav>
    &lt;/header>
    &lt;div class="container">
        &lt;main role="main" class="pb-3">
            @RenderBody()
        &lt;/main>
    &lt;/div>

    &lt;footer class="border-top footer text-muted">
        &lt;div class="container">
            &amp;copy; 2024 - NZWalksUI - &lt;a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy&lt;/a>
        &lt;/div>
    &lt;/footer>
    &lt;script src="~/lib/jquery/dist/jquery.min.js">&lt;/script>
    &lt;script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js">&lt;/script>
    &lt;script src="~/js/site.js" asp-append-version="true">&lt;/script>
    @await RenderSectionAsync("Scripts", required: false)
&lt;/body>
&lt;/html>
</pre>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1261" height="380" src="https://lycos7560.com/wp-content/uploads/2024/10/image-184.png" alt="" class="wp-image-38616" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-184.png 1261w, https://lycos7560.com/wp-content/uploads/2024/10/image-184-300x90.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-184-768x231.png 768w" sizes="(max-width: 1261px) 100vw, 1261px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1553" height="518" src="https://lycos7560.com/wp-content/uploads/2024/10/image-182.png" alt="" class="wp-image-38617" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-182.png 1553w, https://lycos7560.com/wp-content/uploads/2024/10/image-182-300x100.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-182-768x256.png 768w, https://lycos7560.com/wp-content/uploads/2024/10/image-182-1536x512.png 1536w" sizes="(max-width: 1553px) 100vw, 1553px" /><figcaption class="wp-element-caption">폴더 이름 수정</figcaption></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1308" height="556" src="https://lycos7560.com/wp-content/uploads/2024/10/image-183.png" alt="" class="wp-image-38618" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-183.png 1308w, https://lycos7560.com/wp-content/uploads/2024/10/image-183-300x128.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-183-768x326.png 768w" sizes="(max-width: 1308px) 100vw, 1308px" /><figcaption class="wp-element-caption">break point</figcaption></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1381" height="600" src="https://lycos7560.com/wp-content/uploads/2024/10/image-186.png" alt="" class="wp-image-38620" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-186.png 1381w, https://lycos7560.com/wp-content/uploads/2024/10/image-186-300x130.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-186-768x334.png 768w" sizes="(max-width: 1381px) 100vw, 1381px" /><figcaption class="wp-element-caption">API 적용 확인</figcaption></figure>
</div>
</div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4. RegionDto.cs 생성 및 Index.cshtml 적용</h3>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>RegionDto.cs</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">namespace NZWalksUI.Models.DTO
{
    public class RegionDto
    {
        public Guid Id { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
        public string? RegionImageUrl { get; set; } // Nullable
    }
}</pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Index.cshtml </strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="html" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@model IEnumerable&lt;NZWalksUI.Models.DTO.RegionDto> &lt;!-- 뷰 모델을 IEnumerable&lt;RegionDto>로 설정 -->

@* MVC를 빈 프로젝트에 대해 활성화하는 방법에 대한 추가 정보는 https://go.microsoft.com/fwlink/?LinkID=397860를 참조 *@

@{} &lt;!-- 블록 코드, 현재 비어 있음 -->

&lt;h1 class="mt-3">Regions&lt;/h1> &lt;!-- 페이지 제목 -->

&lt;table>
    &lt;thead>
        &lt;tr>
            &lt;th>Id&lt;/th> &lt;!-- Id 열 -->
            &lt;th>Code&lt;/th> &lt;!-- Code 열 -->
            &lt;th>Name&lt;/th> &lt;!-- Name 열 -->
        &lt;/tr>
    &lt;/thead>
    &lt;tbody>
        @foreach (var walk in Model) &lt;!-- Model을 반복하여 각 walk에 대해 테이블 행 생성 -->
        {
            &lt;tr>
                &lt;th>@walk.Id&lt;/th> &lt;!-- 현재 walk의 Id 표시 -->
                &lt;th>@walk.Code&lt;/th> &lt;!-- 현재 walk의 Code 표시 -->
                &lt;th>@walk.Name&lt;/th> &lt;!-- 현재 walk의 Name 표시 -->
            &lt;/tr>
        }
    &lt;/tbody>
&lt;/table>
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1188" height="696" src="https://lycos7560.com/wp-content/uploads/2024/10/image-187.png" alt="" class="wp-image-38621" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-187.png 1188w, https://lycos7560.com/wp-content/uploads/2024/10/image-187-300x176.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-187-768x450.png 768w" sizes="(max-width: 1188px) 100vw, 1188px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1360" height="575" src="https://lycos7560.com/wp-content/uploads/2024/10/image-188.png" alt="" class="wp-image-38622" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-188.png 1360w, https://lycos7560.com/wp-content/uploads/2024/10/image-188-300x127.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-188-768x325.png 768w" sizes="(max-width: 1360px) 100vw, 1360px" /></figure>
</div>
</div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">5. POST Method 생성 </h3>



<p><strong>Index.cshtml 수정</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="html" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@model IEnumerable&lt;NZWalksUI.Models.DTO.RegionDto>
@*
    For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}

&lt;h1 class="mt-3">Regions&lt;/h1>

&lt;div class="d-flex justify-content-end">
    &lt;a class="btn btn-secondary" asp-controller="Regions" asp-action="Add">Add Region&lt;/a>
&lt;/div>


&lt;table class="table-bordered">
    &lt;thead>
        &lt;tr>
            &lt;th>Id&lt;/th>
            &lt;th>Code&lt;/th>
            &lt;th>Name&lt;/th>
        &lt;/tr>
    &lt;/thead>
    &lt;tbody>
        @foreach (var walk in Model)
        {
            &lt;tr>
                &lt;td>@walk.Id&lt;/td>
                &lt;td>@walk.Code&lt;/td>
                &lt;td>@walk.Name&lt;/td>
            &lt;/tr>
        }
    &lt;/tbody>
&lt;/table></pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>AddRegionViewModel.cs 생성</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">namespace NZWalksUI.Models
{
    public class AddRegionViewModel
    {
        public string Code { get; set; }
        public string Name { get; set; }
        public string RegionImageUrl { get; set; }
    }
}
</pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>RegionsController.cs 수정</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Mvc;
using NZWalksUI.Models;
using NZWalksUI.Models.DTO;
using System.Net.Http;
using System.Text;
using System.Text.Json;

namespace NZWalksUI.Controllers
{
    public class RegionsController : Controller
    {
        private readonly IHttpClientFactory httpClientFactory;

        // Http 클라이언트 팩토리를 삽입하기 위한 생성자를 생성
        public RegionsController(IHttpClientFactory httpClientFactory)
        {
            this.httpClientFactory = httpClientFactory;
        }

        [HttpGet]
        // Index 액션 메서드
        public async Task&lt;IActionResult> Index()
        {
            List&lt;RegionDto> response = new List&lt;RegionDto>();
            try
            {
                // Get All Regions From Web API
                // 새로운 Http 클라이언트가 생성
                var client = httpClientFactory.CreateClient();

                // Web API로 GET 요청을 보냄
                var httpResponseMessage = await client.GetAsync("https://localhost:7256/api/regions");

                // 요청이 성공적으로 완료되었는지 확인
                httpResponseMessage.EnsureSuccessStatusCode();

                // 응답 본문을 JSON으로 읽어와 리스트에 추가
                response.AddRange(await httpResponseMessage.Content.ReadFromJsonAsync&lt;IEnumerable&lt;RegionDto>>());
            }
            catch (HttpRequestException e)
            {
                // 예외 발생 시 예외 메시지를 로그로 기록
                Console.WriteLine($"Request error: {e.Message}");
            }
            catch (Exception ex)
            {
                // 기타 예외 발생 시 예외 메시지를 로그로 기록
                Console.WriteLine($"An error occurred: {ex.Message}");
            }

            // View를 반환
            return View(response);
        }

        [HttpGet]
        public IActionResult Add()
        {
            return View(); // Add View 반환
        }

        [HttpPost]
        public async Task&lt;IActionResult> Add(AddRegionViewModel model)
        {
            var client = httpClientFactory.CreateClient();

            var httpRequestMessage = new HttpRequestMessage()
            {
                Method = HttpMethod.Post,
                RequestUri = new Uri("https://localhost:7256/api/regions"),
                Content = new StringContent(JsonSerializer.Serialize(model), Encoding.UTF8, "application/json") // JSON 요청 본문 설정
            };

            var httpResponseMessage = await client.SendAsync(httpRequestMessage);
            httpResponseMessage.EnsureSuccessStatusCode(); // 요청이 성공적으로 완료되었는지 확인

            var response = await httpResponseMessage.Content.ReadFromJsonAsync&lt;RegionDto>();

            if (response is not null)
            {
                return RedirectToAction("Index", "Regions"); // Index 액션으로 리디렉션
            }

            return View(); // View 반환
        }
    }
}
</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="553" height="334" src="https://lycos7560.com/wp-content/uploads/2024/10/image-193.png" alt="" class="wp-image-38627" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-193.png 553w, https://lycos7560.com/wp-content/uploads/2024/10/image-193-300x181.png 300w" sizes="(max-width: 553px) 100vw, 553px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<p><strong>Add.cshtml</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="css" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@model NZWalksUI.Models.AddRegionViewModel;

@*
*@

@{
}

&lt;h1 class="mt-3">Add Region&lt;/h1>

&lt;form method="post">

    &lt;div class="mt-3">
        &lt;label class="form-label">Code&lt;/label>
        &lt;input type="text" class="form-control" asp-for="Code" />
    &lt;/div>

    &lt;div class="mt-3">
        &lt;label class="form-label">Name&lt;/label>
        &lt;input type="text" class="form-control" asp-for="Name" />
    &lt;/div>

    &lt;div class="mt-3">
        &lt;label class="form-label">Image URL&lt;/label>
        &lt;input type="text" class="form-control" asp-for="RegionImageUrl" />
    &lt;/div>

    &lt;div class="mt-3">
        &lt;button type="submit" class="btn btn-primary">Save&lt;/button>
    &lt;/div>

&lt;/form></pre>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="831" height="346" src="https://lycos7560.com/wp-content/uploads/2024/10/image-194.png" alt="" class="wp-image-38628" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-194.png 831w, https://lycos7560.com/wp-content/uploads/2024/10/image-194-300x125.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-194-768x320.png 768w" sizes="(max-width: 831px) 100vw, 831px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1175" height="462" src="https://lycos7560.com/wp-content/uploads/2024/10/image-195.png" alt="" class="wp-image-38630" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-195.png 1175w, https://lycos7560.com/wp-content/uploads/2024/10/image-195-300x118.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-195-768x302.png 768w" sizes="(max-width: 1175px) 100vw, 1175px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1013" height="436" src="https://lycos7560.com/wp-content/uploads/2024/10/image-196.png" alt="" class="wp-image-38631" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-196.png 1013w, https://lycos7560.com/wp-content/uploads/2024/10/image-196-300x129.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-196-768x331.png 768w" sizes="(max-width: 1013px) 100vw, 1013px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="903" height="407" src="https://lycos7560.com/wp-content/uploads/2024/10/image-197.png" alt="" class="wp-image-38632" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-197.png 903w, https://lycos7560.com/wp-content/uploads/2024/10/image-197-300x135.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-197-768x346.png 768w" sizes="(max-width: 903px) 100vw, 903px" /></figure>
</div>
</div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">6. 단일 편집 기능</h3>



<p><strong>RegionsController.cs 수정</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Mvc;
using NZWalksUI.Models;
using NZWalksUI.Models.DTO;
using System.Net.Http;
using System.Text;
using System.Text.Json;

namespace NZWalksUI.Controllers
{
    public class RegionsController : Controller
    {
        private readonly IHttpClientFactory httpClientFactory;

        // Http 클라이언트 팩토리를 삽입하기 위한 생성자를 생성
        public RegionsController(IHttpClientFactory httpClientFactory)
        {
            this.httpClientFactory = httpClientFactory;
        }

        [HttpGet]
        // Index 액션 메서드
        public async Task&lt;IActionResult> Index()
        {
            List&lt;RegionDto> response = new List&lt;RegionDto>();


            try
            {
                // Get All Regions From Web API
                // 새로운 Http 클라이언트가 생성
                var client = httpClientFactory.CreateClient();

                // Web API로 GET 요청을 보냄
                var httpResponseMessage = await client.GetAsync("https://localhost:7256/api/regions");
               

                // 요청이 성공적으로 완료되었는지 확인
                httpResponseMessage.EnsureSuccessStatusCode();

                // // 응답 본문을 문자열로 읽어옴
                // var stringResponse = await httpResponseMessage.Content.ReadAsStringAsync();


                response.AddRange(await httpResponseMessage.Content.ReadFromJsonAsync&lt;IEnumerable&lt;RegionDto>>());

            }
            catch (HttpRequestException e)
            {
                // 예외 발생 시 예외 메시지를 로그로 기록
                Console.WriteLine($"Request error: {e.Message}");
            }
            catch (Exception ex)
            {
                // 기타 예외 발생 시 예외 메시지를 로그로 기록
                Console.WriteLine($"An error occurred: {ex.Message}");
            }

            // View를 반환
            return View(response);
        }

        [HttpGet]
        public IActionResult Add()
        { 
            return View();
        }

        [HttpPost]
        public async Task&lt;IActionResult> Add(AddRegionViewModel model)
        {
            var client = httpClientFactory.CreateClient();

            var httpRequestMessage = new HttpRequestMessage()
            {
                Method = HttpMethod.Post,
                RequestUri = new Uri("https://localhost:7256/api/regions"),
                Content = new StringContent(JsonSerializer.Serialize(model), Encoding.UTF8, "application/json")
            };

            var httpResponseMessage = await client.SendAsync(httpRequestMessage);
            httpResponseMessage.EnsureSuccessStatusCode();

            var respose = await httpResponseMessage.Content.ReadFromJsonAsync&lt;RegionDto>();

            if (respose is not null)
            {
                return RedirectToAction("Index", "Regions");
            }

            return View();
        }

        [HttpGet]
        public async Task&lt;IActionResult> Edit(Guid id)
        {
            ViewBag.Id = id;
            return View();
        
        }
    }
}
</pre>



<figure class="wp-block-image size-full"><img decoding="async" width="502" height="194" src="https://lycos7560.com/wp-content/uploads/2024/10/image-198.png" alt="" class="wp-image-38633" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-198.png 502w, https://lycos7560.com/wp-content/uploads/2024/10/image-198-300x116.png 300w" sizes="(max-width: 502px) 100vw, 502px" /></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Edite View 생성</p>



<p><strong>Edit.cshtml</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="html" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@*
    For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}

&lt;h1 class="mt-3">Edit Region&lt;/h1>

&lt;p>
    @ViewBag.Id
&lt;/p>
</pre>



<div style="height:41px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Index.cshtml 수정</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="html" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@model IEnumerable&lt;NZWalksUI.Models.DTO.RegionDto>
@*
    For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}

&lt;h1 class="mt-3">Regions&lt;/h1>

&lt;div class="d-flex justify-content-end">
    &lt;a class="btn btn-secondary" asp-controller="Regions" asp-action="Add">Add Region&lt;/a>
&lt;/div>


&lt;table class="table-bordered">
    &lt;thead>
        &lt;tr>
            &lt;th>Id&lt;/th>
            &lt;th>Code&lt;/th>
            &lt;th>Name&lt;/th>
            &lt;th> &lt;/th>
        &lt;/tr>
    &lt;/thead>
    &lt;tbody>
        @foreach (var walk in Model)
        {
            &lt;tr>
                &lt;td>@walk.Id&lt;/td>
                &lt;td>@walk.Code&lt;/td>
                &lt;td>@walk.Name&lt;/td>
                &lt;td>
                    &lt;a asp-controller="Regions" asp-action="Edit" asp-route-id="@walk.Id" 
                    class="btn btn-light">Eidt&lt;/a>
                &lt;/td>
            &lt;/tr>
        }
    &lt;/tbody>
&lt;/table></pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="824" height="472" src="https://lycos7560.com/wp-content/uploads/2024/10/image-199.png" alt="" class="wp-image-38634" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-199.png 824w, https://lycos7560.com/wp-content/uploads/2024/10/image-199-300x172.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-199-768x440.png 768w" sizes="(max-width: 824px) 100vw, 824px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="776" height="369" src="https://lycos7560.com/wp-content/uploads/2024/10/image-201.png" alt="" class="wp-image-38636" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-201.png 776w, https://lycos7560.com/wp-content/uploads/2024/10/image-201-300x143.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-201-768x365.png 768w" sizes="(max-width: 776px) 100vw, 776px" /></figure>
</div>
</div>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide"/>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Error.cshtml 수정</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="html" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@model NZWalksUI.Models.DTO.RegionDto

@{
}

&lt;h1 class="mt-3">Edit Region&lt;/h1>

@if (Model is not null)
{
    &lt;form method="post">
        &lt;div class="mt-3">
            &lt;label class="form-label">Id&lt;/label>
            &lt;input type="text" class="form-control" asp-for="Id"  readonly/>
        &lt;/div>
        &lt;div class="mt-3">
            &lt;label class="form-label">Code&lt;/label>
            &lt;input type="text" class="form-control" asp-for="Code" />
        &lt;/div>

        &lt;div class="mt-3">
            &lt;label class="form-label">Name&lt;/label>
            &lt;input type="text" class="form-control" asp-for="Name" />
        &lt;/div>

        &lt;div class="mt-3">
            &lt;label class="form-label">Image URL&lt;/label>
            &lt;input type="text" class="form-control" asp-for="RegionImageUrl" />
        &lt;/div>

        &lt;div class="mt-3">
            &lt;button type="submit" class="btn btn-primary">Save&lt;/button>
        &lt;/div>

    &lt;/form>
}
</pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>RegionsController.cs 수정</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Mvc;
using NZWalksUI.Models;
using NZWalksUI.Models.DTO;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Text.Json;
using static System.Net.WebRequestMethods;

namespace NZWalksUI.Controllers
{
    public class RegionsController : Controller
    {
        private readonly IHttpClientFactory httpClientFactory;

        // Http 클라이언트 팩토리를 삽입하기 위한 생성자를 생성
        public RegionsController(IHttpClientFactory httpClientFactory)
        {
            this.httpClientFactory = httpClientFactory;
        }

        [HttpGet]
        // Index 액션 메서드
        public async Task&lt;IActionResult> Index()
        {
            List&lt;RegionDto> response = new List&lt;RegionDto>();


            try
            {
                // Get All Regions From Web API
                // 새로운 Http 클라이언트가 생성
                var client = httpClientFactory.CreateClient();

                // Web API로 GET 요청을 보냄
                var httpResponseMessage = await client.GetAsync("https://localhost:7256/api/regions");
               

                // 요청이 성공적으로 완료되었는지 확인
                httpResponseMessage.EnsureSuccessStatusCode();

                // // 응답 본문을 문자열로 읽어옴
                // var stringResponse = await httpResponseMessage.Content.ReadAsStringAsync();


                response.AddRange(await httpResponseMessage.Content.ReadFromJsonAsync&lt;IEnumerable&lt;RegionDto>>());

            }
            catch (HttpRequestException e)
            {
                // 예외 발생 시 예외 메시지를 로그로 기록
                Console.WriteLine($"Request error: {e.Message}");
            }
            catch (Exception ex)
            {
                // 기타 예외 발생 시 예외 메시지를 로그로 기록
                Console.WriteLine($"An error occurred: {ex.Message}");
            }

            // View를 반환
            return View(response);
        }

        [HttpGet]
        public IActionResult Add()
        { 
            return View();
        }

        [HttpPost]
        public async Task&lt;IActionResult> Add(AddRegionViewModel model)
        {
            var client = httpClientFactory.CreateClient();

            var httpRequestMessage = new HttpRequestMessage()
            {
                Method = HttpMethod.Post,
                RequestUri = new Uri("https://localhost:7256/api/regions"),
                Content = new StringContent(JsonSerializer.Serialize(model), Encoding.UTF8, "application/json")
            };

            var httpResponseMessage = await client.SendAsync(httpRequestMessage);
            httpResponseMessage.EnsureSuccessStatusCode();

            var respose = await httpResponseMessage.Content.ReadFromJsonAsync&lt;RegionDto>();

            if (respose is not null)
            {
                return RedirectToAction("Index", "Regions");
            }

            return View();
        }

        [HttpGet]
        public async Task&lt;IActionResult> Edit(Guid id)
        {
            var client = httpClientFactory.CreateClient();

            var response = await client.GetFromJsonAsync&lt;RegionDto>($"https://localhost:7256/api/regions/{id.ToString()}");

            if (response is not null) 
            { 
                return View(response);
            }

            return View(null);
        
        }

        [HttpPost]
        public async Task&lt;IActionResult> Edit(RegionDto request) 
        {
            var client = httpClientFactory.CreateClient();

            var httpRequestMessage = new HttpRequestMessage()
            {
                Method = HttpMethod.Put,
                RequestUri = new Uri($"https://localhost:7256/api/regions/{request.Id}"),
                Content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json")
            };

            var httpResponseMessage = await client.SendAsync(httpRequestMessage);
            httpResponseMessage.EnsureSuccessStatusCode();

            var respose = await httpResponseMessage.Content.ReadFromJsonAsync&lt;RegionDto>();

            if (respose is not null)
            {
                return RedirectToAction("Edit", "Regions");
            }

            return View();
        }

    }
}
</pre>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="895" height="503" src="https://lycos7560.com/wp-content/uploads/2024/10/image-202.png" alt="" class="wp-image-38637" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-202.png 895w, https://lycos7560.com/wp-content/uploads/2024/10/image-202-300x169.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-202-768x432.png 768w" sizes="(max-width: 895px) 100vw, 895px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="884" height="478" src="https://lycos7560.com/wp-content/uploads/2024/10/image-204.png" alt="" class="wp-image-38639" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-204.png 884w, https://lycos7560.com/wp-content/uploads/2024/10/image-204-300x162.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-204-768x415.png 768w" sizes="(max-width: 884px) 100vw, 884px" /></figure>
</div>
</div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">7. 삭제 기능</h3>



<p><strong>Edit.cshtml 수정</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="html" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@model NZWalksUI.Models.DTO.RegionDto

@{
}

&lt;h1 class="mt-3">Edit Region&lt;/h1>

@if (Model is not null)
{
    &lt;form method="post">
        &lt;div class="mt-3">
            &lt;label class="form-label">Id&lt;/label>
            &lt;input type="text" class="form-control" asp-for="Id"  readonly/>
        &lt;/div>
        &lt;div class="mt-3">
            &lt;label class="form-label">Code&lt;/label>
            &lt;input type="text" class="form-control" asp-for="Code" />
        &lt;/div>

        &lt;div class="mt-3">
            &lt;label class="form-label">Name&lt;/label>
            &lt;input type="text" class="form-control" asp-for="Name" />
        &lt;/div>

        &lt;div class="mt-3">
            &lt;label class="form-label">Image URL&lt;/label>
            &lt;input type="text" class="form-control" asp-for="RegionImageUrl" />
        &lt;/div>

        &lt;div class="mt-3 d-flex justify-content-between">
            &lt;button type="submit" class="btn btn-primary">Save&lt;/button>
            &lt;button type="submit" asp-controller="Regions" asp-action="Delete" class="btn btn-danger">Delete&lt;/button>
        &lt;/div>

    &lt;/form>
}
</pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p>RegionsController.cs 수정</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Mvc;
using NZWalksUI.Models;
using NZWalksUI.Models.DTO;
using System.Text;
using System.Text.Json;

namespace NZWalksUI.Controllers
{
    public class RegionsController : Controller
    {
        private readonly IHttpClientFactory httpClientFactory;

        // Http 클라이언트 팩토리를 삽입하기 위한 생성자를 생성
        public RegionsController(IHttpClientFactory httpClientFactory)
        {
            this.httpClientFactory = httpClientFactory;
        }

        [HttpGet]
        // Index 액션 메서드
        public async Task&lt;IActionResult> Index()
        {
            List&lt;RegionDto> response = new List&lt;RegionDto>();


            try
            {
                // Get All Regions From Web API
                // 새로운 Http 클라이언트가 생성
                var client = httpClientFactory.CreateClient();

                // Web API로 GET 요청을 보냄
                var httpResponseMessage = await client.GetAsync("https://localhost:7256/api/regions");
               

                // 요청이 성공적으로 완료되었는지 확인
                httpResponseMessage.EnsureSuccessStatusCode();

                // // 응답 본문을 문자열로 읽어옴
                // var stringResponse = await httpResponseMessage.Content.ReadAsStringAsync();


                response.AddRange(await httpResponseMessage.Content.ReadFromJsonAsync&lt;IEnumerable&lt;RegionDto>>());

            }
            catch (HttpRequestException e)
            {
                // 예외 발생 시 예외 메시지를 로그로 기록
                Console.WriteLine($"Request error: {e.Message}");
            }
            catch (Exception ex)
            {
                // 기타 예외 발생 시 예외 메시지를 로그로 기록
                Console.WriteLine($"An error occurred: {ex.Message}");
            }

            // View를 반환
            return View(response);
        }

        [HttpGet]
        public IActionResult Add()
        { 
            return View();
        }

        [HttpPost]
        public async Task&lt;IActionResult> Add(AddRegionViewModel model)
        {
            var client = httpClientFactory.CreateClient();

            var httpRequestMessage = new HttpRequestMessage()
            {
                Method = HttpMethod.Post,
                RequestUri = new Uri("https://localhost:7256/api/regions"),
                Content = new StringContent(JsonSerializer.Serialize(model), Encoding.UTF8, "application/json")
            };

            var httpResponseMessage = await client.SendAsync(httpRequestMessage);
            httpResponseMessage.EnsureSuccessStatusCode();

            var respose = await httpResponseMessage.Content.ReadFromJsonAsync&lt;RegionDto>();

            if (respose is not null)
            {
                return RedirectToAction("Index", "Regions");
            }

            return View();
        }

        [HttpGet]
        public async Task&lt;IActionResult> Edit(Guid id)
        {
            var client = httpClientFactory.CreateClient();

            var response = await client.GetFromJsonAsync&lt;RegionDto>($"https://localhost:7256/api/regions/{id.ToString()}");

            if (response is not null) 
            { 
                return View(response);
            }

            return View(null);
        
        }

        [HttpPost]
        public async Task&lt;IActionResult> Edit(RegionDto request) 
        {
            var client = httpClientFactory.CreateClient();

            var httpRequestMessage = new HttpRequestMessage()
            {
                Method = HttpMethod.Put,
                RequestUri = new Uri($"https://localhost:7256/api/regions/{request.Id}"),
                Content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json")
            };

            var httpResponseMessage = await client.SendAsync(httpRequestMessage);
            httpResponseMessage.EnsureSuccessStatusCode();

            var respose = await httpResponseMessage.Content.ReadFromJsonAsync&lt;RegionDto>();

            if (respose is not null)
            {
                return RedirectToAction("Edit", "Regions");
            }

            return View();
        }

        [HttpPost]
        public async Task&lt;IActionResult> Delete(RegionDto request)
        {
            try 
            {
                var client = httpClientFactory.CreateClient();

                var httpResponseMessage = await client.DeleteAsync($"https://localhost:7256/api/regions/{request.Id}");
                httpResponseMessage.EnsureSuccessStatusCode();

                return RedirectToAction("Index", "Regions");

            }
            catch (Exception ex) 
            { 
            
            }

            return View("Edit");
        }

    }
}
</pre>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="1214" height="479" src="https://lycos7560.com/wp-content/uploads/2024/10/image-205.png" alt="" class="wp-image-38640" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-205.png 1214w, https://lycos7560.com/wp-content/uploads/2024/10/image-205-300x118.png 300w, https://lycos7560.com/wp-content/uploads/2024/10/image-205-768x303.png 768w" sizes="(max-width: 1214px) 100vw, 1214px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:50%">
<figure class="wp-block-image size-full"><img decoding="async" width="557" height="315" src="https://lycos7560.com/wp-content/uploads/2024/10/image-206.png" alt="" class="wp-image-38641" srcset="https://lycos7560.com/wp-content/uploads/2024/10/image-206.png 557w, https://lycos7560.com/wp-content/uploads/2024/10/image-206-300x170.png 300w" sizes="(max-width: 557px) 100vw, 557px" /></figure>
</div>
</div>



<p></p>
<p>The post <a href="https://lycos7560.com/c/consuming-rest-web-apis/38585/">Consuming REST Web APIs</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/consuming-rest-web-apis/38585/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
