갈루아의 반서재

Haskell 웹프레임워크 Yesod 퀵 스타트 가이드

Yesod 웹 프레임워크의 주요 특징은 다음과 같다.

  • safety & security guaranteed at compile time
  • developer productivity: tools for all your basic web development needs
  • raw performance
    • fast, compiled code
    • techniques for constant-space memory consumption
  • asynchronous IO
    • this is built in to the Haskell programming language (like Erlang)


1. Stack build tool은 다음 포스팅을 참조하여 설치한다.

하스켈 설치 및 Hello World 출력해보기 Quick steps to get up and running with Haskell on Ubuntu
http://www.antilibrary.org/1528


2. 새로운 사이트를 만든다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
(venvhaskell) root@gcloudx:~/venvhaskell# stack new blackbriar yesod-postgres && cd blackbriar
Downloading template "yesod-postgres" to create project "blackbriar" in blackbriar/ ...
Looking for .cabal or package.yaml files to use to init the project.
Using cabal packages:
- blackbriar/blackbriar.cabal
 
Selecting the best among 11 snapshots...
 
* Matches lts-9.14
 
Selected resolver: lts-9.14
Initialising configuration using resolver: lts-9.14
Total number of user packages considered: 1
Writing configuration to file: blackbriar/stack.yaml
All done.
(venvhaskell) root@gcloudx:~/venvhaskell/blackbriar#
 
cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
(venvhaskell) root@gcloudx:~/venvhaskell/blackbriar# ls -al
합계 56
drwxr-xr-8 root root 4096 11월 24 13:18 .
drwxr-xr-7 root root 4096 11월 24 13:18 ..
-rw-r--r-- 1 root root  191 11월 24 13:18 .dir-locals.el
-rw-r--r-- 1 root root  241 11월 24 13:18 .gitignore
drwxr-xr-2 root root 4096 11월 24 13:18 app
-rw-r--r-- 1 root root 4709 11월 24 13:18 blackbriar.cabal
drwxr-xr-2 root root 4096 11월 24 13:18 config
-rw-r--r-- 1 root root 2256 11월 24 13:18 package.yaml
drwxr-xr-5 root root 4096 11월 24 13:18 src
-rw-r--r-- 1 root root 2172 11월 24 13:18 stack.yaml
drwxr-xr-4 root root 4096 11월 24 13:18 static
drwxr-xr-2 root root 4096 11월 24 13:18 templates
drwxr-xr-3 root root 4096 11월 24 13:18 test
(venvhaskell) root@gcloudx:~/venvhaskell/blackbriar#
 
cs


3. yesod command line tool 설치

1
2
3
4
5
6
7
8
9
(venvhaskell) root@gcloudx:~/venvhaskell/blackbriar# stack build yesod-bin cabal-install --install-ghc
[1 of 2] Compiling Main             ( /root/.stack/setup-exe-src/setup-mPHDZzAJ.hs, /root/.stack/setup-exe-src/setup-mPHDZzAJ.o )
[2 of 2] Compiling StackSetupShim   ( /root/.stack/setup-exe-src/setup-shim-mPHDZzAJ.hs, /root/.stack/setup-exe-src/setup-shim-mPHDZzAJ.o )
Linking /root/.stack/setup-exe-cache/x86_64-linux/tmp-Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2 ...
ansi-terminal-0.6.3.1: download
ansi-terminal-0.6.3.1: configure
ansi-terminal-0.6.3.1: build
ansi-terminal-0.6.3.1: copy/register
 
cs


