<?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>Performance Archives - 어제와 내일의 나 그 사이의 이야기</title>
	<atom:link href="https://lycos7560.com/tag/performance/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>생각의 흐름을 타고 다니며 만드는 블로그</description>
	<lastBuildDate>Tue, 25 Nov 2025 14:58:38 +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>Performance Archives - 어제와 내일의 나 그 사이의 이야기</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Apache Virtual Host Guide (Apache 가상 호스트 설정)</title>
		<link>https://lycos7560.com/ubuntu/apache-%ea%b0%80%ec%83%81%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c/40358/</link>
					<comments>https://lycos7560.com/ubuntu/apache-%ea%b0%80%ec%83%81%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c/40358/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Tue, 25 Nov 2025 14:56:56 +0000</pubDate>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[기타]]></category>
		<category><![CDATA[301Redirect]]></category>
		<category><![CDATA[301리다이렉트]]></category>
		<category><![CDATA[403Forbidden]]></category>
		<category><![CDATA[404NotFound]]></category>
		<category><![CDATA[500Error]]></category>
		<category><![CDATA[502Error]]></category>
		<category><![CDATA[503Error]]></category>
		<category><![CDATA[504GatewayTimeout]]></category>
		<category><![CDATA[AccessControl]]></category>
		<category><![CDATA[AccessLog]]></category>
		<category><![CDATA[AllowOverride]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Apache2]]></category>
		<category><![CDATA[ApacheModules]]></category>
		<category><![CDATA[ARecord]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[BasicAuth]]></category>
		<category><![CDATA[BestPractices]]></category>
		<category><![CDATA[Brotli]]></category>
		<category><![CDATA[BrowserCache]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[Certbot]]></category>
		<category><![CDATA[Cheatsheet]]></category>
		<category><![CDATA[chmod]]></category>
		<category><![CDATA[Chown]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Clustering]]></category>
		<category><![CDATA[CNAME]]></category>
		<category><![CDATA[command]]></category>
		<category><![CDATA[Compression]]></category>
		<category><![CDATA[ConfigTest]]></category>
		<category><![CDATA[CrtFile]]></category>
		<category><![CDATA[CSR]]></category>
		<category><![CDATA[CSRF]]></category>
		<category><![CDATA[Curl]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[DirectoryIndex]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[DocumentRoot]]></category>
		<category><![CDATA[Domain]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[ErrorLog]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[Flask]]></category>
		<category><![CDATA[FreeSSL]]></category>
		<category><![CDATA[Guide]]></category>
		<category><![CDATA[Gzip]]></category>
		<category><![CDATA[HighAvailability]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[HSTS]]></category>
		<category><![CDATA[htpasswd]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[HTTP2]]></category>
		<category><![CDATA[HTTP3]]></category>
		<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[Iptables]]></category>
		<category><![CDATA[Journalctl]]></category>
		<category><![CDATA[KeepAlive]]></category>
		<category><![CDATA[KeyFile]]></category>
		<category><![CDATA[LetsEncrypt]]></category>
		<category><![CDATA[LinuxCommands]]></category>
		<category><![CDATA[LinuxServer]]></category>
		<category><![CDATA[LoadBalancing]]></category>
		<category><![CDATA[LoadTest]]></category>
		<category><![CDATA[LogAnalysis]]></category>
		<category><![CDATA[Manual]]></category>
		<category><![CDATA[mod_deflate]]></category>
		<category><![CDATA[mod_expires]]></category>
		<category><![CDATA[mod_headers]]></category>
		<category><![CDATA[mod_proxy]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[mod_ssl]]></category>
		<category><![CDATA[MPM]]></category>
		<category><![CDATA[MPM_Event]]></category>
		<category><![CDATA[MPM_Worker]]></category>
		<category><![CDATA[NameServer]]></category>
		<category><![CDATA[netstat]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Nodejs]]></category>
		<category><![CDATA[OpenSSL]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[options]]></category>
		<category><![CDATA[PemFile]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Permission]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[port]]></category>
		<category><![CDATA[PortForwarding]]></category>
		<category><![CDATA[PrivateKey]]></category>
		<category><![CDATA[Proxy]]></category>
		<category><![CDATA[ProxyPass]]></category>
		<category><![CDATA[ProxyPassReverse]]></category>
		<category><![CDATA[PublicKey]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Redirect]]></category>
		<category><![CDATA[Reference]]></category>
		<category><![CDATA[RequireAllGranted]]></category>
		<category><![CDATA[Restore]]></category>
		<category><![CDATA[ReverseProxy]]></category>
		<category><![CDATA[Rewrite]]></category>
		<category><![CDATA[RewriteRule]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SelfSigned]]></category>
		<category><![CDATA[ServerConfig]]></category>
		<category><![CDATA[ServerMaintenance]]></category>
		<category><![CDATA[ServerMigration]]></category>
		<category><![CDATA[ServerMonitoring]]></category>
		<category><![CDATA[ServerName]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[SpeedUp]]></category>
		<category><![CDATA[ss]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[subdomain]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[systemctl]]></category>
		<category><![CDATA[systemd]]></category>
		<category><![CDATA[TCP]]></category>
		<category><![CDATA[Terminal]]></category>
		<category><![CDATA[TLS]]></category>
		<category><![CDATA[Tomcat]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[TUTORIAL]]></category>
		<category><![CDATA[UbuntuServer]]></category>
		<category><![CDATA[ufw]]></category>
		<category><![CDATA[URLRewrite]]></category>
		<category><![CDATA[Vhost]]></category>
		<category><![CDATA[VirtualHost]]></category>
		<category><![CDATA[VPS]]></category>
		<category><![CDATA[WAS]]></category>
		<category><![CDATA[WebAdmin]]></category>
		<category><![CDATA[WebDev]]></category>
		<category><![CDATA[WebPerformance]]></category>
		<category><![CDATA[WebSecurity]]></category>
		<category><![CDATA[WebServer]]></category>
		<category><![CDATA[WebSocket]]></category>
		<category><![CDATA[Wget]]></category>
		<category><![CDATA[WSS]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[가상호스트]]></category>
		<category><![CDATA[가이드]]></category>
		<category><![CDATA[고가용성]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[권한설정]]></category>
		<category><![CDATA[기본인증]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[네임서버]]></category>
		<category><![CDATA[네트워크]]></category>
		<category><![CDATA[데비안]]></category>
		<category><![CDATA[뎁스옵스]]></category>
		<category><![CDATA[도메인]]></category>
		<category><![CDATA[디버깅]]></category>
		<category><![CDATA[레퍼런스]]></category>
		<category><![CDATA[렛츠인크립트]]></category>
		<category><![CDATA[로그분석]]></category>
		<category><![CDATA[로드밸런싱]]></category>
		<category><![CDATA[리눅스명령어]]></category>
		<category><![CDATA[리눅스서버]]></category>
		<category><![CDATA[리다이렉트]]></category>
		<category><![CDATA[리버스프록시]]></category>
		<category><![CDATA[매뉴얼]]></category>
		<category><![CDATA[명령어]]></category>
		<category><![CDATA[모범사례]]></category>
		<category><![CDATA[무료인증서]]></category>
		<category><![CDATA[문제해결]]></category>
		<category><![CDATA[방화벽]]></category>
		<category><![CDATA[백업]]></category>
		<category><![CDATA[백엔드]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[복구]]></category>
		<category><![CDATA[부하테스트]]></category>
		<category><![CDATA[브라우저캐시]]></category>
		<category><![CDATA[사설인증서]]></category>
		<category><![CDATA[사용법]]></category>
		<category><![CDATA[서버모니터링]]></category>
		<category><![CDATA[서버설정]]></category>
		<category><![CDATA[서버유지보수]]></category>
		<category><![CDATA[서버이전]]></category>
		<category><![CDATA[서브도메인]]></category>
		<category><![CDATA[설정확인]]></category>
		<category><![CDATA[성능최적화]]></category>
		<category><![CDATA[속도향상]]></category>
		<category><![CDATA[시스템관리]]></category>
		<category><![CDATA[아파치]]></category>
		<category><![CDATA[아파치2]]></category>
		<category><![CDATA[아파치모듈]]></category>
		<category><![CDATA[압축]]></category>
		<category><![CDATA[액세스로그]]></category>
		<category><![CDATA[에러로그]]></category>
		<category><![CDATA[우분투]]></category>
		<category><![CDATA[웹개발]]></category>
		<category><![CDATA[웹보안]]></category>
		<category><![CDATA[웹서버]]></category>
		<category><![CDATA[웹성능]]></category>
		<category><![CDATA[웹소켓]]></category>
		<category><![CDATA[웹어드민]]></category>
		<category><![CDATA[웹호스팅]]></category>
		<category><![CDATA[인증서]]></category>
		<category><![CDATA[인프라]]></category>
		<category><![CDATA[접근제어]]></category>
		<category><![CDATA[최적화]]></category>
		<category><![CDATA[치트시트]]></category>
		<category><![CDATA[캐싱]]></category>
		<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=40358</guid>

					<description><![CDATA[<p>기본 설정 확인 Apache 상태 및 설정 검증 필수 모듈 활성화 가상호스트 생성 1. 설정 파일 생성 2. 기본 HTTP 가상호스트 3. HTTP → HTTPS 리다이렉트 4. HTTPS 가상호스트 (정적 파일) 다양한 설정 예제 리버스 프록시 WebSocket 프록시 여러 백엔드로 로드 밸런싱 경로별 다른 백엔드 라우팅 특정 IP만 접근 허용 SSL/HTTPS 설정 Certbot으로 SSL 인증서 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/ubuntu/apache-%ea%b0%80%ec%83%81%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c/40358/">Apache Virtual Host Guide (Apache 가상 호스트 설정)</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-692d8850      "
					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="#기본-설정-확인" class="uagb-toc-link__trigger">기본 설정 확인</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#apache-상태-및-설정-검증" class="uagb-toc-link__trigger">Apache 상태 및 설정 검증</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#필수-모듈-활성화" class="uagb-toc-link__trigger">필수 모듈 활성화</a></li></ul></li><li class="uagb-toc__list"><a href="#가상호스트-생성" class="uagb-toc-link__trigger">가상호스트 생성</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-설정-파일-생성" class="uagb-toc-link__trigger">1. 설정 파일 생성</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-기본-http-가상호스트" class="uagb-toc-link__trigger">2. 기본 HTTP 가상호스트</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-http-https-리다이렉트" class="uagb-toc-link__trigger">3. HTTP → HTTPS 리다이렉트</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#4-https-가상호스트-정적-파일" class="uagb-toc-link__trigger">4. HTTPS 가상호스트 (정적 파일)</a></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#다양한-설정-예제" class="uagb-toc-link__trigger">다양한 설정 예제</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="#websocket-프록시" class="uagb-toc-link__trigger">WebSocket 프록시</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="#특정-ip만-접근-허용" class="uagb-toc-link__trigger">특정 IP만 접근 허용</a></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#sslhttps-설정" class="uagb-toc-link__trigger">SSL/HTTPS 설정</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#certbot으로-ssl-인증서-발급" class="uagb-toc-link__trigger">Certbot으로 SSL 인증서 발급</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#ssl-설정-최적화" class="uagb-toc-link__trigger">SSL 설정 최적화</a></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#가상호스트-관리" class="uagb-toc-link__trigger">가상호스트 관리</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></ul></li><li class="uagb-toc__list"><a href="#문제-해결" class="uagb-toc-link__trigger">문제 해결</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></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#보안-강화" class="uagb-toc-link__trigger">보안 강화</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="#htpasswd-파일-생성" class="uagb-toc-link__trigger">.htpasswd 파일 생성</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#rate-limiting-mod-ratelimit" class="uagb-toc-link__trigger">Rate Limiting (mod_ratelimit)</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#성능-최적화" class="uagb-toc-link__trigger">성능 최적화</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="#gzip-brotli-압축" class="uagb-toc-link__trigger">Gzip &amp; Brotli 압축</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#keepalive-설정" class="uagb-toc-link__trigger">KeepAlive 설정</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#mpm-설정-최적화" class="uagb-toc-link__trigger">MPM 설정 최적화</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#디렉토리-구조" class="uagb-toc-link__trigger">디렉토리 구조</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#apache-설정-파일-구조" class="uagb-toc-link__trigger">Apache 설정 파일 구조</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></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#유용한-명령어-모음" class="uagb-toc-link__trigger">유용한 명령어 모음</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></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#문제-상황별-체크리스트" class="uagb-toc-link__trigger">문제 상황별 체크리스트</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="#502-bad-gateway-발생-시" class="uagb-toc-link__trigger">502 Bad Gateway 발생 시</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#ssl-인증서-오류-시" class="uagb-toc-link__trigger">SSL 인증서 오류 시</a></ul></ul></ul></ul></ul></ul></ul></ul></ul></ul></ul></ol>					</div>
									</div>
				</div>
			


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



<h2 class="wp-block-heading">기본 설정 확인</h2>



<h3 class="wp-block-heading">Apache 상태 및 설정 검증</h3>



<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=""># Apache 서비스 상태 확인
sudo systemctl status apache2

# 설정 파일 문법 검사
sudo apache2ctl configtest

# 활성화된 가상호스트 목록 확인
sudo apache2ctl -S

# Apache 버전 확인
apache2 -v

# 로드된 모듈 확인
apache2ctl -M
</pre>



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



<h3 class="wp-block-heading">필수 모듈 활성화</h3>



<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=""># 프록시 및 SSL 관련 모듈 활성화
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod ssl
sudo a2enmod rewrite
sudo a2enmod headers

# 변경사항 적용
sudo systemctl restart apache2
</pre>



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



<h2 class="wp-block-heading">가상호스트 생성</h2>



<h3 class="wp-block-heading">1. 설정 파일 생성</h3>



<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=""># 새 가상호스트 설정 파일 생성
sudo vim /etc/apache2/sites-available/testdomain.conf
</pre>



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



<h3 class="wp-block-heading">2. 기본 HTTP 가상호스트</h3>



<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="">&lt;VirtualHost *:80>
    ServerName testdomain.com
    ServerAlias www.testdomain.com
    ServerAdmin admin@testdomain.com
    
    DocumentRoot /var/www/testdomain
    
    &lt;Directory /var/www/testdomain>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    &lt;/Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/testdomain_error.log
    CustomLog ${APACHE_LOG_DIR}/testdomain_access.log combined
&lt;/VirtualHost>
</pre>



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



<h3 class="wp-block-heading">3. HTTP → HTTPS 리다이렉트</h3>



<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="">&lt;VirtualHost *:80>
    ServerName testdomain.com
    ServerAlias www.testdomain.com
    
    # 모든 HTTP 요청을 HTTPS로 리다이렉트
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
    
    ErrorLog ${APACHE_LOG_DIR}/testdomain_http_error.log
    CustomLog ${APACHE_LOG_DIR}/testdomain_http_access.log combined
&lt;/VirtualHost>
</pre>



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



<h3 class="wp-block-heading">4. HTTPS 가상호스트 (정적 파일)</h3>



<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="">&lt;VirtualHost *:443>
    ServerName testdomain.com
    ServerAlias www.testdomain.com
    ServerAdmin admin@testdomain.com
    
    DocumentRoot /var/www/testdomain
    
    &lt;Directory /var/www/testdomain>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    &lt;/Directory>
    
    # SSL 설정
    SSLEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/testdomain.com/privkey.pem
    
    # 보안 헤더
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    Header always set X-Content-Type-Options nosniff
    Header always set X-Frame-Options SAMEORIGIN
    Header always set X-XSS-Protection "1; mode=block"
    
    ErrorLog ${APACHE_LOG_DIR}/testdomain_https_error.log
    CustomLog ${APACHE_LOG_DIR}/testdomain_https_access.log combined
&lt;/VirtualHost>
</pre>



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



<h2 class="wp-block-heading">다양한 설정 예제</h2>



<h3 class="wp-block-heading">리버스 프록시 </h3>



<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="">&lt;VirtualHost *:443>
    ServerName api.testdomain.com
    
    # SSL 설정
    SSLEngine on
    SSLProxyEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/api.testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/api.testdomain.com/privkey.pem
    
    # 프록시 설정
    ProxyPreserveHost On
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
    
    # 프록시 헤더 설정
    RequestHeader set X-Forwarded-Proto "https"
    RequestHeader set X-Forwarded-Port "443"
    ProxyAddHeaders On
    
    # 타임아웃 설정
    ProxyTimeout 300
    
    # 요청 크기 제한 해제
    LimitRequestBody 0
    LimitRequestLine 65536
    LimitRequestFieldSize 65536
    
    ErrorLog ${APACHE_LOG_DIR}/api_error.log
    CustomLog ${APACHE_LOG_DIR}/api_access.log combined
&lt;/VirtualHost>
</pre>



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



<h3 class="wp-block-heading">WebSocket 프록시</h3>



<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="">&lt;VirtualHost *:443>
    ServerName ws.testdomain.com
    
    SSLEngine on
    SSLProxyEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/ws.testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/ws.testdomain.com/privkey.pem
    
    # WebSocket 지원을 위한 프록시 설정
    ProxyPreserveHost On
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /(.*)           ws://localhost:8080/$1 [P,L]
    RewriteCond %{HTTP:Upgrade} !=websocket [NC]
    RewriteRule /(.*)           http://localhost:8080/$1 [P,L]
    
    ProxyPassReverse / http://localhost:8080/
    
    ErrorLog ${APACHE_LOG_DIR}/ws_error.log
    CustomLog ${APACHE_LOG_DIR}/ws_access.log combined
&lt;/VirtualHost>
</pre>



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



<h3 class="wp-block-heading">여러 백엔드로 로드 밸런싱</h3>



<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="">sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests</pre>



<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="">&lt;Proxy balancer://mycluster>
    BalancerMember http://localhost:3001
    BalancerMember http://localhost:3002
    BalancerMember http://localhost:3003
    ProxySet lbmethod=byrequests
&lt;/Proxy>

&lt;VirtualHost *:443>
    ServerName testdomain.com
    
    SSLEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/testdomain.com/privkey.pem
    
    ProxyPreserveHost On
    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/
    
    ErrorLog ${APACHE_LOG_DIR}/testdomain_error.log
    CustomLog ${APACHE_LOG_DIR}/testdomain_access.log combined
&lt;/VirtualHost>
</pre>



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



<h3 class="wp-block-heading">경로별 다른 백엔드 라우팅</h3>



<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="">&lt;VirtualHost *:443>
    ServerName testdomain.com
    
    SSLEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/testdomain.com/privkey.pem
    
    # API 요청은 백엔드 서버로
    ProxyPass /api http://localhost:8000/api
    ProxyPassReverse /api http://localhost:8000/api
    
    # 정적 파일은 직접 제공
    DocumentRoot /var/www/testdomain
    &lt;Directory /var/www/testdomain>
        Require all granted
    &lt;/Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/testdomain_error.log
    CustomLog ${APACHE_LOG_DIR}/testdomain_access.log combined
&lt;/VirtualHost>
</pre>



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



<h3 class="wp-block-heading">특정 IP만 접근 허용</h3>



<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="">&lt;VirtualHost *:443>
    ServerName admin.testdomain.com
    
    SSLEngine on
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/admin.testdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/admin.testdomain.com/privkey.pem
    
    DocumentRoot /var/www/admin
    
    &lt;Directory /var/www/admin>
        # 특정 IP만 허용
        Require ip 192.168.1.0/24
        Require ip 10.0.0.5
    &lt;/Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/admin_error.log
    CustomLog ${APACHE_LOG_DIR}/admin_access.log combined
&lt;/VirtualHost>
</pre>



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



<h2 class="wp-block-heading">SSL/HTTPS 설정</h2>



<h3 class="wp-block-heading">Certbot으로 SSL 인증서 발급</h3>



<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=""># 자동 설정 (권장)
sudo certbot --apache -d testdomain.com -d www.testdomain.com

# 인증서만 발급 (수동 설정)
sudo certbot certonly --standalone -d testdomain.com -d www.testdomain.com

# 와일드카드 인증서 발급
sudo certbot certonly --manual --preferred-challenges dns -d testdomain.com -d *.testdomain.com

# 인증서 갱신 테스트
sudo certbot renew --dry-run

# 인증서 강제 갱신
sudo certbot renew --force-renewal

# 인증서 자동 갱신 크론잡 설정
sudo crontab -e
# 매일 새벽 2시에 갱신 확인
0 2 * * * certbot renew --quiet
</pre>



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



<h3 class="wp-block-heading">SSL 설정 최적화</h3>



<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=""># /etc/letsencrypt/options-ssl-apache.conf 참고
# 또는 직접 설정

SSLEngine on
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off

# OCSP Stapling 활성화
SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
</pre>



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



<h2 class="wp-block-heading">가상호스트 관리</h2>



<h3 class="wp-block-heading">활성화/비활성화</h3>



<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=""># 가상호스트 활성화
sudo a2ensite testdomain.conf

# 가상호스트 비활성화
sudo a2dissite testdomain.conf

# 기본 사이트 비활성화
sudo a2dissite 000-default.conf

# 설정 적용 (다운타임 없음)
sudo systemctl reload apache2

# 설정 재시작 (다운타임 발생)
sudo systemctl restart apache2
</pre>



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



<h3 class="wp-block-heading">모듈 관리</h3>



<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=""># 모듈 활성화
sudo a2enmod 모듈명

# 모듈 비활성화
sudo a2dismod 모듈명

# 자주 사용하는 모듈들
sudo a2enmod rewrite      # URL 재작성
sudo a2enmod headers      # HTTP 헤더 조작
sudo a2enmod proxy        # 프록시 기능
sudo a2enmod proxy_http   # HTTP 프록시
sudo a2enmod proxy_wstunnel  # WebSocket 프록시
sudo a2enmod ssl          # SSL/TLS
sudo a2enmod deflate      # 압축
sudo a2enmod expires      # 캐시 제어
</pre>



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



<h2 class="wp-block-heading">문제 해결</h2>



<h3 class="wp-block-heading">로그 확인</h3>



<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=""># 실시간 에러 로그 모니터링
sudo tail -f /var/log/apache2/error.log

# 실시간 액세스 로그 모니터링
sudo tail -f /var/log/apache2/access.log

# 특정 가상호스트 로그
sudo tail -f /var/log/apache2/testdomain_error.log

# 마지막 100줄 확인
sudo tail -100 /var/log/apache2/error.log

# 특정 키워드로 검색
sudo grep "testdomain" /var/log/apache2/*.log

# 에러만 필터링
sudo grep "error" /var/log/apache2/error.log

# 최근 에러 (systemd)
sudo journalctl -u apache2 -n 50
</pre>



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



<h3 class="wp-block-heading">연결 테스트</h3>



<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=""># HTTP 응답 헤더 확인
curl -I http://testdomain.com/

# HTTPS 응답 헤더 확인
curl -I https://testdomain.com/

# 상세 디버깅 정보
curl -v https://testdomain.com/

# POST 요청 테스트
curl -X POST https://testdomain.com/api/endpoint \
  -H "Content-Type: application/json" \
  -d '{"key":"value"}'

# SSL 인증서 정보 확인
openssl s_client -connect testdomain.com:443 -servername testdomain.com &lt; /dev/null

# 백엔드 서비스 테스트
curl -v http://localhost:3000/
</pre>



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



<h3 class="wp-block-heading">포트 및 프로세스 확인</h3>



<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=""># 특정 포트 사용 확인
sudo netstat -tlnp | grep :80
sudo netstat -tlnp | grep :443
sudo netstat -tlnp | grep :3000

# 또는 ss 명령어 사용 (더 빠름)
sudo ss -tlnp | grep :80

# Apache 프로세스 확인
ps aux | grep apache2

# 열린 파일 확인
sudo lsof -i :80
sudo lsof -i :443
</pre>



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



<h3 class="wp-block-heading">일반적인 문제 해결</h3>



<h4 class="wp-block-heading">포트 충돌 문제 체크</h4>



<p>Apache + Nginx 동시 사용 시 자주 발생<br>특히 Certbot &#8211;apache 사용 시 충돌할 수 있음.</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="">sudo ss -tlnp | grep :80
sudo ss -tlnp | grep :443

// 만약 Nginx가 잡고 있다면
sudo systemctl stop nginx
sudo systemctl disable nginx
</pre>



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



<h4 class="wp-block-heading">403 Forbidden 오류</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=""># Directory 권한 확인
&lt;Directory /var/www/testdomain>
    Require all granted
    # 또는
    Options +Indexes
&lt;/Directory>

# 파일 시스템 권한 확인
sudo chmod -R 755 /var/www/testdomain
sudo chown -R www-data:www-data /var/www/testdomain
</pre>



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



<h4 class="wp-block-heading">500 Internal Server Error</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=""># 설정 문법 오류 확인
sudo apache2ctl configtest

# .htaccess 문제 확인
sudo tail -50 /var/log/apache2/error.log

# SELinux 확인 (CentOS/RHEL)
sudo setenforce 0  # 임시 비활성화
</pre>



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



<h4 class="wp-block-heading">SSL 인증서 오류</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=""># 인증서 파일 존재 확인
ls -la /etc/letsencrypt/live/testdomain.com/

# 인증서 유효기간 확인
sudo certbot certificates

# 인증서 갱신
sudo certbot renew

# SSL 인증서 권한 변경 주의
# SSLCertificateFile: file '/etc/letsencrypt/live/.../fullchain.pem' does not exist or is empty // 원인은 보통 인증서 폴더 권한 문제

sudo chmod 755 /etc/letsencrypt/live
sudo chmod 644 /etc/letsencrypt/live/DOMAIN/fullchain.pem
sudo chmod 600 /etc/letsencrypt/live/DOMAIN/privkey.pem

</pre>



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



<h4 class="wp-block-heading">프록시 오류 (502 Bad Gateway)</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=""># 백엔드 서비스 작동 확인
curl http://localhost:3000/

# SELinux 설정 (CentOS/RHEL)
sudo setsebool -P httpd_can_network_connect 1

# 프록시 타임아웃 늘리기
ProxyTimeout 600
</pre>



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



<h4 class="wp-block-heading">Proxy 헤더 관련 ForwardedHeaders 추가</h4>



<p>ASP.NET Core, Node.js, Django 모두 HTTPS 프록시 환경에서 필수</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="">RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Host %{HTTP_HOST}s

# (예시) ASP.NET Core
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});</pre>



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



<h2 class="wp-block-heading">보안 강화</h2>



<h3 class="wp-block-heading">보안 헤더 설정</h3>



<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="">&lt;VirtualHost *:443>
    ServerName testdomain.com
    
    # ... SSL 설정 ...
    
    # HSTS (HTTP Strict Transport Security)
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    
    # XSS 방지
    Header always set X-XSS-Protection "1; mode=block"
    
    # MIME 타입 스니핑 방지
    Header always set X-Content-Type-Options "nosniff"
    
    # 클릭재킹 방지
    Header always set X-Frame-Options "SAMEORIGIN"
    
    # Referrer 정책
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    
    # CSP (Content Security Policy)
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"
    
    # 서버 정보 숨기기
    ServerTokens Prod
    ServerSignature Off
&lt;/VirtualHost>
</pre>



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



<h3 class="wp-block-heading">접근 제어</h3>



<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=""># IP 기반 접근 제어
&lt;Directory /var/www/admin>
    # 특정 IP만 허용
    Require ip 192.168.1.0/24
    Require ip 10.0.0.5
    
    # 또는 특정 IP 차단
    Require all granted
    Require not ip 192.168.1.100
&lt;/Directory>

# HTTP Basic 인증
&lt;Directory /var/www/protected>
    AuthType Basic
    AuthName "Restricted Area"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
&lt;/Directory>
</pre>



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



<h3 class="wp-block-heading">.htpasswd 파일 생성</h3>



<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=""># htpasswd 파일 생성 (첫 사용자)
sudo htpasswd -c /etc/apache2/.htpasswd username

# 추가 사용자 등록 (-c 옵션 제거)
sudo htpasswd /etc/apache2/.htpasswd username2
</pre>



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



<h3 class="wp-block-heading">Rate Limiting (mod_ratelimit)</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;Location /api>
    SetOutputFilter RATE_LIMIT
    SetEnv rate-limit 400
    SetEnv rate-initial-burst 100
&lt;/Location>
</pre>



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



<h2 class="wp-block-heading">성능 최적화</h2>



<h3 class="wp-block-heading">캐싱 설정</h3>



<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="">&lt;VirtualHost *:443>
    ServerName testdomain.com
    
    # ... 기본 설정 ...
    
    # 정적 파일 캐싱
    &lt;IfModule mod_expires.c>
        ExpiresActive On
        
        # 이미지
        ExpiresByType image/jpg "access plus 1 year"
        ExpiresByType image/jpeg "access plus 1 year"
        ExpiresByType image/gif "access plus 1 year"
        ExpiresByType image/png "access plus 1 year"
        ExpiresByType image/webp "access plus 1 year"
        ExpiresByType image/svg+xml "access plus 1 year"
        
        # CSS/JS
        ExpiresByType text/css "access plus 1 month"
        ExpiresByType application/javascript "access plus 1 month"
        
        # 폰트
        ExpiresByType font/woff2 "access plus 1 year"
        ExpiresByType font/woff "access plus 1 year"
        
        # HTML
        ExpiresByType text/html "access plus 1 hour"
    &lt;/IfModule>
    
    # Cache-Control 헤더
    &lt;FilesMatch "\.(jpg|jpeg|png|gif|webp|svg|css|js|woff|woff2)$">
        Header set Cache-Control "max-age=31536000, public"
    &lt;/FilesMatch>
&lt;/VirtualHost>
</pre>



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



<h3 class="wp-block-heading">Gzip &amp; Brotli 압축</h3>



<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="">&lt;IfModule mod_deflate.c>
    # 압축 활성화
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
    AddOutputFilterByType DEFLATE application/javascript application/json
    AddOutputFilterByType DEFLATE application/xml application/xhtml+xml
    AddOutputFilterByType DEFLATE image/svg+xml
    
    # 이미지는 압축 제외 (이미 압축됨)
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp)$ no-gzip
&lt;/IfModule>


sudo apt install libapache2-mod-brotli
sudo a2enmod brotli

&lt;IfModule mod_brotli.c>
    BrotliCompressionQuality 5
    AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css application/javascript application/json image/svg+xml
&lt;/IfModule></pre>



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



<h3 class="wp-block-heading">KeepAlive 설정</h3>



<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=""># /etc/apache2/apache2.conf

# KeepAlive 활성화
KeepAlive On

# 최대 요청 수
MaxKeepAliveRequests 100

# 타임아웃 (초)
KeepAliveTimeout 5
</pre>



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



<h3 class="wp-block-heading">MPM 설정 최적화</h3>



<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=""># /etc/apache2/mods-available/mpm_event.conf

&lt;IfModule mpm_event_module>
    StartServers             2
    MinSpareThreads          25
    MaxSpareThreads          75
    ThreadLimit              64
    ThreadsPerChild          25
    MaxRequestWorkers        150
    MaxConnectionsPerChild   0
&lt;/IfModule>
</pre>



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



<h2 class="wp-block-heading">디렉토리 구조</h2>



<h3 class="wp-block-heading">Apache 설정 파일 구조</h3>



<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="">/etc/apache2/
├── apache2.conf              # 메인 설정 파일
├── ports.conf                # 포트 설정
├── conf-available/           # 사용 가능한 설정
├── conf-enabled/             # 활성화된 설정
├── mods-available/           # 사용 가능한 모듈
├── mods-enabled/             # 활성화된 모듈 (심볼릭 링크)
├── sites-available/          # 사용 가능한 가상호스트
│   ├── 000-default.conf
│   ├── testdomain.conf
│   └── api.testdomain.conf
├── sites-enabled/            # 활성화된 가상호스트 (심볼릭 링크)
│   ├── 000-default.conf -> ../sites-available/000-default.conf
│   └── testdomain.conf -> ../sites-available/testdomain.conf
└── envvars                   # 환경 변수
</pre>



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



<h3 class="wp-block-heading">웹 컨텐츠 디렉토리</h3>



<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="">/var/www/
├── html/                     # 기본 DocumentRoot
├── testdomain/               # 가상호스트 디렉토리
│   ├── public/
│   ├── index.html
│   └── .htaccess
└── logs/                     # 로그 (선택사항)
</pre>



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



<h2 class="wp-block-heading">유용한 명령어 모음</h2>



<h3 class="wp-block-heading">빠른 참조</h3>



<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=""># 설정 테스트
sudo apache2ctl configtest

# 가상호스트 목록
sudo apache2ctl -S

# 설정 리로드 (무중단)
sudo systemctl reload apache2

# 재시작
sudo systemctl restart apache2

# 상태 확인
sudo systemctl status apache2

# 로그 실시간 모니터링
sudo tail -f /var/log/apache2/error.log

# 특정 도메인 설정 확인
sudo apache2ctl -D DUMP_VHOSTS | grep testdomain

# 활성화된 모듈 목록
apache2ctl -M

# 설정 파일 문법 체크
sudo apachectl -t
</pre>



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



<h3 class="wp-block-heading">자주 사용하는 작업</h3>



<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=""># 새 가상호스트 생성부터 활성화까지
sudo vim /etc/apache2/sites-available/newsite.conf
sudo a2ensite newsite.conf
sudo apache2ctl configtest
sudo systemctl reload apache2

# SSL 인증서 발급 및 자동 설정
sudo certbot --apache -d newsite.com

# 로그 분석
sudo tail -1000 /var/log/apache2/access.log | grep "POST" | wc -l

# 디스크 사용량 확인
sudo du -sh /var/log/apache2/*

# 오래된 로그 정리
sudo find /var/log/apache2/ -name "*.log.*" -mtime +30 -delete
</pre>



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



<h2 class="wp-block-heading">문제 상황별 체크리스트</h2>



<h3 class="wp-block-heading">사이트가 접속되지 않을 때</h3>



<ul class="wp-block-list">
<li>[ ] Apache 서비스 작동 확인: <code>sudo systemctl status apache2</code></li>



<li>[ ] 포트 리스닝 확인: <code>sudo netstat -tlnp | grep :80</code></li>



<li>[ ] 방화벽 확인: <code>sudo ufw status</code></li>



<li>[ ] DNS 설정 확인: <code>nslookup testdomain.com</code></li>



<li>[ ] 가상호스트 활성화 확인: <code>sudo apache2ctl -S</code></li>



<li>[ ] 설정 문법 확인: <code>sudo apache2ctl configtest</code></li>
</ul>



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



<h3 class="wp-block-heading">502 Bad Gateway 발생 시</h3>



<ul class="wp-block-list">
<li>[ ] 백엔드 서비스 작동 확인: <code>curl http://localhost:3000/</code></li>



<li>[ ] 프록시 설정 확인: ProxyPass, ProxyPassReverse</li>



<li>[ ] SELinux 설정 확인 (CentOS/RHEL)</li>



<li>[ ] 타임아웃 설정 확인: ProxyTimeout</li>



<li>[ ] 에러 로그 확인: <code>sudo tail -50 /var/log/apache2/error.log</code></li>
</ul>



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



<h3 class="wp-block-heading">SSL 인증서 오류 시</h3>



<ul class="wp-block-list">
<li>[ ] 인증서 파일 존재 확인</li>



<li>[ ] 인증서 유효기간 확인: <code>sudo certbot certificates</code></li>



<li>[ ] 인증서 경로 확인</li>



<li>[ ] 포트 443 리스닝 확인</li>



<li>[ ] SSL 모듈 활성화 확인: <code>apache2ctl -M | grep ssl</code></li>
</ul>



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



<p></p>
<p>The post <a href="https://lycos7560.com/ubuntu/apache-%ea%b0%80%ec%83%81%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c/40358/">Apache Virtual Host Guide (Apache 가상 호스트 설정)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/ubuntu/apache-%ea%b0%80%ec%83%81%ed%98%b8%ec%8a%a4%ed%8a%b8-%ec%84%a4%ec%a0%95-%ea%b0%80%ec%9d%b4%eb%93%9c/40358/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>HTML iframe 정리</title>
		<link>https://lycos7560.com/etc/html-iframe-%ec%a0%95%eb%a6%ac/40225/</link>
					<comments>https://lycos7560.com/etc/html-iframe-%ec%a0%95%eb%a6%ac/40225/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Mon, 04 Aug 2025 12:42:26 +0000</pubDate>
				<category><![CDATA[Blazor]]></category>
		<category><![CDATA[기타]]></category>
		<category><![CDATA[a11y]]></category>
		<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[allow]]></category>
		<category><![CDATA[allow-forms]]></category>
		<category><![CDATA[allow-popups]]></category>
		<category><![CDATA[allow-same-origin]]></category>
		<category><![CDATA[allow-scripts]]></category>
		<category><![CDATA[allowfullscreen]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Aspect Ratio]]></category>
		<category><![CDATA[autoplay]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[Clickjacking]]></category>
		<category><![CDATA[compatibility]]></category>
		<category><![CDATA[Content Security Policy]]></category>
		<category><![CDATA[CORS]]></category>
		<category><![CDATA[cross-origin]]></category>
		<category><![CDATA[CSP]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[DevTools]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[embed]]></category>
		<category><![CDATA[embed 태그]]></category>
		<category><![CDATA[Frame]]></category>
		<category><![CDATA[Frontend]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[height]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[HTML기초]]></category>
		<category><![CDATA[HTML태그]]></category>
		<category><![CDATA[iframe]]></category>
		<category><![CDATA[iframe 통신]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[lazy loading]]></category>
		<category><![CDATA[loading]]></category>
		<category><![CDATA[Map Embed]]></category>
		<category><![CDATA[microphone]]></category>
		<category><![CDATA[object 태그]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[PDF]]></category>
		<category><![CDATA[PDF뷰어]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Permissions Policy]]></category>
		<category><![CDATA[picture-in-picture]]></category>
		<category><![CDATA[postMessage]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[referrerpolicy]]></category>
		<category><![CDATA[Responsive iframe]]></category>
		<category><![CDATA[Responsive Web]]></category>
		<category><![CDATA[Same-Origin Policy]]></category>
		<category><![CDATA[sandbox]]></category>
		<category><![CDATA[Screen Reader]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SPA]]></category>
		<category><![CDATA[src]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Third-Party Content]]></category>
		<category><![CDATA[title]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[Vue.js]]></category>
		<category><![CDATA[WAI-ARIA]]></category>
		<category><![CDATA[Web Components]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Performance]]></category>
		<category><![CDATA[Web Security]]></category>
		<category><![CDATA[Web Standards]]></category>
		<category><![CDATA[width]]></category>
		<category><![CDATA[X-Frame-Options]]></category>
		<category><![CDATA[YouTube]]></category>
		<category><![CDATA[YouTube Embed]]></category>
		<category><![CDATA[개발자도구]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[구글맵임베드]]></category>
		<category><![CDATA[구글지도]]></category>
		<category><![CDATA[기능정책]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[동일출처정책]]></category>
		<category><![CDATA[디버깅]]></category>
		<category><![CDATA[리액트]]></category>
		<category><![CDATA[문제해결]]></category>
		<category><![CDATA[반응형iframe]]></category>
		<category><![CDATA[반응형웹]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[뷰]]></category>
		<category><![CDATA[브라우저]]></category>
		<category><![CDATA[블레이저]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[스크린리더]]></category>
		<category><![CDATA[싱글페이지애플리케이션]]></category>
		<category><![CDATA[외부콘텐츠]]></category>
		<category><![CDATA[웹개발]]></category>
		<category><![CDATA[웹메시징]]></category>
		<category><![CDATA[웹보안]]></category>
		<category><![CDATA[웹성능]]></category>
		<category><![CDATA[웹접근성]]></category>
		<category><![CDATA[웹컴포넌트]]></category>
		<category><![CDATA[웹퍼블리셔]]></category>
		<category><![CDATA[웹페이지]]></category>
		<category><![CDATA[웹표준]]></category>
		<category><![CDATA[유튜브]]></category>
		<category><![CDATA[유튜브임베드]]></category>
		<category><![CDATA[이벤트리스너]]></category>
		<category><![CDATA[인라인요소]]></category>
		<category><![CDATA[인라인프레임]]></category>
		<category><![CDATA[임베드]]></category>
		<category><![CDATA[자바스크립트]]></category>
		<category><![CDATA[접근성]]></category>
		<category><![CDATA[종횡비]]></category>
		<category><![CDATA[지연로딩]]></category>
		<category><![CDATA[최적화]]></category>
		<category><![CDATA[코딩]]></category>
		<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=40225</guid>

					<description><![CDATA[<p>HTML iframe? &#60;iframe> (Inline Frame) 태그는 현재 HTML 문서 안에 다른 웹 페이지나 미디어 콘텐츠를 임베드(embed)할 때 사용하는 HTML 요소입니다. 외부 콘텐츠를 현재 페이지에 &#8220;창문처럼&#8221; 삽입하는 기능을 제공하며, 웹 개발에서 매우 유용한 도구입니다. 1. 기본 구조와 문법 기본 문법 최소 권장 구조 2. 핵심 속성 속성 설명 예시 필수여부 src 임베드할 콘텐츠의 URL src="https://www.youtube.com/embed/동영상ID" 필수 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/etc/html-iframe-%ec%a0%95%eb%a6%ac/40225/">HTML iframe 정리</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-d4c23dad      "
					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="#html-iframe" class="uagb-toc-link__trigger">HTML iframe?</a><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="#기본-문법" 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><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><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-youtube-동영상-임베드" class="uagb-toc-link__trigger">1) YouTube 동영상 임베드</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-google-maps-임베드" class="uagb-toc-link__trigger">2) Google Maps 임베드</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-pdf-문서-표시" class="uagb-toc-link__trigger">3) PDF 문서 표시</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#4-인라인-html-콘텐츠-srcdoc-사용" class="uagb-toc-link__trigger">4) 인라인 HTML 콘텐츠 (srcdoc 사용)</a></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#4-보안-및-권한-제어-속성-sandbox-allow" class="uagb-toc-link__trigger">4. 보안 및 권한 제어 속성 (sandbox &amp; allow)</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#41-sandbox-속성-보안-제한-설정" class="uagb-toc-link__trigger">4.1 sandbox 속성 &#8211; 보안 제한 설정</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#42-allow-속성-기능-권한-제어" class="uagb-toc-link__trigger">4.2 allow 속성 &#8211; 기능 권한 제어</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#43-사용-예시" class="uagb-toc-link__trigger">4.3 사용 예시</a></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="#보안-고려사항" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f512.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/26a1.png" alt="⚡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 성능 최적화</a></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 class="uagb-toc__list"><li class="uagb-toc__list"><a href="#css를-이용한-반응형-iframe" class="uagb-toc-link__trigger">CSS를 이용한 반응형 iframe</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></ul></li><li class="uagb-toc__list"><a href="#7-javascript와의-상호작용" class="uagb-toc-link__trigger">7. JavaScript와의 상호작용</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#postmessage-api-사용" class="uagb-toc-link__trigger">postMessage API 사용</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#iframe-로드-완료-감지" class="uagb-toc-link__trigger">iframe 로드 완료 감지</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#8-프레임워크별-사용-예시" class="uagb-toc-link__trigger">8. 프레임워크별 사용 예시</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#react" class="uagb-toc-link__trigger">React</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#vuejs" class="uagb-toc-link__trigger">Vue.js</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#blazor" class="uagb-toc-link__trigger">Blazor</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#9-접근성-accessibility" class="uagb-toc-link__trigger">9. 접근성 (Accessibility)</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></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#10-문제-해결-및-디버깅" class="uagb-toc-link__trigger">10. 문제 해결 및 디버깅</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></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#11-모범-사례-및-권장사항" class="uagb-toc-link__trigger">11. 모범 사례 및 권장사항</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/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 피해야 할 것들</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#12-대안-기술들" class="uagb-toc-link__trigger">12. 대안 기술들</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-object-태그" class="uagb-toc-link__trigger">1. object 태그</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-embed-태그" class="uagb-toc-link__trigger">2. embed 태그</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-web-components" class="uagb-toc-link__trigger">3. Web Components</a></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li><li class="uagb-toc__list"><a href="#결론" class="uagb-toc-link__trigger">결론</a></ul></ul></ul></ul></ul></ul></ul></ul></ul></ul></ul></ol>					</div>
									</div>
				</div>
			


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



<h2 class="wp-block-heading">HTML iframe?</h2>



<p><code>&lt;iframe></code> (Inline Frame) 태그는 <strong>현재 HTML 문서 안에 다른 웹 페이지나 미디어 콘텐츠를 임베드(embed)할 때 사용하는 HTML 요소</strong>입니다. </p>



<p>외부 콘텐츠를 현재 페이지에 &#8220;창문처럼&#8221; 삽입하는 기능을 제공하며, <strong>웹 개발에서 매우 유용한 도구</strong>입니다.</p>



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



<h2 class="wp-block-heading">1. 기본 구조와 문법</h2>



<h3 class="wp-block-heading">기본 문법</h3>



<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;iframe 
    src="삽입할_콘텐츠_URL" 
    width="너비" 
    height="높이" 
    title="프레임 설명"
    allow="fullscreen">
    &lt;!-- 대체 콘텐츠 (iframe을 지원하지 않는 브라우저용) -->
    &lt;p>이 브라우저는 iframe을 지원하지 않습니다.&lt;/p>
&lt;/iframe>
</pre>



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



<h3 class="wp-block-heading">최소 권장 구조</h3>



<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;iframe 
    src="https://example.com" 
    title="Example Website"
    width="600" 
    height="400">
&lt;/iframe>
</pre>



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



<h2 class="wp-block-heading">2. 핵심 속성</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>속성</th><th>설명</th><th>예시</th><th>필수여부</th></tr></thead><tbody><tr><td><code>src</code></td><td>임베드할 콘텐츠의 URL</td><td><code>src="https://www.youtube.com/embed/동영상ID"</code></td><td><strong>필수</strong></td></tr><tr><td><code>width</code>/<code>height</code></td><td>프레임 크기 (픽셀 또는 %)</td><td><code>width="600" height="400"</code></td><td>권장</td></tr><tr><td><code>title</code></td><td>접근성을 위한 프레임 설명</td><td><code>title="YouTube 동영상"</code></td><td><strong>권장</strong></td></tr><tr><td><code><s>frameborder</s></code></td><td><s>테두리 표시 여부 </s>(HTML5에선 CSS로 대체)</td><td><code><s>frameborder="0"</s></code></td><td><s>선택</s></td></tr><tr><td><code>allowfullscreen</code><br><code>allowfullscreen</code>은 오래된 방식이며, <br>최신 표준인 <strong>권한 정책(Permissions Policy)에서는</strong><br><strong><code>allow="fullscreen"</code>을 사용</strong>하는 것을 권장</td><td>전체 화면 모드 허용</td><td>불리언 속성</td><td>선택</td></tr><tr><td><code>sandbox</code></td><td>보안 제한 설정</td><td><code>sandbox="allow-scripts allow-same-origin"</code></td><td>선택</td></tr><tr><td><code>loading</code></td><td>로딩 방식 (lazy/eager)</td><td><code>loading="lazy"</code></td><td>선택</td></tr><tr><td><code>allow</code></td><td>기능 정책 설정</td><td><code>allow="camera; microphone"</code></td><td>선택</td></tr><tr><td><code>name</code></td><td>프레임 이름 (target으로 사용)</td><td><code>name="myFrame"</code></td><td>선택</td></tr><tr><td><code>srcdoc</code></td><td>인라인 HTML 콘텐츠</td><td><code>srcdoc="&lt;p&gt;Hello World&lt;/p&gt;"</code></td><td>선택</td></tr><tr><td><code>id</code></td><td>고유 식별자 (CSS, JavaScript에서 참조)</td><td><code>id="myIframe"</code></td><td>권장</td></tr></tbody></table></figure>



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



<h2 class="wp-block-heading">3. 주요 사용 사례</h2>



<h3 class="wp-block-heading">1) YouTube 동영상 임베드</h3>



<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;div class="video-container">
    &lt;iframe src="https://www.youtube.com/embed/rdwz7QiG0lk?enablejsapi=1"
            id="ytPlayer"
            width="560"
            height="315"
            title="YouTube on the tube!"
            allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; fullscreen; picture-in-picture; web-share">
    &lt;/iframe>
&lt;/div>

&lt;style>
    .video-container {
        position: relative;
        padding-bottom: 56.25%; /* 16:9 비율 */
        height: 0;
        overflow: hidden;
    }

    .video-container iframe {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
    }
&lt;/style></pre>



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



<h3 class="wp-block-heading">2) Google Maps 임베드</h3>



