LISP和Web:通过LISP和GCE创建Web应用程序

2021-04-16 15:06:27

这是一个非常快的(给定单词长度听起来像轻描淡写;但是,鉴于主题的复杂性,是真实的)通过Google Compute Engine上的Lisp Web服务器实现Web应用程序的指南。 Hunchentoot将是我们的服务器。

我们的服务器将连接到PostgreSQL数据库,以执行创建,读取,更新和删除操作,我将为潜行峰值提供存储和验证用户。

我可以在未来编写一个更详细的指南,但现在我只是记录了我的设置说明。假设熟悉常见的LISP和EMACS。道歉如果下面缺乏解释,它非常一步一步一步参考(主要是对我!)。

如果您喜欢该指南,请明白押回报,并在此处留下评论,让我知道它是否适合您。希望它做到了。

首先,登录GCE控制台(如果您没有,则创建帐户)。选择“创建实例”如下所示:

然后,您需要输入实例的名称和其他设置。目前,输入名称,将引导磁盘更改为Ubuntu 20.04 LTS,然后选择允许HTTP流量并允许HTTPS流量:

注释在右上方有估计每月费用。我相信新的木匠获得了300美元的GCE学分,但是,使用GCE不是免费或便宜的,只能在您有实际项目时使用。最好在您的本地机器上免费进行大部分原型和开发,然后在您准备部署时迁移到GCE。

单击“管理”,“安全性,磁盘”,“网络”,“唯一租赁”链接到页面底部并导航到“网络”选项卡。单击网络接口下的下拉列表:

现在我们将通过在外部IP下选择创建IP地址来切换到静态IP:

这会带来一个菜单,您可以在其中输入静态IP的名称(这不是您的IP地址,只是一个标识符)。

单击“保留”后,将分配给您静态IP,此后可以看到哪个:

GCE将需要一分钟左右才能初始化您的实例。一旦完成这一点,如下SSH。

$ curl -o https://beta.quicklisp.org/quicklisp.lisp $ curl -o https://beta.quicklisp.org/quicklisp.lisp.asc $ sbcl - reload quicklisp.lisp然后在提示时(在" *"提示,即时在安装中有暂停):*(QuickLisp-QuickStart:安装)*(QL:System-Apropos" Vecto")*(QL: Quickload" vecto")*(ql:add-to-init-file)[按Enter] *(退出)

现在,我们需要安装粘液,这是在Emacs上构建的惊人的常见的Lisp IDE。首先登录EMACS:

现在通过将以下内容添加到您的.macs文件中来安装Melpa存储库,然后通过C-X C-S保存:

然后用m-x包刷新内容或m-x包列表包刷新包列表(后者为我工作)。我也必须用C-X C-C退出我的Emacs,然后再次运行它(即重新启动它以允许上述效果),但也许您不需要。

然后通过m-x包 - 列表转到包列表,然后向下滚动到粘液(由于您在终端中,鼠标可能无法正常工作。我用页面向下快速滚动)。按Slime键进入键移动到安装页面,从您可以在[Install]上以便安装以安装它。按键Enter On,我的意思是您需要将光标移动到单词,然后按Enter键。

您可能需要导航到具有[安装]文本的窗口。为此,请键入c-x o(在可用窗口之间交替)。这一切可能有点震动,因为你不是在GUI中,但从长远来看,它会让你更好地用emacs快捷方式:)(第5页)

此时,您的.macs文件应该看起来像这样的东西(我删除了可能出现在您的版本中的注释行):

重启Emacs。现在尝试m-x slime,看看它是否会带来lisp repl。用以下内容测试:

它应该下载并加载Hunchentoot包。如果这两个项目中的任何一个不起作用或者您获得错误,则需要Google并在继续之前修复它。

现在让我们快速完成一些PostgreSQL基础知识,并设置一个我们将在Web服务器中使用的数据库。 您可以在其中输入postgreSQL命令。 您可以通过在提示符下键入退出时退出PostgreSQL: 现在我们可以创建用户,例如, TestUser,来自Ubuntu的终端: 它将提出一个提示输入密码,现在请使用MyPassword作为我们的示例Lisp Server将使用此密码访问我们的数据库。 PSQL是基于终端的前端到PostgreSQL。 我们可以通过在Postgres提示符下输入PSQL来登录IT: PostgreSQL权限和访问设置有时会变得复杂。 然而,下面应该有效地登录PostgreSQL作为普通用户(例如,我们创建的测试程序): 以下命令用于启动,停止和重新启动PostgreSQL服务。 请注意,重新加载用于重新加载配置而不停止服务。