4. 라이브러리 빌드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
(venvhaskell) root@gcloudx:~/venvhaskell/blackbriar# stack build
StateVar-1.1.0.4: download
StateVar-1.1.0.4: configure
StateVar-1.1.0.4: build
StateVar-1.1.0.4: copy/register
...
classy-prelude-yesod-1.2.0: download
classy-prelude-yesod-1.2.0: configure
classy-prelude-yesod-1.2.0: build
classy-prelude-yesod-1.2.0: copy/register
blackbriar-0.0.0: configure (lib + exe)
Configuring blackbriar-0.0.0...
blackbriar-0.0.0: build (lib + exe)
Preprocessing library blackbriar-0.0.0...
1 of 11] Compiling Settings         ( src/Settings.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Settings.o )
2 of 11] Compiling Settings.StaticFiles ( src/Settings/StaticFiles.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Settings/StaticFiles.o )
3 of 11] Compiling Model            ( src/Model.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Model.o )
4 of 11] Compiling Import.NoFoundation ( src/Import/NoFoundation.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Import/NoFoundation.o )
5 of 11] Compiling Foundation       ( src/Foundation.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Foundation.o )
6 of 11] Compiling Import           ( src/Import.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Import.o )
7 of 11] Compiling Handler.Comment  ( src/Handler/Comment.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Comment.o )
8 of 11] Compiling Handler.Common   ( src/Handler/Common.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Common.o )
9 of 11] Compiling Handler.Home     ( src/Handler/Home.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Home.o )
[10 of 11] Compiling Handler.Profile  ( src/Handler/Profile.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Profile.o )
[11 of 11] Compiling Application      ( src/Application.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Application.o )
Preprocessing executable 'blackbriar' for blackbriar-0.0.0...
[1 of 1] Compiling Main             ( app/main.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/blackbriar/blackbriar-tmp/Main.o )
Linking .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/blackbriar/blackbriar ...
blackbriar-0.0.0: copy/register
Installing library in
/root/venvhaskell/blackbriar/.stack-work/install/x86_64-linux/lts-9.14/8.0.2/lib/x86_64-linux-ghc-8.0.2/blackbriar-0.0.0-2VBmQYLKFgeLhypfZqR3QO
Installing executable(s) in
/root/venvhaskell/blackbriar/.stack-work/install/x86_64-linux/lts-9.14/8.0.2/bin
Registering blackbriar-0.0.0...
Progress: 97/98
cs

5. PostgreSQL 사용자 및 데이터베이스 생성 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
postgres@gcloudx:~$ createuser --interactive
Enter name of role to add: bourne
Shall the new role be a superuser? (y/n) y
postgres@gcloudx:~$ createdb blackbriardb
postgres@gcloudx:~$ su - root
암호:
root@gcloudx:~# adduser bourne
'bourne' 사용자를 추가 중...
새 그룹 'bourne' (1005) 추가 ...
새 사용자 'bourne' (1004) 을(를) 그룹 'bourne' (으)로 추가 ...
'/home/bourne' 홈 디렉터리를 생성하는 중...
'/etc/skel'에서 파일들을 복사하는 중...
새 UNIX 암호 입력:
새 UNIX 암호 재입력:
passwd: password updated successfully
Changing the user information for bourne
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
정보가 올바릅니까? [Y/n] y
root@gcloudx:~# sudo -i -u bourne
bourne@gcloudx:~$ psql -d blackbriardb
psql (9.5.10, server 9.3.19)
Type "help" for help.
 
blackbriardb=# \conninfo
You are connected to database "blackbriardb" as user "bourne" via socket in "/var/run/postgresql" at port "5432".
blackbriardb=#
 
cs


6. pgAdmin 파이썬 휠 다운로드하여 설치한다. 

자세한 설치방법은 http://redhotkorea.tistory.com/1522 참조한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
(venvhaskell) root@gcloudx:~# wget https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v2.0/pip/pgadmin4-2.0-py2.py3-none-any.whl
--2017-11-24 16:16:10--  https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v2.0/pip/pgadmin4-2.0-py2.py3-none-any.whl
Resolving ftp.postgresql.org (ftp.postgresql.org)... 87.238.57.227174.143.35.246217.196.149.55, ...
접속 ftp.postgresql.org (ftp.postgresql.org)|87.238.57.227|:443... 접속됨.
HTTP request sent, awaiting response... 200 OK
Length: 62056473 (59M) [application/octet-stream]
Saving to: ‘pgadmin4-2.0-py2.py3-none-any.whl’
 
pgadmin4-2.0-py2.py3-none-any.whl          100%[========================================================================================>]  59.18M   935KB/s    in 45s
 
2017-11-24 16:16:58 (1.31 MB/s) - ‘pgadmin4-2.0-py2.py3-none-any.whl’ saved [62056473/62056473]
 
 
cs


7. 데이터베이스 정보 수정

/root/blackbriar/blackbriar/config/settings.yml

1
2
3
4
5
6
7
8
database:
  user:     "_env:PGUSER:bourne"
  password: "_env:PGPASS:******"
  host:     "_env:PGHOST:localhost"
  port:     "_env:PGPORT:5432"
  # See config/test-settings.yml for an override during tests
  database: "_env:PGDATABASE:blackbriar"
  poolsize: "_env:PGPOOLSIZE:10"
cs


8. 개발 서버 런칭

1
2
3
4
5
(blackbriar) root@gcloudx:~/blackbriar# stack exec -- yesod devel
Yesod devel server. Enter 'quit' or hit Ctrl-C to quit.
yesod: user error (No cabal file found.
Please create a package description file <pkgname>.cabal)
 
cs

