Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions base-images/frameworks/next.js/v16/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# These ARGs can be overridden at build time to customize the image
ARG REPO=labring-actions/devbox-base-images
ARG REGISTRY=ghcr.io
ARG L10N=en_US
ARG L10N_NORMALIZED=en-us

# These ARGs are not recommended to be overridden at build time.
# Instead, update the Dockerfile directly for consistent builds,
# and release new versions as needed.
ARG NODE_IMAGE_VERSION=v0.0.1-alpha.1-${L10N_NORMALIZED}

FROM ${REGISTRY}/${REPO}/node.js-20:${NODE_IMAGE_VERSION}
ARG L10N
LABEL org.opencontainers.image.authors="The Devbox Authors"
ENV L10N=${L10N}
# Add build script and execute it
COPY build.sh /build.sh
RUN chmod +x /build.sh && \
/build.sh && \
rm -f /build.sh
7 changes: 7 additions & 0 deletions base-images/frameworks/next.js/v16/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail

NEXT_VERSION=${NEXT_VERSION:-16.2.6}

# Install the Next.js project scaffolding CLI globally for convenience.
npm install -g "create-next-app@${NEXT_VERSION}"
24 changes: 24 additions & 0 deletions runtime-images/frameworks/next.js/v16/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# These ARGs can be overridden at build time to customize the image
ARG REPO=labring-actions/devbox-base-images
ARG REGISTRY=ghcr.io
ARG L10N=en_US
ARG L10N_NORMALIZED=en-us

# These ARGs are not recommended to be overridden at build time.
# Instead, update the Dockerfile directly for consistent builds,
# and release new versions as needed.
ARG RUNTIME_IMAGE_VERSION=v0.0.1-alpha.1-${L10N_NORMALIZED}

FROM ${REGISTRY}/${REPO}/next.js-v16:${RUNTIME_IMAGE_VERSION}
ARG L10N
LABEL org.opencontainers.image.authors="The Devbox Authors"
ENV L10N=${L10N}
ENV PROJECT_TEMPLATE_DIR=/project-template
COPY ./project-template ${PROJECT_TEMPLATE_DIR}
COPY ./build.sh /build.sh
RUN chmod +x /build.sh && \
/build.sh && \
rm -f /build.sh && \
rm -rf ${PROJECT_TEMPLATE_DIR}
# Set the working directory to the default devbox user's project directory
WORKDIR /home/${DEFAULT_DEVBOX_USER}/project
49 changes: 49 additions & 0 deletions runtime-images/frameworks/next.js/v16/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
set -euo pipefail

L10N=${L10N:-en_US}
DEFAULT_DEVBOX_USER=${DEFAULT_DEVBOX_USER:-devbox}
PROJECT_TEMPLATE_DIR=${PROJECT_TEMPLATE_DIR:-/project-template}

if ! id -u "$DEFAULT_DEVBOX_USER" &>/dev/null; then
echo "User $DEFAULT_DEVBOX_USER does not exist"
exit 1
fi

TARGET_DIR="/home/$DEFAULT_DEVBOX_USER/project"
mkdir -p "$TARGET_DIR"

if [ -f "$PROJECT_TEMPLATE_DIR/README.$L10N.md" ]; then
echo "README $PROJECT_TEMPLATE_DIR/README.$L10N.md exists. Copying to $TARGET_DIR/README.md"
cp "$PROJECT_TEMPLATE_DIR/README.$L10N.md" "$TARGET_DIR/README.md"
else
echo "README $PROJECT_TEMPLATE_DIR/README.$L10N.md does not exist. Skipping copy."
fi

DOCS_DIR=${DOCS_DIR:-/usr/share/devbox/docs}
if [ -f "$DOCS_DIR/README.s6-user-guide.$L10N.md" ]; then
cp "$DOCS_DIR/README.s6-user-guide.$L10N.md" "$TARGET_DIR/README.s6-user-guide.md"
elif [ -f "$DOCS_DIR/README.s6-user-guide.en_US.md" ]; then
cp "$DOCS_DIR/README.s6-user-guide.en_US.md" "$TARGET_DIR/README.s6-user-guide.md"
fi

# Copy project template contents (except localized readmes handled above).
# Using `/.` keeps hidden files/dirs if present.
cp -R "${PROJECT_TEMPLATE_DIR}/." "$TARGET_DIR/"

# If we wrote a localized README.md, remove the localized variants to keep the
# project dir clean (optional; safe if they don't exist).
rm -f "$TARGET_DIR/README.en_US.md" "$TARGET_DIR/README.zh_CN.md" || true

# Ensure entrypoint is executable if present.
if [ -f "$TARGET_DIR/entrypoint.sh" ]; then
chmod +x "$TARGET_DIR/entrypoint.sh"
fi

# Install dependencies and build the Next.js project.
cd "$TARGET_DIR"
npm install
npm run build

# Set ownership to default devbox user
chown -R "$DEFAULT_DEVBOX_USER:$DEFAULT_DEVBOX_USER" "$TARGET_DIR"
25 changes: 25 additions & 0 deletions runtime-images/frameworks/next.js/v16/project-template/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# dependencies
/node_modules

