[42SEOUL] Server : 구현 방법

[42SEOUL] Server : 구현 방법

웹 서버 환경을 구축하는 과제

Dockerfile

FROM debian:buster : 새 이미지를 생성하기 위한 베이스 이미지로 데비안 버스터를 사용하겠다고 명시함.

새 이미지를 생성하기 위한 베이스 이미지로 데비안 버스터를 사용하겠다고 명시함. MAINTAINER [이메일] : 이 도커파일을 관리하는 사람의 정보를 표기함.

이 도커파일을 관리하는 사람의 정보를 표기함. ENV AUTOINDEX on : 환경변수 AUTOINDEX 를 만들고 on 으로 초기화 함.

환경변수 AUTOINDEX 를 만들고 on 으로 초기화 함. RUN apt-get update && apt-get install -y ... : apt-get 패키지 목록을 최신 버전으로 업데이트하며 필요한 패키지들을 설치함.

wordpress

RUN wget []() && tar -xvf latest.tar.gz && mv wordpress/ var/www/html && rm -r latest.tar.gz : wordpress 를 설치하기 위한 압축 파일을 다운로드하여 압축을 풀고, 압축 해제된 폴더를 적합한 경로로 이동시킨 후 압축 파일을 삭제함. ⇒ 여기서 latest 는 가장 최신의 파일을 뜻함.

wordpress 를 설치하기 위한 압축 파일을 다운로드하여 압축을 풀고, 압축 해제된 폴더를 적합한 경로로 이동시킨 후 압축 파일을 삭제함. ⇒ 여기서 latest 는 가장 최신의 파일을 뜻함. chown -R www-data:www-data /var/www/html/wordpress/ : 워드프레스 폴더의 소유주를 www-data:www-data (www-data 그룹의 www-data) 로 바꿔주어야 함. => 워드프레스 GUI 를 이용해 업로드를 할 수 있게 하기 위해서!

워드프레스 폴더의 소유주를 www-data:www-data (www-data 그룹의 www-data) 로 바꿔주어야 함. => 워드프레스 GUI 를 이용해 업로드를 할 수 있게 하기 위해서! chmod -R 755 var/www/html/wordpress/ : 미리 작성해둔 wp-config.php 파일을 wordpress 폴더에 복사하기 위해 먼저 권한을 변경해줌.

미리 작성해둔 wp-config.php 파일을 wordpress 폴더에 복사하기 위해 먼저 권한을 변경해줌. COPY srcs/wp-config.php var/www/html/wordpress/ : 미리 작성해둔 wp-config.php 파일을 wordpress 폴더로 복사함.

mysql

COPY srcs/mysqlset.sql ./ : 미리 작성해둔 mysqlset.sql 파일을 복사함.

미리 작성해둔 mysqlset.sql 파일을 복사함. RUN service mysql start && mysql -u root < mysqlset.sql : mysql 을 실행시킴. 동시에 mysqlset.sql 기반으로 root 라는 이름의 계정(사용자)을 생성함.

phpmyadmin

RUN wget []() && tar -xvf phpMyAdmin-5.0.2-all-languages.tar.gz && rm -r phpMyAdmin-5.0.2-all-languages.tar.gz && mv phpMyAdmin-* var/www/html/phpmyadmin/ : phpmyadmin 을 설치하기 위한 압축 파일을 다운로드하여 압축을 풀고, 압축 해제된 폴더를 적합한 경로로 이동시킨 후 압축 파일을 삭제함.

phpmyadmin 을 설치하기 위한 압축 파일을 다운로드하여 압축을 풀고, 압축 해제된 폴더를 적합한 경로로 이동시킨 후 압축 파일을 삭제함. COPY srcs/config.inc.php var/www/html/phpmyadmin/ : 미리 작성해둔 config.inc.php 파일을 phpmyadmin 폴더로 복사함.

ssl

RUN mkdir -p etc/nginx/ssl/ : ssl 인증서를 담을 폴더를 생성함.

ssl 인증서를 담을 폴더를 생성함. RUN openssl req -x509 -newkey rsa:2048 -nodes -keyout \\ etc/nginx/ssl/private.key -out etc/nginx/ssl/private.crt -days 365 -subj \\ "/C=KR/ST=SEOUL/L=Gaepo-dong/O=42SEOUL/OU=jiwonlee/CN=localhost" : openssl 로 2048 비트의 RSA 개인키(key)와 인증서(crt)를 발급받음. req : CSR 생성 (인증서 서명 요청 / 인증서 발급에 필요한 정보를 담고 있는 인증서 신청 형식 데이터) 을 위한 명령어 -x509 : 인증서 요청 생성 대신 자체 서명된 인증서 파일을 만들도록 지정 (공인 인증 요청이 아니도록) -newkey rsa:2048 : (공개키 암호화 알고리즘) 2048 비트의 RSA 개인키 생성 ⇒ 속도 문제로 2030년까지 4096 대신 2048을 사용하는 것을 권장함. -nodes : 비밀번호를 넣지 않고 돌아갈 수 있도록 개인키를 생성할 때 암호화 하지 않게 하는 명령어 -keyout : 개인키 파일의 출력 경로 및 이름을 지정 -out : CSR 파일의 출력 경로 및 이름을 지정 -days 365 : 생성하는 인증서가 1년 동안 유효함을 지정 -subj : CSR 의 정보 입력