cabal 파일이 없다는 에러가 발생했다. 실행위치가 잘못되었음을 알 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
(blackbriar) root@gcloudx:~/blackbriar# cd blackbriar
(blackbriar) root@gcloudx:~/blackbriar/blackbriar# ls -al
합계 60
drwxr-xr-9 root root 4096 11월 25 10:50 .
drwxr-xr-3 root root 4096 11월 25 10:49 ..
-rw-r--r-- 1 root root  191 11월 25 10:49 .dir-locals.el
-rw-r--r-- 1 root root  241 11월 25 10:49 .gitignore
drwxr-xr-4 root root 4096 11월 25 10:51 .stack-work
drwxr-xr-2 root root 4096 11월 25 10:49 app
-rw-r--r-- 1 root root 4709 11월 25 10:49 blackbriar.cabal
drwxr-xr-2 root root 4096 11월 25 10:49 config
-rw-r--r-- 1 root root 2256 11월 25 10:49 package.yaml
drwxr-xr-5 root root 4096 11월 25 10:49 src
-rw-r--r-- 1 root root 2172 11월 25 10:49 stack.yaml
drwxr-xr-4 root root 4096 11월 25 10:49 static
drwxr-xr-2 root root 4096 11월 25 10:49 templates
drwxr-xr-3 root root 4096 11월 25 10:49 test
 
cs


9. 사이트 보기

인증에 실패했다는 메시지가 뜬다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
(blackbriar) root@gcloudx:~/blackbriar/blackbriar# stack exec -- yesod devel
Yesod devel server. Enter 'quit' or hit Ctrl-C to quit.
Application can be accessed at:
 
http://localhost:3000
https://localhost:3443
If you wish to test https capabilities, you should set the following variable:
  export APPROOT=https://localhost:3443
 
blackbriar-0.0.0: unregistering (flags changed from [] to ["-fdev","-flibrary-only"])
blackbriar-0.0.0: configure (lib)
Configuring blackbriar-0.0.0...
blackbriar-0.0.0: build (lib)
Preprocessing library blackbriar-0.0.0...
1 of 11] Compiling Settings         ( src/Settings.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Settings.o )
2 of 11] Compiling Settings.StaticFiles ( src/Settings/StaticFiles.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Settings/StaticFiles.o )
3 of 11] Compiling Model            ( src/Model.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Model.o )
4 of 11] Compiling Import.NoFoundation ( src/Import/NoFoundation.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Import/NoFoundation.o )
5 of 11] Compiling Foundation       ( src/Foundation.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Foundation.o )
6 of 11] Compiling Import           ( src/Import.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Import.o )
7 of 11] Compiling Handler.Comment  ( src/Handler/Comment.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Comment.o )
8 of 11] Compiling Handler.Common   ( src/Handler/Common.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Common.o )
9 of 11] Compiling Handler.Home     ( src/Handler/Home.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Home.o )
[10 of 11] Compiling Handler.Profile  ( src/Handler/Profile.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Profile.o )
[11 of 11] Compiling Application      ( src/Application.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Application.o )
blackbriar-0.0.0: copy/register
Installing library in
/root/blackbriar/blackbriar/.stack-work/install/x86_64-linux/lts-9.14/8.0.2/lib/x86_64-linux-ghc-8.0.2/blackbriar-0.0.0-18HzyIwvGfYDpXww1S7q4t
Registering blackbriar-0.0.0...
ExitSuccess
Type help for available commands. Press enter to force a rebuild.
Starting devel application
devel.hs: libpq: failed (FATAL:  password authentication failed for user "bourne"
FATAL:  password authentication failed for user "bourne"
)
Unexpected: child process exited with ExitFailure 1
Trying again
Starting devel application
devel.hs: libpq: failed (FATAL:  password authentication failed for user "bourne"
FATAL:  password authentication failed for user "bourne"
)
 
cs


패스워드를 수정하고 다시 띄워보면 아래와 같이 정상적으로 작동함을 확인할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
(blackbriar) root@gcloudx:~/blackbriar/blackbriar# stack exec -- yesod devel
Yesod devel server. Enter 'quit' or hit Ctrl-C to quit.
Application can be accessed at:
 
http://localhost:3000
https://localhost:3443
If you wish to test https capabilities, you should set the following variable:
  export APPROOT=https://localhost:3443
 