<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;iframe
    src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3165.303576908283!2d127.024612!3d37.515582!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x0!2zMzfCsDMwJzU2LjEiTiAxMjfCsDAxJzI4LjYiRQ!5e0!3m2!1sen!2skr!4v1620000000000!5m2!1sen!2skr"
    width="600"
    height="450"
    title="Google Maps"
    style="border:0;"
    allow="fullscreen"
    loading="lazy"
    referrerpolicy="no-referrer-when-downgrade">
&lt;/iframe>
</pre>



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



<h3 class="wp-block-heading">3) PDF 문서 표시</h3>



<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;iframe 
    src="/documents/sample.pdf" 
    width="100%" 
    height="600px"
    title="PDF 문서">
    &lt;p>PDF를 표시할 수 없습니다. &lt;a href="/documents/sample.pdf">다운로드&lt;/a>하세요.&lt;/p>
&lt;/iframe>
</pre>



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



<h3 class="wp-block-heading">4) 인라인 HTML 콘텐츠 (srcdoc 사용)</h3>



<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;iframe 
    srcdoc="&lt;html>&lt;body>&lt;h1>안녕하세요!&lt;/h1>&lt;p>이것은 인라인 HTML입니다.&lt;/p>&lt;/body>&lt;/html>"
    width="400" 
    height="200"
    title="인라인 HTML">
