You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
(format *error-output* "~&An error occured: ~a~&" c)
37
+
(uiop:quit 1)))
38
+
~~~
39
+
40
+
In addition we have allowed the user to set the application's port
41
+
with an environment variable.
42
+
43
+
We can run the file like so:
44
+
45
+
sbcl --load run.lisp
46
+
47
+
After loading the project, the web server is started in the
48
+
background. We are offered the usual Lisp REPL, from which we can
49
+
interact with the running application.
50
+
51
+
We can also connect to the running application from our preferred
52
+
editor, from home, and compile the changes in our editor to the
53
+
running instance. See the following section:
54
+
[connecting to a remote lisp image](https://lispcookbook.github.io/cl-cookbook/debugging.html#remote-debugging) on the Cookbook.
55
+
56
+
57
+
### Building a self-contained executable
58
+
59
+
{{% notice info %}}
60
+
See the tutorial.
61
+
{{% /notice %}}
62
+
63
+
As for all Common Lisp applications, we can bundle our web app in one
64
+
single executable, including the assets. It makes deployment very
65
+
easy: copy it to your server and run it.
66
+
67
+
```
68
+
$ ./my-web-app
69
+
Hunchentoot server is started.
70
+
Listening on localhost:9003.
71
+
```
72
+
73
+
See this recipe on [scripting#for-web-apps](scripting.html#for-web-apps).
74
+
75
+
As for any executable, you need this in your .asd file:
76
+
77
+
~~~lisp
78
+
:build-operation "program-op" ;; leave as is
79
+
:build-pathname "<binary-name>"
80
+
:entry-point "<my-package:main-function>"
81
+
~~~
82
+
83
+
and you build the binary with `(asdf:make :myproject)`.
84
+
85
+
However, you might find that as soon as you start your app, its
86
+
stops. That happens because the server thread is started in the background, and nothing tells the binary to wait for it. We can simply sleep (for a large-enough amount of time).
87
+
88
+
89
+
~~~lisp
90
+
(defun main ()
91
+
(start-app :port 9003) ;; our start-app
92
+
;; keep the binary busy in the foreground, for binaries and SystemD.
93
+
(sleep most-positive-fixnum))
94
+
~~~
95
+
96
+
If you want to learn more, see… [the Cookbook: scripting, command line arguments, executables](https://lispcookbook.github.io/cl-cookbook/scripting.html).
(format *error-output* "~&An error occured: ~a~&" c)
35
-
(uiop:quit 1)))
36
-
~~~
37
-
38
-
In addition we have allowed the user to set the application's port
39
-
with an environment variable.
40
-
41
-
We can run the file like so:
42
-
43
-
sbcl --load run.lisp
44
-
45
-
After loading the project, the web server is started in the
46
-
background. We are offered the usual Lisp REPL, from which we can
47
-
interact with the running application.
48
-
49
-
We can also connect to the running application from our preferred
50
-
editor, from home, and compile the changes in our editor to the
51
-
running instance. See the following section:
52
-
[connecting to a remote lisp image](https://lispcookbook.github.io/cl-cookbook/debugging.html#remote-debugging) on the Cookbook.
53
-
54
-
55
-
### Building a self-contained executable
56
-
57
-
As for all Common Lisp applications, we can bundle our web app in one
58
-
single executable, including the assets. It makes deployment very
59
-
easy: copy it to your server and run it.
60
-
61
-
```
62
-
$ ./my-web-app
63
-
Hunchentoot server is started.
64
-
Listening on localhost:9003.
65
-
```
66
-
67
-
See this recipe on [scripting#for-web-apps](scripting.html#for-web-apps).
68
-
69
-
As for any executable, you need this in your .asd file:
70
-
71
-
~~~lisp
72
-
:build-operation "program-op" ;; leave as is
73
-
:build-pathname "<binary-name>"
74
-
:entry-point "<my-package:main-function>"
75
-
~~~
76
-
77
-
and you build the binary with `(asdf:make :myproject)`.
78
-
79
-
However, you might find that as soon as you start your app, its
80
-
stops. That happens because the server thread is started in the background, and nothing tells the binary to wait for it. Let's do it by putting the server thread in the foreground.
81
-
82
-
You need the `bordeaux-threads` library, which as the `bt` global nickname.
83
-
84
-
~~~lisp
85
-
(defun main ()
86
-
(start-app :port 9003) ;; our start-app
87
-
;; let the webserver run.
88
-
;; note: we hardcoded our webserver name, "hunchentoot" here.
(error (c) (format t "Woops, an unknown error occured:~&~a~&" c))))
103
-
~~~
104
-
105
-
If you want to learn more, see… [the Cookbook: scripting, command line arguments, executables](https://lispcookbook.github.io/cl-cookbook/scripting.html).
106
-
107
-
108
-
<!-- ### Multi-platform delivery with Electron -->
109
-
110
-
<!-- [Ceramic](https://ceramic.github.io/) makes all the work for us. -->
111
-
112
-
<!-- It is as simple as this: -->
113
-
114
-
<!-- ~~~lisp -->
115
-
<!-- ;; Load Ceramic and our app -->
116
-
<!-- (ql:quickload '(:ceramic :our-app)) -->
117
-
118
-
<!-- ;; Ensure Ceramic is set up -->
119
-
<!-- (ceramic:setup) -->
120
-
<!-- (ceramic:interactive) -->
121
-
122
-
<!-- ;; Start our app (here based on the Lucerne framework) -->
<!-- and we can ship this on Linux, Mac and Windows. -->
133
-
134
-
<!-- There is more: -->
135
-
136
-
<!-- > Ceramic applications are compiled down to native code, ensuring both performance and enabling you to deliver closed-source, commercial applications. -->
@@ -160,7 +32,7 @@ Here's [a cheatsheet](https://tmuxcheatsheet.com/) that was handy.
160
32
Unfortunately, if your app crashes or if your server is rebooted, your apps will be stopped. We can do better.
161
33
162
34
163
-
###SystemD: daemonizing, restarting in case of crashes, handling logs
35
+
## SystemD: daemonizing, restarting in case of crashes, handling logs
164
36
165
37
This is actually a system-specific task. See how to do that on your system.
166
38
@@ -209,7 +81,7 @@ to enable it:
209
81
sudo systemctl enable my-app.service
210
82
211
83
212
-
###With Docker
84
+
## With Docker
213
85
214
86
There are several Docker images for Common
215
87
Lisp. For example:
@@ -223,17 +95,52 @@ is CentOs based and contains the source for building a Quicklisp based
223
95
Common Lisp application as a reproducible docker image using OpenShift's
224
96
source-to-image.
225
97
98
+
### Running behind Nginx
99
+
100
+
There is nothing CL-specific to run your Lisp web app behind Nginx. Here's an example to get you started.
101
+
102
+
We suppose you are running your Lisp app on a web server, with the IP
103
+
address 1.2.3.4, on the port 8001. Nothing special here. We want to
104
+
access our app with a real domain name (and eventuall benefit of other
105
+
Nginx's advantages, such as rate limiting etc). We bought our domain
106
+
name and we created a DNS record of type A that links the domain name
107
+
to the server's IP address.
108
+
109
+
We must configure our server with Nginx to tell it that all
110
+
connections coming from "your-domain-name.org", on port 80, are to be
111
+
sent to the Lisp app running locally.
112
+
113
+
Create a new file: `/etc/nginx/sites-enabled/my-lisp-app.conf` and add this proxy directive:
114
+
115
+
~~~lisp
116
+
server {
117
+
listen www.your-domain-name.org:80;
118
+
server_name your-domain-name.org www.your-domain-name.org; # with and without www
119
+
location / {
120
+
proxy_pass http://1.2.3.4:8001/;
121
+
}
122
+
123
+
# Optional: serve static files with nginx, not the Lisp app.
124
+
location /files/ {
125
+
proxy_pass http://1.2.3.4:8001/files/;
126
+
}
127
+
}
128
+
~~~
226
129
227
-
### With Guix
130
+
Note that on the proxy_pass directive: `proxy_pass
131
+
http://1.2.3.4:8001/;` we are using our server's public IP
132
+
address. Often, your Lisp webserver such as Hunchentoot directly
133
+
listens on it. You might want, for security reasons, to run the Lisp
134
+
app on localhost.
228
135
229
-
[GNU Guix](https://www.gnu.org/software/guix/) is a transactional
230
-
package manager, that can be installed on top of an existing OS, and a
231
-
whole distro that supports declarative system configuration. It allows
232
-
to ship self-contained tarballs, which also contain system
233
-
dependencies. For an example, see the [Nyxt browser](https://github.com/atlas-engineer/nyxt/).
136
+
Reload nginx (send the "reload" signal):
234
137
138
+
$ nginx -s reload
235
139
236
-
### Deploying on Heroku and other services
140
+
and that's it: you can access your Lisp app from the outside through `http://www.your-domain-name.org`.
141
+
142
+
143
+
## Deploying on Heroku and other services
237
144
238
145
See [heroku-buildpack-common-lisp](https://gitlab.com/duncan-bayne/heroku-buildpack-common-lisp) and the [Awesome CL#deploy](https://github.com/CodyReichert/awesome-cl#deployment) section for interface libraries for Kubernetes, OpenShift, AWS, etc.
239
146
@@ -244,30 +151,8 @@ See [Prometheus.cl](https://github.com/deadtrickster/prometheus.cl)
244
151
for a Grafana dashboard for SBCL and Hunchentoot metrics (memory,
245
152
threads, requests per second,…).
246
153
247
-
## Connecting to a remote Lisp image
248
-
249
-
This this section: [debugging#remote-debugging](https://lispcookbook.github.io/cl-cookbook/debugging.html#remote-debugging) on the Cookbook.
250
-
251
-
## Hot reload
154
+
See [cl-sentry-client](https://github.com/mmontone/cl-sentry-client/) for error reporting.
252
155
253
-
This is an example from [Quickutil](https://github.com/stylewarning/quickutil/blob/master/quickutil-server/). It is actually an automated version of the precedent section.
0 commit comments