feat: initialize HEC IA Wiki with Docker setup, build process, and content structure

- Add .dockerignore t
- Create Gitea Action to build and publish image
- Update Dockerfile to include build steps and health check
- Revise README.md
- Modify config.ts for site-specific settings
- Enhance content.config.ts to define collections for events, workshops, news, and technical articles
This commit is contained in:
vorpax
2026-01-29 11:44:34 +01:00
parent c29b05bff3
commit 6971fc231d
6 changed files with 425 additions and 89 deletions

View File

@@ -1,8 +1,27 @@
# Ignore Astro files # Development files
*.astro .git/
.gitignore
.vscode/
.DS_Store
# Ignore node_modules directory # Cache and temp files
.astro/
node_modules/ node_modules/
# Ignore build output # Build output (will be rebuilt in Docker)
dist/ dist/
# Environment files
.env
.env.*
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Documentation (optional - comment if needed in image)
# *.md
# !README.md

View File

@@ -0,0 +1,46 @@
name: Build and Push Docker Image - HEC IA Wiki
on:
push:
branches:
- main
- master
env:
REGISTRY: "gitea.vorpax.dev"
IMAGE_NAME: "vorpax_admin/hecia-wiki"
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Gitea Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=sha,prefix=
type=raw,value=latest,enable=${{ gitea.ref == format('refs/heads/{0}', 'main') || gitea.ref == format('refs/heads/{0}', 'master') }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -5,13 +5,32 @@ WORKDIR /app
# Install pnpm # Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate RUN corepack enable && corepack prepare pnpm@latest --activate
# Copy package files
COPY package.json pnpm-lock.yaml ./ COPY package.json pnpm-lock.yaml ./
# Install dependencies
RUN pnpm install --frozen-lockfile RUN pnpm install --frozen-lockfile
# Copy all source files (respecting .dockerignore)
COPY . . COPY . .
# Build the application
# Note: The build script includes: astro check && astro build && pagefind --site dist && cp -r dist/pagefind public/
RUN pnpm run build RUN pnpm run build
# Runtime stage for serving the application # Runtime stage for serving the application
FROM nginx:mainline-alpine-slim AS runtime FROM nginx:mainline-alpine-slim AS runtime
# Copy the built site from dist directory
COPY --from=base /app/dist /usr/share/nginx/html COPY --from=base /app/dist /usr/share/nginx/html
# The build script copies pagefind to public/, so we need to copy it back to dist for the runtime
# Copy pagefind if it exists in public/
COPY --from=base /app/public/pagefind /usr/share/nginx/html/pagefind
# Expose port 80
EXPOSE 80 EXPOSE 80
# Add healthcheck
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1

312
README.md
View File

@@ -1,72 +1,234 @@
# AstroPaper 📄 # HEC IA Wiki 🤖
![AstroPaper](public/astropaper-og.jpg) ![HEC IA Wiki](public/hec-ia-og.jpg)
[![Figma](https://img.shields.io/badge/Figma-F24E1E?style=for-the-badge&logo=figma&logoColor=white)](https://www.figma.com/community/file/1356898632249991861)
![Typescript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
![GitHub](https://img.shields.io/github/license/satnaing/astro-paper?color=%232F3741&style=for-the-badge)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white&style=for-the-badge)](https://conventionalcommits.org)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=for-the-badge)](http://commitizen.github.io/cz-cli/)
AstroPaper is a minimal, responsive, accessible and SEO-friendly Astro blog theme. This theme is designed and crafted based on [my personal blog](https://satnaing.dev/blog). The official wiki and knowledge base for HEC IA student association. Built with [Astro](https://astro.build/) and the [AstroPaper](https://github.com/satnaing/astro-paper) theme.
Read [the blog posts](https://astro-paper.pages.dev/posts/) or check [the README Documentation Section](#-documentation) for more info. ## 📚 About
## 🔥 Features This wiki serves as a central hub for HEC IA's content, including:
- [x] type-safe markdown - **Events**: Information about upcoming and past events
- [x] super fast performance - **Workshops**: Hands-on technical workshops and tutorials
- [x] accessible (Keyboard/VoiceOver) - **News**: Latest updates and announcements from HEC IA
- [x] responsive (mobile ~ desktops) - **Technical Deep Dives**: In-depth technical articles on AI topics
- [x] SEO-friendly
- [x] light & dark mode
- [x] fuzzy search
- [x] draft posts & pagination
- [x] sitemap & rss feed
- [x] followed best practices
- [x] highly customizable
- [x] dynamic OG image generation for blog posts [#15](https://github.com/satnaing/astro-paper/pull/15) ([Blog Post](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/))
_Note: I've tested screen-reader accessibility of AstroPaper using **VoiceOver** on Mac and **TalkBack** on Android. I couldn't test all other screen-readers out there. However, accessibility enhancements in AstroPaper should be working fine on others as well._ ## 🚀 Quick Start
## ✅ Lighthouse Score ### Prerequisites
<p align="center"> - Node.js 18+
<a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fastro-paper.pages.dev%2F&form_factor=desktop"> - npm or pnpm
<img width="710" alt="AstroPaper Lighthouse Score" src="AstroPaper-lighthouse-score.svg">
</a>
</p>
## 🚀 Project Structure ### Installation
Inside of AstroPaper, you'll see the following folders and files: ```bash
# Clone the repository
git clone https://github.com/hec-ia/wiki.git
cd wiki
# Install dependencies
npm install
# Start development server
npm run dev
```
The site will be available at `http://localhost:4321`
### Building for Production
```bash
# Build the site
npm run build
# Preview the build
npm run preview
```
## 📝 Adding Content
### Events
Create a new markdown file in `src/data/events/`:
```markdown
---
title: "Your Event Title"
description: "Event description"
author: "HEC IA"
pubDatetime: 2026-01-15T10:00:00Z
eventDate: 2026-02-05T14:00:00Z
eventEndDate: 2026-02-05T18:00:00Z
location: "Event Location"
tags: ["tag1", "tag2"]
featured: true
registrationLink: "https://registration-link.com"
---
Your event content here...
```
### Workshops
Create a new markdown file in `src/data/workshops/`:
```markdown
---
title: "Workshop Title"
description: "Workshop description"
author: "HEC IA"
pubDatetime: 2026-01-15T10:00:00Z
workshopDate: 2026-02-05T14:00:00Z
duration: "3 hours"
level: "beginner" # beginner, intermediate, or advanced
tags: ["machine-learning", "python"]
featured: true
materials: "https://github.com/hec-ia/workshop-materials"
---
Your workshop content here...
```
### News
Create a new markdown file in `src/data/news/`:
```markdown
---
title: "News Title"
description: "News description"
author: "HEC IA"
pubDatetime: 2026-01-25T10:00:00Z
tags: ["news", "announcement"]
featured: true
---
Your news content here...
```
### Technical Deep Dives
Create a new markdown file in `src/data/technical/`:
```markdown
---
title: "Technical Article Title"
description: "Article description"
author: "HEC IA Technical Team"
pubDatetime: 2026-01-28T10:00:00Z
tags: ["deep-learning", "nlp"]
difficulty: "advanced" # beginner, intermediate, or advanced
readingTime: "25 min"
featured: true
---
Your technical content here...
```
## 🎨 Customization
### Site Configuration
Edit `src/config.ts` to customize:
- Site title and description
- Author information
- Social links
- Posts per page
- And more...
### Theme Colors
The site uses Tailwind CSS. Customize colors in:
- `src/styles/base.css` for global styles
- `tailwind.config.js` for theme configuration
## 📂 Project Structure
```bash ```bash
/ /
├── public/ ├── public/
── pagefind/ # auto-generated when build ── assets/ # Static assets
│ ├── favicon.svg
│ └── astropaper-og.jpg
├── src/ ├── src/
│ ├── assets/ │ ├── assets/ # SVG icons and images
│ ├── icons/ │ ├── components/ # Astro components
│ └── images/ ├── data/ # Content collections
│ ├── components/ │ ├── events/
│ ├── data/ │ ├── workshops/
│ │ ── blog/ │ │ ── news/
│ │ └── some-blog-posts.md │ │ └── technical/
│ ├── layouts/ │ ├── layouts/ # Page layouts
│ ├── pages/ │ ├── pages/ # Route pages
│ ├── scripts/ │ ├── styles/ # Global styles
│ ├── styles/ │ ├── utils/ # Utility functions
│ ├── utils/ │ ├── config.ts # Site configuration
── config.ts ── content.config.ts # Content collections config
│ ├── constants.ts ├── astro.config.ts
│ ├── content.config.ts ├── package.json
│ ├── env.d.ts └── README.md
│ └── remark-collapse.d.ts
└── astro.config.ts
``` ```
## 🧞 Available Commands
| Command | Action |
| :--------------------- | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run format:check` | Check code format with Prettier |
| `npm run format` | Format codes with Prettier |
| `npm run sync` | Generates TypeScript types for all Astro modules |
| `npm run lint` | Lint with ESLint |
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
## 📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
## 🙏 Acknowledgments
Built with:
- [Astro](https://astro.build/) - The web framework for content-driven websites
- [AstroPaper](https://github.com/satnaing/astro-paper) - The base theme
- [Tailwind CSS](https://tailwindcss.com/) - For styling
- [TypeScript](https://www.typescriptlang.org/) - For type safety
---
Made with ❤️ by HEC IA
│ │ ├── icons/
│ │ └── images/
│ ├── components/
│ ├── data/
│ │ └── blog/
│ │ └── some-blog-posts.md
│ ├── layouts/
│ ├── pages/
│ ├── scripts/
│ ├── styles/
│ ├── utils/
│ ├── config.ts
│ ├── constants.ts
│ ├── content.config.ts
│ ├── env.d.ts
│ └── remark-collapse.d.ts
└── astro.config.ts
````
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name. Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
Any static assets, like images, can be placed in the `public/` directory. Any static assets, like images, can be placed in the `public/` directory.
@@ -84,15 +246,15 @@ Documentation can be read in two formats\_ _markdown_ & _blog post_.
## 💻 Tech Stack ## 💻 Tech Stack
**Main Framework** - [Astro](https://astro.build/) **Main Framework** - [Astro](https://astro.build/)
**Type Checking** - [TypeScript](https://www.typescriptlang.org/) **Type Checking** - [TypeScript](https://www.typescriptlang.org/)
**Styling** - [TailwindCSS](https://tailwindcss.com/) **Styling** - [TailwindCSS](https://tailwindcss.com/)
**UI/UX** - [Figma Design File](https://www.figma.com/community/file/1356898632249991861) **UI/UX** - [Figma Design File](https://www.figma.com/community/file/1356898632249991861)
**Static Search** - [FuseJS](https://pagefind.app/) **Static Search** - [FuseJS](https://pagefind.app/)
**Icons** - [Tablers](https://tabler-icons.io/) **Icons** - [Tablers](https://tabler-icons.io/)
**Code Formatting** - [Prettier](https://prettier.io/) **Code Formatting** - [Prettier](https://prettier.io/)
**Deployment** - [Cloudflare Pages](https://pages.cloudflare.com/) **Deployment** - [Cloudflare Pages](https://pages.cloudflare.com/)
**Illustration in About Page** - [https://freesvgillustration.com](https://freesvgillustration.com/) **Illustration in About Page** - [https://freesvgillustration.com](https://freesvgillustration.com/)
**Linting** - [ESLint](https://eslint.org) **Linting** - [ESLint](https://eslint.org)
## 👨🏻‍💻 Running Locally ## 👨🏻‍💻 Running Locally
@@ -111,7 +273,7 @@ yarn create astro --template satnaing/astro-paper
# bun # bun
bun create astro@latest -- --template satnaing/astro-paper bun create astro@latest -- --template satnaing/astro-paper
``` ````
Then start the project by running the following commands: Then start the project by running the following commands:
@@ -150,20 +312,20 @@ All commands are run from the root of the project, from a terminal:
> **_Note!_** For `Docker` commands we must have it [installed](https://docs.docker.com/engine/install/) in your machine. > **_Note!_** For `Docker` commands we must have it [installed](https://docs.docker.com/engine/install/) in your machine.
| Command | Action | | Command | Action |
| :----------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | | :------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------- |
| `pnpm install` | Installs dependencies | | `pnpm install` | Installs dependencies |
| `pnpm run dev` | Starts local dev server at `localhost:4321` | | `pnpm run dev` | Starts local dev server at `localhost:4321` |
| `pnpm run build` | Build your production site to `./dist/` | | `pnpm run build` | Build your production site to `./dist/` |
| `pnpm run preview` | Preview your build locally, before deploying | | `pnpm run preview` | Preview your build locally, before deploying |
| `pnpm run format:check` | Check code format with Prettier | | `pnpm run format:check` | Check code format with Prettier |
| `pnpm run format` | Format codes with Prettier | | `pnpm run format` | Format codes with Prettier |
| `pnpm run sync` | Generates TypeScript types for all Astro modules. [Learn more](https://docs.astro.build/en/reference/cli-reference/#astro-sync). | | `pnpm run sync` | Generates TypeScript types for all Astro modules. [Learn more](https://docs.astro.build/en/reference/cli-reference/#astro-sync). |
| `pnpm run lint` | Lint with ESLint | | `pnpm run lint` | Lint with ESLint |
| `docker compose up -d` | Run AstroPaper on docker, You can access with the same hostname and port informed on `dev` command. | | `docker compose up -d` | Run AstroPaper on docker, You can access with the same hostname and port informed on `dev` command. |
| `docker compose run app pnpm install` | You can run any command above into the docker container. | | `docker compose run app pnpm install` | You can run any command above into the docker container. |
| `docker build -t astropaper .` | Build Docker image for AstroPaper. | | `docker build -t astropaper .` | Build Docker image for AstroPaper. |
| `docker run -p 4321:80 astropaper` | Run AstroPaper on Docker. The website will be accessible at `http://localhost:4321`. | | `docker run -p 4321:80 astropaper` | Run AstroPaper on Docker. The website will be accessible at `http://localhost:4321`. |
> **_Warning!_** Windows PowerShell users may need to install the [concurrently package](https://www.npmjs.com/package/concurrently) if they want to [run diagnostics](https://docs.astro.build/en/reference/cli-reference/#astro-check) during development (`astro check --watch & astro dev`). For more info, see [this issue](https://github.com/satnaing/astro-paper/issues/113). > **_Warning!_** Windows PowerShell users may need to install the [concurrently package](https://www.npmjs.com/package/concurrently) if they want to [run diagnostics](https://docs.astro.build/en/reference/cli-reference/#astro-check) during development (`astro check --watch & astro dev`). For more info, see [this issue](https://github.com/satnaing/astro-paper/issues/113).

View File

@@ -1,10 +1,10 @@
export const SITE = { export const SITE = {
website: "https://astro-paper.pages.dev/", // replace this with your deployed domain website: "https://wiki.hec-ia.com/", // replace this with your deployed domain
author: "Sat Naing", author: "HEC IA",
profile: "https://satnaing.dev/", profile: "https://wiki.hec-ia.com/about",
desc: "A minimal, responsive and SEO-friendly Astro blog theme.", desc: "HEC IA student association wiki - Events, workshops, news, and technical deep dives on artificial intelligence.",
title: "AstroPaper", title: "HEC IA Wiki",
ogImage: "astropaper-og.jpg", ogImage: "hec-ia-og.jpg",
lightAndDarkMode: true, lightAndDarkMode: true,
postPerIndex: 4, postPerIndex: 4,
postPerPage: 4, postPerPage: 4,
@@ -14,10 +14,10 @@ export const SITE = {
editPost: { editPost: {
enabled: true, enabled: true,
text: "Edit page", text: "Edit page",
url: "https://github.com/satnaing/astro-paper/edit/main/", url: "https://github.com/hec-ia/wiki/edit/main/",
}, },
dynamicOgImage: true, dynamicOgImage: true,
dir: "ltr", // "rtl" | "auto" dir: "ltr", // "rtl" | "auto"
lang: "en", // html lang code. Set this empty and default will be "en" lang: "en", // html lang code. Set this empty and default will be "en"
timezone: "Asia/Bangkok", // Default global timezone (IANA format) https://en.wikipedia.org/wiki/List_of_tz_database_time_zones timezone: "Europe/Paris", // Default global timezone (IANA format) https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
} as const; } as const;

View File

@@ -3,6 +3,10 @@ import { glob } from "astro/loaders";
import { SITE } from "@/config"; import { SITE } from "@/config";
export const BLOG_PATH = "src/data/blog"; export const BLOG_PATH = "src/data/blog";
export const EVENTS_PATH = "src/data/events";
export const WORKSHOPS_PATH = "src/data/workshops";
export const NEWS_PATH = "src/data/news";
export const TECHNICAL_PATH = "src/data/technical";
const blog = defineCollection({ const blog = defineCollection({
loader: glob({ pattern: "**/[^_]*.md", base: `./${BLOG_PATH}` }), loader: glob({ pattern: "**/[^_]*.md", base: `./${BLOG_PATH}` }),
@@ -23,4 +27,90 @@ const blog = defineCollection({
}), }),
}); });
export const collections = { blog }; const events = defineCollection({
loader: glob({ pattern: "**/[^_]*.md", base: `./${EVENTS_PATH}` }),
schema: ({ image }) =>
z.object({
author: z.string().default(SITE.author),
pubDatetime: z.date(),
eventDate: z.date(),
eventEndDate: z.date().optional(),
location: z.string().optional(),
modDatetime: z.date().optional().nullable(),
title: z.string(),
featured: z.boolean().optional(),
draft: z.boolean().optional(),
tags: z.array(z.string()).default(["event"]),
ogImage: image().or(z.string()).optional(),
description: z.string(),
canonicalURL: z.string().optional(),
hideEditPost: z.boolean().optional(),
timezone: z.string().optional(),
registrationLink: z.string().optional(),
}),
});
const workshops = defineCollection({
loader: glob({ pattern: "**/[^_]*.md", base: `./${WORKSHOPS_PATH}` }),
schema: ({ image }) =>
z.object({
author: z.string().default(SITE.author),
pubDatetime: z.date(),
workshopDate: z.date(),
duration: z.string().optional(),
level: z.enum(["beginner", "intermediate", "advanced"]).optional(),
modDatetime: z.date().optional().nullable(),
title: z.string(),
featured: z.boolean().optional(),
draft: z.boolean().optional(),
tags: z.array(z.string()).default(["workshop"]),
ogImage: image().or(z.string()).optional(),
description: z.string(),
canonicalURL: z.string().optional(),
hideEditPost: z.boolean().optional(),
timezone: z.string().optional(),
materials: z.string().optional(),
}),
});
const news = defineCollection({
loader: glob({ pattern: "**/[^_]*.md", base: `./${NEWS_PATH}` }),
schema: ({ image }) =>
z.object({
author: z.string().default(SITE.author),
pubDatetime: z.date(),
modDatetime: z.date().optional().nullable(),
title: z.string(),
featured: z.boolean().optional(),
draft: z.boolean().optional(),
tags: z.array(z.string()).default(["news"]),
ogImage: image().or(z.string()).optional(),
description: z.string(),
canonicalURL: z.string().optional(),
hideEditPost: z.boolean().optional(),
timezone: z.string().optional(),
}),
});
const technical = defineCollection({
loader: glob({ pattern: "**/[^_]*.md", base: `./${TECHNICAL_PATH}` }),
schema: ({ image }) =>
z.object({
author: z.string().default(SITE.author),
pubDatetime: z.date(),
modDatetime: z.date().optional().nullable(),
title: z.string(),
featured: z.boolean().optional(),
draft: z.boolean().optional(),
tags: z.array(z.string()).default(["technical"]),
ogImage: image().or(z.string()).optional(),
description: z.string(),
canonicalURL: z.string().optional(),
hideEditPost: z.boolean().optional(),
timezone: z.string().optional(),
difficulty: z.enum(["beginner", "intermediate", "advanced"]).optional(),
readingTime: z.string().optional(),
}),
});
export const collections = { blog, events, workshops, news, technical };