서버 이전 경험 공유기 – 1. Dockerizing

이번에 서버이전을 하면서 이것저것 알게된 지식 및 경험을 공유하고자 이 글을 작성합니다.

서버 이전

서버 이전을 하게 되었습니다.
기존엔 cloudv 를 쓰고 있었는데, 같은 회사에서 나온 iwinv 가 한국형 AWS가 되겠다고 하고 과감하게 출사표를 던저서 가격을 보던 중, iwinv 가 압도적으로 좋다고 판단해서 서버이전을 마음먹었습니다.

기존 cloudv 사양

1core, 3G memory, 100G ssd -> 월 31900원

이전 iwinv 사양

2core, 6G memory, 25G ssd -> 월 20900원

iwinv 는 블록스토리지 20g 추가 당 2000원.

굳이 이전하지 않을 이유가 없었습니다.

아무튼…

이전하는 김에 제 개인 서버를 모두 Dockerizing 하기로 마음을 먹고, 작업을 진행하던 중에, 요즘 무료로 https 를 발급해주는 Let’s Encrypt 라는 프로젝트가 있다는 사실을 알게 되었습니다.

그래서 이것도한 시도를 하겠다는 마음을 덜컥 먹어버린…

이런 이유로 시작한 설치 경험을 공유합니다.

Docker

소개

Docker 는 요즘 모르는 사람이 별로 없을 것 같습니다만, 상세소개는 페이지 링크로 대체합니다.

Official Site Overview
nacyot의 프로그래밍 이야기 :: 도커(Docker) 튜토리얼 : 깐 김에 배포까지

간단히 Docker 에 대해 설명하자면 아래 아키택트 이미지로 쉽게 표현이 가능할 것이라고 생각합니다.

Docker Architecture vs Virtual machine

Docker 를 이해하기 위해선 가상 머신(Virtual machine)과의 비교는 필수라고 생각합니다.

한마디로 제게 Docker 를 표현하라고 한다면, Virtual machine 의 장점(isolation, distribution)을 취했으나, 훨씬 더 비용이 적게드는 시스템이 아닐까합니다.

Docker 를 적용하는 이유

이런 도커를 이용해서 제 블로그 및 서버를 구성하기로 마음먹은 겁니다.

이유는 여러가지가 있지만 가장 큰 이유는, 개인서버는 형편상 이사갈 일이 많습니다.
좀 더 저렴하고 좋은 서비스가 나오면 이사를 가야하기 때문이죠.
적고보니 회사든 개인이든 비용문제는 같은 거군요..

Docker를 적용한다면 앞으로 다른 더 좋은 호스팅 서비스가 나올 경우, 쉽게 갈아탈 수 있게 하기 위함입니다. 도커 이미지만 Download 받고 실행하면 그만이거든요.

Dockerizing 본격 시작

이 블로그는 블로그계의 원탑 wordpress 로 이뤄져있고, 워드프레스는 역시 유명한 만큼 자료가 많더군요.

Quickstart: Compose and WordPress

Docker 공식 사이트에 이렇게 docker compose 로 결합하는게 나옵니다.

하지만 부족합니다…
이유는 저는 일단 mysql 을 사용하지 싫고, mariadb를 사용하고 싶기 때문이며,
하나는 역시나 이것또한 비용 문제로 docker image size 를 조금이라도 줄이고 싶기 때문입니다.

그러기에 저는 Alpine Linux 를 쓸 생각을 하게 됩니다.

Using docker compose

GitHub – 9to6/docker-wordpress-nginx: Docker compose for WordPress

docker compose 를 이용해서 워드프래스를 구성하실 분은 위 링크를 참고하시면 좋을 듯합니다.

구성은,

nginx 1.13 alpine, mariadb 10.2.6, wordpress 4.8 alpine

으로 구성했으며, wordpress Plugin인 duplicator 의 손쉬운 사용을 위해, 기본 Dockerfile에서 zip 라이브러리를 추가했습니다.

Using only Dockerfile

심플하기는 위에 것보다 아래 링크가 더 심플합니다.
GitHub – 9to6/docker-wordpress: docker + nginx + mariadb + supervisor + php7

이건 docker compose 를 사용하지 않고, 하나의 도커파일에 nginx + mariadb + wordpress + supervisor 를 한번에 담은 것으로 단순 wordpress 를 호스팅하길 원하시는 분은 이것이 훨씬 단순할 것입니다.

$ sudo docker pull 9to5/wordpress