# Next.js
/.next
/out

# production
/build

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# environment
.env*.local

# editor
.idea
.vscode

# system
.DS_Store
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Next.js v16 Runtime Template

This template provides a React web application runtime powered by **Next.js 16** using the App Router and TypeScript.

## Runtime Summary

- Framework/runtime version: `Next.js 16`
- Base runtime image: `next.js-v16`
- Entrypoint script: `entrypoint.sh`
- Default service port: `3000`

## Template Files

- `app/layout.tsx`: root layout and page metadata
- `app/page.tsx`: default homepage rendered by the App Router
- `app/globals.css`: shared application styles
- `next.config.ts`: Next.js configuration
- `tsconfig.json`: TypeScript compiler configuration
- `entrypoint.sh`: starts Next.js in dev or production mode

## Run in DevBox

Run commands from `/home/devbox/project`.

### Development mode

```bash
bash entrypoint.sh
```

Behavior:
- Runs `npm install` to ensure dependencies are up to date.
- Starts `next dev` on `0.0.0.0:3000` for hot reloading.

### Production mode

```bash
bash entrypoint.sh production
```

Behavior:
- Installs dependencies needed for the production build.
- Builds the project with `npm run build`.
- Prunes development dependencies after the build.
- Starts `next start` on `0.0.0.0:3000`.

## Verify Service

```bash
curl http://127.0.0.1:3000
```

## Customization

- Edit `app/page.tsx` to change the default page.
- Add routes by creating folders under `app/`.
- Update `app/globals.css` for shared styling.
- Modify `next.config.ts` for framework options such as image domains or build output.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Next.js v16 运行时模板

该模板提供一个基于 **Next.js 16** 的 React Web 应用运行时,使用 App Router 和 TypeScript。

## 运行时概览

- 框架/运行时版本:`Next.js 16`
- 基础运行时镜像:`next.js-v16`
- 启动脚本:`entrypoint.sh`
- 默认服务端口:`3000`

## 模板文件

- `app/layout.tsx`:根布局和页面元数据
- `app/page.tsx`:由 App Router 渲染的默认首页
- `app/globals.css`:应用共享样式
- `next.config.ts`:Next.js 配置
- `tsconfig.json`:TypeScript 编译配置
- `entrypoint.sh`:以开发或生产模式启动 Next.js

## 在 DevBox 中运行

以下命令在 `/home/devbox/project` 目录执行。

### 开发模式

```bash
bash entrypoint.sh
```

行为说明:
- 执行 `npm install` 确保依赖已安装。
- 以 `next dev` 启动,监听 `0.0.0.0:3000` 并支持热重载。

### 生产模式

```bash
bash entrypoint.sh production
```

行为说明:
- 安装生产构建所需依赖。
- 执行 `npm run build` 构建项目。
- 构建完成后裁剪开发依赖。
- 以 `next start` 启动,监听 `0.0.0.0:3000`。

## 验证服务

```bash
curl http://127.0.0.1:3000
```

## 自定义建议

- 修改 `app/page.tsx` 调整默认页面。
- 在 `app/` 下创建目录以添加路由。
- 修改 `app/globals.css` 调整全局样式。
- 修改 `next.config.ts` 配置图片域名、构建输出等框架选项。
135 changes: 135 additions & 0 deletions runtime-images/frameworks/next.js/v16/project-template/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
:root {
color-scheme: light;
--background: #f8fafc;
--foreground: #172033;
--muted: #5f6c7b;
--panel: #ffffff;
--border: #d9e2ec;
--accent: #0f766e;
--accent-strong: #115e59;
}

* {
box-sizing: border-box;
}

html,
body {
margin: 0;
min-height: 100%;
}

body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}

a {
color: inherit;
}

.page {
min-height: 100vh;
display: grid;
place-items: center;
padding: 48px 20px;
}

.shell {
width: min(880px, 100%);
display: grid;
gap: 28px;
}

.intro {
display: grid;
gap: 18px;
}

.eyebrow {
margin: 0;
color: var(--accent-strong);
font-size: 0.85rem;
font-weight: 700;
letter-spacing: 0;
text-transform: uppercase;
}

h1 {
margin: 0;
max-width: 760px;
font-size: clamp(2.25rem, 7vw, 4.75rem);
line-height: 1;
letter-spacing: 0;
}

.summary {
margin: 0;
max-width: 660px;
color: var(--muted);
font-size: 1.08rem;
line-height: 1.7;
}

.actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
}

.button {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 44px;
padding: 0 18px;
border: 1px solid var(--accent);
border-radius: 6px;
background: var(--accent);
color: #ffffff;
font-size: 0.95rem;
font-weight: 700;
text-decoration: none;
}

.button.secondary {
background: transparent;
color: var(--accent-strong);
}

.details {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
}

.detail {
min-height: 112px;
padding: 18px;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--panel);
}

.detail h2 {
margin: 0 0 10px;
font-size: 0.95rem;
}

.detail p {
margin: 0;
color: var(--muted);
font-size: 0.92rem;
line-height: 1.55;
}

@media (max-width: 720px) {
.page {
place-items: start;
}

.details {
grid-template-columns: 1fr;
}
}
Loading