Skip to content

docs(vi): Add Vietnamese documentation for create-t3-app #2113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
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
44 changes: 44 additions & 0 deletions www/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const KNOWN_LANGUAGES = {
no: "Norsk",
pl: "Polski",
uk: "Українська",
vi: "Tiếng Việt",
"zh-hans": "简体中文",
} as const;
export type KnownLanguageCode = keyof typeof KNOWN_LANGUAGES;
Expand Down Expand Up @@ -413,6 +414,44 @@ export const SIDEBAR: Sidebar = {
{ text: "Docker", link: "zh-hans/deployment/docker" },
],
},
vi: {
"Create T3 App": [
{ text: "Giới thiệu", link: "vi/introduction" },
{ text: "Tại sao chọn CT3A?", link: "vi/why" },
{ text: "Cài đặt", link: "vi/installation" },
{
text: "Cấu trúc thư mục (Pages Router)",
link: "vi/folder-structure-pages",
},
{
text: "Cấu trúc thư mục (App Router)",
link: "vi/folder-structure-app",
},
{ text: "Câu hỏi thường gặp", link: "vi/faq" },
{ text: "T3 Collection", link: "vi/t3-collection" },
{ text: "Ví dụ", link: "vi/examples" },
{ text: "Các khuyến nghị khác", link: "vi/other-recs" },
],
Usage: [
{ text: "Bước đầu tiên", link: "vi/usage/first-steps" },
{ text: "Next.js", link: "vi/usage/next-js" },
{ text: "TypeScript", link: "vi/usage/typescript" },
{ text: "tRPC", link: "vi/usage/trpc" },
{ text: "Prisma", link: "vi/usage/prisma" },
{ text: "Drizzle", link: "vi/usage/drizzle" },
{ text: "NextAuth.js", link: "vi/usage/next-auth" },
{
text: "Biến môi trường",
link: "vi/usage/env-variables",
},
{ text: "Tailwind CSS", link: "vi/usage/tailwind" },
],
Deployment: [
{ text: "Vercel", link: "vi/deployment/vercel" },
{ text: "Netlify", link: "vi/deployment/netlify" },
{ text: "Docker", link: "vi/deployment/docker" },
],
},
};

export const SIDEBAR_HEADER_MAP: Record<
Expand Down Expand Up @@ -475,4 +514,9 @@ export const SIDEBAR_HEADER_MAP: Record<
Usage: "用法",
Deployment: "部署",
},
vi: {
"Create T3 App": "Create T3 App",
Usage: "Sử dụng",
Deployment: "Triển khai",
},
};
209 changes: 209 additions & 0 deletions www/src/pages/vi/deployment/docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
---
title: Docker
description: Triển khai với Docker
layout: ../../../layouts/docs.astro
lang: vi
---

