====== Xenial Xerus 설치 기록 ======
미니서버를 2016년 5월 31일부로 14.04에서 16.04로 새로 설치하였다. 많이 변한 건 없는데, 해 놓은 게 많아서인지 설정할 것이 많았다. 특히 Nginx 변환 부분은 조금 힘들었음. 설치 기록을 남겨 본다.
===== Ubuntu 16.04 설치 =====
/dev/sdb1을 시스템, /dev/sda1을 주 저장소로 지정하였다. /dev/sda1을 이전과 마찬가지로 /media/storage(스토리지)에 마운트하여 사용하는 전략은 변함이 없다. 일부 읽기, 쓰기가 잦은 시스템의 디렉토리를 스토리지로 연결하는 전략을 쓴다. 예를 들면 /var/log, /tmp 은 심볼릭 링크 처리하고 실제로는 /media/storage/log, /media/storage/tmp가 역할을 대신한다.
우분투 설치는 매우 심플하게 한다. 스토리지를 기본으로 마운팅하게 하는 것 이외에는 그냥 있는 그대로의 설정을 사용하는 편이다. 사실 USB 스틱에서 부팅하는 방식이니 당연히 복잡하게 할 이유가 없다.
사용자 계정 패스워드를 입력하는 단계에서 패스워드를 평문으로 확인할 수 있도록 체크박스가 추가되었다는 점이 특이하다. 그 외에는 외견상 변한 점은 없다. 기본으로 삼바 서버와 OpenSSH 서버 패키지를 설치해 주고 설치를 마친다. 부팅 모두 문제 없다.
예전에는 기본 리포지터리를 다음이나 다른 곳으로 변경했었지만, 지금은 그것마저도 별 필요 없는 듯.
===== Database 설치 =====
데이터베이스는 간결하게 mysql-server를 사용하기로 했다.
apt-get install mysql-server
==== 데이터베이스 저장소 변경 ====
시스템이 USB 스틱 메모리에 위치한지라, 여기에 계속 읽기/쓰기가 반복되는 것이 조금 껄끄럽다 생각했다. MySQL 5.5 -> 5.7로 마이그레이션하는 것이라 귀찮지만 미리 SQL 파일로 미리 데이터베이스를 모두 덤프해 두었다.
예전에는 눈치를 못챘거나 없었던 디렉토리가 생겼다.
* /var/lib/mysql-files - 700 mysql:mysql
* /var/lib/mysql-keyring - 700 mysql:mysql
* /var/lib/mysql-upgrade - 755 root:root
이 세 디렉토리도 같이 옮기기로 결정.
==== AppArmor 설정 변경 ====
나는 /tmp, /var/tmp를 모두 스토리지의 tmp 디렉토리로 심볼릭 링크를 걸었기 때문에, tmp 디렉토리까지도 설정을 변경해야 한다. 그러므로 ''/etc/apparmor.d/abstractions/user-tmp'' 파일의 마지막 부분에 다음 항목을 추가한다.
# media/storage/tmp
owner /media/storage/tmp/** rwkl,
/media/storage/tmp/ rw,
다음으로 MySQL과 관련된 부분을 수정한다.
''/etc/apparmor.d/usr.sbin.mysqld''
# Allow data dir access
/media/storage/mysql/ r,
/media/storage/mysql/** rwk,
# Allow data files dir access
/media/storage/mysql-files/ r,
/media/storage/mysql-files/** rwk,
# Allow keyring dir access
/media/storage/mysql-keyring/ r,
/media/storage/mysql-keyring/** rwk,
# Allow log file access
/media/storage/log/mysql.err rw,
/media/storage/log/mysql.log rw,
/media/storage/log/mysql/ r,
/media/storage/log/mysql/** rw,
==== my.cnf 변경 ====
''/etc/mysql/mysql.conf.d/mysqld.cnf''
버퍼 사이즈, 캐시 사이즈는 적절히 조정해줬다. 기준이 없으니 적절히 더 주는 정도?
datadir = /media/storage/mysql
tmpdir = /media/storage/tmp
===== PHP 7.0 =====
PHP 7.0이 기본으로 되었다. 쓰지 않을 이유가 없다. Nginx를 쓰기로 결정한 이상 FPM 방식을 사용해야 한다.
''apt-get install php php-fpm php-gd php-mcrypt php-mbstring''
FPM에서 발생하는 에러를 덤프하려면 ''/etc/php/7.0/fpm/pool.d/www.conf'''
catch_workers_output = yes
php.ini에는 여러 사이트에서 입을 모아 설정을 변경하려는 부분이 있다.
''/etc/php/7.0/php.ini''
cgi.fix_pathinfo=0
그리고 적절하게 업로드 사이즈를 변경해준다.
upload_max_filesize = 64M
post_max_size = 64M
==== pool 조정 ====
특정 사이트의 PHP 실행 유저를 다르게 만들어 동작시킬 때 사용한다.
''/etc/php/7.0/fpm/pool.d'' 디렉토리의 www.conf 기본 파일을 적절히 편집해서 변경한다.
nginx설정에서 원하는 사이트의 fastcgi 소켓 경로를 변경해 준다.
opcache 문제도 있을 수 있는데, 이건 그냥 스킵.
[[https://www.digitalocean.com/community/tutorials/how-to-host-multiple-websites-securely-with-nginx-and-php-fpm-on-ubuntu-14-04|참고 사이트]]
===== NGINX =====
내 도메인이 주소가 아닌 직접 IP 접속은 같은 공유기 안의 주소가 아니면 오지 못하도록 막을 필요가 있다.
''/etc/nginx/sites-available/default''
# allow only localhost
allow 192.168.0.0/24;
allow 192.168.10.0/24;
deny all;
===== 웹 애플리케이션 세팅 =====
==== PhpMyAdmin ====
''apt-get install phpmyadmin''
''/media/storage/www-data/conf.d/phpmyadmin.conf''
location /phpmyadmin {
alias /usr/share/phpmyadmin;
index index.php index.html index.htm;
location ~ ^/phpmyadmin/(.+\.php)$ {
root /usr/share;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
이 파일을 default에서 삽입한다.
# Include PhpMyAdmin address
include /media/storage/www-data/conf.d/phpmyadmin.conf;
==== Dokuwiki ====
# Nginx Configuration
# 아래 설정은 https 적용 이후 http -> https 이동에 사용됨.
server {
listen 80;
server_name wiki.changwoo.pe.kr;
return 301 https://$server_name$request_uri;
}
server {
listen 80;
server_name wiki.changwoo.pe.kr;
client_max_body_size 32M;
client_body_buffer_size 256k;
root /media/storage/www-data/changwoo.pe.kr/wiki;
index doku.php;
# Remember to comment the below out when you're installing, and uncomment it when done.
location ~ /(data/|conf/|bin/|inc/|install.php) {
deny all;
}
# Uncomment this prevents images being displayed !
#location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
# expires 31536000s;
# add_header Pragma "public";
# add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
# log_not_found off;
#}
location / {
try_files $uri $uri/ @dokuwiki;
}
location @dokuwiki {
rewrite ^/_media/(.*) /lib/exe/fetch.php?media=$1 last;
rewrite ^/_detail/(.*) /lib/exe/detail.php?media=$1 last;
rewrite ^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2 last;
rewrite ^/(.*) /doku.php?id=$1&$args last;
}
location ~ \.php {
include snippets/fastcgi-php.conf;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
nginx라면 복구 이후 멋진 URL에서 .htaccess 방식을 선택해야 문서가 올바르게 보인다.
==== WordPress ====
이 녀석은 조금 복잡하다.
# Global restrictions configuration file.
# Designed to be included in any server {} block.
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~ /\. {
deny all;
}
# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
# WordPress single site rules.
# Designed to be included in any server {} block.
# This order might seem weird - this is attempted to match last if rules below fail.
# http://wiki.nginx.org/HttpCoreModule
location / {
try_files $uri $uri/ /index.php?$args;
}
# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
# Directives to send expires headers and turn off 404 error logging.
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off;
log_not_found off;
expires max;
}
# Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-wp-super-cache.conf;
#include global/wordpress-w3-total-cache.conf;
# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
# This is a robust solution for path info security issue and works with "cgi.fix_pathinfo = 1" in /etc/php.ini (default)
# include fastcgi_params;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# fastcgi_intercept_errors on;
# fastcgi_pass php;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
# 아래 설정은 https 적용 이후 http -> https 이동에 사용됨.
server {
listen 80;
server_name wiki.changwoo.pe.kr;
return 301 https://$server_name$request_uri;
}
server {
server_name blog.changwoo.pe.kr;
root /media/storage/www-data/changwoo.pe.kr/wordpress;
index index.php;
# wp-login.php, wp-admin 접근을 IP로 제한 (단, wp-ajax.php는 AJAX를 활용해야 하므로 허용)
location ~ ^/(wp-admin(?!/admin-ajax\.php)|wp-login.php) {
allow 192.168.0.0/24;
deny all;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
include /media/storage/www-data/conf.d/wordpress-restrictions.conf;
include /media/storage/www-data/conf.d/wordpress.conf;
}
==== Ampache ====
그동안 모바일 기기에서 제대로 재생이 되지 않는 문제가 있었다가, nginx 설정을 변경해 줌으로써 해결하였다. 아래는 성공한 설정 텍스트. [[https://github.com/ampache/ampache/wiki/Installation#nginx|이 쪽의 설정]]을 가져와 문제가 되는 부분을 적절히 수정한 것.
server {
# listen to
#listen [::]:used_port; #ssl; ipv6 optional with ssl enabled
listen 80; #ssl; ipv4 optional with ssl enabled
server_name stream.changwoo.pe.kr;
charset utf-8;
# Logging, error_log mode [notice] is necessary for rewrite_log on,
# (very usefull if rewrite rules do not work as expected)
error_log /var/log/ampache/error.log; #notice;
access_log /var/log/ampache/access.log;
# rewrite_log on;
# only optional for ssl encryption enabled: Path to certificate/key
# ssl_certificate /etc/ssl/certs/cert.crt;
# ssl_certificate_key /etc/ssl/private/key.key;
root /media/storage/www-data/changwoo.pe.kr/ampache;
index index.php;
# Somebody said this helps, in my setup it doesn't prevent temporary saving in files
proxy_max_temp_file_size 0;
# Rewrite rule for Subsonic backend
if ( !-d $request_filename ) {
rewrite ^/rest/(.*).view$ /rest/index.php?action=$1 last;
rewrite ^/rest/fake/(.+)$ /play/$1 last;
}
# Rewrite rule for Channels
if (!-d $request_filename){
rewrite ^/channel/([0-9]+)/(.*)$ /channel/index.php?channel=$1&target=$2 last;
}
# Beautiful URL Rewriting
# rewrite ^/play/ssid/(.*)/type/(\w+)/oid/([0-9]+)/uid/([0-9]+)/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4&name=$5 last;
# rewrite ^/play/ssid/(.*)/type/(\w+)/oid/([0-9]+)/uid/([0-9]+)/client/(.*)/noscrobble/([0-1])/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4&client=$5&noscrobble=$6&name=$7 last;
# rewrite ^/play/ssid/(.*)/type/(.*)/oid/([0-9]+)/uid/([0-9]+)/client/(.*)/noscrobble/([0-1])/player/(.*)/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4&client=$5&noscrobble=$6&player=$7&name=$8 last;
# rewrite ^/play/ssid/(.*)/type/(.*)/oid/([0-9]+)/uid/([0-9]+)/client/(.*)/noscrobble/([0-1])/transcode_to/(w+)/bitrate/([0-9]+)/player/(.*)/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4&client=$5&noscrobble=$6&transcode_to=$7&bitrate=$8&player=$9&name=$10 last;
# Subsonic Apps (not working!)
# rewrite ^/play/ssid/(.*)/type/(.*)/oid/([0-9]+)/uid/([0-9]+)/client/(.*)/noscrobble/([0-1])/content_length/(.*)/player/(.*)/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4&client=$5&noscrobble=$6&content_length=$7&player=$8&name=$9 redirect;
# rewrite ^/play/ssid/(.*)/type/(.*)/oid/([0-9]+)/uid/([0-9]+)/client/(.*)/noscrobble/([0-1])/bitrate/([0-9]+)/player/(.*)/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4&client=$5&noscrobble=$6&bitrate=$7&player=$8&name=$9 redirect;
# rewrite ^/play/ssid/(.*)/type/(.*)/oid/([0-9]+)/uid/([0-9]+)/client/(.*)/noscrobble/([0-1])/player/(.*)/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4&client=$5&noscrobble=$6&player=$7&name=$8 redirect;
# the following line was needed for me to get downloads of single songs to work
rewrite ^/play/ssid/(.*)/type/(.*)/oid/([0-9]+)/uid/([0-9]+)/action/(.*)/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4action=$5&name=$6 last;
location /play/ssid {
if (!-e $request_filename) {
# Subsonic Apps
rewrite ^/play/ssid/(.*)/type/(.*)/oid/([0-9]+)/uid/([0-9]+)/client/(.*)/noscrobble/([0-1])/content_length/(.*)/player/(.*)/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4&client=$5&noscrobble=$6&content_length=$7&player=$8&name=$9 last;
rewrite ^/play/ssid/(.*)/type/(.*)/oid/([0-9]+)/uid/([0-9]+)/client/(.*)/noscrobble/([0-1])/bitrate/([0-9]+)/player/(.*)/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4&client=$5&noscrobble=$6&bitrate=$7&player=$8&name=$9 last;
rewrite ^/play/ssid/(.*)/type/(.*)/oid/([0-9]+)/uid/([0-9]+)/client/(.*)/noscrobble/([0-1])/player/(.*)/name/(.*)$ /play/index.php?ssid=$1&type=$2&oid=$3&uid=$4&client=$5&noscrobble=$6&player=$7&name=$8 last;
break;
}
}
location /play {
if (!-e $request_filename) {
rewrite ^/play/art/([^/]+)/([^/]+)/([0-9]+)/thumb([0-9]*)\.([a-z]+)$ /image.php?object_type=$2&object_id=$3&auth=$1;
break;
}
rewrite ^/([^/]+)/([^/]+)(/.*)?$ /play/$3?$1=$2;
rewrite ^/(/[^/]+|[^/]+/|/?)$ /play/index.php last;
break;
}
location /rest {
limit_except GET POST {
deny all;
}
}
location ^~ /bin/ {
deny all;
return 403;
}
location ^~ /config/ {
deny all;
return 403;
}
location / {
limit_except GET POST HEAD{
deny all;
}
}
location ~ ^/.*.php {
try_files $uri = 404;
fastcgi_index index.php;
# sets the timeout for requests in [s] , 60s are normally enough
fastcgi_read_timeout 600s;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Mitigate HTTPOXY https://httpoxy.org/
fastcgi_param HTTP_PROXY "";
# has to be set to on if encryption (https) is used:
# fastcgi_param HTTPS on;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# chose as your php-fpm is configured to listen on
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# fastcgi_pass 127.0.0.1:8000/;
}
# Rewrite rule for WebSocket
location /ws {
rewrite ^/ws/(.*) /$1 break;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8100/;
}
}
==== Python 계열 세팅 ====
내가 운용 중인 모든 애플리케이션은 Python3로 작성되어 있으니, 그 쪽으로 세팅을 맞춘다.
apt install python3-pip
virtualenv, virtualenvwrapper도 다시 설정해 주자.
pip3 install virtualenv virtualenvwrapper
uwsgi는 시스템 쪽으로 맞춰 줬다.
pip3 install uwsgi
=== Nginx ===
# Nginx configuration for miniserver-apps
upstream django {
server unix://
}
server {
listen 80;
server_name apps.changwoo.pe.kr;
charset utf-8;
client_max_body_size 8M;
location /favicon.ico {
access_log off;
log_not_found off;
}
location /static {
alias /static;
}
location / {
uwsgi_pass django;
include uwsgi_params;
}
}
=== uWSGI ===
앱이 하나일 때는 아래와 같이 간단하게 master로 돌렸다.
[uwsgi]
# Djnago project base directory
chdir =
# WSGI Python module
module = miniserver.wsgi
# Virtualenv path
home =
master = true
processes = 4
socket =
vacuum = true
chmod-socket = 664
chown-socket = owner:group
enable-threads = true
pidfile =
daemonize =
그러나 복수의 앱을 운영해야 할 시점이 생기자 엡퍼러(emperor) 모드가 필요해졌다. 엠퍼러 모드는 간단하게 이렇게 쓸 수 있다.
uid=owner
daemonize=
emperor=
에는 그룹으로 돌릴 ini 파일들을 넣으면 된다. 즉 miniserver-apps.ini 파일 같은 것을 그대로 이 디렉토리에 넣으면 되는데, 이 때 주의할 점은 몇몇 설정들은 이미 엠퍼러에서 진행되었으므로 삭제해야 한다. 예를 들어 miniserver-apps.ini에서 demonize, uid 같은 설정값은 에러를 낼 수 있다.
=== rc.local ===
매번 부팅때마다 돌려 줘야 하므로,
/usr/local/bin/uwsgi --ini ini_file.ini
자 이렇게 대략 세팅해 주면 파이썬은 돌아간다.
uwsgi --stop /tmp/project-master.pid
uwsgi --reload /tmp/project-master.pid
kill -HUP `cat /tmp/project-master.pid`
killall -s INT uwsgi
===== 사용자 계정 생성 =====
changwoo 계정 생성
useradd -m -d /media/storage/changwoo -s /bin/bash
===== Samba =====
삼바는 이미 설치되어 있으므로 아주 간단하게 내부에서 공유 디렉토리만 되도록 설정 추가한다.
''/etc/samba/smb.conf''
[changwoo]
path = /media/storage/changwoo
writable = yes
create mask = 0644
directory mask = 0755
심볼릭 링크를 추가하기 위해 다음과 같은 세팅을 주었다((http://unix.stackexchange.com/questions/5120/how-do-you-make-samba-follow-symlink-outside-the-shared-path))
[global]
allow insecure wide links = yes
[share]
follow symlinks = yes
wide links = yes
service smbd restart
===== Dropbox =====
#!/bin/sh
#
# Copied from http://forums.dropbox.com/topic.php?id=38529#post-414344
# Modified by jay@gooby.org (@jaygooby on Twitter)
### BEGIN INIT INFO
# Provides: dropbox
# Required-Start: $local_fs $remote_fs $network $syslog $named
# Required-Stop: $local_fs $remote_fs $network $syslog $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: false
# Short-Description: dropbox service
### END INIT INFO
# dropbox service
DROPBOX_USERS="changwoo"
start() {
echo "Starting dropbox..."
for dbuser in $DROPBOX_USERS; do
HOMEDIR=$(getent passwd $dbuser | cut -d: -f6)
DAEMON=$(find $HOMEDIR/.dropbox-dist/dropbox-lnx.* -name dropboxd)
if [ -x $DAEMON ]; then
HOME="$HOMEDIR" start-stop-daemon -b -o -c $dbuser -S -u $dbuser -x $DAEMON -p "$HOMEDIR/.dropbox/dropbox.pid"
fi
done
}
stop() {
echo "Stopping dropbox..."
for dbuser in $DROPBOX_USERS; do
HOMEDIR=$(getent passwd $dbuser | cut -d: -f6)
DAEMON=$(find $HOMEDIR/.dropbox-dist/dropbox-lnx.* -name dropbox)
if [ -x $DAEMON ]; then
start-stop-daemon -o -c $dbuser -K -u $dbuser -x $DAEMON
fi
done
}
status() {
for dbuser in $DROPBOX_USERS; do
dbpid=$(pgrep -u $dbuser dropbox)
if [ -z $dbpid ] ; then
echo "dropboxd for USER $dbuser: not running."
else
echo "dropboxd for USER $dbuser: running (pid $dbpid)"
fi
done
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload|force-reload)
stop
start
;;
status)
status
;;
*)
echo "Usage: /etc/init.d/dropbox {start|stop|reload|force-reload|restart|status}"
exit 1
esac
exit 0
''/etc/init.d/dropbox''
===== Torrent =====
언제나 그렇듯 deluge를 애용한다.
apt-get install deluge-common deluge-web deluged
같이 데몬 스크립트도 설치되지만, 이 스크립트는 web UI를 기본 지원하지 않아 불만족스럽다. 기존 스크립트로 대체한다.
''/etc/default/deluge-daemon''
# Configuration for /etc/init.d/deluge-daemon
# The init.d script will only run if this variable non-empty.
DELUGED_USER="changwoo" # !!!CHANGE THIS!!!!
# Should we run at startup?
RUN_AT_STARTUP="YES"
''/etc/init.d/deluge-daemon''
#!/bin/sh
### BEGIN INIT INFO
# Provides: deluge-daemon
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Daemonized version of deluge and webui.
# Description: Starts the deluge daemon with the user specified in
# /etc/default/deluge-daemon.
### END INIT INFO
# Author: Adolfo R. Brandes
# Updated by: Jean-Philippe "Orax" Roemer
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="Deluge Daemon"
NAME1="deluged"
NAME2="deluge"
DAEMON1=/usr/bin/deluged
DAEMON1_ARGS="-d -c /media/storage/changwoo/.config/deluge -L info -l /media/storage/changwoo/.config/deluge/deluge.log" # Consult `man deluged` for more options
DAEMON2=/usr/bin/deluge-web
DAEMON2_ARGS="" # Consult `man deluge-web` for more options
PIDFILE1=/var/run/$NAME1.pid
PIDFILE2=/var/run/$NAME2.pid
UMASK=022 # Change this to 0 if running deluged as its own user
PKGNAME=deluge-daemon
SCRIPTNAME=/etc/init.d/$PKGNAME
# Exit if the package is not installed
[ -x "$DAEMON1" -a -x "$DAEMON2" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$PKGNAME ] && . /etc/default/$PKGNAME
# Load the VERBOSE setting and other rcS variables
[ -f /etc/default/rcS ] && . /etc/default/rcS
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
if [ -z "$RUN_AT_STARTUP" -o "$RUN_AT_STARTUP" != "YES" ]
then
log_warning_msg "Not starting $PKGNAME, edit /etc/default/$PKGNAME to start it."
exit 0
fi
if [ -z "$DELUGED_USER" ]
then
log_warning_msg "Not starting $PKGNAME, DELUGED_USER not set in /etc/default/$PKGNAME."
exit 0
fi
#
# Function to verify if a pid is alive
#
is_alive()
{
pid=`cat $1` > /dev/null 2>&1
kill -0 $pid > /dev/null 2>&1
return $?
}
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
is_alive $PIDFILE1
RETVAL1="$?"
if [ $RETVAL1 != 0 ]; then
rm -f $PIDFILE1
start-stop-daemon --start --background --quiet --pidfile $PIDFILE1 --make-pidfile \
--exec $DAEMON1 --chuid $DELUGED_USER --user $DELUGED_USER --umask $UMASK -- $DAEMON1_ARGS
RETVAL1="$?"
else
is_alive $PIDFILE2
RETVAL2="$?"
[ "$RETVAL2" = "0" -a "$RETVAL1" = "0" ] && return 1
fi
is_alive $PIDFILE2
RETVAL2="$?"
if [ $RETVAL2 != 0 ]; then
sleep 2
rm -f $PIDFILE2
start-stop-daemon --start --background --quiet --pidfile $PIDFILE2 --make-pidfile \
--exec $DAEMON2 --chuid $DELUGED_USER --user $DELUGED_USER --umask $UMASK -- $DAEMON2_ARGS
RETVAL2="$?"
fi
[ "$RETVAL1" = "0" -a "$RETVAL2" = "0" ] || return 2
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --user $DELUGED_USER --pidfile $PIDFILE2
RETVAL2="$?"
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --user $DELUGED_USER --pidfile $PIDFILE1
RETVAL1="$?"
[ "$RETVAL1" = "2" -o "$RETVAL2" = "2" ] && return 2
rm -f $PIDFILE1 $PIDFILE2
[ "$RETVAL1" = "0" -a "$RETVAL2" = "0" ] && return 0 || return 1
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME1"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME1"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME1"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
:
패키지로 설치된 /etc/init.d/deluged는 실행되지 않도록 수정.
/etc/init.d# systemctl disable deluged
chmod -x /etc/init.d/deluged
동작하도록 재설정
systemctl daemon-reload
service deluge-daemon start
===== CronTab =====
==== python-onedrive ====
이 프로젝트는 폐기되었지만, 간단하게 쓰고 있었고 당분간은 동작하므로 그냥 쓴다.
apt install python-pip requests pyYAML
''~/.lcrc''에 client id, secret을 설정하고
onedrive-cli quota
==== 스크립트들 ====
* dokuwiki_autobackup: 도쿠위키 백업
* wp_backup: 워드프레스 백업
도쿠위키는 월요일 오전 4시에, 워드프레스는 월요일 오전 5시에 백업.
0 4 * * 1 /media/storage/changwoo/Dropbox/MiniServer/scripts/dokuwiki_autobackup
0 5 * * 1 /media/storage/changwoo/Dropbox/MiniServer/scripts/wp_backup.sh
===== Resilio-Sync =====
[[https://www.resilio.com/ | Resilio-Sync ]]로 비트토렌트 방식의 싱크. [[project:btsyncforrpi | 라즈베리 파이에서 BitTorrentSync로 데이터 동기화하기 ]] 같은 문서로도 작성한 바가 있다. 이게 이름이 바뀌었다.
가정용은 무료이니 나같이 그냥 비디오 디렉토리 공유하는 수준에서는 괜찮은 선택인 것 같다.
deb 패키지가 제공되니 깔아 주면 그만이다. service resilio-sync start 명령으로 실행하면 되는데, 변경은 다음과 같은 명령으로
$ sudo systemctl edit resilio-sync.service
[Service]
User=changwoo
Group=changwoo
PIDFile=
PIDFile=/home/changwoo/.config/resilio-sync/sync.pid
ExecStartPre=
ExecStartPre=/bin/mkdir -p /home/changwoo/.config/resilio-sync
ExecStartPre=/bin/chown -R changwoo:changwoo /home/changwoo/.config/resilio-sync
ExecStart=
ExecStart=/usr/bin/rslsync --config /home/changwoo/.config/resilio-sync/config.json
systemctl edit 명령은 파일 자체를 변경하는 것이 아니라 overriding 하는 방식이다.그리고 override 할 때 기존 명령어는 한번 비워주는 작업이 필요하다. 그래서 "''ExexStart=''" 같은 라인이 생기는 것이다. 저것이 없으면 에러.
$ sudo systemctl cat resilio-sync.service
[Unit]
Description=Resilio Sync service
Documentation=https://help.getsync.com/
After=network.target network-online.target
[Service]
Type=forking
User=rslsync
Group=rslsync
UMask=0002
Restart=on-failure
PermissionsStartOnly=true
PIDFile=/var/run/resilio-sync/sync.pid
ExecStartPre=/bin/mkdir -p /var/run/resilio-sync
ExecStartPre=/bin/chown -R rslsync:rslsync /var/run/resilio-sync
ExecStart=/usr/bin/rslsync --config /etc/resilio-sync/config.json
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/resilio-sync.service.d/override.conf
[Service]
User=changwoo
Group=changwoo
PIDFile=
PIDFile=/home/changwoo/.config/resilio-sync/sync.pid
ExecStartPre=
ExecStartPre=/bin/mkdir -p /home/changwoo/.config/resilio-sync
ExecStartPre=/bin/chown -R changwoo:changwoo /home/changwoo/.config/resilio-sync
ExecStart=
ExecStart=/usr/bin/rslsync --config /home/changwoo/.config/resilio-sync/config.json
이렇게 덧붙여지는 것을 참고하자.
===== SSL 설비 =====
이제는 필수로 구비하자. Let's Encrypt가 있다. 아래의 가이드를 따라하면 어렵지 않다.
* https://certbot.eff.org/#ubuntuxenial-nginx
* http://riseshia.github.io/2016/10/16/certbot-let-s-encrypt.html
3개월마다 갱신해야 하는데, 나는 아직 자동 갱신을 하지는 않았다. 나중에 확인하고 달아 보도록 하자.