이 문서는 Docker Engine이 설치된 Linux 서버에서 Nginx 컨테이너를 실행하고, Windows 관리 PC의 웹 브라우저에서 접속을 확인하며, 컨테이너를 관리하는 과정을 설명합니다.
—
1. 이 문서에서 완성할 환경
이 문서를 마치면 다음 작업을 할 수 있습니다.
- VS Code의 Remote – SSH 확장으로
project-dev-server에 연결하고 Linux 서버의 원격 터미널과 프로젝트 폴더에서 작업할 수 있습니다. - Nginx 공식 이미지
nginx:alpine로nginx-web컨테이너를 백그라운드에서 실행하고unless-stopped재시작 정책을 적용할 수 있습니다. - Linux 서버 내부 IP 주소의 8080번 포트를 Nginx 컨테이너의 80번 포트에 게시하고, Linux 서버와 Windows 관리 PC에서 Nginx 응답을 확인할 수 있습니다.
docker ps,docker logs,docker stop,docker start,docker restart와docker rm으로 컨테이너 상태와 로그를 확인하고 실행 주기를 관리할 수 있습니다.- Docker의 포트 공개 범위와 UFW의 관계를 이해하고, 서버의 내부 IP 주소에만 포트를 게시하는 방법을 적용할 수 있습니다.
- Linux 서버의
nginx-web/html폴더를 Nginx 웹 문서 폴더에 읽기 전용 바인드 마운트하여 사용자 웹페이지를 표시할 수 있습니다. - 컨테이너 이름 중복, 포트 충돌과 접속 거부 문제가 발생했을 때 상태, 로그, 포트와 네트워크를 순서대로 점검할 수 있습니다.
2. 시작하기 전에
다음 항목이 준비되어 있어야 합니다.
project-dev-server에 Docker Engine이 설치되어 있고 Docker 서비스가 실행 중이어야 합니다.- 현재 Linux 사용자가
docker그룹에 포함되어 있거나 Docker 명령을sudo로 실행할 수 있어야 합니다. - Windows 관리 PC에서 VS Code와 Remote – SSH 확장을 사용해
project-dev-server에 접속할 수 있어야 합니다. - Windows 관리 PC와 Linux 서버가 같은 네트워크에 연결되어 있고, Windows 관리 PC에서 사용할 서버의 내부 IP 주소를 알고 있어야 합니다.
- Linux 서버의 내부 IP 주소가 실제 네트워크 인터페이스에 설정되어 있어야 합니다. 이 문서에서는 예시 주소로
192.168.1.231을 사용합니다. - Linux 서버가 Docker Hub에서
nginx:alpine이미지를 내려받을 수 있도록 인터넷에 연결되어 있어야 합니다. - 호스트의 8080번 포트를 다른 프로그램이나 컨테이너가 사용하고 있지 않아야 합니다.
- Linux 서버에서 접속 확인에 사용할
curl명령을 실행할 수 있어야 합니다. - Linux 사용자에게 프로젝트 폴더를 만들고 HTML 파일을 저장할 수 있는 권한이 있어야 합니다.
- 실제 암호, 개인 키와 인증정보를 명령, 문서 또는 화면 캡처에 기록하지 않아야 합니다.
Docker Engine 설치와 사용자 권한 설정은 Docker Engine 설치에서, VS Code의 Remote – SSH 연결은 VS Code 환경에서 확인할 수 있습니다.
3. VS Code에서 project-dev-server 접속
3.1 Remote – SSH 연결
Command Palette 또는 Remote Explorer에서 원격 서버에 연결할 수 있습니다.
여기서는 VS Code 환경에서 설명한 Remote Explorer를 사용합니다.
왼쪽 Activity Bar에서 Remote Explorer를 선택한 뒤 SSH 호스트 목록에서 project-dev-server를 찾습니다.
등록된 호스트 목록에서 project-dev-server를 선택합니다.

연결되면 VS Code 왼쪽 아래의 원격 연결 표시와 새로 열린 창을 확인합니다. 이때부터 VS Code의 터미널과 파일 탐색기는 Windows가 아니라 Linux 서버를 대상으로 동작합니다.

왼쪽 Activity Bar에서 Explorer를 선택한 뒤 Open Folder를 엽니다. /home/apple2ne1/ 폴더를 확인하고 OK 버튼을 선택합니다.