Bạn có thể containerize stack này và triển khai nó như một container duy nhất bằng Docker, hoặc như một phần của một nhóm container bằng docker-compose. Bạn có thể tham khảo [`ajcwebdev/ct3a-docker`](https://github.com/ajcwebdev/ct3a-docker) như là một repo ví dụ dựa trên tài liệu này.

## Cấu hình dự án Docker

Đối với Next.js, sẽ có những quy trình khác nhau cho môi trường build time (có sẵn trong frontend, được đặt trước bằng `NEXT_PUBLIC`) và môi trường runtime (server-side only, biến). Trong ví dụ dưới đây, chúng tôi sử dụng hai biến môi trường, và bạn hãy chú ý tớ vị trí của chúng trong `Dockerfile`, đối số dòng lệnh, và file `docker-compose.yml`:

- `DATABASE_URL` (Dùng bên phía server)
- `NEXT_PUBLIC_CLIENTVAR` (Dùng bên phía client)

### 1. Next Configuration

Trong file [`next.config.js`](https://github.com/t3-oss/create-t3-app/blob/main/cli/template/base/next.config.js), bạn hãy thêm cấu hình `standalone` để [tối ưu hóa kích thước hình ảnh bằng cách tự động sử dụng trace output](https://nextjs.org/docs/advanced-features/output-file-tracing):

```diff
export default defineNextConfig({
reactStrictMode: true,
swcMinify: true,
+ output: "standalone",
});
```

### 2. Tạo file .dockerignore

<details>
<summary>
Click vào đây để xem nội dung của <code>.dockerignore</code>:
</summary>
<div class="content">

```
.env
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
```

</div>

</details>

### 3. Tạo Dockerfile

> Vì chúng tôi không muốn tạo biến môi trường (environment variables) server vào container, vì thế [các bước xác thực biến môi trường](/vi/usage/env-variables) sẽ không thành công. Để ngăn điều này, chúng tôi đã thêm flag `SKIP_ENV_VALIDATION=1` vào lệnh build để không xác thực biến môi trường tại thời điểm build.

<details>
<summary>
Click vào đây để xem nội dung của <code>Dockerfile</code>:
</summary>
<div class="content">

```docker
##### DEPENDENCIES

FROM --platform=linux/amd64 node:20-alpine AS deps
RUN apk add --no-cache libc6-compat openssl
WORKDIR /app

# Install Prisma Client - remove if not using Prisma

COPY prisma ./

# Install dependencies based on the preferred package manager

COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml\* ./

RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then npm install -g pnpm && pnpm i; \
else echo "Lockfile not found." && exit 1; \
fi

##### BUILDER

FROM --platform=linux/amd64 node:20-alpine AS builder
ARG DATABASE_URL
ARG NEXT_PUBLIC_CLIENTVAR
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# ENV NEXT_TELEMETRY_DISABLED 1

RUN \
if [ -f yarn.lock ]; then SKIP_ENV_VALIDATION=1 yarn build; \
elif [ -f package-lock.json ]; then SKIP_ENV_VALIDATION=1 npm run build; \
elif [ -f pnpm-lock.yaml ]; then npm install -g pnpm && SKIP_ENV_VALIDATION=1 pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi

##### RUNNER

FROM --platform=linux/amd64 gcr.io/distroless/nodejs20-debian12 AS runner
WORKDIR /app

ENV NODE_ENV production

# ENV NEXT_TELEMETRY_DISABLED 1

COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json

COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

EXPOSE 3000
ENV PORT 3000

CMD ["server.js"]
```

> **_Ghi chú_**
>
> - _Việc giả lập môi trường bằng `--platform=linux/amd64` có thể là không cần thiết sau khi chuyển sang Node 18._
> - _Tham khảo [`node:alpine`](https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine) để hiểu tại sao `libc6-compat` có thể cần thiết._
> - _Sử dụng Alpine 3.17 [có thể tạo ra một số vấn đề với Prisma](https://github.com/t3-oss/create-t3-app/issues/975). Vì thế, hãy đặt `engineType = "binary"` giải quyết vấn đề trong Alpine 3.17, tuy nhiên [hiệu suất sẽ bị ảnh hưởng](https://www.prisma.io/docs/concepts/components/prisma-engines/query-engine#the-query-engine-at-runtime)._
> - _Next.js thu thập [dữ liệu sử dụng tổng quan](https://nextjs.org/telemetry). Bỏ comment dòng đầu tiên của `ENV NEXT_TELEMETRY_DISABLED 1` để tắt thu thập dữ liệu (telemetry) trong quá trình build. Bỏ comment dòng thứ hai để tắt thu thập dữ liệu (telemetry) trong quá trình runtime._

</div>
</details>

## Xây dựng và chạy image cục bộ

Xây dựng và chạy image này cục bộ với các lệnh sau:

```bash
docker build -t ct3a-docker --build-arg NEXT_PUBLIC_CLIENTVAR=clientvar .
docker run -p 3000:3000 -e DATABASE_URL="database_url_goes_here" ct3a-docker
```

Mở [localhost:3000](http://localhost:3000/) để xem ứng dụng của bạn đang chạy.

## Docker Compose

Bạn có thể sử dụng Docker Compose để xây dựng image và chạy container.

<details>
<summary>
Theo các bước 1-3 ở trên, click vào đây, và bao gồm nội dung trong <code>docker-compose.yml</code>:
</summary>
<div class="content">

```yaml
version: "3.9"
services:
app:
platform: "linux/amd64"
build:
context: .
dockerfile: Dockerfile
args:
NEXT_PUBLIC_CLIENTVAR: "clientvar"
working_dir: /app
ports:
- "3000:3000"
image: t3-app
environment:
- DATABASE_URL=database_url_goes_here
```

Xây dựng và chạy bằng lệnh `docker compose up --build`:

```bash
docker compose up --build
```

Mở [localhost:3000](http://localhost:3000/) để xem ứng dụng của bạn đang chạy.

</div>
</details>

## Triển khai lên Railway

Bạn có thể sử dụng một PaaS như [Railway's](https://railway.app) để tự động triển khai [Dockerfile](https://docs.railway.app/deploy/dockerfiles) của bạn. Nếu bạn đã cài đặt [Railway CLI](https://docs.railway.app/develop/cli#install) bạn có thể triển khai ứng dụng của bạn với các lệnh sau:

```bash
railway login
railway init
railway link
railway up
railway open
```

Đi đến "Variables" và thêm `DATABASE_URL` của bạn. Sau đó đi đến "Settings" và chọn "Generate Domain". Để tham khảo một ví dụ được triển khai trên Railway, truy cập [ct3a-docker.up.railway.app](https://ct3a-docker.up.railway.app/).

## Tài liệu hữu ích

| Tài liệu | Đường dẫn |
| ------------------------------------- | -------------------------------------------------------------------- |
| Tài liệu Dockerfile | https://docs.docker.com/engine/reference/builder/ |
| Tài liệu Compose file version 3 | https://docs.docker.com/compose/compose-file/compose-file-v3/ |
| Tài liệu Docker CLI | https://docs.docker.com/engine/reference/commandline/docker/ |
| Tài liệu Docker Compose CLI | https://docs.docker.com/compose/reference/ |
| Triển khai Next.js với Docker Image | https://nextjs.org/docs/deployment#docker-image |
| Next.js trong Docker | https://benmarte.com/blog/nextjs-in-docker/ |
| Ví dụ Next.js với Docker | https://github.com/vercel/next.js/tree/canary/examples/with-docker |
| Tạo Docker Image của ứng dụng Next.js | https://blog.tericcabrel.com/create-docker-image-nextjs-application/ |
24 changes: 24 additions & 0 deletions www/src/pages/vi/deployment/index.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
import IndexPage from "../../../components/docs/indexPage.astro";
import { SIDEBAR, type Frontmatter } from "../../../config";
import { getLanguageFromURL } from "../../../languages";
import Layout from "../../../layouts/docs.astro";

const frontmatter: Frontmatter = {
title: "Deployment",
layout: "docs",
description: "Learn how to deploy your T3 app to production.",
};

const lang = getLanguageFromURL(Astro.url.pathname);
const sidebarEntries = SIDEBAR[lang]["Deployment"]!;
const files = await Astro.glob("./*.{md,mdx,astro}");
---

<Layout frontmatter={frontmatter} headings={[]}>
<IndexPage
frontmatter={frontmatter}
sidebarEntries={sidebarEntries}
files={files}
/>
</Layout>
93 changes: 93 additions & 0 deletions www/src/pages/vi/deployment/netlify.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title: Netlify
description: Triển khai lên Netlify
layout: ../../../layouts/docs.astro
lang: vi
isMdx: true
---

import Callout from "../../../components/docs/callout.tsx";

Netlify là một nhà cung cấp khác giúp bạn triển khai ứng dụng web của bạn tương tự như Vercel. Bạn có thể tham khảo [`ajcwebdev/ct3a-netlify`](https://github.com/ajcwebdev/ct3a-netlify) như là một repo ví dụ triển khai lên Netlify dựa trên tài liệu này.

## Tại sao nên triển khai lên Netlify

Một sự thật mà chúng ta không thể phủ nhận được đó chính là việc Vercel chính là cha đẻ của Next.js, thế nên Vercel hỗ trợ Next.js tốt hơn là điều tất nhiên. Thế nên, họ luôn đi đầu trong việc đảm bảo nền tảng được tối ưu hóa cho hiệu suất và nâng cao DX cho Next.js. Đối với hầu hết các trường hợp sử dụng, điều này sẽ đúng và sẽ không có lý do gì để chúng ta tách biệt ra khỏi cái khuôn khổ này.

Và chúng ta cũng đều có chung một suy nghĩ rằng nhiều tính năng của Next.js chỉ được hỗ trợ trên Vercel. Mặc dù Vercel luôn đi đầu trong việc cho phép thử nghiệm các tính năng mới của Next.js và cho phép sử dụng chúng ngay khi được ra mắt, nhưng đồng thời cũng là trường hợp tương tự cho các nhà cung cấp khác như Netlify, khi mà họ cũng sẽ [nhanh chóng triển khai và phát hành hỗ trợ](https://www.netlify.com/blog/deploy-nextjs-13/) cho [các tính năng Next.js khi chúng được ra mắt](https://docs.netlify.com/integrations/frameworks/next-js/overview/).

Tất nhiên, tất cả các nhà cung cấp triển khai sẽ đều có nhiều ưu và nhược điểm của riêng mình, vì không có một nhà cung cấp nào có thể có hỗ trợ tốt nhất cho tất cả các trường hợp sử dụng. Ví dụ, Netlify đã xây dựng hẳn một [runtime Next.js riêng cho Netlify's Edge Functions](https://github.com/netlify/next-runtime) (chạy trên Deno Deploy) và [duy trì middleware riêng để truy cập và sửa đổi HTTP responses](https://github.com/netlify/next-runtime#nextjs-middleware-on-netlify).

<Callout type="info">
Để theo dõi những tính năng mới nhất của những phiên bản Next 13 non-stable,
xin mời tham khảo [Sử dụng Next 13 `app` directory trên
Netlify](https://github.com/netlify/next-runtime/discussions/1724).
</Callout>

## Cấu hình dự án

Có muôn vàn cách để cấu hình lệnh build cho dự án của bạn, bao gồm việc cấu hình trực tiếp qua Netlify CLI hoặc Netlify dashboard. Trong khi việc tạo và bao gồm một tệp [`netlify.toml`](https://docs.netlify.com/configure-builds/file-based-configuration/) là việc không bắt buộc, chúng tôi **khuyến khích** bạn nên làm điều này nhằm đảm bảo rằng các phiên bản được fork và clone của dự án sẽ dễ dàng triển khai lại.

```toml
[build]
command = "next build"
publish = ".next"
```

## Sử dụng Netlify Dashboard

1. Hãy đẩy code của bạn lên một repository GitHub và đăng ký tài khoản [Netlify](https://app.netlify.com/signup). Sau khi đã tạo tài khoản, hãy click vào **Add new site** và sau đó **Import an existing project**.

![New project on Netlify](/images/netlify-01-new-project.webp)

2. Kết nối với Git provider của bạn.

![Import repository](/images/netlify-02-connect-to-git-provider.webp)

3. Chọn repository của dự án của bạn.

![Select your project's repository](/images/netlify-03-pick-a-repository-from-github.webp)

4. Netlify sẽ tự động phát hiện xem bạn có tệp `netlify.toml` hay không và tự động cấu hình lệnh build và thư mục publish.

![Nextjs build settings](/images/netlify-04-configure-build-settings.webp)

5. Click **Show advanced** và sau đó **New variable** để thêm biến môi trường của bạn.

![Add environment variables](/images/netlify-05-env-vars.webp)

6. Chọn **Deploy site**, đợi cho quá trình build hoàn tất và xem trang web mới của bạn.

## Sử dụng Netlify CLI

Để triển khai sử dụng Netlify CLI, bạn phải đầu tiên đẩy code của bạn lên một repository GitHub và [cài đặt Netlify CLI](https://docs.netlify.com/cli/get-started/). Bạn có thể cài đặt `netlify-cli` dưới dạng **Dev Dependency** cho dự án hoặc cài đặt nó toàn cục trên máy của bạn với lệnh sau:

```bash
npm i -g netlify-cli
```

Để chạy dự án của bạn trên máy của bạn, chạy lệnh [`ntl dev`](https://docs.netlify.com/cli/get-started/#run-a-local-development-environment) và mở [`localhost:8888`](http://localhost:8888/) để xem dự án Netlify của bạn đang chạy:

```bash
ntl dev
```

Chạy lệnh [`ntl init`](https://docs.netlify.com/cli/get-started/#continuous-deployment) để bắt đầu cấu hình dự án của bạn:

```bash
ntl init
```

Nhập biến môi trường của dự án của bạn từ tệp `.env` với lệnh [`ntl env:import`](https://cli.netlify.com/commands/env#envimport):

```bash
ntl env:import .env
```

Triển khai dự án của bạn với lệnh [`ntl deploy`](https://docs.netlify.com/cli/get-started/#manual-deploys). Bạn sẽ cần truyền `--build` để chạy lệnh build trước khi triển khai và `--prod` để triển khai lên URL chính của trang web của bạn:

```bash
ntl deploy --prod --build
```

Để xem một ví dụ chạy trên Netlify, hãy truy cập [ct3a.netlify.app](https://ct3a.netlify.app/).
Loading