Host OS Timezone 설정

$ sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
$ cat /etc/localtime 


Docker Container Timezone 설정

아래의 명령어처럼 Docker 실행시 localtime 파일을 지정해주어야 한다.


$ sudo docker run -v /etc/localtime:/etc/localtime:ro -it busybox date


Docker 컨테이너 이미지를 생성하여 Private Docker registry에 올리는 방법을 설명합니다.

Dockerfile 작성

자세한 설명은 공식 홈페이지(https://docs.docker.com/engine/reference/builder/) 를 참고하시면 됩니다. 아래의 예시는 nginx 컨테이너를 그대로 사용하는 예시입니다. nginx컨테이너를 받아서 사용하지않고 만드는 방법도 가능합니다.

//원본 컨테이너 이름과 버전을 명시합니다.
FROM nginx:1.10
MAINTAINER name <test@email.com>

Build & Push

Dockerfile 을 기준으로 빌드를 해야합니다.

$ docker build -t Private저장소주소/Container 이름:버전 -f Dockerfile Path
# 예시
$ docker build -t docker.test.com/nginx:1.10 -f ./Dockerfile

 
# Docker Container 이미지를 커밋하고 푸쉬하기 위해 실행해야합니다.
$ docker run -d --name nginx1 docker.test.com/nginx:1.10
 
# Docker Container 이미지 Commit
$ docker commit -m "커밋 메세지" "실행시 옵션으로 주었던 --name" Private저장소주소/Container 이름:버전
# 예시
$ docker commit -m "add nginx:1.10" nginx1 docker.test.com/nginx:1.10

 
//Push
$ docker push docker.test.com/nginx:1.10


Go 인스턴스 실행

이 이미지를 사용하는 가장 직접적인 방법은 Go 컨테이너를 빌드 및 런타임 환경으로 사용하는 것입니다. Dockerfile에서 다음 내용을 따라 뭔가를 작성하면 프로젝트를 컴파일하고 실행할 수 있습니다.

FROM golang:1.6-onbuild

이 이미지에는 대부분의 애플리케이션을 다루는 여러 개의 ONBUILD 트리거가 포함되어 있습니다. 이 빌드는 ./go/src/app 경로에 복사되고, get -d -v 와 같은 명령어를 실행하며, go install -v를 실행합니다.

arguments없이 이미지를 실행할 때, 해당 이미지에 기본명령 인 CMD [ "app"] 명령도 포함되어 있습니다.

Docker 이미지를 작성하고 실행할 수 있습니다.

$ docker build -t my-golang-app . # 사용자의 커스터마이징된 Dockerfile 생성
$ docker run -it --rm --name my-running-app my-golang-app # 사용자가 만든 Dockerfile을 my-running-app이라는 컨테이너 이름으로 실행. 만약 컨테이너가 종료되면 바로 삭제

참고 : golang:onbuild의 기본 명령은 실제로 go-wrapper 실행이며 set -x가 포함되어 있으므로 응용 프로그램 시작시 binary name이 stderr에 인쇄됩니다. 만약 이 동작이 마음에 들지 않으면, CMD [ "app"] (또는 만약 Go custom import 경로가 사용중인 경우 CMD [ "myapp"])를 추가하면 빌드 된 바이너리를 직접 실행합니다.

Docker 컨테이너에서 Go 컴파일하기

컨테이너 내부에서 앱을 실행하는 것이 적절하지 않은 경우가 있습니다. Docker 인스턴스 내부에서 앱을 실행하지 않고 컴파일하기 위해서 다음과 같이 작성합니다.

$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp golang:1.6 go build -v


위에서 지정한 $PWD 경로의 디렉토리가 컨테이너의 볼륨으로 추가되고, -w 옵션으로 컨테이너 안의 프로세스가 실행될 디렉터리를 설정합니다. go 디렉토리(-w 옵션으로 준 디렉토리)에 프로젝트를 컴파일하고 myapp에 실행 파일을 출력하도록 명령하는 go build 명령을 실행합니다. 또는 Makefile이 있으면 컨테이너에서 make 명령을 실행할 수 있습니다.

$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp golang:1.6 bash -c make

Docker 컨테이너에서 Go 크로스컴파일하기

만약 사용자의 OS가 리눅스인데 windows/386으로 컴파일을 하고 싶은 경우 아래와 같이 실행합니다.

$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp -e GOOS=windows -e GOARCH=386 golang:1.6 go build -v


또는 한번에 여러 플랫폼에 맞게 컴파일할 수 있습니다.

$ docker run --rm -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp golang:1.6 bash
$ for GOOS in darwin linux; do
>   for GOARCH in 386 amd64; do
>     go build -v -o myapp-$GOOS-$GOARCH
>   done
> done


정의

  • Docker Container Image를 저장하기 위한 저장소이다.
  • 기본적으로 hub.docker.com 에서 이미지를 다운로드 할 수 있고, 비공개된 저장소를 사용하려면 비용을 지불해야 합니다.
  • Docker에서 개인저장소를 구축할 수 있는 시스템을 공개하였고, 저장소 시스템을 Docker Registry라고 부릅니다.
  • Docker Registry 역시 Docker로 제작 되었습니다.

설치

Docker 레지스트리에는 로그인 기능이 없습니다. 따라서 Nginx의 기본 인증(Basic Authentication) 기능을 사용해야 합니다. HTTP 프로토콜에서는 인증을 지원하지 않으므로 반드시 HTTPS 프로토콜을 사용해야 합니다.

SSL 인증서

HTTPS를 사용하기 위해서는 SSL 인증서가 필요한데, 인증서가 없다면 아래의 명령어로 사설 인증서를 만들어서 등록해야 합니다. 사설 인증서 생성시 인증서 서명 요청(Certificate signing request) 파일을 생성하는데 아래의 필요한 정보를 입력해야합니다.

  • Country Name: 국가 코드입니다. 대문자로 KO를 입력합니다.
  • State or Province Name: 주 또는 도입니다. 자신의 상황에 맞게 입력합니다.
  • Locality Name: 도시입니다. 자신의 상황에 맞게 입력합니다.
  • Organization Name: 회사 이름을 입력합니다.
  • Organizational Unit Name: 조직 이름을 입력합니다.
  • Common Name: Docker Registry 실행하는 서버의 도메인입니다. 정확하게 입력하지 않으면 인증서를 사용해도 로그인할 때 에러가 발생합니다. 사용할 도메인을 docker.example.com 입력합니다.
  • Email Address: 이메일 주소입니다.

Step1

$ openssl genrsa -out docker.example.com.key 2048

Step2

$ openssl req -new -key docker.example.com.key -out docker.example.com.csr

Step3

$ openssl x509 -req -days 365 -in docker.example.com.csr -signkey docker.example.com.key -out docker.example.com.crt 

Step4

사설 인증서 사용시 다른 시스템에서 Docker Registry에 접근하기 위해 아래처럼 생성한 인증서를 등록해야 합니다.

Ubuntu 인증서 등록

$ sudo cp docker.example.com.crt /usr/share/ca-certificates/
$ echo "docker.example.com.crt" | sudo tee -a /etc/ca-certificates.conf
$ sudo update-ca-certificates

CentOS 인증서 등록

$ sudo cp docker.example.com.crt /etc/pki/ca-trust/source/anchors/
$ sudo update-ca-trust enable
$ sudo update-ca-trust extract


Step5

$ sudo service docker restart 

사용자 계정 설정

사용자 계정을 설정하기 위해서 .htpasswd 파일을 생성해야 합니다.

Step1

Ubuntu 패키지 설치

$ sudo apt-get install apache2-utils 

CentOS 패키지 설치

$ sudo yum install httpd-tools


Step2

$ htpasswd -c .htpasswd <아이디 입력>
New password:<비밀번호 입력>
Re-type new password:<비밀번호 입력>
Adding password for user <아이디 입력> 

Nginx 설정

아래의 내용을 nginx.conf 이름의 파일을 만들어야 합니다.

worker_processes  4; 
events {
    worker_connections  1024;
}
 
http {
    server {
        listen       443;
        server_name  docker.example.com;
 
        ssl on;
        ssl_certificate /etc/docker.example.com.crt;
        ssl_certificate_key /etc/docker.example.com.key;
 
        proxy_set_header Host           $http_host;
        proxy_set_header X-Real-IP      $remote_addr;
        proxy_set_header Authorization  "";
 
        client_max_body_size 0;
 
        chunked_transfer_encoding on;
 
        location / {
            proxy_pass          http://docker-registry:5000;
            proxy_set_header    Host  $host;
            proxy_read_timeout  900;
 
            auth_basic            "Restricted";
            auth_basic_user_file  .htpasswd;
        }
    }
} 

Docker Image Pull

docker registry와 nginx 이미지를 다운로드 합니다.

$ sudo docker pull registry
$ sudo docker pull nginx

Docker Run

Docker를 실행합니다.

$ sudo docker run -d --name=docker-registry \
    -v /home/registry:/tmp/registry \
    registry
 
$ sudo docker run -d --name=nginx \
    -v ./nginx.conf:/etc/nginx/nginx.conf \
    -v ./.htpasswd:/etc/nginx/.htpasswd \
    -v ./docker.example.com.key:/etc/docker.example.com.key \
    -v ./docker.example.com.crt:/etc/docker.example.com.crt \
    --link=docker-registry:docker-registry \
    -p 443:443 \
    nginx

Docker Login

위의 설정된 정보로 로그인을 합니다.

$ sudo docker login https://docker.example.com
Username: <아이디 입력>
Password: <비밀번호>
Email:
WARNING: login credentials saved in /root/.docker/config.json
Login Succeeded 


앞서 설명한 uWSGI는 우분투에서 virtualenv를 사용해 하는 방법이였습니다. 지금부터는CoreOS의 docker에서 uWSGI를 사용하는 방법을 설명하겠습니다.

docker에서 uWSGI를 사용하는 방법은 한 가지가 아닌 여러 방법이 있어 그 중, 대표적인 것을 설명드리겠습니다.


docker-uwsgi-nginx 이미지를 설치하여 사용하는 방법


Core OS를 설치 한 후, 아래 명령어를 실행시켜 docker-uwsgi-nginx 이미지를 PULL 받습니다.

$ sudo docker pull dockerfiles/django-uwsgi-nginx


아래 명령어를 치면 다음과 같이 이미지가 받아진 것을 확인할 수 있습니다.

$ docker images
REPOSITORY                       TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
dockerfiles/django-uwsgi-nginx   latest              184bcb8fc8d3        2 years ago         924.5 MB


다음 아래의 명령어를 실행시켜 test-uwsgi라는 이름의 컨테이너를 생성합니다.

 $ docker run -i -t -d -p 80:80 --name test-uwsgi dockerfiles/django-uwsgi-nginx /bin/bash


도커의 실행 명령어 및 옵션들은 다음 페이지에서 설명하겠습니다. 위 명령어가 정상적으로 동작했으면 다음 명령어를 입력해 현재 동작 중인 컨테이너를 확인할 수 있습니다.

f1c0a6b7427373f31274e5880021f251ff1babf95cc063e4f82f8d975e8f7063
$ docker ps
CONTAINER ID        IMAGE                            COMMAND             CREATED             STATUS              PORTS                NAMES
f1c0a6b74273        dockerfiles/django-uwsgi-nginx   "/bin/bash"         2 minutes ago       Up 2 minutes        0.0.0.0:80->80/tcp   test-uwsgi


다음 명령어로 docker 내부에 들어간 다음, uWSGI가 있는 폴더 내부로 이동합니다.

$ docker exec -i -t test-uwsgi /bin/bash
---- 도커 컨테이너로 이동 --------------
# cd /home/docker/code
# ls
AUTHORS  Dockerfile  README.md  app  nginx-app.conf  supervisor-app.conf  uwsgi.ini  uwsgi_params


현재 설치된 패키지를 확인 하려면 Dockerfile을 열어보면 되지만 컨테이너에는 vi나 namo등 텍스트 편집기가 없어 읽지 못합니다. 그래서 아래 명령어를 실행시켜 vim을 해당 컨테이너에 받아 줍니다.

# apt-get install vim
# vi Dockerfile
 
from ubuntu:precise
maintainer Dockerfiles
run echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
run apt-get update
run apt-get install -y build-essential git
run apt-get install -y python python-dev python-setuptools
run apt-get install -y nginx supervisor
run easy_install pip
# install uwsgi now because it takes a little while
run pip install uwsgi
# install nginx
run apt-get install -y python-software-properties
run apt-get update
RUN add-apt-repository -y ppa:nginx/stable
run apt-get install -y sqlite3
# install our code
add . /home/docker/code/
# setup all the configfiles
run echo "daemon off;" >> /etc/nginx/nginx.conf
run rm /etc/nginx/sites-enabled/default
run ln -s /home/docker/code/nginx-app.conf /etc/nginx/sites-enabled/
run ln -s /home/docker/code/supervisor-app.conf /etc/supervisor/conf.d/
# run pip install
run pip install -r /home/docker/code/app/requirements.txt
# install django, normally you would remove this step because your project would already
# be installed in the code/app/ directory
run django-admin.py startproject website /home/docker/code/app/
expose 80
cmd ["supervisord", "-n"]

 다음과 같이 작성된 것들이 현재 컨테이너 내부에 세팅되어져 있습니다. 

현재 컨테이너에 설치된 패키지들은 다음과 같습니다.



python2.7.3
django1.6.1
nginx1.1.19


만약 필요한 것들이 있을 시, apt-get으로 패키지를 받을 순 있으나 권장하는 방법은 아닙니다.

이후 uWSGI를 하는 방법은 이전에 uWSGI 설명서에 나와 있으니 그대로 따라하면 됩니다.

Dockerfile을 생성해 사용하는 방법


첫 번쨰 방법인 docker-uwsgi-nginx 이미지를 받아서 내부에서 전부 처리하는 것과 같은 방법입니다. 첫 번째 방식은 이미지를 컨테이너로 생성한 후, 컨테이너 내부에서 사용자가 필요한 것들을 명령어로 직접 설치를 해야 한다는 번거로움이 있습니다. 

여기서 사용할 방법은 Dockerfile을 생성해 해당 파일 내에 사용자가 필요한 패키지 설치 명령어를 입력합니다. 다음 이 파일을 이미지 생성 시, 읽도록하여 사용자의 추가적인 설치 없이 사용할 수 있다는 장점이 있습니다.


도커 파일을 생성 후 내부 내용의 예시입니다.

$ sudo vi Dockerfile
 
from ubuntu:14.04
maintainer Dockerfiles


run echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
run apt-get update
run apt-get install -y build-essential git
run apt-get install -y python python-dev python-setuptools
run apt-get install -y nginx supervisor
run easy_install pip
# install uwsgi now because it takes a little while
run pip install uwsgi
# install nginx
run apt-get install -y python-software-properties
run apt-get update
RUN add-apt-repository -y ppa:nginx/stable
run apt-get install -y sqlite3
# install our code
add . /home/docker/code/
# setup all the configfiles
run echo "daemon off;" >> /etc/nginx/nginx.conf
run rm /etc/nginx/sites-enabled/default
run ln -s /home/docker/code/nginx-app.conf /etc/nginx/sites-enabled/
run ln -s /home/docker/code/supervisor-app.conf /etc/supervisor/conf.d/
# run pip install
run pip install -r /home/docker/code/app/requirements.txt
# install django, normally you would remove this step because your project would already
# be installed in the code/app/ directory
run django-admin.py startproject website /home/docker/code/app/
expose 80
cmd ["supervisord", "-n"]


순서대로 살펴보면

FROM ubuntu:14.04
MAINTAINER  Dockerfiles

FROM은 생성되는 이미지 내의 OS이고, MAINTAINER는 해당 파일을 생성 및 관리를 한 사람입니다.


run echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
run apt-get update
run apt-get install -y build-essential git
run apt-get install -y python python-dev python-setuptools
run apt-get install -y nginx supervisor
run easy_install pip
# install uwsgi now because it takes a little while
run pip install uwsgi
# install nginx
run apt-get install -y python-software-properties
run apt-get update
RUN add-apt-repository -y ppa:nginx/stable
run apt-get install -y sqlite3
# install our code
add . /home/docker/code/
# setup all the configfiles
run echo "daemon off;" >> /etc/nginx/nginx.conf
run rm /etc/nginx/sites-enabled/default
run ln -s /home/docker/code/nginx-app.conf /etc/nginx/sites-enabled/
run ln -s /home/docker/code/supervisor-app.conf /etc/supervisor/conf.d/
# run pip install
run pip install -r /home/docker/code/app/requirements.txt
# install django, normally you would remove this step because your project would already
# be installed in the code/app/ directory
run django-admin.py startproject website /home/docker/code/app/

다음은 설치에 필요한 패키지들을 설치합니다. RUN은 직접 쉘 명령어를 실행시키는 명령입니다.


# install django, normally you would remove this step because your project would already
# be installed in the code/app/ directory
run django-admin.py startproject website /home/docker/code/app/
expose 80
cmd ["supervisord", "-n"]

패키지 설치 후, website라는 django 프로젝트를 /home/docker/code/app/에 설치하여 줍니다.

expose는 컨테이너가 오플 할 포트를 지정하여 줍니다.

cmd는 컨테이너에서 실행될 명령어를 지정해 줍니다.


해당 파일을 생성한 후, 아래 명령어로 빌드하여 이미지를 생성합니다.

$ docker build -t test .

마지막 .은 빌드 대상의 디렉토리를 가리킵니다.

위 Dockerfile에서 설정한 run 명령 각각은 이미지로 생성됩니다. 그래서 docker images -a하면 이름없는 이미지들이 다수 생성된 것을 확인할 수 있습니다. (docker image를 하면 처음 설정한 이름만 목록 확인 가능)


생성한 이미지를 run 명령어로 실행 시킨 후, 첫 번째 방법과 동일하게 진행합니다.

+ Recent posts