3.2 터미널에서 자신의 위치 다시 확인
VS Code에서 새 터미널을 열고 다음 명령을 실행합니다.
whoami
hostname
pwd
예상 확인 항목은 다음과 같습니다.
whoami: 서버 작업에 사용할 Linux 사용자hostname:project-dev-server또는 실제로 설정한 호스트 이름pwd: 현재 Linux 작업 경로

4. 프로젝트 루트 준비
Docker를 알아보기 위한 준비로 다음과 같이 실습용 프로젝트 폴더를 만듭니다.
mkdir -p /home/apple2ne1/projects/docker-test
cd /home/apple2ne1/projects/docker-test
현재 위치를 다시 확인합니다.
pwd
ls -la
pwd 결과가 다음과 같은 프로젝트 루트여야 합니다.
/home/apple2ne1/projects/docker-test

4.1 VS Code 작업 폴더로 열기
Remote – SSH로 연결된 VS Code에서 다음 중 한 가지 방법을 사용합니다.
첫 번째 방법:
Remote Explorer의 SSH 목록에서 project-dev-server 오른쪽에 있는 Connect in Current Window 버튼을 선택합니다.

Explorer를 선택한 후 Open Folder를 선택합니다.
Open Folder에서 docker-test 폴더를 찾아 OK 버튼을 선택합니다.

DOCKER-TEST [SSH: PROJECT-DEV-SERVER] 원격 작업 폴더가 표시됩니다.

다시 Remote Explorer를 선택하면 SSH 목록에 docker-test 작업 폴더가 표시됩니다. 이후 이 항목을 사용해 원격 작업 폴더를 바로 열 수 있습니다.

두 번째 방법:
File → Open Folder...에서 프로젝트 폴더 선택- 서버 터미널에서 프로젝트 루트로 이동한 뒤
code .실행
cd /home/apple2ne1/projects/docker-test
code .
새 VS Code 창이 열리면 Explorer의 최상위 폴더가 docker-test인지 확인합니다.
5. Nginx 컨테이너 실행
Nginx(엔진엑스)는 사용자에게 웹페이지를 전달하는 웹 서버 프로그램입니다.
이 문서의 기본 구성에서 사용자가 웹 브라우저로 다음 주소에 접속하면:
http://192.168.1.231:8080
Nginx가 요청을 받아 HTML, CSS, JavaScript, 이미지 등을 브라우저로 전달합니다.
웹 브라우저 → Nginx → 웹페이지 전달
Nginx의 주요 역할은 다음과 같습니다.
- 웹페이지 제공
- React 빌드 결과물 제공
- 사용자 요청을 백엔드로 전달
- HTTPS 인증서 처리
- 여러 서버로 요청 분산
- 외부에서 내부 서비스로 들어오는 입구 역할

예를 들어 /api 요청을 Node.js로 전달할 수 있습니다.
사용자 → Nginx
├─ / → React 화면
└─ /api → Node.js 백엔드
이 가운데 Nginx가 /api 요청을 백엔드로 전달하고 응답을 다시 사용자에게 돌려주는 기능을 리버스 프록시라고 합니다. 정적 파일 제공, TLS 종료와 부하 분산은 Nginx가 수행할 수 있는 서로 다른 역할입니다.
이제 Docker에서 Nginx를 실행합니다.
먼저 IP 주소를 생략한 포트 게시 동작을 확인하기 위해 다음 명령을 실행합니다. 이 명령은 학습을 위한 첫 실행이며, 8절에서 Linux 서버의 내부 IP 주소에만 포트를 게시하는 기본 실습 구성으로 변경합니다.
docker run -d \
--name nginx-web \
--restart unless-stopped \
-p 8080:80 \
nginx:alpine
sudo가 필요한 환경이라면 다음과 같이 실행합니다.
sudo docker run -d \
--name nginx-web \
--restart unless-stopped \
-p 8080:80 \
nginx:alpine
Nginx 공식 Docker 이미지는 컨테이너의 80번 포트를 호스트 포트에 연결하여 외부에서 접속하는 방법을 제공합니다.
명령 분석
docker run
로컬에 이미지가 없으면 저장소에서 이미지를 내려받은 뒤 새 컨테이너를 생성하고 실행합니다.
-d
컨테이너를 백그라운드에서 실행합니다.
--name nginx-web
컨테이너 이름을 nginx-web으로 지정합니다.
--restart unless-stopped
서버 재부팅이나 Docker 데몬 재시작 후 컨테이너를 다시 실행합니다. 단, 사용자가 직접 중지한 컨테이너는 사용자가 다시 시작하기 전까지 자동으로 실행되지 않습니다.
-p 8080:80
포트를 연결합니다.
Linux 서버 포트 : 컨테이너 포트
8080 : 80
Nginx는 격리된 컨테이너 환경에서 실행되며 컨테이너 내부의 80번 포트를 사용합니다. -p 8080:80은 Linux 서버의 8080번 포트로 들어온 요청을 Nginx 컨테이너의 80번 포트로 전달한다는 의미입니다.
즉 다음과 같은 흐름입니다.
Windows 관리 PC의 웹 브라우저 (192.168.1.231:8080) → 서버 8080번 포트 → Nginx 컨테이너 80번 포트

