Docker로 NextCloud 설치하기 2

Automated Reverse Proxy 만들기

참고 : Automated Nginx Reverse Proxy for Docker · , jwilder/nginx-proxy - Docker Hub

  • 공부, 테스트 앞으로 혹시나 활용을 위해 리버스 프록시를 만들기로 함

Why Use A Reverse Proxy With Docker

Docker containers are assigned random IPs and ports which makes addressing them much more complicated from a client perspsective. By default, the IPs and ports are private to the host and cannot be accessed externally unless they are bound to the host.
Binding the container to the hosts port can prevent multiple containers from running on the same host. For example, only one container can bind to port 80 at a time. This also complicates rolling out new versions of the container without downtime since the old container must be stopped before the new one is started.

docker-gen

  • Docker API를 이용 컨테이너에 이벤트가 발생 시 nginx config 자동 생성 및  재기동​ 유틸리티
  • API
  • Inspect  : 컨테이너 정보 제공
  • real-time-event : 컨테이너 stop/start 이벤트 정보 제공

docker-proxy

사용방법

  • docker-proxy 실행
$ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
  • 프록시 대상 컨테이너 환경변수(-e) VIRTUAL_HOST를 지정하여 실행
$ docker run -e VIRTUAL_HOST=foo.bar.com  ...

기본 docker-proxy 생성 및 테스트

  • nginx-proxy와 whomai 컨테이너를 생성하는 docker-compse.yml 작성
version: '2'

services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

  whoami:
    image: jwilder/whoami
    environment:
      - VIRTUAL_HOST=whoami.local
  • 빌드/실행
bori@BorilikeGame:/media/usbhdd1/test/docker-proxy$ docker-compose up
Creating network "docker-proxy_default" with the default driver
Pulling nginx-proxy (jwilder/nginx-proxy:)...
latest: Pulling from jwilder/nginx-proxy
be8881be8156: Pull complete
b4babd36efe5: Pull complete
f4eba7658e18: Pull complete
fc141716ac64: Pull complete
87b964c68304: Pull complete
d07092114f4c: Pull complete
5092b1e0c1da: Pull complete
d90a3596290d: Pull complete
5ca9f664a671: Pull complete
eb9b93208683: Pull complete
Digest: sha256:e869d7aea7c5d4bae95c42267d22c913c46afd2dd8113ebe2a24423926ba1fff
Status: Downloaded newer image for jwilder/nginx-proxy:latest
Pulling whoami (jwilder/whoami:)...
latest: Pulling from jwilder/whoami
605ce1bd3f31: Pull complete
6f87ebbce1a4: Pull complete
42dfabe11397: Pull complete
Digest: sha256:c621c699e1becc851a27716df9773fa9a3f6bccb331e6702330057a688fd1d5a
Status: Downloaded newer image for jwilder/whoami:latest
Creating docker-proxy_whoami_1      ... done
Creating docker-proxy_nginx-proxy_1 ... done
Attaching to docker-proxy_whoami_1, docker-proxy_nginx-proxy_1
nginx-proxy_1  | WARNING: /etc/nginx/dhparam/dhparam.pem was not found. A pre-generated dhparam.pem will be used for now while a new one
nginx-proxy_1  | is being generated in the background.  Once the new dhparam.pem is in place, nginx will be reloaded.
whoami_1       | Listening on :8000
nginx-proxy_1  | forego     | starting dockergen.1 on port 5000
nginx-proxy_1  | forego     | starting nginx.1 on port 5100
nginx-proxy_1  | dockergen.1 | 2018/09/08 11:22:49 Generated '/etc/nginx/conf.d/default.conf' from 2 containers
nginx-proxy_1  | dockergen.1 | 2018/09/08 11:22:49 Running 'nginx -s reload'
nginx-proxy_1  | dockergen.1 | 2018/09/08 11:22:49 Watching docker events
nginx-proxy_1  | dockergen.1 | 2018/09/08 11:22:49 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification 'nginx -s reload'
^CGracefully stopping... (press Ctrl+C again to force)
Stopping docker-proxy_nginx-proxy_1 ... done
Stopping docker-proxy_whoami_1      ... done