$ sudo service postgresql start $ sudo service postgresql stop $ sudo service postgresql重新启动$ sudo service postgresql重新加载

看到在VM实例上运行的后台进程非常有用。我们可以用以下方式执行此操作,可以使用F10退出。

现在是时候安装了Lisp服务器。我们将使用的代码是vetle Roeim在普通LISP中实施博客的优秀指南的适应,这是向普通LISP引入我的指南。他的指导更详细,有一个值得注意的是自己的权利。但是我已经将它调整为postgreSQL,所以我建议您阅读他的指南,并使用我的代码。

请注意,我的指南的目的不是通过常见的LISP教授或走路。也就是说,如果你仔细阅读我们将使用的代码,你将学习它的工作方式。它实际上非常简单(一旦你掌握了东西)。

如果您的语言是新的,您可以阅读我的介绍式指南或互联网上可用的许多免费材料之一。

让我们现在将文件复制到我们的主目录中,例如,通过如下内容(在我们的主目录文件夹中输入时)

打开Emacs,并启动与m-x slime的新粘液会话。然后,您可以直接从REPP加载我们的Web服务器文件:

您第一次执行此项将需要一点时间,因为QuickLisp将下载所有必要的依赖项。如果一切成功,则不应收到任何错误消息。我们的服务器现在在端口4242上生活(我们在代码中指定端口)。

我们的示例repo是非常基本的代码,没有错误检查和amp;管理。它在我们之前创建的TestDB中创建了一个table mybloftable,然后插入一些记录。因此,每次我们重新加载服务器时,我们都会收到错误,说明表格和这些记录已经存在。只需读取错误提示并选择“忽略错误”,例如选择1中的选择以继续。

这并不漂亮,但我不想在这个阶段增加对文件的太多复杂性,而且您现在也有Lisp中的Live调试经验。

假设上面没有错误,我们的Web服务器已启动并运行,但我们无法查看它。这将很难做到,因为我们目前仅在我们的远程会话中终端模式到我们的GCE实例中。我们现在将向世界开辟我们的服务器并从公共互联网上访问它。

目前,我们的LISP服务器可在LocalHost:4242上访问。我们将使用nginx作为另一个服务器将Lisp Web服务器连接到Internet。此过程称为反向代理。我们使用nginx,因为当我们添加SSL证书时,它会让我们的生活更轻松。

首先,在不关闭我们现有的远程会话时,将新的SSH会话启动到VM计算机中。虽然我们所处,请注意我们的VM机器的外部IP地址(例如,它是35.224.222.114。您将拥有不同的IP,由GCE分配给您)。

nginx将其配置文件存储在/ etc / nginx /启用站点/默认值中。让我们用以下删除此文件:

将以下代码粘贴到此文件中。我们现在可以忽略“example.com”位,我们将稍后改变。请注意,端口80用于HTTP访问,虽然端口443用于HTTPS访问。我们将在下一节上到达HTTPS。