Docker hub 에 이미지도 올려놓았으니 필요한 분들은 사용하시면 됩니다.

결론

이렇게 해서 도커를 이용해서 워드프레스 서버 구성을 끝냈습니다.
여러분이 보고 있는 이 화면이 결과물입니다.

다음 글은 wordpress 블로그에 무료 https 적용하는 방법을 기술하겠습니다.

리눅스에서 git ssh접속시 password 입력하지 않기

예전 포스팅에서 git 서버 구축하고 ssh로 접속하는 것 까지 포스팅했었다.

그런데 linux에서 git를 커맨드로 직접 다루려니 비번을 자꾸 물어봐서 너무 스트레스를 받았다.

그래서 ssh를 패스워드 대신 공개키 기반 인증으로 사용하기로 했다.

1. 클라이언트 설정(리눅스)

$ ssh-keygen -t rsa -b 4096 -C "weep@weeppp.com"

본인의 이메일을 입력하고 위 명령 실행하면 키가 생성되는데

첫번째 입력은 key의 이름이고, 두번째는 비밀번호 설정 유무인데, 입력안할꺼면 엔터치면 된다.

git.key  git.key.pub

필자는 git.key라는 이름으로 생성했더니 이렇게 두개의 파일이 생성되었다.

첫번째는 개인키고, 두번째 pub 확장자 파일은 public key, 즉 공개키이다.

두개의 파일을 ~/.ssh 폴더에 위치시킨다. 폴더가 없으면 생성한다.

 

다음으로 ssh-agent 실행유무를 확인하자.

$ eval $(ssh-agent -s)
  Agent pid 2933

위처럼 pid가 나온다면 정상적으로 실행중인 것이다.

$ ssh-add ~/.ssh/git.key

위의 명령이 정상적으로 실행되었다면 이제 password대신 rsa키를 이용해서 ssh접속이 가능해진 것이다.

 

2. 서버 설정

클라이언트의 설정만으로는 물론 서버에 접속이 가능할리가 없다.

클라이언트에서 생성한 공개키를 서버에 복사하자.

여기서는 귀찮으니까 vi를 이용해서 클립보드에 옮겼다.

$ vi ~/.ssh/git.key.pub

cat으로 해도 되고, 파일을 서버로 복사해서 “>>” 명령을 이용해서 append시켜도 되니 취향대로 한다.

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAgEAyKnGRx/DsvDonZQxe4r39XOxlm5BLhx+ksjEubNNq1PWL5Z5XP/96xzf7PwY6C4SXKRc/vnrgqynL4qmcWbU/qXgEqazybTp76egttjRXI7NVKOXeh02pTI67MiEJYRTxcgwP1FS1YerVnBZb79odnAVZZ0utyGU6HZIWgnEk0YL8waygHZFke1PWN+clZedtGDjhO1CfcxmDWmiWWJFtJ/DJHo3nFGP8noQy+Fm/LWSyxwvFqsL6vLi1zftC4NqMfwbvUDNXfaRFjkRdfiq1rgn4Sx/48cs2KhH2utZh5Q21wzFYdEAFAnSlDKtZDmukx/WfcrLkid+yG53Vkv0RmGBe+k1pOaa97X6WFG+7vHhYRY8anQIDie4A56MDfwGRZi0eklxXfVn2dtOKnSXLZxCMucADHJwaT0xE9ANUq7Je+jgoONsCyyDWVpPOMEVF49t4DKbEJux7Ncir0jJ4sid3u4upjar7QNZHnOLEfiOHDoJ2km4+fXizwBqwnPytmkEjbiGuxpQrymQfbcEHsXFjNhRgFTE4u3PYpRyMxaSpE7dHrfH3ZLPSjFtAh39l6Whe2hds3oNr3VwwpRJERzQERhicu6oKHP8s9r2Qlhb4dwYbbLV1Q/TuV1PcMWXUz/Z3SuKelZ9czebkkFhfJXzDDaBNEj4+9i+h1jFXqk= weep@weeppp.com

내가 생성한 공개키이다.

일단 본인의 공개키를 잘 복사해둔다.

 

여기서부터가 진짜 서버설정이다.

서버의 git user 의 홈디렉토리로 이동한다.

$ cd /home/git
$ mkdir .ssh
$ touch .ssh/authorized_keys

git홈에 .ssh 디렉토리를 만들고 공개키들을 저장하는 파일을 만든다.

이때 root로 작업했다면 소유자를 변경해주자.