bori@BorilikeGame:/media/usbhdd1/test/docker-proxy$ docker-compose up -d
Starting docker-proxy_nginx-proxy_1 ... done
Starting docker-proxy_whoami_1      ... done
bori@BorilikeGame:/media/usbhdd1/test/docker-proxy$ curl -H "Host: whoami.local" localhost
I'm 68eb4228389b
bori@BorilikeGame:/media/usbhdd1/test/docker-proxy$ docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                NAMES
480e5f9027af        jwilder/nginx-proxy   "/app/docker-entrypo…"   6 minutes ago       Up 5 minutes        0.0.0.0:80->80/tcp   docker-proxy_nginx-proxy_1
68eb4228389b        jwilder/whoami        "/app/http"              6 minutes ago       Up 5 minutes        8000/tcp             docker-proxy_whoami_1
  • 재기동 테스트
bori@BorilikeGame:/media/usbhdd1/test/docker-proxy$ docker-compose stop
Stopping docker-proxy_nginx-proxy_1 ... done
Stopping docker-proxy_whoami_1      ... done
bori@BorilikeGame:/media/usbhdd1/test/docker-proxy$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
bori@BorilikeGame:/media/usbhdd1/test/docker-proxy$ docker-compose start
Starting nginx-proxy ... done
Starting whoami      ... done
bori@BorilikeGame:/media/usbhdd1/test/docker-proxy$ curl -H "Host: whoami.local" localhost
I'm 68eb4228389b

※ curl -H 옵션 referer 헤더를 지정 - 참고: curl 설치 및 사용법 - HTTP GET/POST, REST API 연계등

※ HTTP referer  - 출처 : HTTP referer - Wikipedia

The HTTP referer (originally a misspelling of referrer[1]) is an HTTP header field that identifies the address of the webpage (i.e. the URI or IRI) that linked to the resource being requested. By checking the referrer, the new webpage can see where the request originated.
In the most common situation this means that when a user clicks a hyperlink in a web browser, the browser sends a request to the server holding the destination webpage. The request includes the referer field, which indicates the last page the user was on (the one where they clicked the link).

Multiple Networks

  • --net 옵션으로 docker 기본 네트워크(bridge) 이외의 네트워크에 접속 가능
By default, if you don't pass the --net flag when your nginx-proxy container is created, it will only be attached to the default bridge network. This means that it will not be able to connect to containers on networks other than bridge.
$ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro \
    --name my-nginx-proxy --net my-network jwilder/nginx-proxy
$ docker network connect my-other-network my-nginx-proxy
In this example, the my-nginx-proxy container will be connected to my-network and my-other-networkand will be able to proxy to other containers attached to those networks.

Internet vs. Local Network Access

  • NETWORK_ACCESS=internal과 /etc/nginx/network_internal.conf  파일 마운트로 인터넷 접근을 내부 네트워크로 한정 할 수 있음
On containers that should be restricted to the internal network, you should set the environment variable NETWORK_ACCESS=internal. By default, the internal network is defined as 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16. To change the list of networks considered internal, mount a file on the nginx-proxy at /etc/nginx/network_internal.conf with these contents, edited to suit your needs

컨테이너 분리

docker socket 바인드 된 컨테이너의 외부접속 차단를 위해 nginx-proxy와 docker-gen 분리

컨테이터 분리 테스트

  • docker-compose-separate-containers.yml
version: '2'
services:
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "80:80"
    volumes:
      - /etc/nginx/conf.d

  dockergen:
    image: jwilder/docker-gen
    command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    volumes_from:
      - nginx
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl #nginx.tmpl 파일

  whoami:
    image: jwilder/whoami
    environment:
      - VIRTUAL_HOST=whoami.local
  • 테스트 1 - 실패
bori@BorilikeGame:/media/usbhdd1/test/docker-gen$ docker-compose --file docker-compose-seperate-containers.yml  up
Starting docker-gen_whoami_1    ... done
Starting nginx2              ... done
Starting docker-gen_dockergen_1 ... done
Attaching to nginx2, docker-gen_whoami_1, docker-gen_dockergen_1
whoami_1     | Listening on :8000
dockergen_1  | 2018/09/10 15:45:23 Unable to parse template: read /etc/docker-gen/templates/nginx.tmpl: is a directory
docker-gen_dockergen_1 exited with code 1
^CGracefully stopping... (press Ctrl+C again to force)
Stopping nginx2                 ... done
Stopping docker-gen_whoami_1    ... done

$ docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx
$ docker run --volumes-from nginx \
    -v /var/run/docker.sock:/tmp/docker.sock:ro \
    -v $(pwd):/etc/docker-gen/templates \ # 현재 디렉토리와 templates 디렉토리 매핑
    -t jwilder/docker-gen -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
  • 테스트 2
  • docker-compose-separate-containers.yml 볼륨 매핑 수정
  • nginx.tmpl를 파일로 착각??
version: '2'
services:
  nginx2:
    image: nginx
    container_name: nginx2
    ports:
      - "80:80"
    volumes:
      - /etc/nginx/conf.d

  dockergen:
    image: jwilder/docker-gen
    command: -notify-sighup nginx2 -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    volumes_from:
      - nginx2
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./:/etc/docker-gen/templates #볼륨 매핑 수정 

  whoami:
    image: jwilder/whoami
    environment:
      - VIRTUAL_HOST=whoami.local

bori@BorilikeGame:/media/usbhdd1/test/docker-gen$ docker-compose --file docker-compose-seperate-containers.yml up
Starting docker-gen_whoami_1      ... done
Starting nginx2              ... done
Recreating docker-gen_dockergen_1 ... done
Attaching to nginx2, docker-gen_whoami_1, docker-gen_dockergen_1
whoami_1     | Listening on :8000
dockergen_1  | 2018/09/10 16:31:28 Generated '/etc/nginx/conf.d/default.conf' from 3 containers
dockergen_1  | 2018/09/10 16:31:28 Sending container 'nginx2' signal '1'
dockergen_1  | 2018/09/10 16:31:28 Watching docker events
dockergen_1  | 2018/09/10 16:31:28 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification ''
nginx2       | 172.20.0.1 - - [10/Sep/2018:16:32:12 +0000] "GET /favicon.ico HTTP/1.1" 503 615 "http://localhost/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36"
nginx2       | 172.20.0.1 - - [10/Sep/2018:16:32:25 +0000] "GET /favicon.ico HTTP/1.1" 503 615 "http://localhost/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36"
nginx2       | 172.20.0.1 - - [10/Sep/2018:16:34:56 +0000] "GET / HTTP/1.1" 200 17 "-" "curl/7.58.0"
whoami_1     | I'm b5b059d33aa4

version: '2'
services:
  nginx-proxy: # defines a service that listens for containers with the `VIRTUAL_HOST` env
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "8888:80" # maps port 8888 on your host to port 80 on the container's network
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro # Used for getting container information e.g start, stop events, id, name, environment variables...
  whoami:  # defines a service, or rather, a simple HTTP server that responds with the container's hostname in response to a GET request
    image: jwilder/whoami
    container_name: whoami
    environment:
      - VIRTUAL_HOST=whoami.local # nginx-proxy looks for this env to generate a nginx config for this host name. 

Bringing up this service with generates a nginx configuration with a virtual host roughly like this

# A gross oversimplification 
server {
    server_name whoami.local;
    listen 80;
    location / {
        proxy_pass 172.17.0.2:8000;
    }
}
server {
    server_name _; 
    listen 80;
    return 503
}

curl -H "Host: whoami.local" localhost:8888 Sends a GET request with the Host header whoami.local. Requests with this header with hit the first server block in the above nginx configuration.

Your browser likely sends the request with the Host header set to localhost. Requests with any other Host header will hit the "catch all" in second server block, returning a HTTP 503.

  • nginx2 container /etc/nginx/conf.d/default.conf 보기
  • dockergen_1  | 2018/09/10 16:31:28 Generated '/etc/nginx/conf.d/default.conf' from 3 containers
