기본 콘텐츠로 건너뛰기

docker+alias를 사용해서 golang 편하게 쓰기

이 글은 docker 설치를 했다는 가정에서 진행한다.

먼저 go docker 버전을 가져오자
docker pull 해도 되지만 필요한 걸 추가할 수도 있을 것 같아
Dockerfile 을 만들었다.
FROM golang:1.7-alpine
go 1.7을 비교적 가벼운 alpine linux버전에 올리자.
docker build .
해서 image를 만들자
docker images를 해서 확인할 수 있다.
alpine 이 아니라 그냥 1.7도 docker pull golang:1.7 해서 가져와봤는데 

$ docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED            SIZE
golang                      1.7-alpine          52493611af1e        5 days ago          241.1 MB
golang                      1.7                 fe25c00086fb        5 days ago          669.6 MB

용량 차이가 제법 난다.
1.7은 안쓸거니까 docker rmi golang:1.7 해서 바이바이.

docker run -it --rm --name migolang golang:1.7-alpine go

작동을 확인해보자. 잘되면 OK. golang:1.7-alpine이 불편하면 docker build -t migolang . 과 같이 태그를 지정할 수도 있다. docker run -it --rm --name migolang migolang go 처럼 쓸 수 있는 것.

옵션에 대해 구구절절 설명을 좀 하면
docker run -it --rm --name migolang golang:1.7-alpine go
-it 옵션은 -i -t 를 붙여서 쓴건데 -i 입력을 유지하는 옵션이고 -t는 TTY 즉 docker 에서 일어난 결과를 화면 포워딩 하는 것으로 사실 이 경우엔 쓸 필요없지만 습관처럼 붙여쓰고 있다.
그러니까 줘서 해 될거 없는 옵션

docker run -it --rm --name migolang golang:1.7-alpine go
--rm 옵션은 docker run 을 할 때마다 컨테이너를 생성하는데 이게 매번 지우기가 귀찮을 때가 많다. 그래서 만일 컨테이너가 있다면 자동으로 지우는 옵션. 역시 습관처럼 붙여쓰고 있다.

docker run -it --rm --name migolang golang:1.7-alpine go
--name 옵션은 컨테이너 이름을 지정하지 않으면 지맘대로 임의로 생성한다.
역시 귀찮으니까 지정해서 --rm 옵션으로 지정했다. my > me > mi + golang 해서 migolang 이라고 지었다.
미고랭. 그것은 넘나 맛있는 것. 원래는 Mie goreng이다.

이제 go 소스코드를 작성하고 실행해보자.
package main
import "fmt"
func main() {
  fmt.Printf("Hello, world.\n")
}
hello.go 를 이렇게 만들고 
docker run -it --rm --name migolang golang:1.7-alpine go run hello.go
하면 안될거다 (읭?)
왜냐면 go run은 docker 컨테이너 안에서 실행하고 우리들의 hello.go는 그 바깥에 있기 때문이다.
그러면 현재 hello.go를 docker 컨테이너 않으로 넣어야하는데 -v 옵션으로 서로 연결해주자.
-v "내 경로":"docker 컨테이너 경로" 로 맞춰주자. 현재 경로로 할거고 임의로 docker 컨테이너 안에 /usr/src/myapp (이 경로는 자유롭게) 이란 곳이랑 붙여준다. 
하는 김에 -v 옵션으로 지정한 경로를 go 명령이 실행하는 위치가 되도록 -w 옵션으로 경로를 맞춰주자.
docker run -it -v `echo $PWD`:/usr/src/myapp -w /usr/src/myapp --rm --name migolang golang:1.7-alpine go run hello.go
Hello, world. 가 나오는가? 좋다. 근데 이거 매번 일일이 다 치긴 나는 좀 많이 귀찮다.

alias @="docker run -it -v '$PWD':/usr/src/myapp -w /usr/src/myapp --rm --name migolang golang:1.7-alpine"

go 명령이 시작되는 부분 딱 이전까지 alias로 만들어서 사용하면 편할 것 같다.
@ go run hello.go 해보자.
$ @ go run hello.go
Hello, world.
잘 된다. @ 만 앞에 붙여주면 되니까 편하다.

------------- 절 취 선 -------------

조금 더 욕심을 내서 간단한 웹서버를 하나 띄워보자.
node.js 랑 비슷하게 특정포트를 웹서버로 열어주고 응답을 보내는 예를 만들어서
package mainimport (        "net/http")
func main() {        http.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {                res.Write([]byte("Hello, world!"))        })        http.ListenAndServe(":8000", nil)}
web.go를 이런 식으로 해보자. 8000 포트를 열고 '/'로 요청이 오면 "Hello, world!"를 출력하는 간단한 예다.
먼저 Dockerfile 을 약간 수정하자.
vi Dockerfile 해서
FROM golang:1.7-alpine
이었던 것에 포트를 노출하기 위해 EXPOSE 를 사용하자
FROM golang:1.7-alpine
EXPOSE 8000
8000번 포트를 노출해주었다.
그리고 alias @도 조금 수정하자.
alias @='docker run -it -v '\''/Users/spectrum/Documents/go/jadeExam/src'\'':/usr/src/myapp -w /usr/src/myapp --rm --name migolang -p 8000:8000 golang:1.7-alpine'
-p 부분을 추가하여 포트 매핑을 해주자 -p <실제포트>:<Docker안에서 Expose한 포트> 순서가 되겠다.
@ docker run web.go
한 뒤, 다른 터미널 하나를 열고 curl http://localhost:8000 해보자.
$ curl localhost:8000
Hello, world!
이렇게 나온다면 승리자.
docker run 커맨드가 너무 길어서 포기하는 경우가 많은데 alias나 sh(혹은 .bat)등을 이용해서 조금만 자동화하면 생각보다 어렵지 않게 쓸 수 있다.