$ chown -R git.git /home/git/.ssh

authorized_keys에 복사한 공개키를 넣으면 끝.

 

이제 클라이언트에서 git push나 git pull을 해보자

비밀번호를 묻지않으면 성공이다.

 

참고 사이트

나만의 Git 서버 설정하기

나만의 기트 서버를 설치해보자. ssh와 연동하기

 

Git server 설정하기.

 

centos 에 설치하기

git server 의존 패키지 설치

yum install curl-devel expat-devel gettext-devel \
  openssl-devel zlib-devel

git 설치

yum install git-core

리눅스에 git 계정 만들기

adduser git
passwd git
cd /opt
mkdir git
chown git.git git
cd /opt/git
sudo vi ReadMe

아래 내용을 위의 ReadMe파일에 넣어두고 앞으로 쭉 사용하자~

#create repository
git init --bare --shared my_project.git
chown -R git.git my_project.git

모든 유저들이 서버에 저장할 때 git계정을 이용할 수 있도록 설정해준다.

sudo vi /etc/passwd

위 명령 후 아래 내용을 찾는다.

git:x:502:503::/home/git:/bin/bash
which git-shell

명령으로 git-shell 위치를 확인한다.

/bin/bash 를 위에 나온 결과값(여기서는 /usr/bin/git-shell)로 변경한다

변경 후 부터는 git 계정은 Git 저장소에 Push하고 Pull하는 것만 가능하고 리눅스의 쉘에는 접근할 수 없다.

——– 샘플 프로젝트 설정 ——–

서버 설정이 끝났으니 샘플 프로젝트를 하나 만들어보자.

방금 만들었던 ReadMe를 읽고 아래 명령을 처보자.

cd /opt/git
sudo git init --bare --shared my_project.git
sudo chown -R git.git my_project.git

클리이언트에서 나의 git 서버와 연동을 해본다.

SourceTree를 사용할 경우
“복제 / 생성” -> “소스 경로 / URL” 에 아래 값 입력

ssh://git@weeppp.com/opt/git/my_project.git

포트가 다를 경우
ssh://git@weeppp.com:[PORT]/opt/git/my_project.git

이제 git를 이용하면 된다.

[centos] svn server(subversion) 아파치 https 연동하기

예전부터 종종 해오면서 “해야지, 해야지”했던 svn 서버 설정에 대해 블로깅하려 한다.

지금은 git가 대세라서 git도 좀 써보려하지만 일단 친숙한 svn서버 설정부터 해놓으려는게 목적이다.

서버 환경은 Centos 6.5 이고 minimun을 다운받아서 기본만 설치한 상태이다.

1. 아파치 설치

$> sudo yum install httpd

a. 정상설치 확인

$> rpm -qa httpd
httpd-2.2.15-39.el6.centos.x86_64

b. 아파치 iptables 예외 설정

$>sudo vi /etc/sysconfig/iptables

아래 내용 추가

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

아파치 svn연동 모듈 설치

$> sudo yum install mod_dav_svn mod_ssl

 

2. 아파치 https 설정

https 키생성(self signing)

$> openssl genrsa -des3 -out cert.key 1024
$> openssl req -new -key cert.key -out cert.csr
$> openssl x509 -req -days 3650 -in cert.csr -signkey cert.key -out cert.crt

키를 특정 경로에 저장, 여기서는 /etc/httpd폴더에 cert폴더를 만듬

$> mkdir /etc/httpd/cert

httpd-svn.conf파일을 /etc/httpd/conf.d/ 경로에 생성 한 뒤,

$> vi /etc/httpd/conf.d/httpd-svn.conf

 

아래 내용을 자신에게 맞도록 설정을 변경한다.

ServerName: 본인의 서버 이름

ServerAlias: 서버의 약칭

AuthUserFile: svn의 repository의 유저 패스워드 파일(뒤에 생성)

AuthzSVNAccessFile: svn의 repository 각 프로젝트의 권한 설정 파일(뒤에 생성)

SSLCertificateFile: 생성한 인증서파일

SSLCertificateKeyFile: 생성한 개인키

<VirtualHost *:443>

ServerName weeppp.com
ServerAlias weeppp.com
DocumentRoot "/var/www/svn"

<Location /test>
    DAV                svn