&lt;/iframe>
</pre>



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



<h2 class="wp-block-heading">4. 보안 및 권한 제어 속성 (sandbox &amp; allow)</h2>



<h3 class="wp-block-heading">4.1 sandbox 속성 &#8211; 보안 제한 설정</h3>



<p><code>sandbox</code> 속성은 iframe 내 콘텐츠의 보안을 강화하기 위해 사용됩니다. </p>



<p><strong>기본적으로 모든 것을 차단</strong>하고 필요한 기능만 허용하는 방식입니다.</p>



<h4 class="wp-block-heading">sandbox 기본 사용법</h4>



<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;!-- 모든 제한 적용 (최고 보안) -->
&lt;iframe src="..." sandbox>&lt;/iframe>

&lt;!-- 특정 기능만 허용 -->
&lt;iframe src="..." sandbox="allow-scripts allow-same-origin allow-forms">&lt;/iframe></pre>



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



<h4 class="wp-block-heading">sandbox 값들</h4>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>sandbox 값</th><th>설명</th><th>사용 예시</th></tr></thead><tbody><tr><td><code>allow-forms</code></td><td>폼 제출 허용</td><td>로그인, 검색 폼이 있는 페이지</td></tr><tr><td><code>allow-scripts</code></td><td>JavaScript 실행 허용</td><td>인터랙티브 콘텐츠</td></tr><tr><td><code>allow-same-origin</code></td><td>동일 출처 정책 적용</td><td>API 호출, 쿠키 접근</td></tr><tr><td><code>allow-popups</code></td><td>팝업 창 열기 허용</td><td>새 창으로 링크 열기</td></tr><tr><td><code>allow-top-navigation</code></td><td>최상위 프레임 네비게이션 허용</td><td>부모 페이지 이동</td></tr><tr><td><code>allow-pointer-lock</code></td><td>포인터 잠금 API 허용</td><td>게임, 3D 앱</td></tr><tr><td><code>allow-fullscreen</code></td><td>전체 화면 모드 허용</td><td>동영상 플레이어</td></tr><tr><td><code>allow-downloads</code></td><td>파일 다운로드 허용</td><td>문서 다운로드</td></tr><tr><td><code>allow-modals</code></td><td>모달 창 허용</td><td>alert, confirm 등</td></tr></tbody></table></figure>



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



<h3 class="wp-block-heading">4.2 allow 속성 &#8211; 기능 권한 제어</h3>



<p><code>allow</code> 속성은 브라우저의 고급 기능에 대한 접근 권한을 제어합니다. </p>



<p><strong>Permissions Policy</strong>를 통해 특정 웹 API 사용을 허용하거나 차단합니다.</p>



<h4 class="wp-block-heading">allow 기본 사용법</h4>



<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;!-- 특정 브라우저 기능 허용 -->
&lt;iframe src="..." 
        allow="camera; microphone; geolocation">
&lt;/iframe>

&lt;!-- YouTube 동영상에 필요한 기능들 -->
&lt;iframe src="https://www.youtube.com/embed/..."
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share">
&lt;/iframe></pre>



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



<h4 class="wp-block-heading">allow 값들</h4>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th><strong>값</strong></th><th><strong>설명</strong></th><th><strong>사용 예시</strong></th></tr></thead><tbody><tr><td><code>camera</code></td><td>카메라 접근 허용</td><td>화상 통화, 사진 촬영</td></tr><tr><td><code>microphone</code></td><td>마이크 접근 허용</td><td>음성 녹음, 통음</td></tr><tr><td><code>geolocation</code></td><td>위치 정보 접근 허용</td><td>지도 서비스, 위치 기반 기능</td></tr><tr><td><code>autoplay</code></td><td>자동 재생 허용</td><td>동영상/음악 자동 재생</td></tr><tr><td><code>encrypted-media</code></td><td>DRM 보호 콘텐츠 재생 허용</td><td>Netflix, 유료 스트리밍 서비스</td></tr><tr><td><code>picture-in-picture</code></td><td>PIP(작은 창) 모드 허용</td><td>동영상 시청 중 다른 작업</td></tr><tr><td><code>accelerometer</code></td><td>가속도계(기기 움직임) 접근 허용</td><td>모바일 게임, VR 콘텐츠</td></tr><tr><td><code>gyroscope</code></td><td>자이로스코프(기기 회전) 접근 허용</td><td>360도 동영상, AR 앱</td></tr><tr><td><code>clipboard-write</code></td><td>클립보드 복사 기능 허용</td><td>텍스트/이미지 복사 버튼</td></tr><tr><td><code>web-share</code></td><td>운영체제 공유 기능 허용</td><td>SNS 공유, 링크 공유</td></tr><tr><td><code>fullscreen</code></td><td>전체 화면 모드 허용</td><td>동영상 전체 화면으로 보기</td></tr></tbody></table></figure>



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



<h3 class="wp-block-heading">4.3 사용 예시</h3>



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



<h4 class="wp-block-heading">신뢰할 수 없는 콘텐츠 (높은 보안)</h4>



<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;!-- 외부 광고, 사용자 생성 콘텐츠 -->
&lt;iframe src="https://untrusted-ads.com/banner" 
        sandbox="allow-scripts"
        width="300" height="250">
&lt;/iframe></pre>



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



<h4 class="wp-block-heading">부분적으로 신뢰하는 콘텐츠 (중간 보안)</h4>



<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;!-- 서드파티 앱, 외부 도구 -->
&lt;iframe src="https://third-party-tool.com"
        sandbox="allow-scripts allow-same-origin allow-forms"
        allow="clipboard-write"
        width="600" height="400">
&lt;/iframe></pre>



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



<h4 class="wp-block-heading">신뢰할 수 있는 서비스 (기능 중심)</h4>



<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;!-- YouTube, Google Maps 등 -->
&lt;iframe src="https://www.youtube.com/embed/rdwz7QiG0lk"
        allow="accelerometer; autoplay; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share">