지금은 go get 을 쓰기 위해 Dockerfile 에 git을 포함하여
FROM golang:1.7-alpine
MAINTAINER spectrum <spectrick@gmail.com>
RUN apk --update add git &&\
    rm -rf /var/lib/apt/lists/* && \
    rm /var/cache/apk/*
EXPOSE 8000
이런 식으로 만들고

docker build -t migolang .

이렇게 migolang 이란 이름을 가진 이미지를 생성하여

alias를 마지막으로

alias @="docker run -it -v $PWD:/usr/src/myapp -w /usr/src/myapp --rm --name migolang -p 8000:8000 migolang"

이렇게 migolang 을 지정.
@ go get 을 잘 쓰고 있다. 아주 좋다.

댓글

이 블로그의 인기 게시물

cURL로 cookie를 다루는 법

http://stackoverflow.com/questions/22252226/passport-local-strategy-and-curl 레거시 소스를 보다보면 인증 관련해서 cookie를 사용하는 경우가 있는데 가령 REST 서버인 경우 curl -H "Content-Type: application/json" -X POST -d '{"email": "aaa@bbb.com", "pw": "cccc"}' "http://localhost/login" 이렇게 로그인이 성공이 했더라도 curl -H "Content-Type: application/json" -X GET -d '' "http://localhost/accounts/" 이런 식으로 했을 때 쿠키를 사용한다면 당연히 인증 오류가 날 것이다. curl의 --cookie-jar 와 --cookie 옵션을 사용해서 cookie를 저장하고 꺼내쓰자. 각각 옵션 뒤엔 저장하고 꺼내쓸 파일이름을 임의로 지정하면 된다. 위의 과정을 다시 수정해서 적용하면 curl -H --cookie-jar jarfile "Content-Type: application/json" -X POST -d '{"email": "aaa@bbb.com", "pw": "cccc"}' "http://localhost/login" curl -H --cookie jarfile "Content-Type: application/json" -X GET -d '' "http://localhost/accounts/" 이렇게 사용하면

MQTT 접속해제 - LWT(Last will and testament)

통신에서 중요하지만 구현이 까다로운 문제로 "상대방이 예상치 못한 상황으로 인하여 접속이 끊어졌을때"의 처리가 있다. 이것이 까다로운 이유는 상대방이 의도적으로 접속을 종료한 경우는 접속 종료 직전에 자신의 종료 여부를 알리고 나갈 수 있지만 프로그램 오류/네트웍 연결 강제 종료와 같은 의도치 않은 상황에선 자신의 종료를 알릴 수 있는 방법 자체가 없기 때문이다. 그래서 전통적 방식으로는 자신의 생존 여부를 계속 ping을 통해 서버가 물어보고 timeout 시간안에 pong이 안올 경우 서버에서 접속 종료를 인식하는 번거로운 방식을 취하는데 MQTT의 경우 subscribe 시점에서 자신이 접속 종료가 되었을 때 특정 topic으로 지정한 메시지를 보내도록 미리 설정할 수 있다. 이를 LWT(Last will and testament) 라고 한다. 선언을 먼저하고 브로커가 처리하게 하는 방식인 것이다. Last Will And Testament 라는 말 자체도 흥미롭다. 법률용어인데  http://www.investopedia.com/terms/l/last-will-and-testament.asp 대략 내가 죽으면 뒷산 xx평은 작은 아들에게 물려주고 어쩌고 하는 상속 문서 같은 내용이다. 즉, 내가 죽었을(연결이 끊어졌을) 때에 변호사(MQTT Broker - ex. mosquitto/mosca/rabbitMQ등)로 하여금 나의 유언(메시지)를 상속자(해당 토픽에 가입한 subscriber)에게 전달한다라는 의미가 된다. MQTT Client 가 있다면 한번 실습해보자. 여러가지가 있겠지만 다른 글에서처럼  https://www.npmjs.com/package/mqtt  을 사용하도록 한다. npm install mqtt --save 로 설치해도 되고 내 경우는 자주 사용하는 편이어서 npm install -g mqtt 로 전역설치를 했다. 호스트는 무료 제공하고 있는 test.mosquitto.org 를

MQTT Broker Mosquitto 설치 후 설정

우분투 기준 $ sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa $ sudo apt-get update 하고 $ sudo apt-get install mosquitto 으로 설치하면 서비스까지 착실하게 올라간다. 설치는 간단한데 사용자를 만들어야한다. /etc/mosquitto/mosquitto.conf 파일에서 권한 설정을 변경하자. allow_anonymous false 를 추가해서 아무나 못들어오게 하자. $ service mosquitto restart 서비스를 재시작. 이제 사용자를 추가하자. mosquitto_passwd <암호파일 경로명> <사용자명> 하면 쉽게 만들 수 있다. # mosquitto_passwd /etc/mosquitto/passwd admin Password:  Reenter password:  암호 넣어준다. 두번 넣어준다. 이제 MQTT 약을 열심히 팔아서 Broker 사글세방 임대업을 하자.