#   SVNPath             "/repository/sample"
    SVNParentPath      "/repository"
    SVNListParentPath  On
    SVNIndexXSLT       "/repos-web/view/repos.xsl"

    AuthType           Basic
    AuthName           "SVN Repository"
    AuthUserFile       "/repository/.passwd"
    AuthzSVNAccessFile "/repository/.authz"
    Require            valid-user
</Location>

# Use separate log files for the SSL virtual host; note that LogLevel
# is not inherited from httpd.conf.
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn

#   SSL Engine Switch:
#   Enable/Disable SSL for this virtual host.
SSLEngine on

#   SSL Protocol support:
# List the enable protocol levels with which clients will be able to
# connect.  Disable SSLv2 access by default:
SSLProtocol all -SSLv2

#   SSL Cipher Suite:
# List the ciphers that the client is permitted to negotiate.
# See the mod_ssl documentation for a complete list.
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW

#   Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate.  If
# the certificate is encrypted, then you will be prompted for a
# pass phrase.  Note that a kill -HUP will prompt again.  A new
# certificate can be generated using the genkey(1) command.
#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateFile /etc/cert/server.crt

#   Server Private Key:
#   If the key is not combined with the certificate, use this
#   directive to point at the key file.  Keep in mind that if
#   you've both a RSA and a DSA private key you can configure
#   both in parallel (to also allow the use of DSA ciphers, etc.)
#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateKeyFile /etc/cert/server.key

#   Server Certificate Chain:
#   Point SSLCertificateChainFile at a file containing the
#   concatenation of PEM encoded CA certificates which form the
#   certificate chain for the server certificate. Alternatively
#   the referenced file can be the same as SSLCertificateFile
#   when the CA certificates are directly appended to the server
#   certificate for convinience.
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt

#   Certificate Authority (CA):
#   Set the CA certificate verification path where to find CA
#   certificates for client authentication or alternatively one
#   huge file containing all of them (file must be PEM encoded)
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt

#   Client Authentication (Type):
#   Client certificate verification type and depth.  Types are
#   none, optional, require and optional_no_ca.  Depth is a
#   number which specifies how deeply to verify the certificate
#   issuer chain before deciding the certificate is not valid.
#SSLVerifyClient require
#SSLVerifyDepth  10

#   Access Control:
#   With SSLRequire you can do per-directory access control based
#   on arbitrary complex boolean expressions containing server
#   variable checks and other lookup directives.  The syntax is a
#   mixture between C and Perl.  See the mod_ssl documentation
#   for more details.
#<Location />
#SSLRequire (    %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
#            and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
#            and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
#            and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
#            and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20       ) \
#           or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
#</Location>

#   SSL Engine Options:
#   Set various options for the SSL engine.
#   o FakeBasicAuth:
#     Translate the client X.509 into a Basic Authorisation.  This means that
#     the standard Auth/DBMAuth methods can be used for access control.  The
#     user name is the `one line' version of the client's X.509 certificate.
#     Note that no password is obtained from the user. Every entry in the user
#     file needs this password: `xxj31ZMTZzkVA'.
#   o ExportCertData:
#     This exports two additional environment variables: SSL_CLIENT_CERT and
#     SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
#     server (always existing) and the client (only existing when client
#     authentication is used). This can be used to import the certificates
#     into CGI scripts.
#   o StdEnvVars:
#     This exports the standard SSL/TLS related `SSL_*' environment variables.
#     Per default this exportation is switched off for performance reasons,
#     because the extraction step is an expensive operation and is usually
#     useless for serving static content. So one usually enables the
#     exportation for CGI and SSI requests only.
#   o StrictRequire:
#     This denies access when "SSLRequireSSL" or "SSLRequire" applied even
#     under a "Satisfy any" situation, i.e. when it applies access is denied
#     and no other module can change it.
#   o OptRenegotiate:
#     This enables optimized SSL connection renegotiation handling when SSL
#     directives are used in per-directory context.
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
    SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>