&lt;/iframe></pre>



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



<h4 class="wp-block-heading">둘 다 사용하는 경우</h4>



<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;!-- 보안과 기능 모두 제어 -->
&lt;iframe src="https://video-chat-app.com"
        sandbox="allow-scripts allow-same-origin allow-forms"
        allow="camera; microphone; autoplay"
        width="800" height="600">
&lt;/iframe></pre>



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



<h2 class="wp-block-heading">5. 보안 및 성능 고려사항</h2>



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



<h4 class="wp-block-heading">X-Frame-Options 헤더</h4>



<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="">X-Frame-Options: DENY          # 모든 프레임에서 차단
X-Frame-Options: SAMEORIGIN   # 동일 출처에서만 허용
X-Frame-Options: ALLOW-FROM https://example.com  # 대부분 지원 중단되었으므로 CSP frame-ancestors를 사용

# "특정 도메인"은 해당 웹사이트를 iframe으로 임베드할 수 있는 허용된 출처(도메인)를 의미</pre>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="965" height="490" src="https://lycos7560.com/wp-content/uploads/2025/08/image-13.png" alt="" class="wp-image-40229" srcset="https://lycos7560.com/wp-content/uploads/2025/08/image-13.png 965w, https://lycos7560.com/wp-content/uploads/2025/08/image-13-300x152.png 300w, https://lycos7560.com/wp-content/uploads/2025/08/image-13-768x390.png 768w" sizes="(max-width: 965px) 100vw, 965px" /><figcaption class="wp-element-caption"><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options#browser_compatibility" target="_blank" rel="noreferrer noopener">https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options#browser_compatibility</a></figcaption></figure>



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



<h4 class="wp-block-heading">Content Security Policy (CSP)</h4>



<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;meta http-equiv="Content-Security-Policy" 
      content="frame-src https://youtube.com https://maps.google.com;">
</pre>



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



<h4 class="wp-block-heading">안전한 iframe 사용법</h4>



<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;iframe 
    src="https://trusted-site.com"
    sandbox="allow-scripts allow-same-origin"
    referrerpolicy="strict-origin-when-cross-origin">
&lt;/iframe>
</pre>



<div style="height:50px" 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/26a1.png" alt="⚡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 성능 최적화</h3>



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



<h4 class="wp-block-heading">지연 로딩 (Lazy Loading)</h4>



<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;iframe 
    src="https://example.com" 
    loading="lazy"
    width="600" 
    height="400">
&lt;/iframe>
</pre>



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



<h4 class="wp-block-heading">리소스 힌트 사용</h4>



<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;!-- DNS 사전 해석 -->
&lt;link rel="dns-prefetch" href="https://www.youtube.com">

&lt;!-- 사전 연결 -->
&lt;link rel="preconnect" href="https://www.youtube.com">

&lt;!-- 리소스 사전 로드 -->
&lt;link rel="preload" href="https://example.com/critical-frame" as="document">
</pre>



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



<h4 class="wp-block-heading">Intersection Observer를 이용한 동적 로딩</h4>



<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="">const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const iframe = entry.target;
            iframe.src = iframe.dataset.src;
            observer.unobserve(iframe);
        }
    });
});

document.querySelectorAll('iframe[data-src]').forEach(iframe => {
    observer.observe(iframe);
});
</pre>



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



<h2 class="wp-block-heading">6. 반응형 디자인</h2>



<h3 class="wp-block-heading">CSS를 이용한 반응형 iframe</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">.iframe-container {
    position: relative;
    width: 100%;
    padding-bottom: 56.25%; /* 16:9 비율 */
    height: 0;
    overflow: hidden;
}

.iframe-container iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border: 0;
}
</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;div class="iframe-container">
    &lt;iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ" 
            title="YouTube 동영상"
            allow="fullscreen">
    &lt;/iframe>
&lt;/div>
</pre>



<h3 class="wp-block-heading">다양한 비율 지원</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">.aspect-16-9 { padding-bottom: 56.25%; }  /* 16:9 */
.aspect-4-3 { padding-bottom: 75%; }      /* 4:3 */
.aspect-1-1 { padding-bottom: 100%; }     /* 1:1 */
.aspect-21-9 { padding-bottom: 42.86%; }  /* 21:9 */
</pre>



<h2 class="wp-block-heading">7. JavaScript와의 상호작용</h2>



<h3 class="wp-block-heading">postMessage API 사용</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 부모 페이지에서 iframe으로 메시지 전송
const iframe = document.getElementById('myFrame');
iframe.contentWindow.postMessage('Hello from parent', '*');

// 메시지 수신 리스너
window.addEventListener('message', (event) => {
    if (event.origin !== 'https://trusted-domain.com') return;
    console.log('받은 메시지:', event.data);
});
</pre>



<h3 class="wp-block-heading">iframe 로드 완료 감지</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const iframe = document.getElementById('myFrame');
iframe.addEventListener('load', () => {
    console.log('iframe 로드 완료');
});
</pre>



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



<h2 class="wp-block-heading">8. 프레임워크별 사용 예시</h2>



<h3 class="wp-block-heading">React</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">function YouTubeEmbed({ videoId }) {
    return (
        &lt;div className="iframe-container">
            &lt;iframe
                src={`https://www.youtube.com/embed/${videoId}`}
                title="YouTube video player"
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen"
            />
        &lt;/div>
    );
}</pre>



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



<h3 class="wp-block-heading">Vue.js</h3>



<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;template>
    &lt;div class="iframe-container">
        &lt;iframe
            :src="`https://www.youtube.com/embed/${videoId}`"
            title="YouTube video player"
            allow="fullscreen"
        />
    &lt;/div>
&lt;/template>

&lt;script>
export default {
    props: ['videoId']
}
&lt;/script>
</pre>



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



<h3 class="wp-block-heading">Blazor</h3>



<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="">@page "/iframe-demo"

&lt;div class="iframe-wrapper">
    &lt;iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ"
            width="560"
            height="315"
            title="YouTube 동영상"
            allow="fullscreen"
            class="youtube-frame">
    &lt;/iframe>
&lt;/div>

&lt;style>
    .youtube-frame {
        border: none;
        border-radius: 8px;
        box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    }
    
    .iframe-wrapper {
        display: flex;
        justify-content: center;
        margin: 20px 0;
    }
&lt;/style>
</pre>



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



<h2 class="wp-block-heading">9. 접근성 (Accessibility)</h2>



<h3 class="wp-block-heading">필수 접근성 고려사항</h3>



<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;iframe
    src="https://example.com"
    title="명확하고 설명적인 제목"
    aria-label="iframe 내용에 대한 추가 설명"
    tabindex="0">
    &lt;p>이 콘텐츠를 보려면 &lt;a href="https://example.com">여기를 클릭&lt;/a>하세요.&lt;/p>
&lt;/iframe>
</pre>



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



<h3 class="wp-block-heading">키보드 네비게이션</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="css" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">iframe:focus {
    outline: 2px solid #007cba;
    outline-offset: 2px;
}
</pre>



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



<h2 class="wp-block-heading">10. 문제 해결 및 디버깅</h2>



<h3 class="wp-block-heading">일반적인 문제들</h3>



<h4 class="wp-block-heading">1. 콘텐츠가 보이지 않을 때</h4>



<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="">// 개발자 도구에서 확인할 사항들
console.log('iframe src:', iframe.src);
console.log('iframe 로드 상태:', iframe.readyState);

// 오류 핸들링
iframe.addEventListener('error', (e) => {
    console.error('iframe 로드 오류:', e);
});
</pre>



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



<h4 class="wp-block-heading">2. X-Frame-Options 오류 해결</h4>



<ul class="wp-block-list">
<li>개발자 도구 → Network 탭에서 응답 헤더 확인</li>



<li>가능한 해결책: 프록시 서버 사용 또는 API를 통한 콘텐츠 가져오기</li>
</ul>



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



<h4 class="wp-block-heading">3. CORS 정책 위반</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 안전한 방법: 서버 사이드에서 콘텐츠 프록시
fetch('/api/proxy?url=' + encodeURIComponent(targetUrl))
    .then(response => response.text())
    .then(html => {
        iframe.srcdoc = html;
    });
</pre>



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



<h3 class="wp-block-heading">디버깅 도구</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// iframe 상태 체크 함수
function checkIframeStatus(iframeId) {
    const iframe = document.getElementById(iframeId);
    console.log({
        src: iframe.src,
        contentDocument: iframe.contentDocument,
        contentWindow: iframe.contentWindow,
        readyState: iframe.readyState
    });
}
</pre>



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



<h2 class="wp-block-heading">11. 모범 사례 및 권장사항</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>



<ol class="wp-block-list">
<li><strong>항상 <code>title</code> 속성 제공</strong> &#8211; 접근성을 위해 필수</li>



<li><strong>적절한 크기 설정</strong> &#8211; 반응형 디자인 고려</li>



<li><strong>loading=&#8221;lazy&#8221; 사용</strong> &#8211; 성능 최적화</li>



<li><strong>sandbox 속성 활용</strong> &#8211; 보안 강화</li>



<li><strong>대체 콘텐츠 제공</strong> &#8211; 호환성 보장</li>



<li><strong>HTTPS 사용</strong> &#8211; 보안 및 호환성</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/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 피해야 할 것들</h3>



<ol class="wp-block-list">
<li><strong>frameborder 속성</strong> &#8211; HTML5에서는 CSS 사용 권장</li>



<li><strong>과도한 중첩</strong> &#8211; 성능 저하 원인</li>



<li><strong>신뢰할 수 없는 소스</strong> &#8211; 보안 위험</li>



<li><strong>고정 크기만 사용</strong> &#8211; 반응형 웹에 부적합</li>



<li><strong>title 속성 누락</strong> &#8211; 접근성 문제</li>
</ol>



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



<h2 class="wp-block-heading">12. 대안 기술들</h2>



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



<h3 class="wp-block-heading">1. object 태그</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;object data="document.pdf" type="application/pdf" width="600" height="400">
    &lt;p>PDF를 표시할 수 없습니다. &lt;a href="document.pdf">다운로드&lt;/a>하세요.&lt;/p>
&lt;/object>
</pre>



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



<h3 class="wp-block-heading">2. embed 태그</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;embed src="movie.mp4" type="video/mp4" width="600" height="400">
</pre>



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



<h3 class="wp-block-heading">3. Web Components</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class CustomEmbed extends HTMLElement {
    connectedCallback() {
        this.innerHTML = `
            &lt;iframe src="${this.getAttribute('src')}" 
                    title="${this.getAttribute('title')}">
            &lt;/iframe>
        `;
    }
}
customElements.define('custom-embed', CustomEmbed);
</pre>



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



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



<p>iframe은 웹 개발에서 외부 콘텐츠를 삽입하는 강력한 도구입니다. </p>



<p>올바른 사용법과 보안 고려사항을 숙지하여 안전하고 효율적인 웹 애플리케이션을 개발할 수 있습니다. </p>



<p>특히 현대 웹 개발에서는 성능, 보안, 접근성을 모두 고려한 구현이 중요합니다.</p>



<p></p>
<p>The post <a href="https://lycos7560.com/etc/html-iframe-%ec%a0%95%eb%a6%ac/40225/">HTML iframe 정리</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/etc/html-iframe-%ec%a0%95%eb%a6%ac/40225/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<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 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의 미들웨어(Middleware)</title>
		<link>https://lycos7560.com/c/asp-net-core%ec%9d%98-%eb%af%b8%eb%93%a4%ec%9b%a8%ec%96%b4middleware/40130/</link>
					<comments>https://lycos7560.com/c/asp-net-core%ec%9d%98-%eb%af%b8%eb%93%a4%ec%9b%a8%ec%96%b4middleware/40130/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Thu, 24 Jul 2025 23:32:09 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[action]]></category>
		<category><![CDATA[API Gateway]]></category>
		<category><![CDATA[API 게이트웨이]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[ASP.NET Core MVC]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[Asynchronous]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[Authorization]]></category>
		<category><![CDATA[Await]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Compression]]></category>
		<category><![CDATA[Conditional Middleware]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Configure]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Controller]]></category>
		<category><![CDATA[Conventional Middleware]]></category>
		<category><![CDATA[CORS]]></category>
		<category><![CDATA[Cross-Origin Resource Sharing]]></category>
		<category><![CDATA[Custom Middleware]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[DELETE]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Developer]]></category>
		<category><![CDATA[Development Environment]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[Event-driven]]></category>
		<category><![CDATA[Exception Handling]]></category>
		<category><![CDATA[Extension Method]]></category>
		<category><![CDATA[Factory-based Middleware]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[HEAD]]></category>
		<category><![CDATA[Headers]]></category>
		<category><![CDATA[HTTP Context]]></category>
		<category><![CDATA[HTTP Method]]></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[HTTP 컨텍스트]]></category>
		<category><![CDATA[HTTP/1.1]]></category>
		<category><![CDATA[HTTP/2]]></category>
		<category><![CDATA[HttpContext]]></category>
		<category><![CDATA[HTTPS Redirection]]></category>
		<category><![CDATA[HTTPS 리디렉션]]></category>
		<category><![CDATA[IApplicationBuilder]]></category>
		<category><![CDATA[IMiddleware]]></category>
		<category><![CDATA[Integration Testing]]></category>
		<category><![CDATA[Invoke]]></category>
		<category><![CDATA[Kestrel]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Logging Provider]]></category>
		<category><![CDATA[Maintainability]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Middleware]]></category>
		<category><![CDATA[Middleware Chain]]></category>
		<category><![CDATA[Minimal APIs]]></category>
		<category><![CDATA[Modularization]]></category>
		<category><![CDATA[next]]></category>
		<category><![CDATA[Non-Terminal Middleware]]></category>
		<category><![CDATA[Ops]]></category>
		<category><![CDATA[options]]></category>
		<category><![CDATA[Order Critical]]></category>
		<category><![CDATA[PATCH]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[pipeline]]></category>
		<category><![CDATA[POST]]></category>
		<category><![CDATA[Production Environment]]></category>
		<category><![CDATA[Program.cs]]></category>
		<category><![CDATA[Protocol]]></category>
		<category><![CDATA[PUT]]></category>
		<category><![CDATA[Request Body]]></category>
		<category><![CDATA[Request Flow]]></category>
		<category><![CDATA[Request Pipeline]]></category>
		<category><![CDATA[RequestDelegate]]></category>
		<category><![CDATA[Response Body]]></category>
		<category><![CDATA[Response Flow]]></category>
		<category><![CDATA[Reusability]]></category>
		<category><![CDATA[Reverse Proxy]]></category>
		<category><![CDATA[Routing]]></category>
		<category><![CDATA[Run]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Separation of Concerns]]></category>
		<category><![CDATA[Service Container]]></category>
		<category><![CDATA[Short-circuit]]></category>
		<category><![CDATA[Single Responsibility Principle]]></category>
		<category><![CDATA[SoC]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[Startup]]></category>
		<category><![CDATA[Static Files]]></category>
		<category><![CDATA[Status Code]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Terminal Middleware]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[TLS]]></category>
		<category><![CDATA[Unit Testing]]></category>
		<category><![CDATA[Use]]></category>
		<category><![CDATA[UseWhen]]></category>
		<category><![CDATA[Web Application]]></category>
		<category><![CDATA[Web Application Framework]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Server]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[WebApplication]]></category>
		<category><![CDATA[WebApplicationBuilder]]></category>
		<category><![CDATA[개발 환경]]></category>
		<category><![CDATA[개발자]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[관심사의 분리]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[단락]]></category>
		<category><![CDATA[단위 테스트]]></category>
		<category><![CDATA[단일 책임 원칙]]></category>
		<category><![CDATA[디버깅]]></category>
		<category><![CDATA[라우팅]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[로깅 프로바이더]]></category>
		<category><![CDATA[리버스 프록시]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[모듈화]]></category>
		<category><![CDATA[미들웨어]]></category>
		<category><![CDATA[미들웨어 체인]]></category>
		<category><![CDATA[배포]]></category>
		<category><![CDATA[보안]]></category>
		<category><![CDATA[비동기]]></category>
		<category><![CDATA[비종료 미들웨어]]></category>
		<category><![CDATA[상태 코드]]></category>
		<category><![CDATA[서비스 메쉬]]></category>
		<category><![CDATA[서비스 컨테이너]]></category>
		<category><![CDATA[설정]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[순서 중요]]></category>
		<category><![CDATA[압축]]></category>
		<category><![CDATA[액션]]></category>
		<category><![CDATA[예외 처리]]></category>
		<category><![CDATA[오류 처리]]></category>
		<category><![CDATA[요청 본문]]></category>
		<category><![CDATA[요청 파이프라인]]></category>
		<category><![CDATA[요청 흐름]]></category>
		<category><![CDATA[웹 개발]]></category>
		<category><![CDATA[웹 서버]]></category>
		<category><![CDATA[웹 서비스]]></category>
		<category><![CDATA[웹 애플리케이션]]></category>
		<category><![CDATA[웹 애플리케이션 프레임워크]]></category>
		<category><![CDATA[유지보수성]]></category>
		<category><![CDATA[응답 본문]]></category>
		<category><![CDATA[응답 흐름]]></category>
		<category><![CDATA[의존성 주입]]></category>
		<category><![CDATA[이벤트]]></category>
		<category><![CDATA[이벤트 드리븐]]></category>
		<category><![CDATA[인가]]></category>
		<category><![CDATA[인증]]></category>
		<category><![CDATA[재사용성]]></category>
		<category><![CDATA[정적 파일]]></category>
		<category><![CDATA[조건부 미들웨어]]></category>
		<category><![CDATA[종료 미들웨어]]></category>
		<category><![CDATA[최소 API]]></category>
		<category><![CDATA[캐싱]]></category>
		<category><![CDATA[커스텀 미들웨어]]></category>
		<category><![CDATA[컨벤셔널 미들웨어]]></category>
		<category><![CDATA[컨테이너]]></category>
		<category><![CDATA[컨트롤러]]></category>
		<category><![CDATA[쿠버네티스]]></category>
		<category><![CDATA[클라우드]]></category>
		<category><![CDATA[테스트]]></category>
		<category><![CDATA[통합 테스트]]></category>
		<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=40130</guid>

					<description><![CDATA[<p>❓ 미들웨어(Middleware) https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0 ASP.NET Core의 미들웨어는 모든 HTTP 요청과 응답 파이프라인을 형성하는 일련의 구성 요소입니다. 각 미들웨어 구성 요소는 다음을 수행할 수 있습니다: 이러한 파이프라인을 통해 애플리케이션의 로직을 모듈화하고, 인증, 로깅, 오류 처리, 라우팅 등과 같은 기능을 깔끔하고 유지 관리하기 쉬운 방식으로 추가할 수 있습니다. ⛓️ 미들웨어 체인 (요청 파이프라인) ASP.NET Core 요청 파이프라인은 차례로 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/asp-net-core%ec%9d%98-%eb%af%b8%eb%93%a4%ec%9b%a8%ec%96%b4middleware/40130/">ASP.NET Core의 미들웨어(Middleware)</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-db9d164c      "
					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="#미들웨어middleware" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어(Middleware)</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/26d3.png" alt="⛓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어 체인 (요청 파이프라인)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#요청-파이프라인-단락short-circuiting" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2702.png" alt="✂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 요청 파이프라인 단락(Short-circuiting)</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#단락과-nextinvoke-이후-코드-실행" 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;" /> 단락과 next.Invoke() 이후 코드 실행</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/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 경고: 응답 전송 후 작업 주의</a></li></ul><li class="uagb-toc__list"><a href="#appuse-vs-apprun" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1fae0.png" alt="🫠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> app.Use vs. app.Run</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#aspnet-core의-커스텀-미들웨어" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ASP.NET Core의 커스텀 미들웨어</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/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 커스텀 미들웨어 클래스의 구조</a></li></ul><li class="uagb-toc__list"><a href="#커스텀-컨벤셔널-미들웨어-custom-conventional-middleware" 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;" /> 커스텀 컨벤셔널 미들웨어 (Custom Conventional Middleware)</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/1f500.png" alt="🔀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어 파이프라인의 이상적인 순서</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#usewhen" 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;" /> UseWhen()</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#usewhen-작동-방식" 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;" /> UseWhen() 작동 방식</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#usewhen-사용-시점" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f98b.png" alt="🦋" class="wp-smiley" style="height: 1em; max-height: 1em;" /> UseWhen() 사용 시점</a></ul></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/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어(Middleware)</h2>



<p><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0</a></p>



<p>ASP.NET Core의 <strong>미들웨어</strong>는 모든 HTTP 요청과 응답 <strong>파이프라인을 형성하는 일련의 구성 요소</strong>입니다.</p>



<p>각 미들웨어 구성 요소는 다음을 수행할 수 있습니다:</p>



<ul class="wp-block-list">
<li>들어오는 <strong>요청을 검사</strong>합니다.</li>



<li>요청 또는 응답을 <strong>수정</strong>합니다 (필요한 경우).</li>



<li>파이프라인의 다음 미들웨어를 <strong>호출</strong>하거나, 프로세스를 <strong>단락(short-circuit)</strong>시키고 자체적으로 응답을 생성합니다.</li>
</ul>



<p>이러한 파이프라인을 통해 <strong>애플리케이션의 로직을 모듈화하고, 인증, 로깅, 오류 처리, 라우팅 등과 </strong>같은 기능을 깔끔하고<strong> 유지 관리하기 쉬운 방식으로 추가</strong>할 수 있습니다.</p>



<div style="height:40px" 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/26d3.png" alt="⛓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어 체인 (요청 파이프라인)</h3>



<p>ASP.NET Core 요청 파이프라인은 차례로 호출되는 일련의 요청 대리자로 구성됩니다.</p>



<p>요청 파이프라인을 일련의 연결된 파이프라고 상상해 보세요. </p>



<p>각 미들웨어 조각은 이 파이프라인의 밸브와 같아서, <strong>정보의 흐름을 제어하고 다양한 단계에서 특정 작업을 적용</strong>할 수 있습니다. </p>



<p>미들웨어를 등록하는 <strong>순서는 매우 중요</strong>하며, 등록된 순서대로 실행됩니다.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="607" height="389" src="https://lycos7560.com/wp-content/uploads/2025/07/image-12.png" alt="" class="wp-image-40131" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-12.png 607w, https://lycos7560.com/wp-content/uploads/2025/07/image-12-300x192.png 300w" sizes="(max-width: 607px) 100vw, 607px" /><figcaption class="wp-element-caption"><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0</a></figcaption></figure>



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



<p>각 델리게이트는 <strong>다음 델리게이트를 호출하기 전과 후에 작업</strong>을 수행할 수 있습니다. </p>



<p>예외 처리 델리게이트는 파이프라인의 후반 단계에서 발생하는 예외를 Catch할 수 있도록 파이프라인의 <strong>초기에 호출</strong>되어야 합니다.</p>



<p>가장 간단한 ASP.NET Core 앱은 모든 요청을 처리하는 <strong>단일 요청 델리게이트</strong>를 설정합니다. </p>



<p>이 경우에는 실제 요청 파이프라인이 포함되지 않습니다. </p>



<p>대신, 모든 HTTP 요청에 대한 응답으로 단일 익명 함수가 호출됩니다.</p>



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



<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);
var app = builder.Build();

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello world!");
});

