如何使用docker和docker-compose启动Gatsby项目?

1,412 阅读4分钟

SPA 的不足

我们使用React将大多数前端构建为单页Javascript应用(SPA),因为我们绝对喜欢这种网站的类似于桌面的用户体验。 虽然这种技术提供了很好的用户界面,但是与传统的网站相比,它有很大的缺点。在传统的网站中,整个网站(或者至少大部分,如果涉及到Ajax)是由服务器呈现的。

  • 对于单个页面的Javascript应用程序,加载第一个页面通常要花费更长的时间,因为必须先加载Javascript资产,然后构建DOM,网站才会正常显示。
  • 谷歌通常不像常规站点那样索引SPA好和快,因为谷歌严重影响了页面加载速度。乍一看,这似乎是矛盾的,因为谷歌使用Angular大量驱动spa。但问题更严重:即使是谷歌也不能准确地知道页面何时被完全加载,因为将来可能会有更多的内容。发送报头的服务器不再意味着所有的内容都在那里。对于谷歌来说,等待更多内容的到来是非常昂贵的,因为它们的爬虫依赖于速度。

服务器端渲染(SSR)结合了这两个方面的优点

  • 有一个网络服务器,预先呈现的 SPA 网页,类似用户浏览器将做的事。
  • 当一个页面被请求时,服务器会像传统的 web 服务器那样提供预渲染的 HTML (而不是像大多数 React 应用那样提供一个相当空的索引页面)。
  • 浏览器即时显示已渲染的网站,从而有一个超快的首页加载。
  • 在后台加载 Javascript 资源,当它们完全加载时,反应渲染器接管 DOM。
  • 如果用户现在点击一个链接,SPA 路由器启动,用户享受 SPA 用户体验,而不需要重新加载整个页面。

目前最常用的React框架是Gatsby和Next.js。

通过docker和docker-compose运行一个Gatsby项目

通常人们会在Netlify上托管他们的Gatsby网站,这绝对是一个不错的选择。但是,出于各种原因,您可能希望运行基于docker和docker compose的自己的设置,例如在您自己的基础设施中托管它(例如为了成本、数据安全性、监控等),或者在docker-compose中。

首先,我们创建一个定义镜像的Dockerfile:

# base image
FROM node:11

# set working directory
RUN mkdir /app
WORKDIR /app

# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH

# install and cache app dependencies using yarn
ADD package.json yarn.lock /app/
RUN yarn --pure-lockfile

# Copy all frontend stuff to new "app" folder
COPY . /app/

ENTRYPOINT ["sh", "./run.sh"]

EXPOSE 9000

原文用的 CMD ["./run.sh"] ,会因权限问题报错。

run.sh的内容可以是这样的:

#!/bin/bash
node_modules/.bin/gatsby build
node_modules/.bin/gatsby serve -H 0.0.0.0

原文用到 ts-node ,这里省去。

多说一句,请耐心等待镜像的构建,30分钟以内都应该是可接受的。

每当运行我们的新docker镜像(本地或在我们的服务器上)时,我们首先执行gatsby构建命令。这将构建Javascript和CSS包,并生成我们的静态站点。

接下来,我们通过运行Gatsby serve启动内置的Gatsby服务器。附加的-H选项将默认值从localhost更改为0.0.0.0,因为在docker-compose网络中,localhost位于容器中,本地浏览器无法访问它。

接下来,我们定义docker-composition.yml:

version: "3.7"

services:
  frontend:
    depends_on:
      - backend
    build: ./frontend # link to subfolder of mono-repo
    command: ts-node node_modules/.bin/gatsby develop -H 0.0.0.0 -p 3000
    volumes:
      - ./frontend:/app
    restart: "no"
    # allows the frontend to access the backend at localhost, which allows Gatsby to access the api
    # and the Api to include localhost:8000 (and not backend:8000) in the image paths.
    network_mode: "service:backend"
  backend:
    # You could define your backend service here.

有趣的部分是network_mode:在我们的例子中,Gatsby应用访问我们后端的api来创建页面。 通常在docker网络中,我们会使用类似 http://backend:8000/ api的URL来访问在docker网络中运行后端的容器。 如果后端使用请求(例如生成镜像的完整路径等),则可能导致问题,因为您的本地浏览器无法从docker网络外部访问后端。 因此,我们将network_mode设置为与后端在同一网络内。 现在,我们可以使用localhost访问后端的api。

现在可以运行docker-compose up来启动docker网络并在本地进行开发。您还可以使用Gatsby docker映像在服务器或容器编制(如Kubernetes)中运行应用程序。

我希望这篇文章能帮助到一些人,并期待你们的意见、回复和掌声。

译自:medium.com/ambient-inn…