안녕하세요.
백수 pesante 입니다.
최근 웹해킹을 공부하면서 APM을 구축해야 할 상황이 생겼는데 도커를 이용하면 굉장히 편리하게 구축할 수 있어서 그에 대한 포스팅을 하려 합니다. 도커에서는 어플리케이션 및 웹서버만 실행하고, 컨테이너 내부의 디렉토리와 외부 OS(Host OS)의 디렉토리를 연동합니다.
이렇게 설정하는 이유는 실질적인 웹 코딩을 외부 OS에서 진행할 수 있기 때문입니다. 즉, 코드를 변경하기 위해 도커에 접속할 필요가 없죠. 환경세팅 및 실행은 도커에 밀어넣고 웹 코딩은 host os에서 하는 겁니다. 그 순서는 다음과 같습니다.
- 도커 이미지 다운로드
- 도커 컨테이너 실행 with 몇 가지 옵션
APM이 설치된 도커 이미지는 사실 많습니다. 그러나 저는 웹해킹을 위한 최소한의 환경만 구축하길 원했고 그 결과 고른 이미지는 다음과 같습니다.
lamp 이미지가 지원하는 php 및 우분투 정보는 다음과 같습니다.

우선 도커 이미지를 다운로드 합니다. 원하는 php 및 우분투 버전에 따라 다르게 pull 하시면 됩니다.
# Launch a 16.04 (php5) based image
docker pull mattrayner/lamp:latest-1604
# Launch a 14.04 (php5) based image
docker pull mattrayner/lamp:latest-1404
# Launch a 16.04 (php7) based image
docker pull mattrayner/lamp:latest-1604-php7
# Launch a 14.04 (php7) based image
docker pull mattrayner/lamp:latest-1404-php7
그 다음 다운로드 받은 이미지를 컨테이너로 만들어 실행하면 됩니다. 그런데 이때 옵션을 주게 됩니다.
- -p “80:80” : 컨테이너의 80포트와 외부 OS의 80포트를 매치시킵니다.
- -v ${PWD}/app:/app : 외부 os의 “실행시점의 폴더”/app 디렉토리를 컨테이너 내부의 /app와 동기화 합니다. /app은 lamp 이미지에서 설정된 웹서버의 루트 디렉토리입니다.
실행하기에 앞서 편한 곳에다가 app 디렉토리를 만들어줍니다. 저는 /root/docker-apm/app에 만들었습니다. 그리고 app 디렉토리 내부에 index.php를 만들어 줍니다.
root@ubuntu:~/docker-apm# mkdir app
root@ubuntu:~/docker-apm# ls
app
root@ubuntu:~/docker-apm# echo "test" >> ./app/index.php
root@ubuntu:~/docker-apm# ls -l ./app/
total 4
-rw-r--r-- 1 pesante staff 10 Jan 13 15:23 index.php
후에 app가 존재하는 디렉토리(저는 /root/docker-apm)에서 컨테이너를 실행합니다. 다운로드 받은 이미지 버전에 맞게 다음 중에서 하나를 골라 실행해주시면 됩니다.
# Launch a 16.04 (php5) based image
docker run -p "80:80" -v ${PWD}/app:/app mattrayner/lamp:latest-1604
# Launch a 14.04 (php5) based image
docker run -p "80:80" -v ${PWD}/app:/app mattrayner/lamp:latest-1404
# Launch a 16.04 (php7) based image
docker run -p "80:80" -v ${PWD}/app:/app mattrayner/lamp:latest-1604-php7
# Launch a 14.04 (php7) based image
docker run -p "80:80" -v ${PWD}/app:/app mattrayner/lamp:latest-1404-php7
위의 명령어를 실행하면 컨테이너 안에 필요한 패키지들을 설치하고 자동으로 설정을 진행합니다. 이 때 작업이 완료되어도 실행종료가 되지 않으므로 마지막 줄의 “INFO success: apache2 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)” 가 실행되었다면 브라우저를 통해 접속해보도록 합니다
rm: cannot remove '/var/run/mysqld/mysqld.sock': No such file or directory
=> An empty or uninitialized MySQL volume is detected in /var/lib/mysql
=> Installing MySQL ...
=> Done!
=> Waiting for confirmation of MySQL service startup
=> Creating MySQL admin user with random password
ERROR 1133 (42000) at line 1: Can't find any matching row in the user table
=> Done!
========================================================================
You can now connect to this MySQL Server with 임시비밀번호
mysql -uadmin -p임시비밀번호 -h<host> -P<port>
Please remember to change the above password as soon as possible!
MySQL user 'root' has no password but only allows local connections
enjoy!
========================================================================
/usr/lib/python2.7/dist-packages/supervisor/options.py:297: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
'Supervisord is running as root and it is searching '
2019-01-13 06:11:00,295 CRIT Supervisor running as root (no user in config file)
2019-01-13 06:11:00,295 WARN Included extra file "/etc/supervisor/conf.d/supervisord-apache2.conf" during parsing
2019-01-13 06:11:00,295 WARN Included extra file "/etc/supervisor/conf.d/supervisord-mysqld.conf" during parsing
2019-01-13 06:11:00,306 INFO RPC interface 'supervisor' initialized
2019-01-13 06:11:00,306 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2019-01-13 06:11:00,307 INFO supervisord started with pid 1
2019-01-13 06:11:01,311 INFO spawned: 'mysqld' with pid 490
2019-01-13 06:11:01,313 INFO spawned: 'apache2' with pid 491
2019-01-13 06:11:02,542 INFO success: mysqld entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2019-01-13 06:11:02,542 INFO success: apache2 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
브라우저로 접속해서 (http://VMip주소) 다음과 같은 화면이 뜨면 성공한 것입니다.

http://VMip주소/phpmyadmin로 접속하면 phpmyadmin도 사용가능합니다. 이때 비밀번호는 위에 컨테이너를 run 했을 때 나오는 로그에서 볼 수 있습니다.
You can now connect to this MySQL Server with 임시비밀번호
mysql -uadmin -p임시비밀번호 -h<host> -P<port>
Please remember to change the above password as soon as possible!
MySQL user 'root' has no password but only allows local connections

그럼 이제 도커에 접속하지 않고 외부의 /docker-apm/app에서 웹 코드를 수정하는 것만으로 개발 및 테스팅이 가능합니다.