feat: 显示文章 metadata 中的 images。
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
45af8732c0
commit
d7c65cf444
@ -17,12 +17,32 @@
|
|||||||
// Configure properties specific to VS Code.
|
// Configure properties specific to VS Code.
|
||||||
"vscode": {
|
"vscode": {
|
||||||
// Add the IDs of extensions you want installed when the container is created.
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
"extensions": ["dbaeumer.vscode-eslint"]
|
"extensions": [
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"formulahendry.auto-rename-tag",
|
||||||
|
"aaron-bond.better-comments",
|
||||||
|
"bierner.color-info",
|
||||||
|
"ldez.ignore-files",
|
||||||
|
"gooooloo.smartquote",
|
||||||
|
"wmaurer.change-case",
|
||||||
|
"streetsidesoftware.code-spell-checker",
|
||||||
|
"naumovs.color-highlight",
|
||||||
|
"EditorConfig.EditorConfig",
|
||||||
|
"mhutchie.git-graph",
|
||||||
|
"donjayamanne.githistory",
|
||||||
|
"ecmel.vscode-html-css",
|
||||||
|
"yzhang.markdown-all-in-one",
|
||||||
|
"christian-kohler.path-intellisense",
|
||||||
|
"esbenp.prettier-vscode",
|
||||||
|
"shardulm94.trailing-spaces",
|
||||||
|
"lihui.vs-color-picker",
|
||||||
|
"bradlc.vscode-tailwindcss"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
// "forwardPorts": [],
|
"forwardPorts": [3000],
|
||||||
|
|
||||||
// Use 'postCreateCommand' to run commands after the container is created.
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
// "postCreateCommand": "yarn install",
|
// "postCreateCommand": "yarn install",
|
||||||
@ -35,5 +55,6 @@
|
|||||||
},
|
},
|
||||||
"mounts": [
|
"mounts": [
|
||||||
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,type=bind,consistency=cached"
|
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,type=bind,consistency=cached"
|
||||||
]
|
],
|
||||||
|
"postStartCommand": "npm ci && npm run dev"
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,10 @@ date: '2022-09-23'
|
|||||||
tags: ['Verdaccio', 'Self-Hosted', 'Docker', 'Caddy', 'registry', 'Node.js']
|
tags: ['Verdaccio', 'Self-Hosted', 'Docker', 'Caddy', 'registry', 'Node.js']
|
||||||
draft: false
|
draft: false
|
||||||
summary: 作为靠着 JavaScript 生态吃饭的 Web 开发者,自建一个 Node regsitry 是很有必要的,我这次继续选择 Verdaccio 来搭建存储库。这次使用 Docker Compose 部署 Verdaccio,并将 Caddy 用于反向代理该服务。
|
summary: 作为靠着 JavaScript 生态吃饭的 Web 开发者,自建一个 Node regsitry 是很有必要的,我这次继续选择 Verdaccio 来搭建存储库。这次使用 Docker Compose 部署 Verdaccio,并将 Caddy 用于反向代理该服务。
|
||||||
|
images:
|
||||||
|
[
|
||||||
|
'https://pan.ivanli.cc/api/v3/file/source/2233/verdaccio.png?sign=qpoeADXzbhHk2MY5CehgTftUJ67pnUj-Ylko9D5jscU%3D%3A0',
|
||||||
|
]
|
||||||
---
|
---
|
||||||
|
|
||||||
## 为何自建存储库?
|
## 为何自建存储库?
|
||||||
@ -19,12 +23,14 @@ summary: 作为靠着 JavaScript 生态吃饭的 Web 开发者,自建一个 No
|
|||||||
## 如何自建存储库
|
## 如何自建存储库
|
||||||
|
|
||||||
已有环境:
|
已有环境:
|
||||||
- Docker, Docker Compose
|
|
||||||
- Caddy (in Docker)
|
- Docker, Docker Compose
|
||||||
|
- Caddy (in Docker)
|
||||||
- 网络:`caddy`
|
- 网络:`caddy`
|
||||||
|
|
||||||
新增:
|
新增:
|
||||||
- Verdaccio
|
|
||||||
|
- Verdaccio
|
||||||
|
|
||||||
接下来使用 Docker Compose 部署 Verdaccio,并将其加入到 `caddy` 网络中,之后配置 Caddy,使其反向代理 Verdaccio。
|
接下来使用 Docker Compose 部署 Verdaccio,并将其加入到 `caddy` 网络中,之后配置 Caddy,使其反向代理 Verdaccio。
|
||||||
|
|
||||||
@ -33,7 +39,7 @@ summary: 作为靠着 JavaScript 生态吃饭的 Web 开发者,自建一个 No
|
|||||||
创建文件 `docker-compose.yml`:
|
创建文件 `docker-compose.yml`:
|
||||||
|
|
||||||
```yml {9,16-17} showLineNumbers
|
```yml {9,16-17} showLineNumbers
|
||||||
version: "3,16-17"
|
version: '3'
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
caddy:
|
caddy:
|
||||||
@ -48,8 +54,8 @@ services:
|
|||||||
- caddy
|
- caddy
|
||||||
expose:
|
expose:
|
||||||
- 4873
|
- 4873
|
||||||
# environment:
|
# environment:
|
||||||
# VERDACCIO_PUBLIC_URL: "https://node-registry.ivanli.cc"
|
# VERDACCIO_PUBLIC_URL: "https://node-registry.ivanli.cc"
|
||||||
volumes:
|
volumes:
|
||||||
- ./verdaccio:/verdaccio/conf
|
- ./verdaccio:/verdaccio/conf
|
||||||
- verdaccio-storage-data:/verdaccio/storage
|
- verdaccio-storage-data:/verdaccio/storage
|
||||||
@ -60,7 +66,7 @@ volumes:
|
|||||||
verdaccio-plugins-data:
|
verdaccio-plugins-data:
|
||||||
```
|
```
|
||||||
|
|
||||||
上面第 9 行可以看到,我现在(2022年09月22日)是使用不是正式版本,因为当前的正式版有个缺陷,就是无法正确读取到反向代理提供的 `X-Forwarded-Proto`,这有可能导致访问问题。如果使用正式版本,需要加上第 17 行的环境变量。
|
上面第 9 行可以看到,我现在(2022 年 09 月 22 日)是使用不是正式版本,因为当前的正式版有个缺陷,就是无法正确读取到反向代理提供的 `X-Forwarded-Proto`,这有可能导致访问问题。如果使用正式版本,需要加上第 17 行的环境变量。
|
||||||
|
|
||||||
**不要启动 compose**,因为你还没有配置文件。当然启动了也没关系,无伤大雅。
|
**不要启动 compose**,因为你还没有配置文件。当然启动了也没关系,无伤大雅。
|
||||||
|
|
||||||
@ -68,6 +74,7 @@ volumes:
|
|||||||
|
|
||||||
因为前面将配置文件目录 `verdaccio/conf` 设为了 `verdaccio`,所以:
|
因为前面将配置文件目录 `verdaccio/conf` 设为了 `verdaccio`,所以:
|
||||||
创建配置文件 `verdaccio/config.yaml`:
|
创建配置文件 `verdaccio/config.yaml`:
|
||||||
|
|
||||||
```zsh {1,2} showLineNumbers
|
```zsh {1,2} showLineNumbers
|
||||||
storage: /verdaccio/storage
|
storage: /verdaccio/storage
|
||||||
plugins: /verdaccio/plugins
|
plugins: /verdaccio/plugins
|
||||||
@ -107,6 +114,7 @@ web:
|
|||||||
因为我们使用了 `bcrypt` 算法保存密码,所以可以借助 [Bcrypt-Generator.com](https://bcrypt-generator.com/) 生成保存的密码。
|
因为我们使用了 `bcrypt` 算法保存密码,所以可以借助 [Bcrypt-Generator.com](https://bcrypt-generator.com/) 生成保存的密码。
|
||||||
|
|
||||||
创建文件:`verdaccio/htpasswd`:
|
创建文件:`verdaccio/htpasswd`:
|
||||||
|
|
||||||
```htpasswd
|
```htpasswd
|
||||||
admin:$2a$12$9xxxxxxxxxxxxxxlO.slh2k2
|
admin:$2a$12$9xxxxxxxxxxxxxxlO.slh2k2
|
||||||
```
|
```
|
||||||
|
@ -7,18 +7,44 @@ import Tag from '@/components/Tag'
|
|||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
import Comments from '@/components/comments'
|
import Comments from '@/components/comments'
|
||||||
import ScrollTopAndComment from '@/components/ScrollTopAndComment'
|
import ScrollTopAndComment from '@/components/ScrollTopAndComment'
|
||||||
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
const editUrl = (fileName) => `${siteMetadata.siteRepo}/raw/master/data/blog/${fileName}`
|
const editUrl = (fileName) => `${siteMetadata.siteRepo}/raw/master/data/blog/${fileName}`
|
||||||
const discussUrl = (slug) =>
|
const discussUrl = (slug) =>
|
||||||
`https://mobile.twitter.com/search?q=${encodeURIComponent(
|
`https://mobile.twitter.com/search?q=${encodeURIComponent(
|
||||||
`${siteMetadata.siteUrl}/blog/${slug}`
|
`${siteMetadata.siteUrl}/blog/${slug}`
|
||||||
)}`
|
)}`
|
||||||
|
const Copyright = () => (
|
||||||
|
<a
|
||||||
|
rel="license"
|
||||||
|
href="http://creativecommons.org/licenses/by-sa/4.0/"
|
||||||
|
className="inline-flex self-center"
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
className="border-0"
|
||||||
|
alt="知识共享许可协议"
|
||||||
|
width="88"
|
||||||
|
height="15"
|
||||||
|
src="https://i.creativecommons.org/l/by-sa/4.0/80x15.png"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
|
||||||
const postDateTemplate = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }
|
const postDateTemplate = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }
|
||||||
|
|
||||||
export default function PostLayout({ frontMatter, authorDetails, next, prev, children }) {
|
export default function PostLayout({ frontMatter, authorDetails, next, prev, children }) {
|
||||||
const { slug, fileName, date, title, images, tags } = frontMatter
|
const { slug, fileName, date, title, images, tags } = frontMatter
|
||||||
|
|
||||||
|
const headerStyles = useMemo(
|
||||||
|
() =>
|
||||||
|
images?.[0]
|
||||||
|
? {
|
||||||
|
backgroundImage: `url(${images[0]})`,
|
||||||
|
}
|
||||||
|
: {},
|
||||||
|
[images]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionContainer>
|
<SectionContainer>
|
||||||
<BlogSEO
|
<BlogSEO
|
||||||
@ -29,8 +55,18 @@ export default function PostLayout({ frontMatter, authorDetails, next, prev, chi
|
|||||||
<ScrollTopAndComment />
|
<ScrollTopAndComment />
|
||||||
<article>
|
<article>
|
||||||
<div className="xl:divide-y xl:divide-gray-200 xl:dark:divide-gray-700">
|
<div className="xl:divide-y xl:divide-gray-200 xl:dark:divide-gray-700">
|
||||||
<header className="pt-6 xl:pb-6">
|
<header className="relative h-48 pt-6 xl:pb-6">
|
||||||
<div className="space-y-1 text-center">
|
{images?.[0] && (
|
||||||
|
<Image
|
||||||
|
alt="background"
|
||||||
|
layout="fill"
|
||||||
|
objectFit="cover"
|
||||||
|
src={images[0]}
|
||||||
|
style={headerStyles}
|
||||||
|
className="blur-xs -z-10 opacity-50 bg-blend-soft-light"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className="space-y-5 text-center">
|
||||||
<dl className="space-y-10">
|
<dl className="space-y-10">
|
||||||
<div>
|
<div>
|
||||||
<dt className="sr-only">Published on</dt>
|
<dt className="sr-only">Published on</dt>
|
||||||
@ -87,10 +123,8 @@ export default function PostLayout({ frontMatter, authorDetails, next, prev, chi
|
|||||||
</dl>
|
</dl>
|
||||||
<div className="divide-y divide-gray-200 dark:divide-gray-700 xl:col-span-3 xl:row-span-2 xl:pb-0">
|
<div className="divide-y divide-gray-200 dark:divide-gray-700 xl:col-span-3 xl:row-span-2 xl:pb-0">
|
||||||
<div className="prose max-w-none pt-10 pb-8 dark:prose-dark">{children}</div>
|
<div className="prose max-w-none pt-10 pb-8 dark:prose-dark">{children}</div>
|
||||||
<div className="pt-6 pb-6 text-sm text-gray-700 dark:text-gray-300">
|
<div className="flex items-center pt-6 pb-6 text-sm text-gray-700 dark:text-gray-300">
|
||||||
<Link href={discussUrl(slug)} rel="nofollow">
|
<Copyright />
|
||||||
{'Discuss on Twitter'}
|
|
||||||
</Link>
|
|
||||||
{` • `}
|
{` • `}
|
||||||
<Link href={editUrl(fileName)}>{'View source'}</Link>
|
<Link href={editUrl(fileName)}>{'View source'}</Link>
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,7 +59,7 @@ module.exports = withBundleAnalyzer({
|
|||||||
dirs: ['pages', 'components', 'lib', 'layouts', 'scripts'],
|
dirs: ['pages', 'components', 'lib', 'layouts', 'scripts'],
|
||||||
},
|
},
|
||||||
images: {
|
images: {
|
||||||
domains: ['pan.ivanli.cc'],
|
domains: ['pan.ivanli.cc', 'i.creativecommons.org'],
|
||||||
},
|
},
|
||||||
async headers() {
|
async headers() {
|
||||||
return [
|
return [
|
||||||
|
Loading…
Reference in New Issue
Block a user