nginx:alpine
Nginx의 Alpine Linux 기반 이미지가 서버에 없으면 자동으로 내려받아 컨테이너를 실행합니다. 사용자가 Nginx 설치 파일을 직접 찾아 내려받고 설치하는 과정을 거칠 필요가 없습니다. 같은 이미지를 다른 서버에서 실행하면 동일한 구성의 컨테이너 환경을 만들 수 있다는 것이 Docker의 장점입니다.
Docker 컨테이너를 실행할 때 포트를 공개하면, Ubuntu의 UFW에서 해당 포트를 차단했더라도 외부 PC가 컨테이너에 접속할 수 있는 경우가 있다는 의미입니다.
예를 들어 다음과 같이 Nginx를 실행했다고 가정하겠습니다.
docker run -d --name nginx-web -p 8080:80 nginx:alpine
의미는 다음과 같습니다.
서버의 8080번 포트 → 컨테이너의 80번 포트
Docker는 이 포트 연결을 위해 Linux의 방화벽 규칙을 직접 추가합니다. 이 규칙은 일반적인 UFW 처리보다 먼저 적용될 수 있습니다. 따라서 UFW에서 다음처럼 표시되더라도,
sudo ufw status
8080 포트 허용 규칙 없음
다른 컴퓨터가 다음 주소로 접속할 가능성이 있습니다.
http://서버-IP:8080
포트를 게시할 호스트 IP 주소
docker run -p에서 호스트 IP 주소를 어떻게 지정하는지에 따라 Docker가 요청을 받을 네트워크 인터페이스가 달라집니다.
모든 네트워크 인터페이스에 게시:
-p 8080:80
이는 기본적으로 다음 설정과 같습니다.
-p 0.0.0.0:8080:80
Linux 서버의 특정 내부 IP 주소에 게시:
-p 192.168.1.231:8080:80
Linux 서버 자체에서만 접속할 수 있도록 루프백 주소에 게시:
-p 127.0.0.1:8080:80
이 설정들은 포트를 게시할 호스트 주소를 선택합니다. 192.168.1.0/24와 같은 출발지 네트워크의 접속만 허용하려면 별도의 방화벽 정책이 필요합니다. —
6. Nginx 컨테이너 상태 확인
이미지로 생성한 컨테이너의 실행 상태를 확인합니다. 컨테이너를 중지해도 삭제하기 전까지는 남아 있습니다.
docker ps
정상 예시:
CONTAINER ID IMAGE COMMAND STATUS PORTS
a123456789ab nginx:alpine "/docker-entrypoint…" Up 41 minute 0.0.0.0:8080->80/tcp