服务器{听80; server_name example.com;位置/ {proxy_set_header X-Forthing-for for $ remote_addr; proxy_set_header htth_host; proxy_pass http://127.0.0.1:4242; }}

现在,我们希望通过以下Symlink在可用的站点中启用启用站点的配置文件(其中nginx查找)到上面的文件中的上述文件:

作为最后一步,重新启动nginx服务器以获取配置文件以生效:

让我们现在测试一切!从早期调用VM实例的IP地址(或检查GCE控制台),打开浏览器并导航到http://外部IP地址/。例如。对我来说是:

我们的Web服务器非常鞍骨,但功能。我们现在将展示如何使用博客文章作为示例创建,查看和编辑数据库条目。

如果您导航到http://外部IP地址/创建/,则可以将条目添加到数据库。对我来说,这是:http://35.224.222.114/create/

您现在应该收到以下错误(如下所示,我创建了一个标题“test”的条目),因为我们的Web服务器已将您重定向到LocalHost而不是实际的外部IP地址:

目前,我们可以通过在http://外部IP-address / View / View / [标题]中键入http:// title-of post of post:http://35.224.2222.114/查看/?测试)。您还可以从我们服务器的主页查看帖子。

除了创建它们,编辑条目非常相似,除此之外您改为导航到http://外部IP地址/编辑/。另请注意,编辑只能在存在的条目上工作,并且对不存在的条目没有影响。

上面的问题与我们的LISP服务器重定向到Localhost,这是无法访问的Publicy令人讨厌和交易破坏者。有两种方法存在这一点。

更新博客-server.lisp中的代码以引用我们的外部IP地址而不是LocalHost。在我的示例中,我会将代码片段更新为以下内容,例如:注意,这不是需要进行此更改的唯一位置,您将能够在阅读代码时弄清楚它) :

(Defun Save-new-blog-post()"读取帖子数据和修改博客文章。"(insert-recort:post-parameter"标题(hunchentoot:post-parameter&# 34;身体"))(hunchentoot:重定向(格式零" http:// 35.224.222.14/view/?~"(make-url-part(hunchentoot:post-parameter&#34 ;标题"))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))

现在让我向你展示一个Lisp的美女之一。在进行上述更改后,您可以通过导航到其结束并输入C-X C-e来简单地重新评估上述功能而无需重新启动您的LISP服务器。如果您现在尝试创建一个新的博客条目,则服务器将自动指向外部IP地址而不是localhost。无需重新编译或停止服务器!

选项2与选项1相同,但使用实际域如下。在这里,我将使用我自己的一个域,你需要用你拥有的域替换它。

(Defun Save-new-blog-post()"读取帖子数据和修改博客文章。"(insert-recort:post-parameter"标题(hunchentoot:post-parameter&# 34;身体"))(Hunchentoot:重定向(格式零" https://ashok-khanna.com/? ~a"(make-url-part(hunchentoot:post-parameter&#34 ;标题"))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))

作为选项2的一部分,我们需要将我们的域链接到我们的外部IP地址,这是下一节的主题。注意如何将上面编辑到HTTPS,我们还将在下一节中添加SSL安全性。

我们现在将域附加到我们的IP地址。要执行此部分,您需要拥有域名。我将使用我的域Ashok-khanna.com在本指南中,每当您看到此时,用自己的域替换它。另请注意,我使用我强烈推荐的Google域,但是您应该能够轻松地调整如果它不同的注册商的步骤。

我们还将为我们的服务器使用CloudFlare。 CloudFlare坐在网站访问者和我们的Web服务器之间,提供宝贵的缓存和速度改进,从而降低我们服务器的整体负载(因此他们的成本!)。 CloudFlare还为我们提供了一些基本的服务器端分析和整体生活质量改进。

现在,转到您的注册商(Google域为我),并使这些名称服务器更改。您可能会提示您关闭DNSSEC,只接受所有提示。

完成此操作后,返回CloudFlare并选择“完成”检查“名称服务器”。请注意,名称服务器更改可能需要一些时间,因此只需耐心等待。

剩余的设置不应该,只需选择默认值。现在只需等待一点,直到名称服务器更改生效,CloudFlare确认我们的网站在其平台上处于活动状态。一旦处于活动状态,它应该如下所示:

我们现在将使用CESTBOT在VM实例上设置SSL证书。这部分有点挑剔,因此我们使用nginx作为我们的反向代理服务器,以尽可能地简化它。

服务器{听80; server_name www.ashok-khanna.com Ashok-khanna.com;位置/ {proxy_set_header X-Forthing-for for $ remote_addr; proxy_set_header htth_host; proxy_pass http://127.0.0.1:4242; }}

请注意,虽然上面仅在端口80(http)上侦听我们使用的Certbot实用程序,但我们不久将更新以上代码以正确考虑端口443(HTTPS)。

我发现指南的这一部分有点挑剔,当我偏离我们这里讨论的路径时,有一些错误。虽然谷歌是你最好的朋友,但我发现在它有错误时卸载,清除和重新安装nginx非常有帮助。这可以通过输入以下命令来实现,然后重复上述6.2和8.2的步骤。

不要现在,但如果你有nginx问题,那绝对会尝试一下。

我们现在回到CloudFlare。我们现在将添加DNS记录以将域名指向我们的域名。有两种主要的记录类型:

当IP已知且稳定时,记录将名称映射到一个或多个IP地址

CNAME记录将名称映射到另一个名称。只有在该名称上没有其他记录时,应该使用它

在这种情况下,我们将添加一个记录。导航到CloudFlare中的“DNS”,然后选择“添加记录”:

添加以下两个记录,然后单击“保存”。您在这些记录中输入的IP地址是VM实例的IP地址(下面是我实例的示例)。请注意,对于www.ashok-khanna.com,我们将以Ashok-khanna.com(即root域)输入www作为名称,而我们将在@作为名称中输入@。

我们现在将通过CESTBOT设置我们的SSL证书。首先,导航到CloudFlare中的SSL / TLS页面,并确保加密模式设置为“灵活”:

然后用以下运行certbot。系统将提示您输入电子邮件(输入IT),以同意服务条款(同意),无论您是否希望与电子前沿基金会(EFF)共享的电子邮件地址(您的选择)。

然后,您将提示您选择要激活的名称来激活HTTPS。按ENTER选择两者:

假设您正确设置了一个记录并正确配置了CloudFlare(非常仔细阅读上述步骤),CertBot将成功生成SSL证书并提示您是否希望HTTP到HTTPS重定向 - 通过输入2选择“是”,然后输入:

恭喜!您的SSL证书即将生存。请注意,SSL证书将过期,因此您可能需要再次生成它,请参阅以下注释。但是,我相信它将在我们的设置中自动续订。

一旦我们设置了SSL证书,导航回CloudFlare并将SSL / TLS认证更改为“完整”:

现在的真理瞬间 - 导航到您的域,看看一切是否正常工作。如果没有,请阅读以上和调试。测试WWW和非WWW版本,并注意到所有请求现在都通过HTTPS固定。

作为倒数第二项,让我们查看一些示例代码来添加用户并将它们验证到我们的Web应用程序。下面是莱德德的临尼比诺博国礼貌。我在我们的示例Repo中的版本中将端口从8000到4242更改为4242。

重新审视您的自定义域并使用我们的新服务器播放。再次,它是非常鞍的,但如果你学习代码,你将能够弄清楚很多东西以及如何将其扩展有用。这里有很多有用的代码,包括哈希密码和inveling hunchentoot的易于处理程序。

目前,只要服务器即时,添加的任何用户都只会存在。一个建议是将用户存储在数据库表中,从而允许您对用户及其密码保持持久存储。

作为最终项目,让我们添加能够为我们的服务器提供服务静态网站。 repo中的示例代码已更新,但基本上我们需要将以下内容设置为静态文件的位置(在我们的情况下,我们将静态文件存储在我们的主目录中的文件夹中的静态文件)。

;主------(setf web-server(hunchentoot:start(make-cornelt' hunchentoot:easy-conceptor:地址" 127.0.0.1":端口4242:文件 - root #pp" www _ /":persistent-connections-p t:read-timeout 3.0:write-timeout 3.0:access-log-destination nil:message-log-destination nil))))

请注意,在我们的示例repo中,我们在www_文件夹中有两个文件,test.html和index.html。通常,index.html文件被加载为网站的默认文件。但是,在我们的示例代码中,这是下面覆盖的(如果删除下面,index.html将再次成为默认主页):

(hunchentoot:define-searm-handler(索引:uri" /")(setf(hunchentoot:content-type *)" text / html")(:( -User(hunchentoot:session-value:用户)))(格式nil"< h4>欢迎 - 到 - 小演示< / h4>< ht;<>信息:〜a< a< a ; / p>< p> user:〜a< / p>< href = \" /注册\">点击此处与注册< / a> < br>< href = \" /登录\">点击这里点击< / a>< br>< a href = \&# 34; /签出\">点击此处 - 到退出< / a>< br>"信息-USER)))

我们的示例服务器非常棒,但包含了构建非常高级的Web应用程序的所有原始功能。

您可以看到我们需要加入这么多的不同部分来构建Web应用程序。希望上面有帮助,你现在可以专注于有趣的东西 - 建立实际的网页和应用!