미니서버를 2016년 5월 31일부로 14.04에서 16.04로 새로 설치하였다. 많이 변한 건 없는데, 해 놓은 게 많아서인지 설정할 것이 많았다. 특히 Nginx 변환 부분은 조금 힘들었음. 설치 기록을 남겨 본다.
/dev/sdb1을 시스템, /dev/sda1을 주 저장소로 지정하였다. /dev/sda1을 이전과 마찬가지로 /media/storage(스토리지)에 마운트하여 사용하는 전략은 변함이 없다. 일부 읽기, 쓰기가 잦은 시스템의 디렉토리를 스토리지로 연결하는 전략을 쓴다. 예를 들면 /var/log, /tmp 은 심볼릭 링크 처리하고 실제로는 /media/storage/log, /media/storage/tmp가 역할을 대신한다.
우분투 설치는 매우 심플하게 한다. 스토리지를 기본으로 마운팅하게 하는 것 이외에는 그냥 있는 그대로의 설정을 사용하는 편이다. 사실 USB 스틱에서 부팅하는 방식이니 당연히 복잡하게 할 이유가 없다.
사용자 계정 패스워드를 입력하는 단계에서 패스워드를 평문으로 확인할 수 있도록 체크박스가 추가되었다는 점이 특이하다. 그 외에는 외견상 변한 점은 없다. 기본으로 삼바 서버와 OpenSSH 서버 패키지를 설치해 주고 설치를 마친다. 부팅 모두 문제 없다.
예전에는 기본 리포지터리를 다음이나 다른 곳으로 변경했었지만, 지금은 그것마저도 별 필요 없는 듯.
데이터베이스는 간결하게 mysql-server를 사용하기로 했다.
apt-get install mysql-server
시스템이 USB 스틱 메모리에 위치한지라, 여기에 계속 읽기/쓰기가 반복되는 것이 조금 껄끄럽다 생각했다. MySQL 5.5 → 5.7로 마이그레이션하는 것이라 귀찮지만 미리 SQL 파일로 미리 데이터베이스를 모두 덤프해 두었다.
예전에는 눈치를 못챘거나 없었던 디렉토리가 생겼다.
이 세 디렉토리도 같이 옮기기로 결정.
나는 /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,
/etc/mysql/mysql.conf.d/mysqld.cnf
버퍼 사이즈, 캐시 사이즈는 적절히 조정해줬다. 기준이 없으니 적절히 더 주는 정도?
datadir = /media/storage/mysql tmpdir = /media/storage/tmp
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
특정 사이트의 PHP 실행 유저를 다르게 만들어 동작시킬 때 사용한다.
/etc/php/7.0/fpm/pool.d
디렉토리의 www.conf 기본 파일을 적절히 편집해서 변경한다.
nginx설정에서 원하는 사이트의 fastcgi 소켓 경로를 변경해 준다. opcache 문제도 있을 수 있는데, 이건 그냥 스킵.
내 도메인이 주소가 아닌 직접 IP 접속은 같은 공유기 안의 주소가 아니면 오지 못하도록 막을 필요가 있다.
/etc/nginx/sites-available/default
# allow only localhost allow 192.168.0.0/24; allow 192.168.10.0/24; deny all;
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;
# 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 방식을 선택해야 문서가 올바르게 보인다.
이 녀석은 조금 복잡하다.
# 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; }
그동안 모바일 기기에서 제대로 재생이 되지 않는 문제가 있었다가, 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/; } }
내가 운용 중인 모든 애플리케이션은 Python3로 작성되어 있으니, 그 쪽으로 세팅을 맞춘다.
apt install python3-pip
virtualenv, virtualenvwrapper도 다시 설정해 주자.
pip3 install virtualenv virtualenvwrapper
uwsgi는 시스템 쪽으로 맞춰 줬다.
pip3 install uwsgi
# Nginx configuration for miniserver-apps upstream django { server unix://<unix_socket> } 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 <path_to_application>/static; } location / { uwsgi_pass django; include uwsgi_params; } }
앱이 하나일 때는 아래와 같이 간단하게 master로 돌렸다.
[uwsgi] # Djnago project base directory chdir = <project root> # WSGI Python module module = miniserver.wsgi # Virtualenv path home = <virtualenv path> master = true processes = 4 socket = <path-to-socket> vacuum = true chmod-socket = 664 chown-socket = owner:group enable-threads = true pidfile = <path-to-pidfile> daemonize = <path-to-log>
그러나 복수의 앱을 운영해야 할 시점이 생기자 엡퍼러(emperor) 모드가 필요해졌다. 엠퍼러 모드는 간단하게 이렇게 쓸 수 있다.
uid=owner daemonize=<path-to-log> emperor=<path-to-store-vassals>
<path-to-store-vassals>에는 그룹으로 돌릴 ini 파일들을 넣으면 된다. 즉 miniserver-apps.ini 파일 같은 것을 그대로 이 디렉토리에 넣으면 되는데, 이 때 주의할 점은 몇몇 설정들은 이미 엠퍼러에서 진행되었으므로 삭제해야 한다. 예를 들어 miniserver-apps.ini에서 demonize, uid 같은 설정값은 에러를 낼 수 있다.
매번 부팅때마다 돌려 줘야 하므로,
/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
삼바는 이미 설치되어 있으므로 아주 간단하게 내부에서 공유 디렉토리만 되도록 설정 추가한다.
/etc/samba/smb.conf
[changwoo] path = /media/storage/changwoo writable = yes create mask = 0644 directory mask = 0755
심볼릭 링크를 추가하기 위해 다음과 같은 세팅을 주었다1)
[global] allow insecure wide links = yes [share] follow symlinks = yes wide links = yes
service smbd restart
#!/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
언제나 그렇듯 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
이 프로젝트는 폐기되었지만, 간단하게 쓰고 있었고 당분간은 동작하므로 그냥 쓴다.
apt install python-pip requests pyYAML
~/.lcrc
에 client id, secret을 설정하고
onedrive-cli quota
도쿠위키는 월요일 오전 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 로 비트토렌트 방식의 싱크. 라즈베리 파이에서 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
이렇게 덧붙여지는 것을 참고하자.
이제는 필수로 구비하자. Let's Encrypt가 있다. 아래의 가이드를 따라하면 어렵지 않다.
3개월마다 갱신해야 하는데, 나는 아직 자동 갱신을 하지는 않았다. 나중에 확인하고 달아 보도록 하자.