app.Run(); // 이 app.Run은 위의 app.Run이 파이프라인을 종료하므로 실행되지 않습니다.</pre>



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



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



<p><strong><code>Use</code> 메서드를 사용하면 여러 요청 델리게이트를 체인으로 연결</strong>할 수 있습니다. </p>



<p>이때 <code>next</code> 매개변수는 파이프라인의 다음 델리게이트를 나타냅니다.</p>



<p><code>next</code> 매개변수를 호출하지 않음으로써 <strong>파이프라인을 단락(short-circuit)</strong>시킬 수 있습니다. </p>



<p>다음 예시에서 보여주듯이, 일반적으로 <code>next</code> 델리게이트를 호출하기 전과 후에 모두 작업을 수행할 수 있습니다.</p>



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



<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); // 웹 애플리케이션 빌더를 생성합니다.
var app = builder.Build(); // 빌더를 사용하여 웹 애플리케이션 인스턴스를 생성합니다.

// 첫 번째 미들웨어: app.Use()를 사용하여 파이프라인에 추가합니다.
app.Use(async (context, next) =>
{
    // 응답에 쓸 수 있는 작업을 수행합니다. (예: 헤더 추가, 응답의 시작 부분 작성)
    // 이 부분의 코드는 다음 미들웨어가 실행되기 전에 실행됩니다.

    await next.Invoke(); // 다음 미들웨어(이 경우 app.Run)를 호출하여 제어를 넘깁니다.

    // 응답에 쓰지 않는 로깅 또는 다른 작업을 수행합니다.
    // 이 부분의 코드는 다음 미들웨어가 실행된 후(응답이 생성된 후) 실행됩니다.
});

// 두 번째 미들웨어: app.Run()을 사용하여 파이프라인에 추가합니다.
// app.Run()은 파이프라인을 종료하는 미들웨어입니다.
app.Run(async context =>
{
    // 이 미들웨어는 "Hello from 2nd delegate."를 응답에 작성하고 파이프라인을 종료합니다.
    await context.Response.WriteAsync("Hello from 2nd delegate.");
});

// 이 app.Run()은 위의 app.Run()이 이미 파이프라인을 종료했기 때문에 실행되지 않습니다.
app.Run();</pre>



<div style="height:40px" 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/2702.png" alt="✂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 요청 파이프라인 단락(Short-circuiting)</h3>



<p>ASP.NET Core의 미들웨어 파이프라인에서, 특정 델리게이트(미들웨어)가 요청을 <strong>다음 델리게이트로 전달하지 않을 때</strong> 이를 <strong>요청 파이프라인을 단락(short-circuiting)시킨다</strong>고 합니다. </p>



<p>파이프라인 단락은 불필요한 작업을 피할 수 있기 때문에 종종 유용합니다.</p>



<p>예를 들어, <strong>정적 파일 미들웨어(Static File Middleware)</strong>는 요청된 파일이 정적 파일(이미지, CSS, JavaScript 등)일 경우 해당 요청을 처리하고</p>



<p> 파이프라인의 나머지 부분을 단락시킴으로써 <strong>종료 미들웨어(terminal middleware)</strong> 역할을 할 수 있습니다. </p>



<p>이렇게 되면 정적 파일을 제공한 후에는 <strong>인증이나 라우팅과 같은 다른 미들웨어들이 실행될 필요가 없으므로 효율성이 높아집니다.</strong></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;" /> 단락과 <code>next.Invoke()</code> 이후 코드 실행</h4>



<p>파이프라인의 추가적인 처리를 종료시키는 미들웨어보다 <strong>앞서 파이프라인에 추가된 미들웨어</strong>는 여전히 <code>next.Invoke()</code> 구문 이후의 코드를 처리합니다. </p>



<p>즉, 비록 파이프라인이 단락되어 최종 응답이 더 이상 아래로 전달되지 않더라도, <code>next.Invoke()</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/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 경고: 응답 전송 후 작업 주의</h4>



<p><strong>응답이 클라이언트에게 이미 전송되었거나 전송되기 시작한 후에는 <code>next.Invoke()</code>를 호출하거나 응답에 쓰려고 시도하지 마세요.</strong> </p>



<p><code>HttpResponse</code>가 시작된 후에는 응답에 변경을 가하려고 하면 <strong>예외가 발생</strong>합니다. </p>



<p>예를 들어, 응답이 시작된 후 헤더나 상태 코드를 설정하려고 하면 예외가 발생합니다.</p>



<p><code>next.Invoke()</code> 호출 후 응답 본문에 쓰는 것은 다음과 같은 문제를 야기할 수 있습니다:</p>



<ul class="wp-block-list">
<li><strong>프로토콜 위반:</strong> 명시된 <code>Content-Length</code>보다 더 많은 내용을 작성하는 것과 같은 프로토콜 위반을 초래할 수 있습니다.</li>



<li><strong>본문 형식 손상:</strong> CSS 파일에 HTML 푸터(footer)를 작성하는 것처럼 본문 형식을 손상시킬 수 있습니다.</li>
</ul>



<p><code>HasStarted</code> 속성은 헤더가 전송되었는지 또는 본문이 작성되었는지 여부를 나타내는 유용한 힌트가 될 수 있습니다.</p>



<div style="height:50px" 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/1fae0.png" alt="🫠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code>app.Use</code> vs. <code>app.Run</code></h3>



<p>이 두 메서드는 파이프라인에 미들웨어를 추가하는 데 기본적이지만, 핵심적인 차이점이 있습니다:</p>



<p><code><strong>app.Use(async (context, next) => { ... })</strong></code></p>



<ul class="wp-block-list">
<li><strong>요청 수정 불가:</strong> <br>마지막 단계이므로 요청을 다음으로 전달하기 전에 수정할 수 없습니다.</li>



<li><strong>비종료(Non-Terminal) 미들웨어:</strong> <br>이 유형의 미들웨어는 일반적으로 어떤 작업을 수행한 다음, <code>next</code> 델리게이트를 호출하여 파이프라인의 다음 미들웨어로 제어를 전달합니다.</li>



<li><strong>요청/응답 수정 가능:</strong> <br>요청을 다음으로 전달하기 전에 요청이나 응답을 변경할 수 있습니다.</li>



<li><strong>예시:</strong> <br>인증, 로깅, 커스텀 헤더 추가 등.</li>
</ul>



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



<p><code>a<strong>pp.Run(async (context) => { ... })</strong></code></p>



<ul class="wp-block-list">
<li><strong>종료(Terminal) 미들웨어:</strong> <br>이 미들웨어는 <code>next</code>를 호출하지 않습니다. <br>파이프라인을 종료하고 <strong>자체적으로 응답을 생성</strong>합니다.</li>



<li><strong>최종 응답에 주로 사용:</strong> <br>더 이상 처리가 필요 없는 요청(예: 간단한 메시지 반환)을 처리하는 데 일반적으로 사용됩니다.</li>
</ul>



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



<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="">// 여러 app.Run 호출의 결과

app.Run(async (HttpContext context) => {
    await context.Response.WriteAsync("Hello");
});

app.Run(async (HttpContext context) => {
    await context.Response.WriteAsync("Hello again");
});

app.Run(); // 이 app.Run은 위의 app.Run들이 이미 파이프라인을 종료했기 때문에 절대 실행되지 않습니다.</pre>



<p>이 코드에서는 <strong>오직 첫 번째 <code>app.Run</code> 미들웨어만 실행됩니다.</strong> </p>



<p>&#8220;Hello&#8221;를 응답에 작성하여 파이프라인을 종료하고, 그 뒤의 <code>app.Run</code> (이것은 &#8220;Hello again&#8221;을 작성할 것임)은 실행될 기회를 얻지 못합니다.</p>



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



<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="">// app.Use와 app.Run으로 미들웨어 체인 연결하기

// 미들웨어 1
app.Use(async (context, next) => {
    await context.Response.WriteAsync("Hello "); // 1. "Hello " 작성
    await next(context); // 2. 다음 미들웨어 호출
});

// 미들웨어 2
app.Use(async (context, next) => {
    await context.Response.WriteAsync("Hello again "); // 3. "Hello again " 작성
    await next(context); // 4. 다음 미들웨어 호출 (이 경우 app.Run)
});

// 미들웨어 3 (종료 미들웨어)
app.Run(async (HttpContext context) => {
    await context.Response.WriteAsync("Hello again"); // 5. "Hello again" 작성 후 파이프라인 종료
});</pre>



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



<p>이 코드는 미들웨어를 올바르게 연결하는 방법을 보여줍니다.</p>



<ol start="1" class="wp-block-list">
<li>첫 번째 <code>app.Use</code>는 응답에 &#8220;Hello &#8220;를 작성하고 <code>next</code>를 호출하여 다음 미들웨어로 제어를 전달합니다.</li>



<li>두 번째 <code>app.Use</code>는 &#8220;Hello again &#8220;을 작성하고 역시 <code>next</code>를 호출합니다.</li>



<li>마지막 <code>app.Run</code> (종료 미들웨어)는 &#8220;Hello again&#8221;을 작성하고 파이프라인을 종료합니다.</li>
</ol>



<div style="height:50px" 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/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ASP.NET Core의 커스텀 미들웨어</h3>



<p>ASP.NET Core는 다양한 내장 미들웨어 구성 요소를 제공하지만, 때로는 애플리케이션 고유의 특정 요구 사항을 해결하기 위해 자신만의 <strong>커스텀 미들웨어</strong>를 만들어야 할 수도 있습니다. </p>



<p>커스텀 미들웨어를 통해 다음을 수행할 수 있습니다:</p>



<ul class="wp-block-list">
<li><strong>로직 캡슐화:</strong> <br>관련 작업(예: 로깅, 보안 검사, 사용자 정의 헤더)을 재사용 가능한 구성 요소로 묶습니다.</li>



<li><strong>동작 사용자 정의:</strong> <br>애플리케이션의 요구 사항에 정확히 맞게 요청/응답 파이프라인을 조정합니다.</li>



<li><strong>코드 구성 개선:</strong> <br>미들웨어 코드를 깔끔하고 유지 관리하기 쉽게 만듭니다.</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/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 커스텀 미들웨어 클래스의 구조</h4>



<p><strong><code>IMiddleware</code> 구현:</strong> 이 인터페이스는 단 하나의 메서드 <code>InvokeAsync(HttpContext context, RequestDelegate next)</code>를 요구합니다. </p>



<p>이 메서드는 미들웨어 로직의 핵심입니다</p>



<p><code>InvokeAsync</code> 또는 <code>Invoke</code> 메서드</p>



<ul class="wp-block-list">
<li><strong><code>context</code>:</strong> <br><code>HttpContext</code>는 요청 및 응답 객체에 대한 접근을 제공합니다.</li>



<li><strong><code>next</code>:</strong> <br><code>RequestDelegate</code>는 파이프라인의 다음 미들웨어를 호출할 수 있도록 합니다.</li>
</ul>



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



<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="">// MyCustomMiddleware.cs
namespace MiddlewareExample.CustomMiddleware
{
    public class MyCustomMiddleware : IMiddleware // IMiddleware 인터페이스 구현
    {
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            await context.Response.WriteAsync("My Custom Middleware - Starts\n"); // 1. 응답 시작 부분에 출력
            await next(context); // 2. 다음 미들웨어 호출
            await context.Response.WriteAsync("My Custom Middleware - Ends\n"); // 3. 다음 미들웨어 완료 후 응답 끝 부분에 출력
        }
    }

    // 쉽게 등록하기 위한 확장 메서드
    public static class CustomMiddlewareExtension
    {
        public static IApplicationBuilder UseMyCustomMiddleware(this IApplicationBuilder app)
        {
            return app.UseMiddleware&lt;MyCustomMiddleware>();
        }
    }
}</pre>



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



<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 (또는 Startup.cs)
using MiddlewareExample.CustomMiddleware;

// ... (다른 설정 코드) ...

builder.Services.AddTransient&lt;MyCustomMiddleware>(); // 트랜지언트 서비스로 등록

app.Use(async (HttpContext context, RequestDelegate next) => {
    await context.Response.WriteAsync("From Middleware 1\n"); // 첫 번째 미들웨어: 시작 부분
    await next(context);
});

app.UseMyCustomMiddleware(); // 확장 메서드를 사용하여 커스텀 미들웨어 추가

app.Run(async (HttpContext context) => {
    await context.Response.WriteAsync("From Middleware 3\n"); // 세 번째 미들웨어: 파이프라인 종료
});</pre>



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



<ul class="wp-block-list">
<li><strong>등록:</strong> <br>ASP.NET Core가 필요할 때 <code>MyCustomMiddleware</code> 인스턴스를 생성할 수 있도록 이를 트랜지언트 서비스로 등록합니다.</li>



<li><strong>파이프라인 통합:</strong> <br><code>app.UseMyCustomMiddleware()</code> 확장 메서드는 커스텀 미들웨어를 파이프라인에 추가합니다.</li>



<li><strong>실행 순서:</strong> <br>미들웨어 구성 요소는 파이프라인에 추가된 순서대로 실행됩니다. 이 경우 순서는 미들웨어 1, <code>MyCustomMiddleware</code>, 그리고 미들웨어 3이 됩니다.</li>
</ul>



<div style="height:50px" 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/1f525.png" alt="🔥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 커스텀 컨벤셔널 미들웨어 (Custom Conventional Middleware)</h3>



<p>ASP.NET Core 미들웨어에는 두 가지 유형이 있습니다: <strong>컨벤셔널(Conventional)</strong>과 <strong>팩토리 기반(Factory-based)</strong> </p>



<p>예시에서 보여진 컨벤셔널 미들웨어는 HTTP 요청 및 응답 처리를 위한 커스텀 로직을 캡슐화하는 간단하면서도 강력한 방법입니다.</p>



<p>주요 특징</p>



<ul class="wp-block-list">
<li><strong>클래스 기반:</strong> <br>컨벤셔널 미들웨어는 클래스로 구현됩니다.</li>



