How to Deploy Your Project with Docker
1. Goals
이 문서는 인터넷에 있는 대부분의 예제들이 Docker Hub에 있는 이미지를 다운받아 구동시키는 것으로 끝나는 것이 아쉬워 개인/회사의 프로젝트를 Dockerfile 로 Build하고 동작시키는 것을 예로 들기 위해 작성하였다.
향후에는 Docker-Compose, Kubernetes 등을 통해 동기화하는 것도 공부해서 올려보려고 한다.
2. Scripts
A. Build
#!/bin/bash
# @author : sunsson
# @date : 2020.01.31
DOMAIN=base
VER=2.0
echo "###docker build"
source ./checkip.sh
IMAGE_NAME=ㅁㅁㅁㅁㅁㅁㅁㅁ-$DOMAIN
echo docker image build --rm $ARGS -t $IMAGE_NAME ..
docker.exe image build --rm $ARGS -t $IMAGE_NAME:$VER ..
#echo
echo docker images [$IMAGE_NAME]
docker.exe images | egrep "REPOSITORY|$IMAGE_NAME"
- You can create
inline code snippets
with the shortcutcmd/ctrl + e
.
B. Run
#!/bin/bash
DOMAIN="base"
VER="2.0"
HOME="/home/ㅁㅁㅁㅁㅁㅁㅁㅁ"
DOCKER_OPTION="-p 22:22"
... 생략 ...
DOCKER_OPTION="$DOCKER_OPTION -v /d/Dockers/volume_storage:/storage"
... 생략 ...
IMAGE_NAME=ㅁㅁㅁㅁㅁㅁㅁㅁ-$DOMAIN
CONTAINER_NAME=gep-$DOMAIN
echo
echo docker run $DOCKER_OPTION --privileged -itd --hostname $CONTAINER_NAME --name $CONTAINER_NAME $IMAGE_NAME:$VER
docker.exe run $DOCKER_OPTION --privileged -itd --network ㅁㅁㅁㅁㅁㅁㅁㅁ-network --name $CONTAINER_NAME $IMAGE_NAME:$VER
echo
docker.exe ps | egrep "CONTAINER|$CONTAINER_NAME"
#echo
echo docker exec ... /root/init_scrip.sh // 해당 script 파일은 Build 시점에 /root로 COPY
docker.exe exec -it `docker.exe ps | grep $CONTAINER_NAME | awk '{print $1}'` /bin/sh /root/init_script.sh
#echo
#echo docker network connect ㅁㅁㅁㅁㅁㅁㅁㅁ-network $CONTAINER_NAME
#docker.exe network connect ㅁㅁㅁㅁㅁㅁㅁㅁ-network $CONTAINER_NAME
/root/init_gep20.sh
#!/bin/bash
source /root/checkip.sh
select_intn_extn gv_internal_ip gv_external_ip
select_internal_nic gv_internic
/root/rabbitmq_config.sh
/root/init_samba.sh
/root/init_gls.sh
/root/init_srv.sh
/root/rabbitmq_config.sh
생략
/root/init_samba.sh
생략
/root/init_gls.sh
생략
/root/init_srv.sh
생략
C. Stop
#!/bin/bash
# @author : sunsson
# @date : 2020.01.31
DOMAIN=base
VER=2.0
IMAGE_NAME=gigaeyes_pro-$DOMAIN
CONTAINER_ID=`docker.exe ps -a | grep $IMAGE_NAME | awk '{print $1}'`
CONTAINER_NAME=gep-$DOMAIN
if [ x$CONTAINER_ID = x ]; then
echo
echo Not exists container [$IMAGE_NAME]
exit
fi
echo
echo docker stop $CONTAINER_ID : [$IMAGE_NAME]
docker.exe stop $CONTAINER_ID
echo
docker.exe ps | egrep "CONTAINER|$CONTAINER_NAME"
~
D. Trash Remove
#!/bin/bash
echo
echo "Clear not running containers"
for container in `docker.exe ps -a | egrep -v "CONTAINER|Up|container_name-" | awk '{print $1}'`
do
docker.exe rm $container -f
done
echo
echo "Clear <none> images"
for image in `docker.exe images | grep "<none>" | awk '{print $3}'`
do
docker.exe rmi $image -f
done
echo
echo docker volume prune
docker.exe volume prune
echo
echo "docker images"
docker.exe images
echo
echo "docker ps -a"
docker.exe ps -a
2. Dockerfiles
A. Dockerfile (2020.01.21)
FROM centos/systemd
LABEL maintainer="aden.park@kt.com"
ENV container docker
ENV PKGBASE=./pkg
ENV OS_CONFIG=os_config
# ----------------------------------------------------------------------------------------------------------------------
# 1. Common
# ----------------------------------------------------------------------------------------------------------------------
# install EPEL(Extra Packages for Enterprise Linux) yum repository
#RUN yum -y update; yum clean all
RUN yum install epel-release -y
RUN yum -y install systemd; yum clean all; \
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
# install Packages
RUN yum install bc bind-utils cronie iftop lrzsz net-tools nmon sudo telnet wget vim chrony cpulimit libgfortran -y
RUN yum install -y openssh-server
RUN yum install -y openssh-clients
COPY ./$PKGBASE/$OS_CONFIG/sysctl.conf /etc/sysctl.conf
# 1.2 copy sudoers
COPY ./$PKGBASE/$OS_CONFIG/sudoers /etc/sudoers
# 1.3 copy limit
COPY ./$PKGBASE/$OS_CONFIG/limits.conf /etc/security/limits.conf
COPY ./$PKGBASE/$OS_CONFIG/20-nproc.conf /etc/security/limits.d/20-nproc.conf
# 1.4 copy firewall config
COPY ./$PKGBASE/$OS_CONFIG/firewall/public.xml /etc/firewalld/zones/public.xml
# 1.5 copy chrony config
COPY ./$PKGBASE/$OS_CONFIG/chrony.conf /etc/chrony.conf
RUN mkdir -p /usr/local/bin/bash
RUN sudo sed -i "s/#PermitRootLogin yes/PermitRootLogin no/g" /etc/ssh/sshd_config
...
생략
...
VOLUME ["/sys/fs/cgroup"]
CMD ["/usr/sbin/init"]
3. Troubleshooting
A. cgroups : cannot find cgroup mount destination: unknown
- 문제 상황
cgroups: cannot find cgroup mount destination: unknown
- 해결
Run-time 시점에 "--privileged -d" 옵션으로 실행
$docker run --privileged -d --name mycent7 centos:7 init
$docker exec -it mycent7 bash
참고 자료 : https://lsjsj92.tistory.com/424
참고 자료 : https://www.snoopybox.co.kr/1756 ==>
B. rabbitmq config shell
- 문제 상황
rabbitmq_config.sh : unable to connect to node rabbit@localhost: nodedown
Error: unable to connect to node rabbit@localhost: nodedown
$
Step 98/102 : RUN $HOME/download/$RABBITMQPKGDIR/rabbitmq_config.sh
---> Running in b5ccba76eedd
================= MQ SETUP : START ===================
Error: unable to connect to node rabbit@localhost: nodedown
DIAGNOSTICS
===========
attempted to contact: [rabbit@localhost]
rabbit@localhost:
* connected to epmd (port 4369) on localhost
* epmd reports: node 'rabbit' not running at all
other nodes on localhost: ['rabbitmq-cli-47']
* suggestion: start the node
current node details:
- node name: 'rabbitmq-cli-47@b5ccba76eedd'
- home dir: /var/lib/rabbitmq
- cookie hash: BBoZJ8rD74zEXYkijcpNnQ==
Error: unable to connect to node rabbit@localhost: nodedown
DIAGNOSTICS
===========
attempted to contact: [rabbit@localhost]
rabbit@localhost:
* connected to epmd (port 4369) on localhost
* epmd reports: node 'rabbit' not running at all
other nodes on localhost: ['rabbitmq-cli-79']
* suggestion: start the node
current node details:
- node name: 'rabbitmq-cli-79@b5ccba76eedd'
- home dir: /var/lib/rabbitmq
- cookie hash: BBoZJ8rD74zEXYkijcpNnQ==
Error: unable to connect to node rabbit@localhost: nodedown
DIAGNOSTICS
===========
attempted to contact: [rabbit@localhost]
rabbit@localhost:
* connected to epmd (port 4369) on localhost
* epmd reports: node 'rabbit' not running at all
other nodes on localhost: ['rabbitmq-cli-15']
* suggestion: start the node
...
- 해결
clearly something was cached somewhere.
참조 : https://github.com/docker-library/rabbitmq/issues/31
$docker system prune
C. yum update fail
- 문제 상황
Yum을 통해 아래와 같이 필요한 Package가 업데이트 되지 않을 때가 있다.
Loaded plugins: fastestmirror, langpacks
Determining fastest mirrors
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 알 수 없는 오류"
One of the configured repositories failed (Unknown),
and yum doesn't have enough cached data to continue. At this point the only
safe thing yum can do is fail. There are a few ways to work "fix" this:
1. Contact the upstream for the repository and get them to fix the problem.
2. Reconfigure the baseurl/etc. for the repository, to point to a working
upstream. This is most often useful if you are using a newer
distribution release than is supported by the repository (and the
packages for the previous distribution release still work).
3. Run the command with the repository temporarily disabled
yum --disablerepo=<repoid> ...
4. Disable the repository permanently, so yum won't use it by default. Yum
will then just ignore the repository until you permanently enable it
again or use --enablerepo for temporary usage:
yum-config-manager --disable <repoid>
or
subscription-manager repos --disable=<repoid>
5. Configure the failing repository to be skipped, if it is unavailable.
Note that yum will try to contact the repo. when it runs most commands,
so will have to try and fail each time (and thus. yum will be be much
slower). If it is a very temporary problem though, this is often a nice
compromise:
yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=true
Cannot find a valid baseurl for repo: base/7/x86_64
- 해결
Guest OS에서 돌아가는 Docker의 경우 Host OS의 DNS Server 정보를 그대로 사용하는 것으로 추정된다.(나중에 Docker Network는 추가로 공부 필요)Yum 을 통해 Package를 설치할 때 *.fedoraproject.org에서 다운을 받게 되는데 실패가 되고 있었다.(Docker에서 RUN cat /etc/yum.repos.d/epel.repo를 출력하고 DNS Lookup을 통해 확인)So, Docker의 Host OS(나의 경우는 Windows 10 Pro) 네트워크에 DNS에 "8.8.8.8"과 "8.8.4.4"를 추가해주었다.
D. /etc/ssh/sshd_config:
- 문제 상황
/etc/ssh/sshd_config: Permission denied
- 해결
sshd_config 파일 작성하여 /etc/sshd/로 이동
...
RUN yum install -y openssh-server
RUN ssh-keygen -A
ADD ./$PKGBASE/$OS_CONFIG/sshd_config /etc/ssh/sshd_config
...
# User ("root") Create
RUN echo 'root:패스워드' | chpasswd
...
- 접속 확인
E. RabbitMQ 구동 실패
- 문제 상황
RabbitMQ를 구동하지 못해 동작하지 않음
error unable to connect to node : rabbit@localhost
- 해결
Docker의 맨 마지막 Line에 아래와 같이 추가하여 Script를 Init 함
### RabbitMQ 실행을 위해 지우지 말 것!!! (init-script) 2020.02.10
CMD ["/usr/sbin/init"]