본문 바로가기

Docker

[Web Server 구축] Docker를 사용해서 웹서버 구축하기 with 공유기 DDNS 기능

2024-1 오픈소스 과목 과제로 개인 홈페이지를 만드는 것을 진행하고 있다. 깃헙에서 제공하는 서버를 사용하면 편하지만 가산점(^^)이라는 존재가 있어서 자체적으로 구축하고 싶어졌다.

맥을 사용하는 입장에서 Apache가 내장되어 있기 때문에 바로 로컬에서 웹서버를 구축할 수 있겠지만, 뭔가 로컬에 구축하면 설정이 꼬이거나 여러 보안적 측면도 고려하게 되어서 도커를 사용해서 구축하기로 결심했다.

구축하는 과정은 꽤 간단하다.

1. 간단한 웹 서버 구축

1-1. 기본적인 Dockerfile

# Use Apache HTTP Server official image
FROM httpd:2.4

# Copy local web files into the container
COPY ./ /usr/local/apache2/htdocs/

# Expose port 80 on the container
EXPOSE 80

 

간단하게 이렇게 구성할 수 있다. COPY의 첫번째 인자로는 내 웹페이지의 코드가 들어갈 디렉토리를 적어주면 된다. 그렇다고 로컬 기준의 경로를 적게되면 Dockerfile은 인지하지 못한다. 현재 내 Dockerfile의 위치에 따라 source위치를 적어주어야 한다. 현재 나는 작업하고 있는 폴더(website) 디렉토리 안에 Dockerfile을 작성해놓았기 때문에 그냥 ./ 이라고 해주었다.

 

1-2. Dockerfile 빌드와 실행

docker build -t my-apache-server .
docker run -d -p 8080:80 --name my-running-app my-apache-server

그 후 위와 같이 빌드를 해주고 실제로 8080포트로 실행을 해준 다음, 'http://localhost:8080'으로 접속을 해보면

입력한 결과

이렇게 웹서버 구축이 완료되어 연결이 된 것을 확인할 수 있다.

하지만 지금 작성한 Dockerfile은 되게 간단하게 작성한 것으로 보면 포트 번호도 사실 80으로 http으로 들어간 것을 확인할 수 있다. 사실 보안을 고려하면 https로 포트를 여는 것이 맞다. 이를 위해서는 또 추가적인 설정을 해주어야 한다.

 


2. Https 설정과 SSL/TLS을 통한 암호화된 포트 열기

필요한 작업만 딱 보자면 SSL 인증서 파일, Apache의 SSL 구성, 그리고 SSL 모듈을 활성화이다. 단순 과제를 위한 개인 홈페이지이고 굳이 인증서를 구매해서 사용할 의향까지 없기 때문에 자체적으로 서명한 인증서를 사용하도록 하겠다.

물론 이는 외부 사용자가 사이트에 접근하려고 할 때, 보안 알람을 발생하고 일일이 추가해야되는 단점이 있고, 그로인해 사이트의 신뢰도가 떨어진다는 점은 고려하고 이러한 점이 싫은 분들은 CA로부터 인증서를 발급받는 것이 맞다. Let's Encrypt와 같은 무료 발급 사이트가 있으니까 이용해보면 좋을 듯 하다.

2-1. 인증서 생성

우선  openssl을 통해서 인증서를 생성해보도록 하겠다. 이를 통해 개인키(key.pem)와 자체 서명한 인증서(cert.pem)를 만든다.

openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365

현재 작업하고 있는 디렉토리에 이 명령어를 작성하면 server.key라는 이름의 내 개인키와 server.crt라는 자체 서명 인증서를 아웃풋으로 얻는다. 밑의 이미지처럼 질문에 대답을 대충하면 된다.

 이렇게 먼저 자체 인증서를 생성한 다음, https 적용을 위한 Dockerfile을 작성해야 한다.

 

2-2. Dockerfile 작성

# Use Apache HTTP Server official image
FROM httpd:2.4

# Copy the HTML files into the container
COPY ./index.html /usr/local/apache2/htdocs/

# Install OpenSSL (if not included)
RUN apt-get update && apt-get install -y openssl

# Enable SSL and required modules in Apache
RUN sed -i '/LoadModule ssl_module modules\/mod_ssl.so/s/^#//g' /usr/local/apache2/conf/httpd.conf \
 && sed -i '/Include conf\/extra\/httpd-ssl.conf/s/^#//g' /usr/local/apache2/conf/httpd.conf \
 && sed -i '/LoadModule socache_shmcb_module modules\/mod_socache_shmcb.so/s/^#//g' /usr/local/apache2/conf/httpd.conf