중요한 부분은 다음입니다.
Up 41 minute
컨테이너가 실행된 지 약 41분이 되었다는 의미입니다.
0.0.0.0:8080->80/tcp
Linux 서버의 모든 네트워크 인터페이스에서 8080번 포트를 받고, 이를 컨테이너의 80번 포트로 전달한다는 의미입니다.
예를 들어 서버에는 다음과 같은 인터페이스가 있을 수 있습니다.
lo → 서버 자기 자신용
eno1 → 유선 LAN
wlan0 → Wi-Fi
tailscale0 → Tailscale 연결
여기서 0.0.0.0은 서버의 특정 IP 하나만이 아니라, 서버가 가진 모든 IPv4 인터페이스에서 8080번 포트를 받겠다는 뜻입니다.
따라서 조건이 맞으면 다음 주소들로 접근할 수 있습니다.
http://127.0.0.1:8080
http://192.168.1.231:8080
http://Tailscale-IP:8080
다만 실제 접속 가능 여부는 방화벽, 라우터, 네트워크 설정에도 영향을 받습니다.
특정 인터페이스에서만 요청을 받으려면 호스트 IP 주소를 직접 지정할 수 있습니다. 다음은 실행 명령이 아니라 포트 게시 문법을 보여 주는 예시입니다.
docker run -d --name nginx-web -p 192.168.1.231:8080:80 nginx:alpine
이 경우에는 192.168.1.231 인터페이스를 통해 들어오는 요청만 받습니다. 이미 다른 컨테이너가 8080번 포트를 사용하고 있다면 이 명령을 그대로 실행할 수 없습니다.
컨테이너가 docker ps의 실행 중인 컨테이너 목록에 나타나지 않으면 중지되었을 수 있습니다. 중지된 컨테이너를 포함한 전체 목록은 다음 명령으로 확인합니다.
docker ps -a

—
7. Linux 서버 내부에서 Nginx 접속 확인
먼저 서버 자체에서 Nginx가 정상적으로 응답하는지 확인합니다.
curl http://localhost:8080
정상이라면 HTML 내용이 출력됩니다.
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

간단하게 HTTP 상태만 확인하려면 다음 명령을 사용할 수 있습니다.
curl -I http://localhost:8080
정상 예시:
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html

200 OK는 Nginx가 정상적으로 웹페이지를 반환하고 있다는 의미입니다.
—
8. 포트 공개 범위와 방화벽 확인
Ubuntu에서는 일반적으로 UFW를 사용합니다. UFW는 Ubuntu에서 사용하는 간단한 방화벽 관리 도구이며 기본적으로 비활성 상태일 수 있습니다.
현재 상태를 확인합니다.
sudo ufw status
UFW가 비활성 상태인 경우
Status: inactive
UFW 자체에서 서버의 8080번 포트를 차단하고 있지는 않습니다.
UFW가 활성 상태인 경우
Status: active
Docker는 게시된 컨테이너 포트에 자체 방화벽 규칙을 추가합니다. IP 주소를 생략한 -p 8080:80은 기본적으로 모든 호스트 인터페이스에 포트를 게시하며, UFW에서 해당 포트를 차단했더라도 외부에서 접근할 수 있습니다.
따라서 Docker 게시 포트의 접근 범위를 UFW 규칙만으로 제한해서는 안 됩니다. 이 문서에서는 모든 인터페이스에 게시하지 않도록 다음과 같이 Linux 서버의 내부 IP 주소에 포트를 바인딩합니다.
먼저 예시에 사용할 내부 IP 주소가 Linux 서버에 실제로 설정되어 있는지 확인합니다.
ip -br addr
이 문서에서는 192.168.1.231을 예시로 사용합니다. 출력에서 확인한 실제 내부 IP 주소가 다르면 이후 명령과 접속 주소를 해당 값으로 바꿉니다.
단, 기존 nginx-web 컨테이너가 이미 8080번 포트를 사용 중이라면 먼저 해당 컨테이너를 중지하고 삭제한 뒤 다시 생성해야 합니다.
먼저 8080번 포트로 실행 중인 nginx-web 컨테이너를 중지하고 삭제합니다. 관련 관리 명령은 13절에서도 정리합니다.
docker rm -f nginx-web
Linux 서버의 192.168.1.231:8080으로 들어온 요청만 Nginx 컨테이너의 80번 포트로 전달하도록 다시 실행합니다.
docker run -d \
--name nginx-web \
--restart unless-stopped \
-p 192.168.1.231:8080:80 \
nginx:alpine

위 화면에서 호스트 IP 주소가 포함된 포트 게시 결과를 확인할 수 있습니다.
—
9. Windows 관리 PC의 웹 브라우저에서 접속
Windows 관리 PC에서 Chrome, Edge 또는 Firefox를 엽니다.
주소창에 다음 주소를 입력합니다.
http://192.168.1.231:8080
여기서:
http://
HTTP 방식으로 연결한다는 의미입니다.
192.168.1.231
Linux 서버의 IP 주소입니다.
:8080
Nginx 컨테이너를 공개한 Linux 서버의 포트입니다.
정상적으로 접속되면 다음 제목의 기본 화면이 나타납니다.
Welcome to nginx!