<li><strong>생성자 주입:</strong> <br>의존성(있는 경우)을 생성자를 통해 받습니다.</li>



<li><strong><code>Invoke</code> 메서드:</strong> <br>이 메서드는 각 요청을 처리하는 로직을 포함하는 미들웨어의 핵심입니다.</li>



<li><strong><code>RequestDelegate</code>:</strong> <br><code>Invoke</code> 메서드는 <code>RequestDelegate</code> 매개변수(<code>_next</code>로 명명)를 받습니다. 이 델리게이트는 파이프라인의 다음 미들웨어를 나타냅니다.</li>



<li><strong>유연성:</strong> <br><code>Invoke</code> 메서드 내에서 요청 및 응답 객체를 완벽하게 제어할 수 있습니다.</li>
</ul>



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



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



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



<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="">// NameConcatenationMiddleware.cs
public class NameConcatenationMiddleware
{
    private readonly RequestDelegate _next;

    public NameConcatenationMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (context.Request.Query.ContainsKey("firstname") &amp;&amp;
            context.Request.Query.ContainsKey("lastname"))
        {
            string fullName = $"{context.Request.Query["firstname"]} {context.Request.Query["lastname"]}";
            await context.Response.WriteAsync(fullName);
            return; // 명시적으로 반환하여 다음 미들웨어 호출 방지
        }
        
        await _next(context);
    }
}

// MiddlewareExtensions.cs
public static class MiddlewareExtensions
{
    public static IApplicationBuilder UseNameConcatenation(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware&lt;NameConcatenationMiddleware>();
    }
}</pre>



<div style="height:50px" 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/1f500.png" alt="🔀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 미들웨어 파이프라인의 이상적인 순서</h3>



<p>미들웨어의 순서는 애플리케이션의 동작과 효율성, 보안에 큰 영향을 미칩니다. </p>



<p>다음은 일반적으로 권장되는 이상적인 순서입니다</p>



<figure class="wp-block-image size-full"><img decoding="async" width="858" height="485" src="https://lycos7560.com/wp-content/uploads/2025/07/image-14.png" alt="" class="wp-image-40133" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-14.png 858w, https://lycos7560.com/wp-content/uploads/2025/07/image-14-300x170.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-14-768x434.png 768w" sizes="(max-width: 858px) 100vw, 858px" /><figcaption class="wp-element-caption"><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0</a></figcaption></figure>



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



<p><strong>예외/오류 처리(Exception/Error Handling):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 파이프라인의 어느 곳에서든 발생하는 예외를 Catch하고 처리합니다.</li>



<li><strong>예시:</strong> <code>UseExceptionHandler</code> (프로덕션용), <code>UseDeveloperExceptionPage</code> (개발 환경용).</li>



<li><strong>이유:</strong> 예외를 초기에 Catch하여 파이프라인 아래로 전파되어 더 큰 문제를 일으키는 것을 방지합니다.</li>
</ul>



<p><strong>HTTPS 리디렉션(HTTPS Redirection):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 보안을 위해 HTTP 요청을 HTTPS로 리디렉션합니다.</li>



<li><strong>예시:</strong> <code>UseHttpsRedirection</code>.</li>



<li><strong>이유:</strong> 보안을 최우선으로 하여 모든 통신이 암호화되도록 합니다.</li>
</ul>



<p><strong>정적 파일(Static Files):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 이미지, CSS, JavaScript 파일과 같은 정적 파일을 클라이언트에게 직접 제공합니다.</li>



<li><strong>예시:</strong> <code>UseStaticFiles</code>.</li>



<li><strong>이유:</strong> 정적 파일 요청은 빠르게 처리되어야 하며, 불필요하게 파이프라인의 다른 무거운 구성 요소를 거치지 않도록 일찍 처리합니다.</li>
</ul>



<p><strong>라우팅(Routing):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> URL을 기반으로 들어오는 요청을 특정 엔드포인트에 매칭합니다.</li>



<li><strong>예시:</strong> <code>UseRouting</code>, <code>UseEndpoints</code>.</li>



<li><strong>이유:</strong> 라우팅은 애플리케이션의 핵심 로직이 요청을 어떻게 처리할지 결정하는 기반이 됩니다.</li>
</ul>



<p><strong>CORS (Cross-Origin Resource Sharing):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 다른 도메인으로부터의 안전한 교차 출처(cross-origin) 요청을 가능하게 합니다.</li>



<li><strong>예시:</strong> <code>UseCors</code>.</li>



<li><strong>이유:</strong> 인증/인가 전에 위치하여, 사전 요청(preflight request)이 불필요하게 인증/인가 미들웨어를 거치지 않도록 합니다.</li>
</ul>



<p><strong>인증(Authentication):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 사용자 신원을 확인하고 사용자 주체(principal)를 설정합니다.</li>



<li><strong>예시:</strong> <code>UseAuthentication</code>.</li>



<li><strong>이유:</strong> 사용자가 누구인지 확인한 후에 리소스에 대한 접근 권한을 부여할 수 있습니다.</li>
</ul>



<p><strong>인가(Authorization):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 사용자가 특정 리소스에 접근하거나 특정 작업을 수행할 수 있는지 여부를 결정합니다.</li>



<li><strong>예시:</strong> <code>UseAuthorization</code>.</li>



<li><strong>이유:</strong> 인증된 사용자에게만 권한 부여 여부를 검사합니다.</li>
</ul>



<p><strong>커스텀 미들웨어(Custom Middleware):</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 로깅, 기능 플래그 등 애플리케이션별 미들웨어 구성 요소를 처리합니다.</li>



<li><strong>이유:</strong> 애플리케이션별 로직을 적절한 단계에서 파이프라인 내에 배치합니다.</li>
</ul>



<p><strong>MVC/Razor Pages/Minimal APIs:</strong></p>



<ul class="wp-block-list">
<li><strong>목적:</strong> 실제 애플리케이션의 최종 엔드포인트 처리 로직을 실행합니다.</li>



<li><strong>예시:</strong> <code>MapControllers()</code>, <code>MapRazorPages()</code>, <code>MapGet()</code> 등.</li>
</ul>



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



<figure class="wp-block-image size-full"><img decoding="async" width="848" height="589" src="https://lycos7560.com/wp-content/uploads/2025/07/image-15.png" alt="" class="wp-image-40134" srcset="https://lycos7560.com/wp-content/uploads/2025/07/image-15.png 848w, https://lycos7560.com/wp-content/uploads/2025/07/image-15-300x208.png 300w, https://lycos7560.com/wp-content/uploads/2025/07/image-15-768x533.png 768w" sizes="(max-width: 848px) 100vw, 848px" /><figcaption class="wp-element-caption"><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0</a></figcaption></figure>



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



<p><code>Program.cs</code> 파일에 미들웨어 구성 요소가 추가되는 순서는 요청 시 미들웨어 구성 요소가 호출되는 순서를 정의하며, 응답 시에는 역순으로 호출됩니다. </p>



<p>이러한 <strong>순서는 보안, 성능 및 기능에 매우 중요합니다.</strong></p>



<p><code>Program.cs</code>의 다음 강조 표시된 코드는 보안 관련 미들웨어 구성 요소를 일반적으로 권장되는 순서로 추가하는 예시입니다:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="19-43" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebMiddleware.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
    ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext&lt;ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity&lt;IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores&lt;ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
// app.UseCookiePolicy();

app.UseRouting();
// app.UseRateLimiter();
// app.UseRequestLocalization();
// app.UseCors();

app.UseAuthentication();
app.UseAuthorization();
// app.UseSession();
// app.UseResponseCompression();
// app.UseResponseCaching();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();</pre>



<div style="height:50px" 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;" /> UseWhen()</h3>



<p><code>UseWhen()</code>은 ASP.NET Core의 <code>IApplicationBuilder</code> 인터페이스에 있는 강력한 확장 메서드입니다. </p>



<p>이는 <strong>조건(predicate)에 따라 미들웨어를 요청 파이프라인에 조건부로 추가</strong>할 수 있도록 합니다. </p>



<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="">app.UseWhen(
    context => /* 여기에 조건 */, // HttpContext를 받아 true/false 반환
    app => /* 이 분기에서 실행될 미들웨어 구성 */ // 조건이 true일 때 실행될 미들웨어 파이프라인
);</pre>



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



<ul class="wp-block-list">
<li><strong><code>context</code>:</strong> <br>현재 요청을 나타내는 <code>HttpContext</code> 객체입니다.</li>



<li><strong>Predicate (조건):</strong> <br><code>HttpContext</code>를 받아들이고 미들웨어 분기가 실행되어야 할 경우 <code>true</code>를, 그렇지 않을 경우 <code>false</code>를 반환하는 함수입니다.</li>



<li><strong>Middleware Configuration (미들웨어 구성):</strong> <br>조건이 <code>true</code>일 때 실행되어야 할 미들웨어 구성 요소를 구성하는 액션입니다. <br>여기서 <code>app.Use()</code>, <code>app.Run()</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/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code>UseWhen()</code> 작동 방식</h4>



<ul class="wp-block-list">
<li><strong>조건 평가:</strong> <br>요청이 들어오면 <code>UseWhen()</code> 메서드는 먼저 <code>HttpContext</code>에 대해 조건 함수를 평가합니다.</li>



<li><strong>분기(조건이 true일 경우):</strong> <br>조건이 <code>true</code>를 반환하면, 구성 액션에 지정된 미들웨어 분기가 실행됩니다. <br>요청은 이 분기를 통해 흐르며, 수정되거나 응답을 생성할 수 있습니다.</li>



<li><strong>메인 파이프라인 재진입:</strong> <br>분기가 실행된 후(또는 조건이 <code>false</code>여서 건너뛰어진 경우), 요청 흐름은 메인 파이프라인으로 다시 진입하여 <code>UseWhen()</code> 호출 뒤에 등록된 다음 미들웨어 구성 요소로 계속 진행됩니다.</li>
</ul>



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



<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="">app.UseWhen(
    context => context.Request.Query.ContainsKey("username"), // 조건: 쿼리 문자열에 "username"이 있는지 확인
    app => {
        app.Use(async (context, next) =>
        {
            await context.Response.WriteAsync("Hello from Middleware branch\n"); // 분기 미들웨어: "Hello from Middleware branch" 작성
            await next(); // 다음 미들웨어 호출
        });
    });

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from middleware at main chain"); // 메인 파이프라인 미들웨어
});</pre>



<ul class="wp-block-list">
<li><strong>조건:</strong> <br><code>context.Request.Query.ContainsKey("username")</code> 조건은 쿼리 문자열에 &#8220;username&#8221;이라는 매개변수가 포함되어 있는지 확인합니다.</li>



<li><strong>분기 미들웨어:</strong> <br>&#8220;username&#8221; 매개변수가 존재하면 분기 미들웨어가 실행됩니다. <br>이 미들웨어는 응답에 &#8220;Hello from Middleware branch&#8221;를 작성하고 <code>next</code>를 호출하여 나머지 파이프라인이 계속되도록 합니다.</li>



<li><strong>메인 파이프라인:</strong> <br>마지막 <code>app.Run</code> 미들웨어는 메인 파이프라인의 일부입니다. <br>이는 응답에 &#8220;Hello from middleware at main chain&#8221;을 작성합니다.</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/1f98b.png" alt="🦋" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <code>UseWhen()</code> 사용 시점</h4>



<ul class="wp-block-list">
<li><strong>조건부 기능:</strong> <br>요청에 따라 특정 기능을 활성화하거나 비활성화합니다 (예: 특정 사용자에게만 로깅, 쿼리 매개변수에 따른 캐싱 규칙 적용).</li>



<li><strong>동적 파이프라인:</strong> <br>다양한 요청에 맞춰 조정되는 파이프라인을 만듭니다 (예: 특정 경로에 대해 다른 인증 미들웨어).</li>



<li><strong>A/B 테스트:</strong> <br>실험을 위해 사용자 하위 집합을 대체 미들웨어 분기를 통해 라우팅합니다.</li>



<li><strong>디버깅 및 진단:</strong> <br>개발 환경에서만 진단 미들웨어를 적용합니다.</li>
</ul>