# Copy SSL certificate and key into the container
COPY server.key /usr/local/apache2/conf/
COPY server.crt /usr/local/apache2/conf/

# Update SSL Configuration to use copied certificates
RUN echo "SSLEngine on" >> /usr/local/apache2/conf/extra/httpd-ssl.conf \
 && echo "SSLCertificateFile /usr/local/apache2/conf/server.crt" >> /usr/local/apache2/conf/extra/httpd-ssl.conf \
 && echo "SSLCertificateKeyFile /usr/local/apache2/conf/server.key" >> /usr/local/apache2/conf/extra/httpd-ssl.conf

# Expose port 443 for SSL
EXPOSE 443

# Start Apache in the foreground
CMD ["httpd-foreground"]

 

그럼 현재 내 작업 디렉토리는 밑과 같이 나타나게 된다. 

VS code 창

그 후 이전 단계와 똑같이 빌드하고 실행을 해준다.

 

2-3. Dockerfile 빌드와 실행

docker build -t my-apache-server .
docker run -d -p 443:443 --name my-secure-app my-apache-server

 

결과창

index.html의 내용이 나타나면서 연결이 된 것을 확인할 수 있다. 다만 사용자 브라우저에서 '주의요함'이 뜨는데 공인된 인증서 발급기관이 아닌 '내'가 발급해서 그런것이다. 거슬린다면 사용하는 브라우저(나의 경우에는 크롬)에서 '고급' 설정에 들어가 '이 사이트에 대한 보안 예외 추가' 등의 옵션을 설정해주면 된다. 물론 도메인을 구매하여 CA 인증서를 발급받으면 해결이 되는 문제이다.

이제 이렇게 대략적으로 도커를 통해서 웹서버 구축을 완료하였고, 템플릿을 적용하거나 직접 웹 사이트를 꾸미려고 할 때는 작업하는 해당 디렉토리 내부에 그 파일들을 업로드하면 된다.

 

3. 외부 사용자가 접속할 수 있도록 하기

위에까지가 로컬호스트에서 웹 서버에 접속하는 방법이다. 웹 페이지를 나만 보려고 만든 것은 아니기 때문에 외부 사용자가 접속할 수 있도록 조정을 해야한다. 그러려면 포트포워딩을 해야한다. 여기서 포트포워딩이란 내부 네트워크로 연결을 담당하는 포트를 외부에서도 그 라우터를 통해 들어올수 있도록 조정해주는 것을 말한다.

나는 공유기를 통해서 인터넷에 접근하고 있기 때문에 공유기 설정을 이용하여 포트포워딩을 진행하겠다. 공유기 밑을 보면 아마 스티커가 붙어있을 것이다. 거기에 공유기 설정 브라우저의 주소(예:https://192.xxx.xxx.x/)와 와이파이 비밀번호와는 별개의 관리자 비밀번호가 존재할 것이다. 해당 웹 브라우저에 들어가 비밀번호와 함께 로그인을 하면 NAT설정이 보일 것이다. NAT 설정에서 포트포워딩을 해주어도 되지만 내가 사용하는 공유기는 DDNS 기능을 제공하기 때문에 이를 사용하기로 했다.

DDNS 기능이란 Dynamic DNS로 DNS를 구매하기 어려운 나같은 학생이나 개인이 활용하기 좋은 기능이다. DNS의 경우에는 고정 IP주소를 가지고 있어야 등록이 가능하지만, 개인이 가지고 있는 유동 IP의 경우는 그게 어렵다. 그 과정속에서 DDNS가 동적으로 유동 IP 주소에 대해서 DNS로 레코드를 업데이트 해주는 것이다.

어찌했든 DDNS 서비스를 제공하는 noip.com을 이용해서 무료로 등록을 하고 내 도메인을 획득했다. 그 후 공유기 설정 브라우저에서 DDNS 설정에 들어가서 내 도메인 주소만 입력해주면 끝난다.

다만 추가로 해주어야 할 일은 앞서 openssl로 서명했던 server.key와 server.crt를 다시 내 도메인 주소에 맞추어서 생성해야 한다.

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt -subj "/C=KR/ST=Yong-in/L=Yong-in/O=South Korea/OU=IT Department/CN=your_domain"

 

+ DDNS 서버를 사용할 것이라면 굳이 https 연결을 한다기보다는 1번에서 했던 80포트 여는 Dockerfile을 사용하여 "http://your_domain"으로 접속하면 편하다.