이 화면이 나타나면 전체 연결이 성공한 것입니다.
Windows 관리 PC의 웹 브라우저
→ Linux 서버 IP
→ 서버의 8080번 포트
→ Docker 포트 게시
→ Nginx 컨테이너 80번 포트
→ Nginx 기본 웹페이지
—
10. Windows 관리 PC에서 서버 주소로 localhost를 사용할 수 없는 이유
Windows 관리 PC의 웹 브라우저에서 다음 주소를 입력하면 안 됩니다.
http://localhost:8080
또는:
http://127.0.0.1:8080
Windows 관리 PC의 웹 브라우저에서 localhost는 Linux 서버가 아니라 현재 사용 중인 Windows 관리 PC 자신을 의미합니다.
따라서 Windows에서 Linux 서버의 Nginx에 접속하려면 반드시 Linux 서버의 IP를 사용해야 합니다.
http://192.168.1.231:8080
정리하면 다음과 같습니다.
| 주소를 입력하는 위치 | localhost가 가리키는 컴퓨터 |
|---|---|
| Linux 서버 터미널 | Linux 서버 |
| Windows 관리 PC의 웹 브라우저 | Windows 관리 PC |
| Nginx 컨테이너 내부 | Nginx 컨테이너 자신 |
—
11. 선택 사항: 8080 없이 서버 IP만으로 접속하기
웹 브라우저에서 다음과 같이 포트 번호 없이 접속하고 싶을 수 있습니다.
http://192.168.1.231
HTTP의 기본 포트는 80입니다.
80번 포트를 사용하려면 먼저 기존 컨테이너를 중지하고 삭제합니다.
docker stop nginx-web
docker rm nginx-web
중지와 삭제를 한 번에 처리하려면 다음 명령을 대신 사용할 수 있습니다.
docker rm -f nginx-web
그다음 Linux 서버 내부 IP 주소의 80번 포트를 컨테이너의 80번 포트에 게시합니다.
docker run -d \
--name nginx-web \
--restart unless-stopped \
-p 192.168.1.231:80:80 \
nginx:alpine

이제 Windows 관리 PC의 웹 브라우저에서 다음 주소로 접속합니다.
http://192.168.1.231

11.1 정적 Nginx 환경과 Vite 개발 환경의 포트
이 문서의 정적 Nginx 환경에서는 Nginx 컨테이너가 웹 문서 폴더의 정적 파일을 직접 제공합니다. 02-vibe-coding-login-admin-dashboard-ui-ko에서 다룰 Vite 개발 환경은 별도의 구조입니다. 웹 브라우저 요청은 먼저 외부 포트를 게시한 Nginx 컨테이너로 들어오고, Nginx는 Docker 네트워크에서 proxy_pass http://vite:5173과 같은 설정을 사용해 Vite 컨테이너의 개발 서버로 전달할 수 있습니다.
따라서 이 구조에서 5173은 웹 브라우저가 직접 연결하는 포트가 아니라 Nginx가 Docker 네트워크를 통해 접근하는 Vite 컨테이너의 내부 포트입니다. 현재 문서에서는 Vite 컨테이너나 리버스 프록시를 구성하지 않습니다.

| Docker 설정 | 웹 브라우저 접속 주소 |
|---|---|
-p 192.168.1.231:8080:80 |
http://192.168.1.231:8080 |
-p 192.168.1.231:80:80 |
http://192.168.1.231 |
처음 테스트할 때는 호스트의 8080번 포트를 사용하는 것이 편리합니다. 서버의 80번 포트를 다른 웹 서버가 이미 사용하고 있을 가능성을 줄일 수 있기 때문입니다.
11.2 기본 실습 구성으로 복구
12절부터 계속 진행하려면 nginx-web 컨테이너를 다시 생성해 기본 실습 구성으로 복구합니다.
docker rm -f nginx-web
docker run -d \
--name nginx-web \
--restart unless-stopped \
-p 192.168.1.231:8080:80 \
nginx:alpine
—
12. Nginx 로그 확인
현재 실행 중인 nginx-web 컨테이너의 웹 브라우저 접속 기록과 오류를 확인합니다.

docker logs nginx-web
실시간으로 로그를 보려면 다음 명령을 사용합니다.
docker logs -f nginx-web

