Create TOC
2020년 9월 11일
2020년 7월 20일
Docker/Caddy 를 이용한 reverse proxy 설정
Caddy를 이용한 reverse proxy 설정을 기록한다. 인증서는 따로 /etc/letsencrypt에 갱신하기 때문에 그 인증서를 그대로 사용하게 설정했다.
bitwarden
https://mydomain.net:1234 -> bitwarden
docker-compose.yml
version: "3"
services:
bitwarden:
container_name: bitwarden
image: bitwardenrs/server:raspberry
environment:
- WEBSOCKET_ENABLED=true
- ./bitwarden_data:/data
restart: unless-stopped
caddy-bitwarden:
container_name: caddy-bitwarden
image: caddy
ports:
- '1234:1234/tcp'
environment:
- ACME_AGREE=false
- DOMAIN=mydomain.net
- CADDY_PORT=1234
- REDIRECT_URL=bitwarden:80
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
restart: unless-stopped
Caddyfile
{$DOMAIN}:{$CADDY_PORT} {
tls /etc/letsencrypt/live/{$DOMAIN}/fullchain.pem /etc/letsencrypt/live/{$DOMAIN}/privkey.pem
header / {
Strict-Transport-Security "max-age=15768000;"
X-XSS-Protection "1; mode=block"
X-Frame-Options "DENY"
X-Robots-Tag "none"
}
# The negotiation endpoint is also proxied to Rocket
reverse_proxy /notifications/hub/negotiate bitwarden:80
# Notifications redirected to the websockets server
reverse_proxy /notifications/hub bitwarden:3012
# Proxy the Root directory to Rocket
reverse_proxy /* {$REDIRECT_URL}
}
nextcloud
https://mydomain.net:1234 -> php-fpm(nextcloud)
docker-compose.yml
version: '3.1'
services:
nextcloud:
image: nextcloud:fpm-alpine
container_name: nextcloud
environment:
- TZ=Asia/Seoul
- PUID=1001
- PGID=1001
- MYSQL_DATABASE=db이름
- MYSQL_USER=mysql사용자이름
- MYSQL_PASSWORD=mysql비밀번호
- MYSQL_HOST=mysql서버주소
- NEXTCLOUD_TRUSTED_DOMAINS=mydomain.net:1234
- NEXTCLOUD_ADMIN_USER=nextcloud관리자이름
- NEXTCLOUD_ADMIN_PASSWORD=nextcloud관리자비밀번호
volumes:
- ./nextcloud_html:/var/www/html
restart: unless-stopped
caddy-nextcloud:
container_name: caddy-nextcloud
image: caddy
ports:
- '1234:1234/tcp'
environment:
- ACME_AGREE=false
- DOMAIN=mydomain.net
- CADDY_PORT=1234
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./nextcloud_html:/var/www/html:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
restart: unless-stopped
Caddyfile
{$DOMAIN}:{$CADDY_PORT} {
tls /etc/letsencrypt/live/{$DOMAIN}/fullchain.pem /etc/letsencrypt/live/{$DOMAIN}/privkey.pem
header / {
Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;"
Referrer-Policy "no-referrer"
X-Content-Type-Options "nosniff"
X-Download-Options "noopen"
X-Frame-Options "SAMEORIGIN"
X-Permitted-Cross-Domain-Policies "none"
X-Robots-Tag "none"
X-XSS-Protection "1; mode=block"
}
root * /var/www/html
file_server
php_fastcgi nextcloud:9000
header /core/fonts {
Cache-Control "max-age=604800"
}
@phpFiles {
path_regexp phpfile ^/(remote|public|cron|core/ajax/update|status|ocs/v1|ocs/v2)\.php
}
rewrite @phpFiles {http.regexp.phpfile.0}
# Service discovery via well-known
redir /.well-known/carddav /remote.php/carddav 301
redir /.well-known/caldav /remote.php/caldav 301
@forbidden {
path /.htaccess
path /data/*
path /config/*
path /db_structure
path /.xml
path /README
path /3rdparty/*
path /lib/*
path /templates/*
path /occ
path /console.php
}
respond @forbidden 404
}
path 제거
{$DOMAIN}:{$CADDY_PORT}/foo/ -> 172.16.10.5:449/
Caddyfile
{$DOMAIN}:{$CADDY_PORT} {
tls /etc/letsencrypt/live/{$DOMAIN}/fullchain.pem /etc/letsencrypt/live/{$DOMAIN}/privkey.pem
header / {
# Enable HTTP Strict Transport Security (HSTS)
Strict-Transport-Security "max-age=15768000;"
X-Frame-Options "DENY"
X-Robots-Tag "none"
}
route /foo/* {
uri strip_prefix /foo
reverse_proxy 172.16.10.5:449
}
}
path 변경
{$DOMAIN}:{$CADDY_PORT}/foo/ -> 172.16.10.5:449/bar/
Caddyfile
{$DOMAIN}:{$CADDY_PORT} {
tls /etc/letsencrypt/live/{$DOMAIN}/fullchain.pem /etc/letsencrypt/live/{$DOMAIN}/privkey.pem
header / {
# Enable HTTP Strict Transport Security (HSTS)
Strict-Transport-Security "max-age=15768000;"
X-Frame-Options "DENY"
X-Robots-Tag "none"
}
route /foo/* {
uri replace /foo/ /bar/
reverse_proxy 172.16.10.5:449
}
}
2020년 1월 3일
Raspbian/docker + GreenTunnel
raspbian에서 GreenTunnel을 docker로 올리는 방법을 기술한다.
docker image 만들기
GreenTunnel 소스를 받는다
$ git clone https://github.com/SadeghHayeri/GreenTunnel GreenTunnel
GreenTunnel/Dockerfile 파일에서 FROM 부분을 아래와 같이 수정한다.
FROM node:lts-buster-slim
이미지를 빌드한다.
$ cd GreenTunnel
$ sudo docker build --tag green-tunnel ./
이미지가 생성되었는지 확인한다.
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
green-tunnel latest e0f67216c1d5 19 hours ago 158MB
node lts-buster-slim b490682c0125 5 days ago 134MB
docker-compose.yml
version: "3"
services:
green-tunnel:
container_name: green-tunnel
image: green-tunnel
ports:
- "8000:8000/tcp"
restart: unless-stopped
docker-compose 명령으로 container를 만든다.
$ sudo docker-compose up -d
테스트
GreenTunnel을 실행시킨 raspberry pi의 ip와 port 8000 으로Firefox 등의 웹 브라우저의 proxy 설정에서 https proxy를 설정한다.
GreenTunnel 로그는 아래 명령으로 확인할 수 있다.
$ sudo docker logs -f green-tunnel
proxy.pac
이제 원하는 사이트에 접속할 때만 GreenTunnel 을 사용하도록 자동 프록시 설정 파일(proxy.pac)을 만든다.
예제는 https://abc*.net, https://def.net, 접속에서만 GreenTunnel을 사용하도록 설정했다.
function FindProxyForURL(url, host) {
url = url.toLowerCase();
host = host.toLowerCase();
isHttp=(url.substring(0, 5) == "http:");
if (isHttp) {
return "DIRECT";
}
if (0
|| isPlainHostName(host)
|| shExpMatch(host, "*.local")
|| isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0")
|| isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0")
|| isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")
|| isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")
) {
return "DIRECT";
}
if (0
|| shExpMatch(url, "https://abc*.net/*")
|| shExpMatch(url, "https://def.net/*")
) {
return "PROXY GreenTunnel주소:8000";
}
return "DIRECT";
}
proxy.pac을 http 로 접속 가능한 위치에 올리고 원하는 브라우저나 시스템 설정에서 http://어딘가/proxy.pac 형식으로 자동 프록시를 등록하면 된다.
2019년 12월 26일
Raspbian/docker + mariadb
Raspbian에서 mariadb를 docker로 올리는 방법을 기술한다.
docker-compose.yml
/docker/mariadb/config에 설정을 저장하는 것으로 설정 파일을 구성한다. 이 경로는 원하는 곳으로 바꾸면 된다.
root의 초기 비밀 번호는 ROOT_ACCESS_PASSWORD 로 설정했다.
db 관리를 위해 adminer도 같이 설치한다. mariadb가 구동되는 ip를 x.x.x.x 라고 가정했다.
version: "3"
services:
mariadb:
container_name: mariadb
image: linuxserver/mariadb
ports:
- '3306:3306/tcp'
environment:
- TZ=Asia/Seoul
- PUID=1001
- PGID=1001
- MYSQL_ROOT_PASSWORD=ROOT_ACCESS_PASSWORD
volumes:
- '//docker/mariadb/config/:/config/'
restart: unless-stopped
adminer:
container_name: adminer
image: adminer
ports:
- '8080:8080/tcp'
environment:
- TZ=Asia/Seoul
- ADMINER_DEFAULT_SERVER=x.x.x.x
- ADMINER_PLUGINS=tables-filter tinymce
restart: unless-stopped
실행
docker-compose 명령으로 실행한다.
$ sudo docker-compose up -d
실행이 잘 되면 바로 root의 비밀번호를 변경한다.
$ sudo docker exec -it mariadb mysqladmin -u root -p password '새비밀번호'
Enter password:
이제 http://x.x.x.x:8080 으로 접속하면 웹으로 db를 관리할 수 있다.
2019년 12월 16일
Raspbian/사용하던 서비스를 docker로 이전
기존에 사용하던 서비스를 docker로 옮기는 과정을 기술한다.
docker로 옮길 서비스는 아래와 같다.
- certbot
- pihole + dnscrypt
- tvheadend
- nginx
- homebridge
docker 환경 구성
docker 설치
get-docker.sh 를 이용해 설치한다.
$ curl -fsSL get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
docker 그룹에 계정을 추가하면 sudo 없이 docker를 실행할 수 있다.
$ usermod -aG docker pi
$ sudo mkdir /docker
$ chown pi /docker
docker-compose 설치
$ sudo apt-get install docker-compose
certbot
설정 옮김
$ mkdir /docker/certbot
$ sudo cp -R /etc/letsencrypt /docker/certbot/config
docker-compose.yml
아래와 같은 /docker/certbot/docker-compose.yml 파일을 만든다.
version: "3"
services:
certbot:
container_name: certbot
image: tobi312/rpi-certbot
ports:
- "80:80/tcp"
- "443:443/tcp"
entrypoint: certbot renew
volumes:
- '/docker/certbot/config/letsencrypt:/etc/letsencrypt'
테스트
$ cd /docker/certbot
$ docker-compose up
문제 없다면 /docker/certbot/docker-compose.yml 파일에서 entrypoint 를 아래와 같이 변경한다.
entrypoint: certbot -q renew
cron
2일 간격으로 인증서 갱신을 위해 certbot을 실행하도록 /etc/cron.d/certbot 파일을 만든다.
0 0 */2 * * root test -x /usr/bin/docker-compose && perl -e 'sleep int(rand(43200))' && docker-compose -f /docker/certbot/docker-compose.yml up
pihole
dnscrypt-proxy-2 대신 cloudflared 를 사용하게 변경했다.
설정 옮김
$ mkdir -p /docker/pihole/
$ sudo cp -R /etc/dnsmasq.d /docker/pihole/config
$ sudo cp -R /etc/pihole /docker/pihole/config
설정 수정
/docker/pihole/config/dnsmasq.d/01-pihole.conf 파일에서 server 를 아래와 같이 수정한다.
server=10.0.0.2#54
/docker/pihole/config/pihole/setupVars.conf 파일에서 PIHOLE_DNS 를 아래와 같이 수정한다.
PIHOLE_DNS_1='10.0.0.2#54'PIHOLE_DNS_2=''
docker-compose.yml
아래와 같이 /docker/pihole/docker-compose.yml 파일을 만든다.
version: "3"
services:
cloudflared:
image: visibilityspots/cloudflared
environment:
- TZ=Asia/Seoul
networks:
pihole_net:
ipv4_address: 10.0.0.2
restart: unless-stopped
app:
image: pihole/pihole:latest
ports:
- '53:53/tcp'
- '53:53/udp'
- '8888:80/udp'
environment:
- TZ=Asia/Seoul
- DNS1=10.0.0.2#54
- DNS2=
- DNSSEC=true
- IPv6=false
- PUID=1000
- PGID=1000
volumes:
- '/docker/pihole/config/pihole/:/etc/pihole/'
- '/docker/pihole/config/dnsmasq.d/:/etc/dnsmasq.d/'
networks:
pihole_net:
ipv4_address: 10.0.0.3
dns:
- 127.0.0.1
- 1.1.1.1
restart: unless-stopped
networks:
pihole_net:
driver: bridge
ipam:
config:
- subnet: 10.0.0.0/29
테스트
아래와 같이 기존 서비스를 중지하고 docker로 pihole 을 실행한다.
$ sudo systemctl stop dnscrypt-proxy.service
$ sudo pihole disable
$ cd /docker/pihole
$ docker-compose up -d
nslookup 으로 dns query가 잘 되는지 확인한다. 문제가 있다면 docker-compose -f /docker/pihole/docker-compose.yml logs app 명령으로 로그를 확인해 본다.
문제가 없는 것이 확인되면 설치되어 있던 dnscrypt-proxy-2와 pihole는 삭제한다.
기타
pihole-FTL 사용법
pihole-FTL은 아래와 같이 container에서 명령을 실행해서 사용할 수 있다.
$ docker-compose -f /docker/pihole/docker-compose.yml exec app bash -c 'echo ">stats" | nc -w 1 127.0.0.1 4711'
lighttpd 중지
안쓰는 웹서버는 아래 명령으로 중지해놓는다.
$ docker-compose -f /docker/pihole/docker-compose.yml exec app service lighttpd stop
tvheadend
설정 옮김
$ mkdir /docker/tvheadend
$ mkdir /docker/tvheadend/rec
$ sudo -s
# cd /home/hts/.hts
# tar cvfj /docker/tvheadend/tvh.tar.bz2 tvheadend
# exit
$ cd /docker/tvheadend
$ sudo tar xvfj tvh.tar.bz2
$ sudo mv tvheadend config
$ sudo rm tvh.tar.bz2
docker-compose.yml
아래와 같이 /docker/tvheaded/docker-compose.yml 파일을 만든다.
version: "3"
services:
app:
image: linuxserver/tvheadend
ports:
- "9981:9981/tcp"
- "9982:9982/tcp"
environment:
- TZ=Asia/Seoul
- PUID=1000
- PGID=1000
devices:
- "/dev/dvb:/dev/dvb"
volumes:
- '/docker/tvheadend/config:/config'
- '/docker/tvheadend/rec:/recordings'
restart: unless-stopped
테스트
$ cd /docker/tvheadend
$ docker-compose up -d
문제
encoding 이슈
nginx
설정 옮김
기존 설치된 nginx 설정 구조와 docker image의 구조가 달라서 우선 docker image를 설치하고 설정을 수정한다.
docker-compose.yml
아래와 같이 /docker/nginx/docker-compose.yml 파일을 만든다.
version: "3"
services:
app:
image: linuxserver/nginx
network_mode: host
environment:
- TZ=Asia/Seoul
- PUID=1000
- PGID=1000
volumes:
- '/docker/certbot/config/letsencrypt:/etc/letsencrypt'
- '/docker/nginx/config:/config'
- '/media/www:/mediw/www'
restart: unless-stopped
설정 수정
우선 container를 실행한다.
$ cd /docker/nginx
$ docker-compose up -d
ssl
/etc/nginx/ssl 폴더가 있다면 /docker/nginx/config/nginx/ssl 로 복사
nginx
linuxserver/nginx 이미지를 그대로 사용하면 nginx에 많은 모듈이 동작하게 된다.
원하는 모듈만 동작하게 하기 위해 /docker/nginx/config/nginx/nginx.conf 파일에서 기존 /etc/nginx/modules/*.conf 대신 /config/nginx/modules/*.conf 를 사용하도록 수정한다.
# include /etc/nginx/modules/*.conf;
include /config/nginx/modules/*.conf;
/docker/nginx/config/nginx/modules 폴더를 만들고 원하는 모듈의 *.conf만 복사한다.
사용가능한 모듈의 conf는 아래 명령으로 확인할 수 있다.
$ docker-compose -f ~/docker/nginx/docker-compose.yml exec app ls /etc/nginx/modules
복사는 아래와 같이 한다.
$ docker-compose -f ~/docker/nginx/docker-compose.yml exec app cp /etc/nginx/modules/http_echo.conf /config/nginx/modules
site-confs
/docker/nginx/config/nginx/site-confs/default 파일 내용을 비우고 /etc/nginx/site-enabled 파일을 가져온다.
가져온 site 설정에서 아래 내용을 수정한다.
- /etc/nginx/ssl 부분을 /config/nginx/ssl 로 변경
- log 경로를 /config/nginx/log 로 변경
- auth_basic_user_file 을 사용하고 있었다면 파일 경로를 /config/nginx 아래로 변경하고 기존에 사용하던 auth_basic_user_file 을 /docker/nginx/config/nginx 의 정해둔 경로로 복사.
homebridge
설정 옮김
$ mkdir /docker/homebridge
$ cp -R ~/.homebridge /docker/homebridge/config
/docker/homebridge/config/startup.sh 파일을 만들고 설치할 package를 등록한다.
#!/bin/sh
if [ ! -f /homebridge/.install_done ]; then
npm i miio
npm i homebridge-websocket
npm i homebridge-mi-fan
npm i homebridge-mi-pm2_5
npm i homebridge-http-temperature-humidity
touch /homebridge/.install_done
fi;
docker-compose.yml
아래와 같이 /docker/nginx/docker-compose.yml 파일을 만든다.
version: "3"
services:
app:
image: oznu/homebridge:raspberry-pi
network_mode: host
environment:
- TZ=Asia/Seoul
- PUID=1000
- PGID=1000
- HOMEBRIDGE_INSECURE=1
- HOMEBRIDGE_CONFig_UI=1
- HOMEBRIDGE_CONFig_UI_PORT=18080
volumes:
- '/docker/homebridge/config:/homebridge'
restart: unless-stopped
테스트
기존에 실행하던 homebridge를 중지하고 homebridge container를 실행한다.
$ cd /docker/homebridge
$ docker-compose up -d
로그를 확인해보고 web ui 접속도 해본다.
$ docker-compose -f /docker/homebridge/docker-compose.yml logs app
2016년 3월 2일
raspbian/docker/node.js
docker 설치
raspbian에 포함된 docker.io 패키지를 설치하고 이미지를 받아보려고 하면 "Could not reach any registry endpoint" 오류가 나면서 이미지를 받아올 수 없다. docker.io가 버전이 너무 낮아서 발생한 문제이다.
docker.io 패키지 대신 http://blog.hypriot.com/downloads/ 에서 deb 파일을 받아서 설치한다.
$ sudo apt-get purge docker.io
$ wget http://downloads.hypriot.com/docker-hypriot_1.10.1-1_armhf.deb
$ sudo dpkg -i docker-hypriot_1.10.1-1_armhf.deb
참고로 docker.io 패키지를 삭제할 때 sudo apt-get purge docker.io으로 완전 삭제하지 않으면 충돌이 발생할 수 있다.
계정 설정
docker 설치 후 docker를 사용할 계정을 docker그룹에 추가한다.
$ sudo adduser 사용하는id docker
그룹 추가 후 다시 로그인 한다.
node.js
$ docker pull hypriot/rpi-node