<p></p>
<p>The post <a href="https://lycos7560.com/c/asp-net-core%ec%9d%98-%eb%af%b8%eb%93%a4%ec%9b%a8%ec%96%b4middleware/40130/">ASP.NET Core의 미들웨어(Middleware)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/asp-net-core%ec%9d%98-%eb%af%b8%eb%93%a4%ec%9b%a8%ec%96%b4middleware/40130/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Microsoft.Extensions.Hosting, 호스팅 모델(Hosting Model)</title>
		<link>https://lycos7560.com/c/microsoft-extensions-hosting-%ed%98%b8%ec%8a%a4%ed%8c%85-%eb%aa%a8%eb%8d%b8hosting-model/40109/</link>
					<comments>https://lycos7560.com/c/microsoft-extensions-hosting-%ed%98%b8%ec%8a%a4%ed%8c%85-%eb%aa%a8%eb%8d%b8hosting-model/40109/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Fri, 11 Jul 2025 14:31:34 +0000</pubDate>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[AddHostedService]]></category>
		<category><![CDATA[AddScoped]]></category>
		<category><![CDATA[AddSingleton]]></category>
		<category><![CDATA[AddTransient]]></category>
		<category><![CDATA[appsettings.json]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[Await]]></category>
		<category><![CDATA[Background Service]]></category>
		<category><![CDATA[BackgroundService]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[CancellationToken]]></category>
		<category><![CDATA[Clean Code]]></category>
		<category><![CDATA[Cloud Native]]></category>
		<category><![CDATA[Code Quality]]></category>
		<category><![CDATA[Command Line Arguments]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[ConfigureAppConfiguration]]></category>
		<category><![CDATA[ConfigureLogging]]></category>
		<category><![CDATA[ConfigureServices]]></category>
		<category><![CDATA[Console Application]]></category>
		<category><![CDATA[Console Logger]]></category>
		<category><![CDATA[CreateDefaultBuilder]]></category>
		<category><![CDATA[Cross Platform]]></category>
		<category><![CDATA[Debug Logger]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[Enterprise Application]]></category>
		<category><![CDATA[Environment Variables]]></category>
		<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[Event Log]]></category>
		<category><![CDATA[Exception Handling]]></category>
		<category><![CDATA[Extensions.Hosting]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Generic Host]]></category>
		<category><![CDATA[Graceful Shutdown]]></category>
		<category><![CDATA[Health Checks]]></category>
		<category><![CDATA[Host]]></category>
		<category><![CDATA[Hosting Model]]></category>
		<category><![CDATA[IHost]]></category>
		<category><![CDATA[IHostBuilder]]></category>
		<category><![CDATA[IHostedService]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Integration Testing]]></category>
		<category><![CDATA[Interlocked]]></category>
		<category><![CDATA[IOptions]]></category>
		<category><![CDATA[Lifecycle Management]]></category>
		<category><![CDATA[Log Provider]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[LogLevel]]></category>
		<category><![CDATA[Maintainability]]></category>
		<category><![CDATA[Memory Management]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Mocking]]></category>
		<category><![CDATA[Options Pattern]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[resource management]]></category>
		<category><![CDATA[RunAsync]]></category>
		<category><![CDATA[Scalability]]></category>
		<category><![CDATA[Service Lifetime]]></category>
		<category><![CDATA[Service Registration]]></category>
		<category><![CDATA[ServiceProvider]]></category>
		<category><![CDATA[Software Architecture]]></category>
		<category><![CDATA[SOLID Principles]]></category>
		<category><![CDATA[StartAsync]]></category>
		<category><![CDATA[StopAsync]]></category>
		<category><![CDATA[Structured Logging]]></category>
		<category><![CDATA[Task]]></category>
		<category><![CDATA[Testability]]></category>
		<category><![CDATA[Thread Safety]]></category>
		<category><![CDATA[Timer]]></category>
		<category><![CDATA[Unit Testing]]></category>
		<category><![CDATA[Windows Service]]></category>
		<category><![CDATA[Worker Service]]></category>
		<category><![CDATA[WPF Application]]></category>
		<category><![CDATA[구성 관리]]></category>
		<category><![CDATA[구조화된 로깅]]></category>
		<category><![CDATA[단위 테스트]]></category>
		<category><![CDATA[디자인 패턴]]></category>
		<category><![CDATA[로그 프로바이더]]></category>
		<category><![CDATA[로깅]]></category>
		<category><![CDATA[리소스 관리]]></category>
		<category><![CDATA[마이크로서비스]]></category>
		<category><![CDATA[메모리 관리]]></category>
		<category><![CDATA[명령줄 인수]]></category>
		<category><![CDATA[모범 사례]]></category>
		<category><![CDATA[모킹]]></category>
		<category><![CDATA[백그라운드 서비스]]></category>
		<category><![CDATA[생명 주기 관리]]></category>
		<category><![CDATA[서비스 등록]]></category>
		<category><![CDATA[서비스 생명주기]]></category>
		<category><![CDATA[성능]]></category>
		<category><![CDATA[소프트웨어 아키텍처]]></category>
		<category><![CDATA[스레드 안전성]]></category>
		<category><![CDATA[엔터프라이즈 애플리케이션]]></category>
		<category><![CDATA[예외 처리]]></category>
		<category><![CDATA[오류 처리]]></category>
		<category><![CDATA[옵션 패턴]]></category>
		<category><![CDATA[워커 서비스]]></category>
		<category><![CDATA[윈도우 서비스]]></category>
		<category><![CDATA[유지보수성]]></category>
		<category><![CDATA[의존성 주입]]></category>
		<category><![CDATA[인프라]]></category>
		<category><![CDATA[정상적인 종료]]></category>
		<category><![CDATA[제네릭 호스트]]></category>
		<category><![CDATA[코드 품질]]></category>
		<category><![CDATA[콘솔 애플리케이션]]></category>
		<category><![CDATA[크로스 플랫폼]]></category>
		<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=40109</guid>

					<description><![CDATA[<p>개요 Microsoft.Extensions.Hosting 네임스페이스는 .NET 애플리케이션의 호스팅 모델(Hosting Model)을 제공하는 핵심 구성 요소입니다. Host 클래스는 이 모델의 시작점 역할을 하며, 애플리케이션의 생명 주기(lifecycle), 구성(configuration), 의존성 주입(dependency injection, DI), 로깅(logging) 등 다양한 인프라 서비스를 중앙 집중식으로 관리합니다. 이 호스팅 모델은 ASP.NET Core 애플리케이션에서 시작되었지만, 현재는 콘솔 애플리케이션, 백그라운드 서비스, Windows 서비스, WPF 애플리케이션 등 다양한 종류의 .NET [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/microsoft-extensions-hosting-%ed%98%b8%ec%8a%a4%ed%8c%85-%eb%aa%a8%eb%8d%b8hosting-model/40109/">Microsoft.Extensions.Hosting, 호스팅 모델(Hosting Model)</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-c19625a0      "
					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="#개요" class="uagb-toc-link__trigger">개요</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-host-클래스의-목적과-역할" class="uagb-toc-link__trigger">1. Host 클래스의 목적과 역할</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-host-클래스-핵심-인터페이스-및-메서드" class="uagb-toc-link__trigger">2. Host 클래스 핵심 인터페이스 및 메서드</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1-ihostbuilder-인터페이스" class="uagb-toc-link__trigger">(1) IHostBuilder 인터페이스</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2-ihost-인터페이스" class="uagb-toc-link__trigger">(2) IHost 인터페이스</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#3-ihostedservice-인터페이스" class="uagb-toc-link__trigger">(3) IHostedService 인터페이스</a></li></ul><li class="uagb-toc__list"><a href="#3-hostcreatedefaultbuilder-메서드의-이점" class="uagb-toc-link__trigger">3. Host.CreateDefaultBuilder() 메서드의 이점</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#예시-코드-콘솔-애플리케이션에서-host-사용하기" class="uagb-toc-link__trigger">예시 코드: 콘솔 애플리케이션에서 Host 사용하기</a></ul></ul></ol>					</div>
									</div>
				</div>
			


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



<h2 class="wp-block-heading">개요</h2>



<p>Microsoft.Extensions.Hosting 네임스페이스는 .NET 애플리케이션의 호스팅 모델(Hosting Model)을 제공하는 핵심 구성 요소입니다. </p>



<p>Host 클래스는 이 모델의 시작점 역할을 하며, 애플리케이션의 생명 주기(lifecycle), 구성(configuration), 의존성 주입(dependency injection, DI), 로깅(logging) 등 다양한 인프라 서비스를 중앙 집중식으로 관리합니다.</p>



<p>이 호스팅 모델은 ASP.NET Core 애플리케이션에서 시작되었지만, 현재는 콘솔 애플리케이션, 백그라운드 서비스, Windows 서비스, WPF 애플리케이션 등 다양한 종류의 .NET 애플리케이션에서 표준적인 방식으로 사용되고 있습니다.</p>



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



<h3 class="wp-block-heading">1. <code>Host</code> 클래스의 목적과 역할</h3>



<p><code>Host</code> 클래스는 특정 애플리케이션 유형에 구애받지 않고, 공통적인 인프라 기능을 쉽게 통합하고 관리할 수 있도록 설계되었습니다.</p>



<ul class="wp-block-list">
<li><strong>생명 주기 관리</strong>: 애플리케이션의 시작(<code>StartAsync</code>) 및 종료(<code>StopAsync</code>)를 관리하고, 이 과정에서 필요한 서비스들이 올바른 순서로 초기화되고 정리될 수 있도록 합니다.</li>



<li><strong>의존성 주입 (DI)</strong>: 애플리케이션 전반에 걸쳐 강력한 DI 컨테이너를 제공하여, 서비스 간의 느슨한 결합을 촉진하고 테스트 용이성을 향상시킵니다.</li>



<li><strong>구성 (Configuration)</strong>: <code>appsettings.json</code>, 환경 변수, 명령줄 인수 등 다양한 소스에서 설정을 로드하고 관리하는 일관된 방법을 제공합니다.</li>



<li><strong>로깅 (Logging)</strong>: 다양한 로깅 프로바이더(콘솔, 파일, 데이터베이스 등)를 쉽게 통합하고, 로깅 레벨을 유연하게 제어할 수 있도록 합니다.</li>



<li><strong>백그라운드 서비스 (IHostedService)</strong>: 장시간 실행되는 백그라운드 작업을 호스트의 생명 주기에 통합하여 관리할 수 있도록 합니다. 이는 API를 제공하지 않고 단순히 작업을 수행하는 서비스에 특히 유용합니다.</li>
</ul>



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



<h3 class="wp-block-heading">2. <code>Host</code> 클래스 핵심 인터페이스 및 메서드</h3>



<p><code>Host</code> 클래스 자체보다는, 이와 관련된 <code>IHost</code> 및 <code>IHostBuilder</code> 인터페이스를 이해하는 것이 중요합니다.</p>



<h4 class="wp-block-heading">(1) <code>IHostBuilder</code> 인터페이스</h4>



<p><code>IHostBuilder</code>는 호스트를 <strong>구성(Configure)</strong>하는 데 사용되는 인터페이스입니다. </p>



<p><code>Host.CreateDefaultBuilder()</code> 메서드가 반환하는 객체가 바로 <strong><code>IHostBuilder</code> </strong>타입입니다. </p>



<p>이 빌더를 통해 다음을 정의할 수 있습니다:</p>



<ul class="wp-block-list">
<li><strong><code>ConfigureAppConfiguration</code></strong>: <br>설정 소스(파일, 환경 변수 등)를 추가하거나 커스터마이징합니다.</li>
</ul>



<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="">.ConfigureAppConfiguration((context, config) =>
{
    config.AddJsonFile("custom.json", optional: true)
          .AddEnvironmentVariables()
          .AddCommandLine(args);
})</pre>



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



<ul class="wp-block-list">
<li><strong><code>ConfigureLogging</code></strong>: <br>로깅 프로바이더(콘솔, 디버그, 파일 등)를 추가하고 로깅 필터링 규칙을 정의합니다.</li>
</ul>



<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="">.ConfigureLogging((context, logging) =>
{
    logging.AddConsole()
           .AddDebug()
           .SetMinimumLevel(LogLevel.Information);
})</pre>



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



<ul class="wp-block-list">
<li><strong><code>ConfigureServices</code></strong>: <br>의존성 주입 컨테이너에 애플리케이션의 서비스들을 등록합니다. <br><code>AddSingleton</code>, <code>AddScoped</code>, <code>AddTransient</code> 등의 메서드를 사용하여 서비스의 생명 주기를 지정할 수 있습니다.</li>
</ul>



<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="">.ConfigureServices((context, services) =>
{
    services.AddSingleton&lt;ISingletonService, SingletonService>();
    services.AddScoped&lt;IScopedService, ScopedService>();
    services.AddTransient&lt;ITransientService, TransientService>();
    services.AddHostedService&lt;MyBackgroundService>();
})</pre>



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



<ul class="wp-block-list">
<li><strong><code>UseConsoleLifetime</code></strong>: <br>콘솔 애플리케이션의 경우, <code>Ctrl+C</code>와 같은 콘솔 시그널을 감지하여 호스트를 정상적으로 종료하도록 설정합니다. <br>(이는 <code>Host.CreateDefaultBuilder()</code>에 의해 기본적으로 포함됩니다.)</li>



<li><strong><code>Build()</code></strong>: <br><code>IHostBuilder</code>에 정의된 모든 구성을 기반으로 최종 <code>IHost</code> 인스턴스를 생성합니다.</li>
</ul>



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



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



<h4 class="wp-block-heading">(2) <code>IHost</code> 인터페이스</h4>



<p><code>IHost</code>는 <strong>빌드된 호스트 인스턴스</strong>를 나타내며, 실제로 애플리케이션을 실행하고 관리하는 데 사용됩니다. </p>



<p>주요 메서드는 다음과 같습니다</p>



<ul class="wp-block-list">
<li><strong><code>Services</code></strong>: <br>등록된 모든 서비스 인스턴스에 접근할 수 있는 <code>IServiceProvider</code>를 제공합니다. <br>이를 통해 런타임에 필요한 서비스를 resolve(가져오기)할 수 있습니다.</li>



<li><strong><code>StartAsync(CancellationToken cancellationToken)</code></strong>: <br>호스트를 비동기적으로 시작합니다. 이 메서드가 호출되면 등록된 모든 <code>IHostedService</code> 인스턴스의 <code>StartAsync</code> 메서드가 호출됩니다.</li>



<li><strong><code>StopAsync(CancellationToken cancellationToken)</code></strong>: <br>호스트를 비동기적으로 종료합니다. 등록된 모든 <code>IHostedService</code> 인스턴스의 <code>StopAsync</code> 메서드가 호출되어 리소스를 정리할 기회를 줍니다.</li>



<li><strong><code>RunAsync(CancellationToken cancellationToken = default)</code></strong>: <br><code>StartAsync</code>를 호출하고, 호스트가 종료될 때까지 대기한 후 <code>StopAsync</code>를 호출합니다. <br>대부분의 콘솔 애플리케이션에서 메인 실행 루프로 사용됩니다.</li>
</ul>



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



<h4 class="wp-block-heading">(3) <code>IHostedService</code> 인터페이스</h4>



<p><code>IHostedService</code>는 호스트의 생명 주기에 통합되어 백그라운드 작업을 수행하는 서비스들을 정의하는 인터페이스입니다. </p>



<p><code>StartAsync</code>와 <code>StopAsync</code> 두 가지 메서드를 구현해야 합니다.</p>



<ul class="wp-block-list">
<li><strong><code>StartAsync(CancellationToken cancellationToken)</code></strong>: <br>호스트가 시작될 때 호출됩니다. 장시간 실행되는 작업을 시작하는 데 사용됩니다.</li>



<li><strong><code>StopAsync(CancellationToken cancellationToken)</code></strong>: <br>호스트가 종료될 때 호출됩니다. <code>StartAsync</code>에서 시작된 작업을 정상적으로 중지하고 리소스를 정리하는 데 사용됩니다.</li>
</ul>



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



<h3 class="wp-block-heading">3. <code>Host.CreateDefaultBuilder()</code> 메서드의 이점</h3>



<p>이 메서드는 많은 &#8220;관습(conventions)&#8221;을 제공하여 애플리케이션 초기 설정을 간소화하는 장점이 있습니다.</p>



<ul class="wp-block-list">
<li><strong>일관성</strong>: <br>모든 .NET 애플리케이션 유형(웹, 콘솔, 백그라운드 서비스)에서 동일한 방식으로 인프라를 설정할 수 있게 하여 코드의 일관성을 유지합니다.</li>



<li><strong>생산성</strong>: <br>설정, 로깅, DI 등 반복적인 초기화 코드를 작성할 필요 없이 바로 비즈니스 로직에 집중할 수 있도록 합니다.</li>



<li><strong>확장성</strong>: <br>기본 설정을 사용하면서도 <code>ConfigureAppConfiguration</code>, <code>ConfigureServices</code> 등의 메서드를 통해 언제든지 필요에 따라 커스터마이징하고 확장할 수 있습니다.</li>



<li><strong>테스트 용이성</strong>: <br>DI 컨테이너를 중심으로 설계되어, 단위 테스트 및 통합 테스트에서 의존성을 쉽게 Mocking하거나 대체할 수 있습니다.<br>참고: Mocking &#8211; 테스트 코드 작성 시 가짜 객체(Mock)를 만들어 실제 객체 대신 사용하는 기법</li>
</ul>



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



<h4 class="wp-block-heading">예시 코드: 콘솔 애플리케이션에서 <code>Host</code> 사용하기</h4>



<p>콘솔 애플리케이션에서 <code>Host</code> 클래스를 사용하여 백그라운드 서비스(카운터)를 실행하고, 설정 및 로깅을 사용하는 예제</p>



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



<ul class="wp-block-list">
<li><code>Microsoft.Extensions.Hosting</code> NuGet 패키지를 설치</li>
</ul>



<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="">dotnet add package Microsoft.Extensions.Hosting</pre>



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



<ul class="wp-block-list">
<li><code>appsettings.json</code> 파일을 추가하고 내용을 작성합니다.</li>
</ul>



<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.Hosting.Lifetime": "Information"
    }
  },
  "AppConfig": {
    "IntervalSeconds": 2
  }
}</pre>



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



<ul class="wp-block-list">
<li><code>Services/MyBackgroundService.cs</code> (커스텀 <code>IHostedService</code> 구현):</li>
</ul>



<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.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration; // IConfiguration 주입을 위해 추가
using System;
using System.Threading;
using System.Threading.Tasks;

namespace MyConsoleApp.Services
{
    // IHostedService를 구현하여 호스트의 생명 주기에 통합될 백그라운드 서비스를 정의합니다.
    public class MyBackgroundService : IHostedService, IDisposable
    {
        private readonly ILogger&lt;MyBackgroundService> _logger;
        private readonly IConfiguration _configuration;
        private Timer? _timer;
        private int _executionCount = 0;
        private int _intervalSeconds;

        public MyBackgroundService(ILogger&lt;MyBackgroundService> logger, IConfiguration configuration)
        {
            _logger = logger;
            _configuration = configuration;

            // appsettings.json에서 설정 값 읽기
            _intervalSeconds = _configuration.GetValue&lt;int>("AppConfig:IntervalSeconds", 5); // 기본값 5초
        }

        // 호스트가 시작될 때 호출됩니다.
        public Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("MyBackgroundService가 시작되었습니다.");

            // 타이머를 설정하여 지정된 간격마다 DoWork 메서드를 호출합니다.
            _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(_intervalSeconds));

            return Task.CompletedTask; // 비동기 작업 시작을 알리고 즉시 반환
        }

        // 타이머에 의해 주기적으로 호출되는 실제 작업 메서드
        private void DoWork(object? state)
        {
            var count = Interlocked.Increment(ref _executionCount);
            _logger.LogInformation(
                "MyBackgroundService가 {count}번째 작업을 수행 중입니다. 현재 시간: {time}",
                count, DateTimeOffset.Now);
        }

        // 호스트가 종료될 때 호출됩니다.
        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("MyBackgroundService가 중지되고 있습니다.");

            // 타이머를 중지하고 리소스를 해제합니다.
            // Change(Timeout.Infinite, 0)은 타이머를 비활성화하는 표준 방법입니다.
            _timer?.Change(Timeout.Infinite, 0);

            _logger.LogInformation("MyBackgroundService가 중지되었습니다.");
            return Task.CompletedTask; // 작업 완료를 알립니다.
        }

        // 리소스 해제를 위한 Dispose 메서드 (IHostedService는 IDisposable을 구현하는 경우가 많음)
        public void Dispose()
        {
            _timer?.Dispose();
        }
    }
}</pre>



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



<ul class="wp-block-list">
<li><code>Program.cs</code> 구현:</li>
</ul>



<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.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MyConsoleApp.Services; // MyBackgroundService를 사용하기 위해 추가
using System;
using System.Threading.Tasks;

namespace MyConsoleApp
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            Console.WriteLine("콘솔 애플리케이션 호스트가 시작됩니다. 종료하려면 Ctrl+C를 누르세요.");

            // 1. IHostBuilder 인스턴스 생성: Host.CreateDefaultBuilder()는 기본적인 구성(config, logging, DI)을 설정합니다.
            var builder = Host.CreateDefaultBuilder(args)
                // 2. 서비스 컨테이너 구성: 의존성 주입을 위한 서비스들을 등록합니다.
                .ConfigureServices((hostContext, services) =>
                {
                    // MyBackgroundService를 IHostedService로 등록합니다.
                    // 호스트가 시작될 때 StartAsync가 호출되고, 종료될 때 StopAsync가 호출됩니다.
                    services.AddHostedService&lt;MyBackgroundService>();

                    // 여기에 다른 서비스들도 등록할 수 있습니다. 예:
                    // services.AddSingleton&lt;IMyService, MyService>();
                    // services.AddScoped&lt;IOtherService, OtherService>();
                })
                // 3. 로깅 구성 (선택 사항: CreateDefaultBuilder가 기본 설정 제공하지만, 커스터마이징 가능)
                .ConfigureLogging(logging =>
                {
                    logging.ClearProviders(); // 기본 로깅 프로바이더를 지우고 새로 추가하거나
                    logging.AddConsole();    // 콘솔 로거를 추가합니다.
                    // logging.AddDebug();    // 디버그 로거 추가
                });
                // 4. 기타 구성 (선택 사항: 파일 경로, 환경 등)
                // .UseContentRoot(Directory.GetCurrentDirectory())
                // .UseEnvironment("Development")
                // .ConfigureAppConfiguration((hostingContext, config) => {
                //    config.AddJsonFile("custom.json", optional: true);
                // });

            // 5. IHost 인스턴스 빌드: 구성된 빌더를 바탕으로 실제 호스트를 생성합니다.
            var host = builder.Build();

            // 6. 호스트 실행: 등록된 모든 IHostedService를 시작하고 애플리케이션 종료를 대기합니다.
            // Ctrl+C 시그널을 감지하여 정상적으로 종료됩니다.
            await host.RunAsync();

            Console.WriteLine("콘솔 애플리케이션 호스트가 종료되었습니다.");
        }
    }
}</pre>



<p></p>



<p></p>



<p></p>