이 상태에서 Windows 관리 PC의 웹 브라우저를 Ctrl+F5로 새로 고치면 다음과 비슷한 접속 기록이 나타납니다.
192.168.1.240 - - [23/Jul/2026:...] "GET / HTTP/1.1" 200
여기서:
192.168.1.240: 접속한 Windows 관리 PC의 IP 주소GET /: 기본 페이지 요청200: 정상 응답
실시간 로그 화면에서 빠져나오려면 다음을 누릅니다.
Ctrl + C
이 명령은 로그 보기만 종료하며 컨테이너는 계속 실행됩니다.
—
13. Nginx 컨테이너 관리 명령
실행 중인 컨테이너 확인
docker ps
모든 컨테이너 확인
docker ps -a
컨테이너 중지
실행 중인 nginx-web 컨테이너를 중지합니다. 중지된 컨테이너는 삭제하기 전까지 남아 있습니다.
docker stop nginx-web
컨테이너 다시 시작
중지된 nginx-web 컨테이너를 같은 구성으로 다시 시작합니다.
docker start nginx-web
컨테이너 재시작
실행 중인 nginx-web 컨테이너의 프로세스를 중지한 뒤 같은 구성으로 다시 시작합니다.
docker restart nginx-web
컨테이너 삭제
Docker 컨테이너를 삭제하는 기본 명령은 다음과 같습니다.
docker rm nginx-web
실행 중인 nginx-web 컨테이너는 먼저 중지한 뒤 삭제합니다.
docker stop nginx-web
docker rm nginx-web

중지와 삭제를 한 번에 강제로 처리하려면 다음 명령을 사용합니다.
docker rm -f nginx-web

docker ps 또는 docker ps -a에서 확인한 컨테이너 ID로도 삭제할 수 있습니다.
docker rm a1b2c3d4e5f6
호스트의 중지된 컨테이너를 모두 삭제하려면 다음 명령을 사용합니다.
docker container prune
다음 확인 메시지가 나타납니다.
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N]

삭제를 진행하려면 y를 입력합니다.

컨테이너 프로세스가 정상적으로 종료되지 않아 즉시 중지해야 할 때는 다음 명령을 사용합니다.
docker kill nginx-web
일반적으로는 프로그램이 안전하게 종료될 시간을 주는 docker stop을 사용하고, 정상적으로 멈추지 않을 때만 docker kill을 사용합니다.
따라서 나중에 같은 이미지로 컨테이너를 다시 만들 수 있습니다.
내려받은 이미지 확인
docker run은 로컬에 지정한 이미지가 없으면 저장소에서 이미지를 내려받고 그 이미지로 컨테이너를 생성합니다. 내려받은 이미지는 다음 명령으로 확인합니다.
docker images

Docker Compose로 만든 컨테이너는 compose.yaml 파일이 있는 폴더에서 다음 명령으로 해당 Compose 프로젝트를 정리할 수 있습니다. 현재 문서의 nginx-web 컨테이너는 docker run으로 생성했으므로 이 명령의 대상이 아닙니다.
docker compose down
명령의 차이는 다음과 같습니다.
| 명령 | 기능 |
|---|---|
docker rm nginx-web |
중지된 nginx-web 컨테이너 삭제 |
docker rm -f nginx-web |
실행 중인 nginx-web 컨테이너를 강제로 중지하고 삭제 |
docker container prune |
호스트의 중지된 모든 컨테이너 삭제 |
docker compose down |
현재 Compose 프로젝트의 컨테이너와 기본 네트워크 삭제 |
—
14. 사용자 웹페이지 표시하기
Nginx 기본 화면 대신 직접 만든 HTML 페이지를 표시할 수 있습니다.
14.1 프로젝트 폴더 생성
4절의 docker-test는 Docker 명령을 연습하기 위한 작업 폴더입니다. 사용자 웹페이지 파일은 역할을 구분하기 위해 별도의 nginx-web 프로젝트 폴더에서 관리합니다.
mkdir -p /home/apple2ne1/projects/nginx-web
프로젝트 폴더로 이동합니다.
cd /home/apple2ne1/projects/nginx-web
pwd
ls -la
pwd 결과는 다음과 같아야 합니다.
/home/apple2ne1/projects/nginx-web

웹 문서를 저장할 html 폴더를 만듭니다.
mkdir -p html