blackbriar-0.0.0: unregistering (local file changes: config/settings.yml)
blackbriar-0.0.0: build (lib)
Preprocessing library blackbriar-0.0.0...
1 of 11] Compiling Settings         ( src/Settings.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Settings.o ) [config/settings.yml changed]
blackbriar-0.0.0: copy/register
Installing library in
/root/blackbriar/blackbriar/.stack-work/install/x86_64-linux/lts-9.14/8.0.2/lib/x86_64-linux-ghc-8.0.2/blackbriar-0.0.0-18HzyIwvGfYDpXww1S7q4t
Registering blackbriar-0.0.0...
ExitSuccess
Type help for available commands. Press enter to force a rebuild.
Starting devel application
Migrating: CREATe TABLE "user"("id" SERIAL8  PRIMARY KEY UNIQUE,"ident" VARCHAR NOT NULL,"password" VARCHAR NULL)
25/Nov/2017:15:27:45 +0900 [Debug#SQL] CREATe TABLE "user"("id" SERIAL8  PRIMARY KEY UNIQUE,"ident" VARCHAR NOT NULL,"password" VARCHAR NULL); []
Migrating: CREATe TABLE "email"("id" SERIAL8  PRIMARY KEY UNIQUE,"email" VARCHAR NOT NULL,"user_id" INT8 NULL,"verkey" VARCHAR NULL)
Migrating: CREATe TABLE "comment"("id" SERIAL8  PRIMARY KEY UNIQUE,"message" VARCHAR NOT NULL,"user_id" INT8 NULL)
Migrating: ALTER TABLE "user" ADD CONSTRAINT "unique_user" UNIQUE("ident")
Migrating: ALTER TABLE "email" ADD CONSTRAINT "unique_email" UNIQUE("email")
Migrating: ALTER TABLE "email" ADD CONSTRAINT "email_user_id_fkey" FOREIGN KEY("user_id") REFERENCES "user"("id")
Migrating: ALTER TABLE "comment" ADD CONSTRAINT "comment_user_id_fkey" FOREIGN KEY("user_id") REFERENCES "user"("id")
Devel application launched: http://localhost:3000
25/Nov/2017:15:27:45 +0900 [Debug#SQL] CREATe TABLE "email"("id" SERIAL8  PRIMARY KEY UNIQUE,"email" VARCHAR NOT NULL,"user_id" INT8 NULL,"verkey" VARCHAR NULL); []
25/Nov/2017:15:27:45 +0900 [Debug#SQL] CREATe TABLE "comment"("id" SERIAL8  PRIMARY KEY UNIQUE,"message" VARCHAR NOT NULL,"user_id" INT8 NULL); []
25/Nov/2017:15:27:45 +0900 [Debug#SQL] ALTER TABLE "user" ADD CONSTRAINT "unique_user" UNIQUE("ident"); []
25/Nov/2017:15:27:45 +0900 [Debug#SQL] ALTER TABLE "email" ADD CONSTRAINT "unique_email" UNIQUE("email"); []
25/Nov/2017:15:27:45 +0900 [Debug#SQL] ALTER TABLE "email" ADD CONSTRAINT "email_user_id_fkey" FOREIGN KEY("user_id") REFERENCES "user"("id"); []
25/Nov/2017:15:27:45 +0900 [Debug#SQL] ALTER TABLE "comment" ADD CONSTRAINT "comment_user_id_fkey" FOREIGN KEY("user_id") REFERENCES "user"("id"); []
25/Nov/2017:15:33:48 +0900 [Debug#SQL] SELECT "id", "message", "user_id" FROM "comment" ORDER BY "id"; []
GET /
  Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
  Status: 200 OK 0.240338s
GET /static/css/bootstrap.css
  Params: [("etag","PDMJ7RwX")]
  Accept: text/css,*/*;q=0.1
  Status: 200 OK 0.000504s
GET /static/tmp/autogen-X_AxVQbl.js
  Accept: */*
  Status: 200 OK 0.000194s
GET /static/tmp/autogen-8iASS6X3.css
  Accept: text/css,*/*;q=0.1
  Status: 200 OK 0.000148s
GET /favicon.ico
  Accept: image/webp,image/apng,image/*,*/*;q=0.8
  Status: 200 OK 0.00035s
 
cs


pgAdmin을 통해 해당 테이블들이 정상적으로 생성되었음을 확인할 수 있다.




크롬에서 로딩한 모습이다. 



참고

1
2
3
4
5
6
7
(blackbriar) root@gcloudx:~# stack exec -- which ghc
/root/.stack/programs/x86_64-linux/ghc-8.0.2/bin/ghc
(blackbriar) root@gcloudx:~# stack exec which runghc
/root/.stack/programs/x86_64-linux/ghc-8.0.2/bin/runghc
(blackbriar) root@gcloudx:~# stack exec -- runghc --version
runghc 8.0.2
 
cs