<p></p>
<p>The post <a href="https://lycos7560.com/c/microsoft-extensions-hosting-%ed%98%b8%ec%8a%a4%ed%8c%85-%eb%aa%a8%eb%8d%b8hosting-model/40109/">Microsoft.Extensions.Hosting, 호스팅 모델(Hosting Model)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/microsoft-extensions-hosting-%ed%98%b8%ec%8a%a4%ed%8c%85-%eb%aa%a8%eb%8d%b8hosting-model/40109/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>C#의 CancellationToken, CancellationTokenSource</title>
		<link>https://lycos7560.com/c/c%ec%9d%98-cancellationtoken-cancellationtokensource/39889/</link>
					<comments>https://lycos7560.com/c/c%ec%9d%98-cancellationtoken-cancellationtokensource/39889/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Sun, 16 Feb 2025 08:07:57 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[AsynchronousProgramming]]></category>
		<category><![CDATA[Await]]></category>
		<category><![CDATA[BestPractice]]></category>
		<category><![CDATA[Cancel]]></category>
		<category><![CDATA[CancelAfter]]></category>
		<category><![CDATA[CancellationToken]]></category>
		<category><![CDATA[CancellationTokenSource]]></category>
		<category><![CDATA[CodeOptimization]]></category>
		<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[CSharp]]></category>
		<category><![CDATA[CSharpProgramming]]></category>
		<category><![CDATA[DataProcessing]]></category>
		<category><![CDATA[Delay]]></category>
		<category><![CDATA[Dispose]]></category>
		<category><![CDATA[ExceptionHandling]]></category>
		<category><![CDATA[Filestream]]></category>
		<category><![CDATA[GetAsync]]></category>
		<category><![CDATA[HighPerformance]]></category>
		<category><![CDATA[HttpClient]]></category>
		<category><![CDATA[LinkedCancellation]]></category>
		<category><![CDATA[LinkedTokenSource]]></category>
		<category><![CDATA[LoopCancellation]]></category>
		<category><![CDATA[MaxDegreeOfParallelism]]></category>
		<category><![CDATA[MemoryLeak]]></category>
		<category><![CDATA[Multithreading]]></category>
		<category><![CDATA[OperationCanceledException]]></category>
		<category><![CDATA[ParallelForEach]]></category>
		<category><![CDATA[ParallelOptions]]></category>
		<category><![CDATA[ParallelProcessing]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Register]]></category>
		<category><![CDATA[ResourceCleanup]]></category>
		<category><![CDATA[ResourceManagement]]></category>
		<category><![CDATA[SafeThreading]]></category>
		<category><![CDATA[SoftwareDevelopment]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Task]]></category>
		<category><![CDATA[TaskCanceledException]]></category>
		<category><![CDATA[TaskManagement]]></category>
		<category><![CDATA[TaskRun]]></category>
		<category><![CDATA[thread]]></category>
		<category><![CDATA[ThreadSafety]]></category>
		<category><![CDATA[ThreadSleep]]></category>
		<category><![CDATA[Timeout]]></category>
		<category><![CDATA[Token]]></category>
		<category><![CDATA[TokenSource]]></category>
		<category><![CDATA[TryCatch]]></category>
		<category><![CDATA[Using]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[비동기처리]]></category>
		<category><![CDATA[코루틴]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=39889</guid>

					<description><![CDATA[<p>🔥 CancellationToken, CancellationTokenSource https://learn.microsoft.com/ko-kr/dotnet/api/system.threading.cancellationtokensource?view=net-9.0 ✅ 개념 정리 CancellationToken과 CancellationTokenSource는 C#에서 비동기 작업(Task)이나 스레드를 안전하게 취소할 수 있도록 제공되는 기능합니다. 이를 활용하면 비동기 작업을 중단하거나, 긴 루프를 중지할 수 있도록 관리할 수 있습니다. 🔹 CancellationTokenSource 🔹 CancellationToken 역할 설명 CancellationTokenSource 취소 요청을 보내는 쪽 (발신자) 역할을 합니다. Cancel(), CancelAfter(), Dispose() 등을 호출 할 수 있습니다. CancellationToken [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/c/c%ec%9d%98-cancellationtoken-cancellationtokensource/39889/">C#의 CancellationToken, CancellationTokenSource</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-735cef37      "
					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="#cancellationtoken-cancellationtokensource" 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;" /> CancellationToken, CancellationTokenSource</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="#cancellationtokensource" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CancellationTokenSource</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#cancellationtoken" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CancellationToken</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="#cancellationtoken-사용-예제" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CancellationToken 사용 예제</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="#throwifcancellationrequested" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ThrowIfCancellationRequested()</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#taskrun에서-cancellationtoken" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Task.Run()에서 CancellationToken</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#register를-활용한-callback-함수" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Register()를 활용한 CallBack 함수</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#async와-cancellationtoken을-활용한-httpclient-요청-취소" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> async와 CancellationToken을 활용한 HttpClient 요청 취소</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#cancelafter를-활용한-자동-취소" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CancelAfter()를 활용한 자동 취소</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#linkedtokensource를-사용하여-여러-토큰을-결합" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> LinkedTokenSource를 사용하여 여러 토큰을 결합</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#parallelforeach에서-cancellationtoken-적용" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Parallel.ForEach()에서 CancellationToken 적용</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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 리소스 정리의 중요성</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#cancellationtoken-확인-빈도" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" />  CancellationToken 확인 빈도</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#cancellationtokensourcedispose-중요성" class="uagb-toc-link__trigger"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CancellationTokenSource.Dispose() 중요성</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></ul></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:50px" 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;" /> CancellationToken, CancellationTokenSource</h2>



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



<div style="height:20px" 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>



<p><code><strong>CancellationToken</strong></code>과 <code><strong>CancellationTokenSource</strong></code>는 C#에서 <strong>비동기 작업(Task)</strong>이나 <strong>스레드를 안전하게 취소</strong>할 수 있도록 제공되는 기능합니다.</p>



<p>이를 활용하면 <strong>비동기 작업을 중단</strong>하거나,<strong> 긴 루프를 중지</strong>할 수 있도록 <strong>관리</strong>할 수 있습니다.</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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CancellationTokenSource</h4>



<ul class="wp-block-list">
<li>취소 요청을 생성하고 관리하는 역할을 합니다.</li>



<li><code><strong>CancellationToken</strong></code>을 생성할 수 있으며, <strong><code>Cancel()</code></strong> 메서드를 호출하면 해당 토큰을 통해 작업을 중단할 수 있습니다.</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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CancellationToken</h4>



<ul class="wp-block-list">
<li><code><strong>CancellationTokenSource</strong></code>에서 생성한 취소 토큰을 <strong>비동기 작업</strong>이나 <strong>스레드</strong>에 전달하여, <strong>취소 여부를 확인</strong>하는 데 사용됩니다.</li>
</ul>



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



<figure class="wp-block-table"><table><thead><tr><th>역할</th><th>설명</th></tr></thead><tbody><tr><td><code>CancellationTokenSource</code></td><td><strong>취소 요청을 보내는 쪽 (발신자)</strong> 역할을 합니다. <code>Cancel()</code>, <code>CancelAfter()</code>, <code>Dispose()</code> 등을 호출 할 수 있습니다.</td></tr><tr><td><code>CancellationToken</code></td><td><strong>취소 요청을 받는 쪽 (수신자)</strong> 역할입니다. <code>IsCancellationRequested</code>로 확인하거나, <code>ThrowIfCancellationRequested()</code> 등을 사용해 취소 여부를 감지할 수 있습니다.</td></tr></tbody></table></figure>



<div style="height:50px" 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>



<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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CancellationToken 사용 예제</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="">using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        CancellationToken token = cts.Token;

        Task task = DoWorkAsync(token);

        // 3초 후에 작업 취소 요청
        await Task.Delay(3000);
        cts.Cancel();

        await task;
    }

    static async Task DoWorkAsync(CancellationToken token)
    {
        for (int i = 0; i &lt; 10; i++)
        {
            // 작업이 취소되었는지 확인
            if (token.IsCancellationRequested)
            {
                Console.WriteLine("작업이 취소되었습니다.");
                return;
            }

            Console.WriteLine($"작업 진행 중... {i}");
            await Task.Delay(1000); // 1초 대기
        }
    }
}
</pre>



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



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">작업 진행 중... 0
작업 진행 중... 1
작업 진행 중... 2
작업이 취소되었습니다.
</pre>



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



<h5 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>설명</strong></h5>



<ol class="wp-block-list">
<li> <code><strong>CancellationTokenSource</strong></code>를 생성하여 <strong><code>CancellationToken</code></strong>을 가져옴</li>



<li> <code><strong>DoWorkAsync()</strong></code> 메서드에서 <code><strong>token.IsCancellationRequested</strong></code>를 통해 취소 여부 확인</li>



<li> <code><strong>Task.Delay(3000)</strong></code> 후 <code><strong>cts.Cancel()</strong></code>을 호출하여 <strong>비동기 작업을 취소</strong></li>
</ol>



<div style="height:50px" 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>



<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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ThrowIfCancellationRequested()</h4>



<p>이전의 예제에서는 <code><strong>IsCancellationRequested</strong></code>로 확인 후 <code>return</code> 했지만, <code><strong>ThrowIfCancellationRequested()</strong></code>를 사용하면 <strong>예외(Exception) 형태로 중단</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="">static async Task DoWorkAsync(CancellationToken token)
{
    for (int i = 0; i &lt; 10; i++)
    {
        token.ThrowIfCancellationRequested(); // 취소 요청 시 예외 발생

        Console.WriteLine($"작업 진행 중... {i}");
        await Task.Delay(1000);
    }
}
</pre>



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



<p><strong>예외 처리 추가</strong> (try-catch로 OperationCanceledException을 catch가 가능)</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="">try
{
    await DoWorkAsync(token);
}
catch (OperationCanceledException)
{
    Console.WriteLine("작업이 취소되었습니다. (예외 발생)");
}
</pre>



<div style="height:40px" 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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Task.Run()에서 CancellationToken</h4>



<p>비동기 작업을 <code><strong>Task.Run()</strong></code>을 사용하여 실행하는 경우, <strong><code>CancellationToken</code>을 직접 전달</strong>할 수 있습니다.</p>



<p><code><strong>Task.Run()</strong></code>과 함께 사용할 경우, <code><strong>CancellationToken</strong></code>을 직접 전달하면 자동으로 <code><strong>OperationCanceledException</strong></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="">CancellationTokenSource cts = new CancellationTokenSource();

Task task = Task.Run(() => 
{
    for (int i = 0; i &lt; 10; i++)
    {
        cts.Token.ThrowIfCancellationRequested();
        Console.WriteLine($"작업 진행 중... {i}");
        Thread.Sleep(1000);
    }
}, cts.Token); // CancellationToken을 직접 전달

await Task.Delay(3000);
cts.Cancel(); // 3초 후 취소
</pre>



<div style="height:40px" 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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Register()를 활용한 CallBack 함수</h4>



<p><code><strong>CancellationToken.Register()</strong></code>를 사용하면, <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="">cts.Token.Register(() => Console.WriteLine("취소 요청이 감지되었습니다!"));
</pre>



<div style="height:20px" 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="">using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        CancellationToken token = cts.Token;

        // 취소 요청 시 실행될 콜백 등록
        token.Register(() => Console.WriteLine("취소 요청이 감지되었습니다!"));

        Task task = DoWorkAsync(token);

        await Task.Delay(3000);
        cts.Cancel(); // 3초 후 취소 요청

        await task;
    }

    static async Task DoWorkAsync(CancellationToken token)
    {
        for (int i = 0; i &lt; 10; i++)
        {
            if (token.IsCancellationRequested)
            {
                Console.WriteLine("작업이 취소되었습니다.");
                return;
            }

            Console.WriteLine($"작업 진행 중... {i}");
            await Task.Delay(1000);
        }
    }
}
</pre>



<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="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">작업 진행 중... 0
작업 진행 중... 1
작업 진행 중... 2
취소 요청이 감지되었습니다!
작업이 취소되었습니다.
</pre>



<div style="height:40px" 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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> async와 CancellationToken을 활용한 HttpClient 요청 취소</h4>



<p><code><strong>HttpClient</strong></code>에서 <code><strong>CancellationToken</strong></code>을 사용하여 HTTP 요청을 중단할 수도 있습니다.</p>



<p><strong><code>HttpClient</code> </strong>요청이 너무 오래 걸리면 <code><strong>CancellationToken</strong></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="">using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using (HttpClient client = new HttpClient())
        using (CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(2))) // 2초 후 자동 취소
        {
            try
            {
                HttpResponseMessage response = await client.GetAsync("https://example.com", cts.Token);
                Console.WriteLine("응답 수신 완료!");
            }
            catch (TaskCanceledException)
            {
                Console.WriteLine("HTTP 요청이 취소되었습니다.");
            }
        }
    }
}
</pre>



<div style="height:40px" 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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CancelAfter()를 활용한 자동 취소</h4>



<p>일정 시간이 지나면 자동으로 취소되도록 설정 가능 (<code><strong>CancelAfter(milliseconds)</strong></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="">cts.Token.Register(() => Console.WriteLine("취소 요청이 감지되었습니다!"));
</pre>



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



<p><strong>사용 예제</strong> (5초 후 자동 취소되는 코드)</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 System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        cts.CancelAfter(5000); // 5초 후 자동 취소

        try
        {
            await DoWorkAsync(cts.Token);
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("작업이 시간 초과로 취소되었습니다.");
        }
    }

    static async Task DoWorkAsync(CancellationToken token)
    {
        for (int i = 0; i &lt; 10; i++)
        {
            token.ThrowIfCancellationRequested();
            Console.WriteLine($"작업 진행 중... {i}");
            await Task.Delay(1000);
        }
    }
}
</pre>



<div style="height:40px" 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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> LinkedTokenSource를 사용하여 여러 토큰을 결합</h4>



<p>여러 <code><strong>CancellationTokenSource</strong></code>를 결합하여 하나의 토큰으로 관리 가능</p>



<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="">using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        CancellationTokenSource cts1 = new CancellationTokenSource();
        CancellationTokenSource cts2 = new CancellationTokenSource();

        // 두 개의 토큰을 하나로 결합
        using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token))
        {
            Task task = DoWorkAsync(linkedCts.Token);

            await Task.Delay(3000);
            cts1.Cancel(); // 하나의 토큰만 취소해도 작업 전체가 중단됨

            await task;
        }
    }

    static async Task DoWorkAsync(CancellationToken token)
    {
        for (int i = 0; i &lt; 10; i++)
        {
            token.ThrowIfCancellationRequested();
            Console.WriteLine($"작업 진행 중... {i}");
            await Task.Delay(1000);
        }
    }
}
</pre>



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



<p>결과적으로 <code><strong>cts1.Cancel();</strong></code> 호출 시 <code><strong>linkedCts</strong></code>도 취소됨</p>



<div style="height:40px" 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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Parallel.ForEach()에서 CancellationToken 적용</h4>



<p><code><strong>Parallel.ForEach()</strong></code>에서 <code><strong>CancellationToken</strong></code>을 사용하여 병렬 처리 도중 특정 조건에서 중단할 수도 있습니다.</p>



<p><code><strong>ParallelOptions</strong></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="">ParallelOptions options = new ParallelOptions
{
    CancellationToken = cts.Token,
    MaxDegreeOfParallelism = 4 // 최대 4개의 스레드 사용
};

try
{
    Parallel.ForEach(Enumerable.Range(1, 100), options, (num, state) =>
    {
        options.CancellationToken.ThrowIfCancellationRequested();
        Console.WriteLine($"Processing {num}");
        Thread.Sleep(500); // 가상의 작업
    });
}
catch (OperationCanceledException)
{
    Console.WriteLine("병렬 작업이 취소되었습니다.");
}
</pre>



<div style="height:50px" 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>



<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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 리소스 정리의 중요성</h4>



<p>취소된 작업에서도 적절한 리소스 정리가 필요합니다. </p>



<p>try/finally 블록이나 using 문을 적절이 활용하는 것이 좋습니다.</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="">static async Task ProcessFileAsync(string path, CancellationToken token)
{
    FileStream file = null;
    try
    {
        file = new FileStream(path, FileMode.Open);
        // 파일 처리 작업
        token.ThrowIfCancellationRequested();
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine("파일 처리가 취소되었습니다.");
        throw;
    }
    finally
    {
        // 취소 여부와 상관없이 항상 실행됨
        file?.Dispose();
    }
}</pre>



<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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" />  CancellationToken 확인 빈도</h4>



<p>장시간 실행되는 작업에서는 <strong>적절한 간격</strong>으로 <strong>취소 토큰을 확인하는 것이 중요</strong>합니다.</p>



<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="">static void ProcessLargeData(IEnumerable&lt;int> items, CancellationToken token)
{
    int count = 0;
    foreach (var item in items)
    {
        // 100개 항목마다 취소 여부 확인 (너무 자주 확인하면 성능 저하)
        if (count++ % 100 == 0 &amp;&amp; token.IsCancellationRequested)
        {
            Console.WriteLine("작업이 취소되었습니다.");
            return;
        }
        
        // 항목 처리...
    }
}</pre>



<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/1f539.png" alt="🔹" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CancellationTokenSource.Dispose() 중요성</h4>



<p>CancellationTokenSource는 사용 후 수명이 끝나면 반드시 Dispose()를 호출해야 합니다. (메모리 누수)</p>



<p>using 문을 사용하는 것을 추천합니다.</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 (var cts = new CancellationTokenSource())
{
    // 작업 수행
}
// 여기서 자동으로 cts.Dispose() 호출됨</pre>



<div style="height:50px" 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>



<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="">// https://learn.microsoft.com/ko-kr/dotnet/api/system.threading.cancellationtokensource?view=net-9.0
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      // Define the cancellation token.
      CancellationTokenSource source = new CancellationTokenSource();
      CancellationToken token = source.Token;

      Random rnd = new Random();
      Object lockObj = new Object();
      
      List&lt;Task&lt;int[]>> tasks = new List&lt;Task&lt;int[]>>();
      TaskFactory factory = new TaskFactory(token);
      for (int taskCtr = 0; taskCtr &lt;= 10; taskCtr++) {
         int iteration = taskCtr + 1;
         tasks.Add(factory.StartNew( () => {
           int value;
           int[] values = new int[10];
           for (int ctr = 1; ctr &lt;= 10; ctr++) {
              lock (lockObj) {
                 value = rnd.Next(0,101);
              }
              if (value == 0) { 
                 source.Cancel();
                 Console.WriteLine("Cancelling at task {0}", iteration);
                 break;
              }   
              values[ctr-1] = value; 
           }
           return values;
        }, token));   
      }
      try {
         Task&lt;double> fTask = factory.ContinueWhenAll(tasks.ToArray(), 
         (results) => {
            Console.WriteLine("Calculating overall mean...");
            long sum = 0;
            int n = 0; 
            foreach (var t in results) {
               foreach (var r in t.Result) {
                  sum += r;
                  n++;
               }
            }
            return sum/(double) n;
         } , token);
         Console.WriteLine("The mean is {0}.", fTask.Result);
      }   
      catch (AggregateException ae) {
         foreach (Exception e in ae.InnerExceptions) {
            if (e is TaskCanceledException)
               Console.WriteLine("Unable to compute mean: {0}", 
                  ((TaskCanceledException) e).Message);
            else
               Console.WriteLine("Exception: " + e.GetType().Name);
         }
      }
      finally {
         source.Dispose();
      }
   }
}
// Repeated execution of the example produces output like the following:
//       Cancelling at task 5
//       Unable to compute mean: A task was canceled.
//       
//       Cancelling at task 10
//       Unable to compute mean: A task was canceled.
//       
//       Calculating overall mean...
//       The mean is 5.29545454545455.
//       
//       Cancelling at task 4
//       Unable to compute mean: A task was canceled.
//       
//       Cancelling at task 5
//       Unable to compute mean: A task was canceled.
//       
//       Cancelling at task 6
//       Unable to compute mean: A task was canceled.
//       
//       Calculating overall mean...
//       The mean is 4.97363636363636.
//       
//       Cancelling at task 4
//       Unable to compute mean: A task was canceled.
//       
//       Cancelling at task 5
//       Unable to compute mean: A task was canceled.
//       
//       Cancelling at task 4
//       Unable to compute mean: A task was canceled.
//       
//       Calculating overall mean...
//       The mean is 4.86545454545455.</pre>
<p>The post <a href="https://lycos7560.com/c/c%ec%9d%98-cancellationtoken-cancellationtokensource/39889/">C#의 CancellationToken, CancellationTokenSource</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/c/c%ec%9d%98-cancellationtoken-cancellationtokensource/39889/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
