Skip to content

Commit d17c19e

Browse files
committed
chore(docker): add Dockerfile, .dockerignore, and CI workflow for Docker image build and push
Signed-off-by: samzong <[email protected]>
1 parent 887f0c0 commit d17c19e

File tree

3 files changed

+305
-0
lines changed

3 files changed

+305
-0
lines changed

.dockerignore

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Git
2+
.git
3+
.gitignore
4+
.gitattributes
5+
6+
# Documentation build artifacts
7+
docs/zh/site/
8+
docs/en/site/
9+
site/
10+
public/
11+
12+
# Python
13+
__pycache__/
14+
*.py[cod]
15+
*$py.class
16+
*.so
17+
.Python
18+
build/
19+
develop-eggs/
20+
dist/
21+
downloads/
22+
eggs/
23+
.eggs/
24+
lib/
25+
lib64/
26+
parts/
27+
sdist/
28+
var/
29+
wheels/
30+
*.egg-info/
31+
.installed.cfg
32+
*.egg
33+
MANIFEST
34+
35+
# Virtual environments
36+
.env
37+
.venv
38+
env/
39+
venv/
40+
ENV/
41+
env.bak/
42+
venv.bak/
43+
44+
# IDE
45+
.vscode/
46+
.idea/
47+
*.swp
48+
*.swo
49+
*~
50+
51+
# OS
52+
.DS_Store
53+
.DS_Store?
54+
._*
55+
.Spotlight-V100
56+
.Trashes
57+
ehthumbs.db
58+
Thumbs.db
59+
60+
# Logs
61+
*.log
62+
npm-debug.log*
63+
yarn-debug.log*
64+
yarn-error.log*
65+
66+
# Dependencies
67+
node_modules/
68+
69+
# Temporary files
70+
*.tmp
71+
*.temp
72+
.cache/
73+
74+
# CI/CD
75+
.github/
76+
.gitlab-ci.yml
77+
78+
# Documentation source in other languages (optional optimization)
79+
# Uncomment to reduce image size if only building specific language
80+
# docs/en/
81+
# docs/zh/
82+
83+
# Scripts (keep if needed in container)
84+
# scripts/
85+
86+
# README files (not needed in production)
87+
README*.md
88+
CONTRIBUTING.md
89+
CODE_OF_CONDUCT.md
90+
SECURITY.md
91+
LICENSE
92+
93+
# Development tools
94+
makefile
95+
Makefile

.github/workflows/docker-build.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: Build and Push Docker Image
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
tags: [ 'v*' ]
7+
8+
env:
9+
REGISTRY: ghcr.io
10+
IMAGE_NAME: ${{ github.repository }}
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
packages: write
18+
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- name: Checkout OpenAPI docs
26+
uses: actions/checkout@v4
27+
with:
28+
repository: daocloud/daocloud-api-docs
29+
path: dao-openapi
30+
fetch-depth: 0
31+
32+
- name: Checkout download docs
33+
uses: actions/checkout@v4
34+
with:
35+
repository: daocloud/daocloud-download-docs
36+
path: daocloud-download-docs
37+
fetch-depth: 0
38+
39+
- name: Setup SSH for private repos
40+
uses: MrSquaare/ssh-setup-action@v1
41+
with:
42+
host: github.com
43+
private-key: ${{ secrets.SSH_PRIVATE_KEY }}
44+
45+
- name: Setup Python for merge script
46+
uses: actions/setup-python@v4
47+
with:
48+
python-version: '3.x'
49+
50+
- name: Install Python dependencies for merge script
51+
run: pip install pyyaml
52+
53+
- name: Merge external content
54+
run: |
55+
# Merge OpenAPI docs
56+
cp -av dao-openapi/docs/openapi docs/zh/docs/
57+
python scripts/merged_nav.py
58+
59+
# Merge download docs
60+
cp -av daocloud-download-docs/docs/zh/docs/download docs/zh/docs/
61+
cp -av daocloud-download-docs/docs/en/docs/download docs/en/docs/
62+
63+
- name: Log in to Container Registry
64+
uses: docker/login-action@v3
65+
with:
66+
registry: ${{ env.REGISTRY }}
67+
username: ${{ github.actor }}
68+
password: ${{ secrets.GITHUB_TOKEN }}
69+
70+
- name: Extract metadata
71+
id: meta
72+
uses: docker/metadata-action@v5
73+
with:
74+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
75+
tags: |
76+
type=ref,event=branch
77+
type=ref,event=pr
78+
type=semver,pattern={{version}}
79+
type=semver,pattern={{major}}.{{minor}}
80+
type=raw,value=latest,enable={{is_default_branch}}
81+
82+
- name: Set up Docker Buildx
83+
uses: docker/setup-buildx-action@v3
84+
85+
- name: Build and push Docker image
86+
uses: docker/build-push-action@v5
87+
with:
88+
context: .
89+
platforms: linux/amd64
90+
push: true
91+
tags: ${{ steps.meta.outputs.tags }}
92+
labels: ${{ steps.meta.outputs.labels }}
93+
ssh: |
94+
default=${{ env.SSH_AUTH_SOCK }}