#   SSL Protocol Adjustments:
#   The safe and default but still SSL/TLS standard compliant shutdown
#   approach is that mod_ssl sends the close notify alert but doesn't wait for
#   the close notify alert from client. When you need a different shutdown
#   approach you can use one of the following variables:
#   o ssl-unclean-shutdown:
#     This forces an unclean shutdown when the connection is closed, i.e. no
#     SSL close notify alert is send or allowed to received.  This violates
#     the SSL/TLS standard but is needed for some brain-dead browsers. Use
#     this when you receive I/O errors because of the standard approach where
#     mod_ssl sends the close notify alert.
#   o ssl-accurate-shutdown:
#     This forces an accurate shutdown when the connection is closed, i.e. a
#     SSL close notify alert is send and mod_ssl waits for the close notify
#     alert of the client. This is 100% SSL/TLS standard compliant, but in
#     practice often causes hanging connections with brain-dead browsers. Use
#     this only for browsers where you know that their SSL implementation
#     works correctly.
#   Notice: Most problems of broken clients are also related to the HTTP
#   keep-alive facility, so you usually additionally want to disable
#   keep-alive for those clients, too. Use variable "nokeepalive" for this.
#   Similarly, one has to force some clients to use HTTP/1.0 to workaround
#   their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
#   "force-response-1.0" for this.
SetEnvIf User-Agent ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

#   Per-Server Logging:
#   The home of a custom SSL log file. Use this when you want a
#   compact non-error SSL logfile on a virtual host basis.
CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

</VirtualHost>

 

 

아파치 설정 폴더로 이동

$> cd /etc/httpd/conf

설정 파일 오픈 및 내용 변경

  • 서버이름은 해당 도메인이나 아이피등으로 변경
  • User와 Group은 아래와 같이 아파치로 변경
ServerName weeppp.com
User apache
Group apache

/etc/httpd/conf 디렉토리에 extra 폴더 생성 및 파일 생성

$> mkdir extra
$> cd extra
$> vi httpd-svn.conf

httpd-svn.conf 파일안에 아래 내용 복사

##############################################################
# SVN
##############################################################

LoadModule dav_svn_module   modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so

<VirtualHost *:443>
    ServerName  weeppp.com
    ServerAlias  weeppp.com
    DocumentRoot "/data/webapps/svn/public_html"
    ServerAdmin  admin@gmail.com

    SetEnvIf Request_URI "\.(gif)|(jpg)|(swf)|(png)$" image_log

    CustomLog    "logs/svn_access_log.log"       common env=!image_log
    CustomLog    "logs/svn_access_image_log.log" common env=image_log
    ErrorLog     "logs/svn_error_log.log"

    <Location /svn>
        DAV                svn
        #SVNPath             "/repository/svn/repo/devsample"
        SVNParentPath /repository
#        SVNParentPath      "/repository/svn/devsample"
#        SVNListParentPath  On
        SVNIndexXSLT       "/repos-web/view/repos.xsl"

        AuthType           Basic
        AuthName           "Weep SVN Repository"
        AuthUserFile       "/repository/.passwd"
        AuthzSVNAccessFile "/repository/.authz"
        Require            valid-user
    </Location>
</VirtualHost>

여기서는 SVNParentPath를 설정해줘서 루트아래의 모든 프로젝트를 접근 가능하도록 함

3. SVN 설정

svn 저장소를 원하는 경로에 생성 및 이동

$> mkdir /repository
$> cd /repository

svn 저장소 소유자 변경

$> chown -R apache.apache /repository

sample프로젝트 생성

$> svnadmin create /repository/sample

프로젝트 소유자 및 권한 변경

$> chown -R apache.apache sample
$> chcon -R -t httpd_sys_content_t sample

svn 계정생성

$> htpasswd -c -m .passwd USER

.authz파일 생성

$> vi /repository/.authz

.authz파일에 하단 내용 추가

admin 그룹에 속한 계정(현재는 weeppp)에게 sample 프로젝트의 read/write 권한을 모두 주는것을 의미한다.

[groups]
admin=weeppp

[sample:/]
@admin = rw

 

.passwd 파일과 .authz파일 소유자를 apache로 변경한다

$> chown apache.apache .passwd
$> chown apache.apache .authz

problems with SELinux context/lables 요 문제가 있으므로 아래 명령을 실행한다.

$> chcon -t httpd_sys_content_t .authz
$> chcon -t httpd_sys_content_t .passwd

위의 명령어들을 잊지 않도록 /repository 폴더안에 ReadMe 파일로 저장해둔다.

#user create
htpasswd -c -m .passwd USER
#user add
htpasswd -m .passwd USER

#create svn repository
svnadmin create /repository/sample
chown -R apache.apache sample
chcon -R -t httpd_sys_content_t sample

subversion 재시작

$> /etc/init.d/svnserve stop
$> /etc/init.d/svnserve start

아파치 재시작

$> /etc/init.d/httpd restart

svn client를 이용해서 서버에 접근해본다.

https://weeppp.com/test/sample

checkout 하고 인증 받은 뒤에 svn을 이용하면 된다.