openssl 로 2048 비트의 RSA 개인키(key)와 인증서(crt)를 발급받음.

nginx

COPY srcs/default etc/nginx/sites-available/ : 미리 작성한 nginx 파일을 설정 파일 경로에 복사함.

미리 작성한 nginx 파일을 설정 파일 경로에 복사함. COPY srcs/run.sh ./ : 컨테이너 생성 시 실행할 쉘 파일을 복사함.

컨테이너 생성 시 실행할 쉘 파일을 복사함. EXPOSE 80 443 : 컨테이너가 실행됐을 때 요청을 기다리고 있는 포트를 지정함.

컨테이너가 실행됐을 때 요청을 기다리고 있는 포트를 지정함. CMD bash run.sh : 생성된 컨테이너를 실행할 명령어를 지정함.

default

server { listen 80; listen [::]:80; return 301 https://$host$request_uri; }

server 블록 : 도메인 단위의 1차 라우팅으로, 하나의 웹 사이트를 선언하는 데 사용됨. server 블록이 여러 개이면 한 대의 머신 (호스트) 에 여러 웹 사이트를 서빙할 수 있음. 값은 host 주소 : 포트 형태를 띔.

도메인 단위의 1차 라우팅으로, 하나의 웹 사이트를 선언하는 데 사용됨. server 블록이 여러 개이면 한 대의 머신 (호스트) 에 여러 웹 사이트를 서빙할 수 있음. 값은 host 주소 : 포트 형태를 띔. listen : 해당 웹 사이트가 바라보는 포트를 의미함. listen 80; : http 포트로, IPv6 에 http 패킷을 리다이렉션 하기 위해 작성함. listen [::]:80; : 위와 동일함 IPv6 에 대응하기 위해 작성함.

해당 웹 사이트가 바라보는 포트를 의미함. return 301 https://$host$request_uri : 80번 포트로 요청이 들어올 경우, 동일한 주소지만 https 로 301 redirect 할 수 있도록 설정하기 위해 작성함. $host : 서버의 도메인 주소 $request_uri : 클라이언트가 요청한 url

80번 포트로 요청이 들어올 경우, 동일한 주소지만 https 로 301 redirect 할 수 있도록 설정하기 위해 작성함.

server { // localhost:443 으로 접속 또는 리다이렉션 + ssl 적용 listen 443 ssl; listen [::]:443 ssl; ssl on; ssl_certificate ssl/private.crt; ssl_certificate_key ssl/private.key; // 루트 폴더 지정 root /var/www/html; // index 로 지정할 파일 목록 index index.html index.htm index.php index.nginx-debian.html; location / { autoindex on; try_files $uri $uri/ =404; } location ~ \\.php$ { // php 스크립트를 FastCGI 서버로 보내기 위함. 보내기 위한 설정 파일을 include 하고 소켓 경로를 표시함. include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; } }

SSL chain 구성 : SSL 인증서 발급 기관이 브라우저에 기본 포함되지 않기 때문에 SSL 경로를 찾지 못할 수도 있기 때문에 직접 지정해주어야 함. ssl on : 1.15 버전부터는 옵션 지원이 종료됨. ssl_certificate : 인증서 파일 경로 ssl_certificate_key : private key 파일 경로

SSL 인증서 발급 기관이 브라우저에 기본 포함되지 않기 때문에 SSL 경로를 찾지 못할 수도 있기 때문에 직접 지정해주어야 함. location 블록 : 도메인 내부의 2차 라우팅임. autoindex on : var/www/html 에 있는 요소들을 리스트로 보여주는 명령어 index.nginx-debian.html 파일이 존재하거나 지정 파일 목록에 있으면 autoindex on 이어도 실행되지 않음. 왜냐하면 autoindex on 이어도 index 목록에 있는 파일이 var/www/html 에 존재하면 리스트 대신 본래 화면을 그대로 보여주기 때문임. 위와 같은 이유로 var/www/html 에 임시로 만든 테스트용 index.php 파일이 있다면 본래 화면이 그대로 보여짐. try_files $uri $uri/ =404 : nginx 는 정적 파일 호스팅을 기본적으로 지원하지 않기 때문에 root 폴더 내에 uri 에 따른 폴더가 있는 지 확인해야 함. 만약 없다면 404 에러를 보여줌. location ~ \\.php$ { ... } : 기본적으로 워드프레스가 php 파일을 읽고 쓸 경우 nginx 를 이용함. 그렇기 때문에 nginx 에서 php 를 사용할 수 있도록 설정해주어야 함. .php 로 끝나는 모든 요청들은 이 블럭에 의해 처리됨.

도메인 내부의 2차 라우팅임.

run.sh

#!/bin/bash : bash shell 로 실행되는 명령어라는 뜻임.

if [ "$AUTOINDEX" == "off" ]; then sed -i "21s/.*/ #autoindex on;/g" /etc/nginx/sites-available/default fi

만약 환경변수 AUTOINDEX 가 off 라면, default 파일의 21번째 줄을 #autoindex on 으로 변경하는 구문임. ⇒ autoindex 비활성화

service nginx start service php7.3-fpm start service mysql restart

nginx , php7.3-fpm 을 실행하고, mysql 을 재시작함.

bash : 웹 서버가 가동되도록 쉘을 실행시켜 서버가 꺼지지 않게 함. ⇒ nginx -g "daemon off;"

mysqlset.sql

// wordpress 데이터베이스를 생성함. CREATE DATABASE wordpress; // wordpress 사용자 생성 및 비밀번호 설정. 생성한 사용자에게 DB 사용 권한을 부여함. (GRANT ALL : 모든 권한) GRANT ALL PRIVILEGES ON wordpress.* TO admin@localhost IDENTIFIED BY '1234'; // MySQL 의 환경설정을 변경한 경우, MySQL 의 재시작 없이 변경한 설정을 적용시키고자 할 때 사용함. // GRANT 옵션을 통해 권한을 할당했을 경우에는 서버가 변경 사항을 인식하고 즉시 리로드하기 때문에 필요하지 않음. 오히려 불필요한 동작임. FLUSH PRIVILEGES;

config.inc.php

$cfg['blowfish_secret'] = 'Hv3LWhJTE3M58daY3uEur{G/7rGK6CMt';

쿠키 권한을 위한 blowfish 암호 설정이 필요함. blowfish 암호 생성 사이트에서 키를 생성/복사한 뒤 추가해주면 됨.

wp-config.php

/** The name of the database for WordPress */ define( 'DB_NAME', 'wordpress' ); /** MySQL database username */ define( 'DB_USER', 'admin' ); /** MySQL database password */ define( 'DB_PASSWORD', '1234' ); /** MySQL hostname */ define( 'DB_HOST', 'localhost' ); /** Database Charset to use in creating database tables. */ define( 'DB_CHARSET', 'utf8' ); /** The Database Collate type. Don't change this if in doubt. */ define( 'DB_COLLATE', '' );

wordpress 에서 사용될 데이터베이스 (mysql) 정보를 등록해주어야 함. mysqlset.sql 에 입력한 내용과 동일하게 입력해야 문제 없이 작동됨.

지식 채우기

Dockerfile

apt 와 apt-get 의 차이점 : apt 는 설치 시 진행바가 표시되는 대신 apt-get 에 비해 기능이 제한됨. apt-get 은 라이브러리 설치 시 에러가 적다는 장점이 있으며 설치 시 진행바가 표시되지 않음.

캐싱 문제를 피하기 위해 apt-get update 와 apt-get install -y 는 동시에 실행하는 것이 좋음. ⇒ 업데이트와 설치를 한 레이어 (동일한 RUN 실행단위) 로 설치해야 캐시 가능한 하나의 유닛이 되며, 오래된 패키지를 설치할 위험도 사라짐. 또한 도커 레이어 개수를 줄이는 것은 최적화 측면에서도 도움이 됨.

업그레이드가 제한된 컨테이너에서는 부모 이미지의 많은 필수 패키지를 업그레이드 할 수 없음. 그래서 apt-get upgrade 는 피하는 것이 좋음.

php-mbstring 은 멀티 바이트 문자열을 처리하는 함수를 제공하는 PHP의 확장 모듈임. 미설치 시 XML 관련 오류가 발생함.

wget : 웹 서버로부터 콘텐츠를 가져오는 컴퓨터 프로그램임.

phpmyadmin 을 설치하기 전에 mysql 을 먼저 시작 및 설정해주어야 함.

mysql 사용법 mysql -u [MYSQL 계정명] -p [접속할 데이터베이스명] : 일반적인 방법 -u : 접속할 MYSQL 계정명을 지정하기 위한 옵션 -p : 패스워드를 입력하기 위한 옵션

phpmyadmin 을 가장 최신 버전을 뜻하는 latest 로 설치할 시 문제가 발생함. 웬만하면 특정 버전을 지정해서 설치해주는 것이 좋음.

mkdir -p : 여기서 -p 옵션은 존재하지 않는 중간의 디렉토리를 자동으로 생성해주는 옵션임. 이 옵션 없이 생성하면 중간 경로에 들어있는 폴더에 접근하고자 할 시 찾을 수 없는 디렉토리라는 에러가 발생함. 즉, 안전하게 파일 경로를 생성해준다고 보면 됨.

EXPOSE 명령 자체가 작성된 포트를 실행하여 listening 상태로 올려주는 것은 아님. 실제 포트를 열기 위해서는 container run 에서 -p 옵션을 사용해야 함.

from http://leejiwonn.tistory.com/9 by ccl(A) rewrite - 2021-11-09 19:25:06