Dockerfile

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Multi-stage Dockerfile for DaoCloud-docs documentation site
2+
# This Dockerfile creates a production-ready static site build
3+
4+
FROM python:3.12-slim as builder
5+
6+
# Set work directory
7+
WORKDIR /app
8+
9+
# Install system dependencies
10+
RUN apt-get update && apt-get install -y \
11+
git \
12+
curl \
13+
openssh-client \
14+
&& rm -rf /var/lib/apt/lists/*
15+
16+
# Copy requirements and constraints
17+
COPY requirements.txt constraints.txt ./
18+
19+
# Install Python dependencies
20+
RUN pip install -r requirements.txt -c constraints.txt
21+
22+
# Install mkdocs-material-insiders from private repo
23+
RUN --mount=type=ssh \
24+
mkdir -p ~/.ssh && \
25+
chmod 700 ~/.ssh && \
26+
ssh-keyscan github.com >> ~/.ssh/known_hosts && \
27+
chmod 600 ~/.ssh/known_hosts && \
28+
git config --global user.email "[email protected]" && \
29+
git config --global user.name "Docker Builder" && \
30+
git clone [email protected]:DaoCloud/mkdocs-material-insiders.git mkdocs-material && \
31+
pip install -e mkdocs-material
32+
33+
# Install custom plugin with PDF support
34+
RUN pip install git+https://github.com/SAMZONG/mkdocs-with-pdf-support-material-v8
35+
36+
# Copy source files (external content already merged by workflow)
37+
COPY . .
38+
39+
# Build Chinese documentation to site
40+
RUN mkdocs build -f docs/zh/mkdocs.yml -d site
41+
42+
# Build English documentation to site/en
43+
RUN mkdocs build -f docs/en/mkdocs.yml -d site
44+
45+
# Production stage with nginx
46+
FROM nginx:alpine as production
47+
48+
# Copy built sites from builder stage
49+
COPY --from=builder /app/docs/zh/site /usr/share/nginx/html
50+
COPY --from=builder /app/docs/en/site /usr/share/nginx/html/en
51+
52+
# Copy nginx configuration
53+
COPY <<EOF /etc/nginx/conf.d/default.conf
54+
server {
55+
listen 80;
56+
listen [::]:80;
57+
server_name localhost;
58+
59+
root /usr/share/nginx/html;
60+
index index.html;
61+
62+
# Enable gzip compression
63+
gzip on;
64+
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
65+
66+
# Cache static assets
67+
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
68+
expires 1y;
69+
add_header Cache-Control "public, immutable";
70+
}
71+
72+
# Handle Chinese docs (root)
73+
location / {
74+
try_files \$uri \$uri/ \$uri.html =404;
75+
76+
# Add security headers
77+
add_header X-Frame-Options "SAMEORIGIN" always;
78+
add_header X-Content-Type-Options "nosniff" always;
79+
add_header Referrer-Policy "no-referrer-when-downgrade" always;
80+
}
81+
82+
# Handle English docs
83+
location /en/ {
84+
try_files \$uri \$uri/ \$uri.html =404;
85+
}
86+
87+
# Health check endpoint
88+
location /health {
89+
access_log off;
90+
return 200 "healthy\n";
91+
add_header Content-Type text/plain;
92+
}
93+
94+
# Redirect old paths if needed
95+
location /zh/ {
96+
return 301 /;
97+
}
98+
99+
# Custom error pages
100+
error_page 404 /404.html;
101+
error_page 500 502 503 504 /50x.html;
102+
location = /50x.html {
103+
root /usr/share/nginx/html;
104+
}
105+
}
106+
EOF
107+
108+
# Expose port
109+
EXPOSE 80
110+
111+
# Health check
112+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
113+
CMD curl -f http://localhost/health || exit 1
114+
115+
# Run nginx
116+
CMD ["nginx", "-g", "daemon off;"]

0 commit comments

Comments
 (0)