14.2 VS Code에서 폴더 열기
VS Code에서 File → Open Folder…를 선택하고 다음 폴더를 엽니다.
/home/apple2ne1/projects/nginx-web
OK 버튼을 선택한 뒤 Explorer의 최상위 작업 폴더가 nginx-web인지 확인합니다.
nginx-web 폴더 안에 html 폴더만 있으면 Explorer의 Compact Folders 기능에 따라 nginx-web/html이 한 줄로 표시될 수 있습니다.

14.3 HTML 파일 만들기
VS Code의 Explorer에서 nginx-web/html 왼쪽의 꺾쇠를 선택하여 아래쪽을 향하게 하고 html 폴더를 펼칩니다.

html 폴더를 마우스 오른쪽 버튼으로 선택한 뒤 New File을 선택합니다.

파일명 입력란이 나타나면 index.html을 입력합니다.

index.html
생성된 index.html 파일을 선택하면 오른쪽 편집기에 파일 내용이 표시됩니다. 편집기에 다음 내용을 복사해 작성하고 Ctrl+S로 저장합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Docker Nginx Server</title>
</head>
<body>
<h1>Docker Nginx 서버 연결 성공</h1>
<p>Windows 관리 PC의 VS Code에서 Linux 서버의 파일을 수정하고 있습니다.</p>
<p>This page is running inside an Nginx container.</p>
</body>
</html>

저장합니다.
Ctrl + S
—
15. HTML 폴더를 Nginx 컨테이너에 연결
기존 컨테이너가 있다면 삭제합니다.
docker rm -f nginx-web
현재 위치를 확인합니다.
pwd
결과 예시:
/home/apple2ne1/projects/nginx-web
다음 명령으로 Nginx 컨테이너를 다시 실행합니다.
docker run -d \
--name nginx-web \
--restart unless-stopped \
-p 192.168.1.231:8080:80 \
-v "$(pwd)/html:/usr/share/nginx/html:ro" \
nginx:alpine

핵심 부분은 다음입니다.
-v "$(pwd)/html:/usr/share/nginx/html:ro"
의미:
Linux 서버의 폴더
/home/apple2ne1/projects/nginx-web/html
↓ 연결
Nginx 컨테이너의 웹 문서 폴더
/usr/share/nginx/html

마지막의 :ro는 컨테이너에서 해당 폴더를 읽기 전용으로 사용한다는 의미입니다.
Windows 관리 PC의 웹 브라우저에서 다시 접속합니다.
http://192.168.1.231:8080
이제 Nginx 기본 화면 대신 다음 문장이 표시되어야 합니다.
Docker Nginx 서버 연결 성공

HTML 파일을 VS Code에서 수정하고 저장한 뒤 웹 브라우저에서 Ctrl+F5로 새로 고치면 변경 내용이 반영됩니다.
15.1 최종 환경 확인
실행 중인 컨테이너와 포트 게시 상태를 확인합니다.
docker ps --filter 'name=^/nginx-web$'
PORTS 항목에는 다음과 같이 Linux 서버의 내부 IP 주소와 호스트 포트가 표시되어야 합니다.
192.168.1.231:8080->80/tcp
Linux 서버에서 사용자 웹페이지의 응답을 확인합니다.
curl -I http://192.168.1.231:8080

사용자 HTML의 제목까지 확인하려면 다음 명령을 실행합니다.
curl -s http://192.168.1.231:8080 | grep -F 'Docker Nginx 서버 연결 성공'
재시작 정책과 바인드 마운트 구성을 확인합니다.
docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' nginx-web
docker inspect --format '{{range .Mounts}}{{.Source}} -> {{.Destination}} (RW={{.RW}}){{end}}' nginx-web
첫 번째 명령은 unless-stopped를 출력해야 합니다. 두 번째 명령은 호스트의 nginx-web/html 폴더가 /usr/share/nginx/html에 연결되어 있고 RW=false인 것을 보여야 합니다.