bori@BorilikeGame:/media/usbhdd1/test/docker-gen$ sudo docker cp nginx2:/etc/nginx/conf.d/default.conf ./
bori@BorilikeGame:/media/usbhdd1/test/docker-gen$ ls -al
합계 13
drwxrwxr-x 1 bori bori 4096  9월 11 01:55 .
drwxrwxr-x 1 bori bori  360  9월 11 01:21 ..
-rw-r--r-- 1 root root  852  9월 11 01:31 default.conf
-rw-rw-r-- 1 bori bori  517  9월 11 01:31 docker-compose-seperate-containers.yml
-rw-rw-r-- 1 bori bori 1794  9월 10 17:17 nginx.tmpl
  • /etc/nginx/conf.d/default.conf
server {
        listen 80 default_server;
        server_name _; # This is just an invalid value which will never trigger on a real hostname.
        error_log /proc/self/fd/2;
        access_log /proc/self/fd/1;
        return 503;
}
upstream whoami.local {
                        # docker-gen_whoami_1
                        server 172.20.0.3:8000;
}
server {
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
        server_name whoami.local;
        proxy_buffering off;
        error_log /proc/self/fd/2;
        access_log /proc/self/fd/1;
        location / {
                proxy_pass http://whoami.local;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                # HTTP 1.1 support
                proxy_http_version 1.1;
                proxy_set_header Connection "";
        }
}
브라우저에서 localhost로 접근시 메세지....
503 Service Temporarily Unavailable

nginx/1.15.3

K8s 가 다해주는 것을 꿍짝 꿍짝 하고 있는 건 아닐까? 2016년 .... 2년전 일인데

도메인 설정 오류

  • 도메인 등록 : igotoo.pw
  • DNS 설정을 잘못하여 오류가 나는걸 모르고 등록해서 전파되는데 시간 어느정도 걸리는지만 검색함
  • 도메인명을 서서 IP 주소와 매핑해주는 A레코드와 CNNA(도메인 별칭, 서브도메인 예 : cld.igotoo.pw)을 설정 해주어야 만 lookup이 됨
A (Address Mapping records)
레코드 A는 주어진 호스트에 대한 IP 주소 (IPv4)를 알려줍니다.
A 레코드는 도메인 이름을 해당하는 IP 주소로 변환하는 데 사용됩니다.
CNAME (Canonical Name)
CNAME 레코드는 도메인 이름의 별칭을 만드는 데 사용됩니다.
CNAME 레코드는 도메인을 외부 도메인으로 별칭을 지정하려는 경우 유용합니다.
경우에 따라 CNAME 레코드를 제거하고 A 레코드로 대체하면 성능 오버 헤드를 줄일 수도 있습니다.
출처: http://win100.tistory.com/360
  • 외장하드에  DB  데이터와 파일 데이터 저장하기

external

If set to true, specifies that this volume has been created outside of Compose. docker-compose up does not attempt to create it, and raises an error if it doesn’t exist.
external cannot be used in conjunction with other volume configuration keys (driver, driver_opts).
In the example below, instead of attempting to create a volume called [projectname]_data, Compose looks for an existing volume simply called data and mount it into the db service’s containers.
volumes on the Docker host
  • 따라서 아래 생성된 볼륨은 Docker 내부에 생성된 볼륨이다. 외장하드에 볼륨을 생성할 수 없고 마운트 할 수  밖에 없다.
  • external 옵션는 docker-compose up 생성 시키는 볼륨이 아닌 이미 생성된 볼륨이라는 말임

root@BorilikeGame:/media/usbhdd1/nextcloud/mariadb-cron-redis/apache# docker volume create --name=nextcloud --driver local --opt device=/media/usbhdd1/nextcloud/var/www/html --opt o=bind
nextcloud
root@BorilikeGame:/media/usbhdd1/nextcloud/mariadb-cron-redis/apache# docker volume inspect nextcloud
[
    {
        "CreatedAt": "2018-09-12T23:34:28+09:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/nextcloud/_data",
        "Name": "nextcloud",
        "Options": {
            "device": "/media/usbhdd1/nextcloud/var/www/html",
            "o": "bind"
        },
        "Scope": "local"
    }
]
root@BorilikeGame:/media/usbhdd1/nextcloud/mariadb-cron-redis/apache# 

igotoo

igotoo