다음 항목이 모두 충족되면 이 문서의 기본 환경이 완성된 것입니다.
- 컨테이너 이름이
nginx-web입니다. - 이미지가
nginx:alpine입니다. - 재시작 정책이
unless-stopped입니다. - Linux 서버의
192.168.1.231:8080이 컨테이너의 80번 포트에 게시되어 있습니다. /home/apple2ne1/projects/nginx-web/html이/usr/share/nginx/html에 읽기 전용 바인드 마운트되어 있습니다.- Linux 서버와 Windows 관리 PC의 웹 브라우저에서 사용자 HTML 페이지가 표시됩니다.
—
16. 자주 발생하는 오류
Docker 데몬 소켓 권한 오류는 Docker Engine 설치에서 설명합니다.
오류 1: 컨테이너 이름이 이미 사용 중
예시:
Conflict. The container name "/nginx-web" is already in use
기존 컨테이너 확인:
docker ps -a
기존 컨테이너 삭제:
docker rm -f nginx-web
그다음 다시 실행합니다.
—
오류 2: 포트가 이미 사용 중
예시:
Bind for 0.0.0.0:8080 failed: port is already allocated
8080번 포트를 사용하는 프로그램을 확인합니다.
sudo ss -lntp | grep :8080
다른 포트를 사용하려면 다음처럼 실행합니다.
docker rm -f nginx-web
cd /home/apple2ne1/projects/nginx-web
docker run -d \
--name nginx-web \
--restart unless-stopped \
-p 192.168.1.231:8081:80 \
-v "$(pwd)/html:/usr/share/nginx/html:ro" \
nginx:alpine
웹 브라우저 주소도 바뀝니다.
http://192.168.1.231:8081
—
오류 3: 웹 브라우저에 Connection refused 표시
확인:
docker ps
curl -I http://192.168.1.231:8080
sudo ss -lntp | grep 8080
컨테이너가 중지되었다면:
docker start nginx-web
—
오류 4: Windows 관리 PC에서는 안 되지만 서버 내부에서는 접속됨
서버에서 다음 명령은 정상인데:
curl http://192.168.1.231:8080
Windows 관리 PC의 웹 브라우저에서는 접속되지 않는다면 다음 가능성이 큽니다.
- UFW 또는 다른 방화벽 문제
- 잘못된 서버 IP 사용
- Windows 관리 PC와 Linux 서버가 서로 다른 네트워크에 연결
- 공유기의 AP Isolation 또는 Client Isolation 기능
- 게스트 Wi-Fi 사용
- 컨테이너 포트를
127.0.0.1에만 연결한 경우
다음처럼 실행했다면 외부 컴퓨터에서 접속되지 않습니다.
-p 127.0.0.1:8080:80
같은 네트워크의 Windows 관리 PC에서 접속하려면 Linux 서버의 실제 내부 IP 주소를 지정합니다.
-p 192.168.1.231:8080:80
—
참고 자료 및 출처
- docker container run
- 컨테이너 실행, 포트 게시, 이미지 가져오기 정책과 바인드 마운트 동작을 확인했습니다.
- 확인 날짜: 2026-08-09
- Packet filtering and firewalls
- Docker 게시 포트와 UFW를 포함한 호스트 방화벽의 관계를 확인했습니다.
- 확인 날짜: 2026-08-09
- Start containers automatically
unless-stopped재시작 정책의 동작을 확인했습니다.- 확인 날짜: 2026-08-09
- nginx Official Image
- Nginx 공식 이미지의 Alpine 변형과 웹 문서 폴더 바인드 마운트 예시를 확인했습니다.
- 확인 날짜: 2026-08-09
—
다음 글
Docker Nginx Compose
다음 글에서 다룰 내용:
docker run으로 만든 기존nginx-web컨테이너를 정리하고 Compose 프로젝트 폴더와 파일을 확인합니다.nginx-compose.yaml에 Nginx 서비스, 이미지, 재시작 정책,8080:80포트 게시와 읽기 전용 바인드 마운트를 선언합니다.docker compose config로 YAML 구문과 Compose가 해석한 최종 구성을 검증합니다.docker compose up -d,ps와logs를 사용해 Nginx 서비스를 실행하고 상태와 로그를 확인합니다.stop,start와down명령으로 Compose 서비스와 프로젝트 리소스를 관리합니다.- Linux 서버의
curl과 Windows 관리 PC의 웹 브라우저를 사용해 사용자 웹페이지가 정상적으로 표시되는지 확인합니다. - 접속되지 않을 때 서버 IP, Compose 구성, 포트 게시, Nginx 로그, 방화벽과 Windows의 포트 연결을 순서대로 점검합니다.
관련 문서
- Docker Engine 설치
- Docker Nginx Compose

