zeabur-dockerfile

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zeabur Dockerfile Generation

Zeabur Dockerfile 生成

Always use
npx zeabur@latest
to invoke Zeabur CLI.
Never use
zeabur
directly or any other installation method. If
npx
is not available, install Node.js first.
When deploying source code to Zeabur, you must generate a Dockerfile. This skill covers how to analyze a project and produce a correct, deployable Dockerfile.
请始终使用
npx zeabur@latest
调用Zeabur CLI。
切勿直接使用
zeabur
或其他安装方式。如果没有
npx
,请先安装Node.js。
将源代码部署到Zeabur时,必须生成Dockerfile。本技能涵盖如何分析项目并生成正确的、可部署的Dockerfile。

Prerequisites

前置条件

Before generating a Dockerfile, read the key project files:
LanguageFiles to read
Node.js
package.json
, lockfile (
package-lock.json
/
yarn.lock
/
pnpm-lock.yaml
)
Python
requirements.txt
,
Pipfile
,
pyproject.toml
Go
go.mod
Rust
Cargo.toml
PHP
composer.json
Ruby
Gemfile
Java
pom.xml
,
build.gradle
.NET
*.csproj
,
*.sln
Elixir
mix.exs
Also check for:
  • Existing
    Dockerfile
    or
    docker-compose.yml
  • Build config (
    vite.config.js
    ,
    webpack.config.js
    ,
    next.config.js
    , etc.)
  • .env.example
    for required environment variables
What NOT to read — skip these to save tokens:
  • HTML files — static assets, never affect deployment logic
  • Lockfile contents — only check which lockfile exists (to determine package manager). Do NOT parse the contents.
  • Markdown files — documentation only, never influences Dockerfile decisions
生成Dockerfile前,请读取项目的关键文件:
编程语言需要读取的文件
Node.js
package.json
、锁文件(
package-lock.json
/
yarn.lock
/
pnpm-lock.yaml
Python
requirements.txt
Pipfile
pyproject.toml
Go
go.mod
Rust
Cargo.toml
PHP
composer.json
Ruby
Gemfile
Java
pom.xml
build.gradle
.NET
*.csproj
*.sln
Elixir
mix.exs
同时检查以下内容:
  • 已存在的
    Dockerfile
    docker-compose.yml
  • 构建配置文件(
    vite.config.js
    webpack.config.js
    next.config.js
    等)
  • .env.example
    中的必填环境变量
无需读取的内容 — 跳过这些以节省令牌:
  • HTML文件 — 静态资源,绝不影响部署逻辑
  • 锁文件内容 — 仅需检查存在哪种锁文件(以确定包管理器),无需解析内容
  • Markdown文件 — 仅为文档,绝不影响Dockerfile的决策

Workflow

工作流程

1. Analyze the Project

1. 分析项目

From the prerequisite files, determine:
  1. Programming language and version
  2. Framework (if any)
  3. Package manager
  4. Build command
  5. Start command
  6. Port the app listens on
  7. Static site vs server-side app
从前置文件中确定:
  1. 编程语言及版本
  2. 框架(如有)
  3. 包管理器
  4. 构建命令
  5. 启动命令
  6. 应用监听的端口
  7. 静态站点还是服务端应用

2. Generate the Dockerfile

2. 生成Dockerfile

General Rules

通用规则

  • No comments in the Dockerfile
  • No
    ENV
    or
    ARG
    instructions (unless required by the framework — see language-specific sections)
  • Add
    LABEL "language"="<lang>"
    — possible values:
    nodejs
    ,
    python
    ,
    go
    ,
    static
    ,
    ruby
    ,
    java
    ,
    php
    ,
    rust
    ,
    dotnet
    ,
    elixir
    ,
    swift
    ,
    bun
  • Add
    LABEL "framework"="<framework>"
    only for actual web frameworks (see list below)
  • Always
    COPY . .
    before running any install/build commands
  • Set
    WORKDIR /src
    unless the user specifies otherwise
  • Add
    EXPOSE
    for the port the app listens on
  • Do not use multi-stage builds unless the build image differs from the runtime image (e.g., build with Node.js, serve with
    zeabur/caddy-static
    )
  • Dockerfile中不添加注释
  • 不使用
    ENV
    ARG
    指令(除非框架要求——见各语言特定章节)
  • 添加
    LABEL "language"="<lang>"
    — 可选值:
    nodejs
    python
    go
    static
    ruby
    java
    php
    rust
    dotnet
    elixir
    swift
    bun
  • 仅为实际Web框架添加
    LABEL "framework"="<framework>"
    (见下方列表)
  • 在运行任何安装/构建命令前始终执行
    COPY . .
  • 除非用户另有指定,否则设置
    WORKDIR /src
  • 为应用监听的端口添加
    EXPOSE
    指令
  • 除非构建镜像与运行时镜像不同(例如用Node.js构建,用
    zeabur/caddy-static
    提供服务),否则不使用多阶段构建

Framework vs Package — Only These Get a Framework Label

框架与包的区分 — 仅以下内容可标记为框架

Frameworks (use
LABEL "framework"="..."
):
vite
,
create-react-app
,
next.js
,
remix
,
nuxt.js
,
umi
,
nest.js
,
hexo
,
vitepress
,
astro
,
sli.dev
,
docusaurus
,
nitropack
,
hono
,
medusa
,
svelte
,
flask
,
django
,
fastapi
,
spring-boot
,
laravel
,
thinkphp
,
rails
,
aspnet
,
blazorwasm
,
elysia
,
baojs
Never label as framework (these are packages/libraries):
  • Python: gradio, pandas, numpy, requests, matplotlib, scikit-learn, tensorflow, pytorch, opencv, pillow, beautifulsoup4, selenium
  • Node.js: express, koa, hapi, fastify, socket.io, moment, lodash, axios
  • Other: bootstrap, jquery, chart.js, three.js, d3.js
If unsure whether something is a framework or package, do NOT add the framework label.
框架(使用
LABEL "framework"="..."
):
vite
create-react-app
next.js
remix
nuxt.js
umi
nest.js
hexo
vitepress
astro
sli.dev
docusaurus
nitropack
hono
medusa
svelte
flask
django
fastapi
spring-boot
laravel
thinkphp
rails
aspnet
blazorwasm
elysia
baojs
绝不能标记为框架(这些是包/库):
  • Python: gradio、pandas、numpy、requests、matplotlib、scikit-learn、tensorflow、pytorch、opencv、pillow、beautifulsoup4、selenium
  • Node.js: express、koa、hapi、fastify、socket.io、moment、lodash、axios
  • 其他: bootstrap、jquery、chart.js、three.js、d3.js
若不确定某内容是框架还是包,请不要添加框架标签。

Static Sites —
zeabur/caddy-static

静态站点 — 使用
zeabur/caddy-static

For pure static websites (Vite, Astro static, Docusaurus, plain HTML), use
zeabur/caddy-static
:
dockerfile
FROM node:22-slim AS build
LABEL "language"="nodejs"
LABEL "framework"="vite"
WORKDIR /src
COPY . .
RUN npm install
RUN npm run build

FROM zeabur/caddy-static
COPY --from=build /src/dist /usr/share/caddy
Rules for
zeabur/caddy-static
:
  • Copy build output to
    /usr/share/caddy
  • Do NOT add
    CMD
    or
    ENTRYPOINT
    — the image handles it
  • It listens on port
    8080
  • Only use for truly static sites. Do NOT use for SSR frameworks (Next.js, Nuxt.js, SvelteKit, etc.)
  • If building with Node.js then serving as static, set
    LABEL "language"="nodejs"
    (not
    "static"
    )
对于纯静态网站(Vite、Astro静态版、Docusaurus、纯HTML),使用
zeabur/caddy-static
dockerfile
FROM node:22-slim AS build
LABEL "language"="nodejs"
LABEL "framework"="vite"
WORKDIR /src
COPY . .
RUN npm install
RUN npm run build

FROM zeabur/caddy-static
COPY --from=build /src/dist /usr/share/caddy
zeabur/caddy-static
使用规则:
  • 将构建产物复制到
    /usr/share/caddy
  • 不要添加
    CMD
    ENTRYPOINT
    — 镜像会自动处理
  • 监听端口为
    8080
  • 仅用于真正的静态站点,不要用于SSR框架(Next.js、Nuxt.js、SvelteKit等)
  • 若用Node.js构建后以静态方式提供服务,请设置
    LABEL "language"="nodejs"
    (而非
    "static"

Node.js

Node.js

  • Default base image:
    node:22-slim
  • Determine package manager by lockfile presence:
LockfilePackage managerInstall command
package-lock.json
npm
npm install
yarn.lock
yarn
yarn install
pnpm-lock.yaml
pnpm
RUN npm install -g pnpm && pnpm install
  • When using
    npm
    , use
    npm install
    . Do NOT use
    npm ci
    or flags like
    --only=production
    ,
    --omit=dev
    ,
    --frozen-lockfile
    .
  • For Vite static sites (React, Vue static builds), use
    zeabur/caddy-static
    to serve.
  • For Vite with SSR frameworks (SvelteKit), use Node.js runtime.
Next.js — Zeabur injects
PORT=8080
into the container, so Next.js production mode listens on 8080 by default. No extra config needed.
dockerfile
FROM node:22-slim
LABEL "language"="nodejs"
LABEL "framework"="next.js"
WORKDIR /src
COPY . .
RUN npm install
RUN npm run build
EXPOSE 8080
CMD ["npm", "start"]
Svelte / SvelteKit — Use
node:22
(not alpine, not slim). Set
ENV PORT=8080
. Single-stage build — do NOT use
zeabur/caddy-static
. Do NOT use
cross-env ADAPTER=static
or adapter-specific build commands.
dockerfile
FROM node:22
LABEL "language"="nodejs"
LABEL "framework"="svelte"
ENV PORT=8080
WORKDIR /src
RUN npm install -g pnpm@9
COPY . .
RUN pnpm install
RUN pnpm build
EXPOSE 8080
CMD ["pnpm", "start"]
  • 默认基础镜像:
    node:22-slim
  • 根据锁文件的存在确定包管理器:
锁文件包管理器安装命令
package-lock.json
npm
npm install
yarn.lock
yarn
yarn install
pnpm-lock.yaml
pnpm
RUN npm install -g pnpm && pnpm install
  • 使用npm时,执行
    npm install
    ,不要使用
    npm ci
    --only=production
    --omit=dev
    --frozen-lockfile
    等参数
  • 对于Vite静态站点(React、Vue静态构建),使用
    zeabur/caddy-static
    提供服务
  • 对于带SSR框架的Vite(如SvelteKit),使用Node.js运行时
Next.js — Zeabur会将
PORT=8080
注入容器,因此Next.js生产模式默认监听8080端口,无需额外配置。
dockerfile
FROM node:22-slim
LABEL "language"="nodejs"
LABEL "framework"="next.js"
WORKDIR /src
COPY . .
RUN npm install
RUN npm run build
EXPOSE 8080
CMD ["npm", "start"]
Svelte / SvelteKit — 使用
node:22
(不要用alpine或slim),设置
ENV PORT=8080
,采用单阶段构建——不要使用
zeabur/caddy-static
,不要使用
cross-env ADAPTER=static
或特定适配器的构建命令。
dockerfile
FROM node:22
LABEL "language"="nodejs"
LABEL "framework"="svelte"
ENV PORT=8080
WORKDIR /src
RUN npm install -g pnpm@9
COPY . .
RUN pnpm install
RUN pnpm build
EXPOSE 8080
CMD ["pnpm", "start"]

Python

Python

  • Default base image:
    python:3.10
Flask — Find the WSGI entry first. For example, if
main.py
contains
app = Flask(__name__)
, the entry is
main:app
.
dockerfile
FROM python:3.10
LABEL "language"="python"
LABEL "framework"="flask"
WORKDIR /src
COPY . .
RUN pip install -r requirements.txt gunicorn
EXPOSE 8080
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "main:app"]
FastAPI — Choose the start method based on what exists:
  1. If
    fastapi-cli
    is in
    requirements.txt
    fastapi run
  2. If
    if __name__ == "__main__":
    exists in a
    .py
    file →
    python <file>.py
  3. Otherwise →
    uvicorn main:app --host 0.0.0.0 --port 8080
    (install
    uvicorn
    if missing)
dockerfile
FROM python:3.10
LABEL "language"="python"
LABEL "framework"="fastapi"
WORKDIR /src
COPY . .
RUN pip install -r requirements.txt
EXPOSE 8080
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]
Generic Python — If WSGI might be applicable, use
gunicorn
. If unsure, just use
python <file>.py
.
  • 默认基础镜像:
    python:3.10
Flask — 先找到WSGI入口。例如,若
main.py
包含
app = Flask(__name__)
,则入口为
main:app
dockerfile
FROM python:3.10
LABEL "language"="python"
LABEL "framework"="flask"
WORKDIR /src
COPY . .
RUN pip install -r requirements.txt gunicorn
EXPOSE 8080
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "main:app"]
FastAPI — 根据现有内容选择启动方式:
  1. requirements.txt
    中包含
    fastapi-cli
    → 使用
    fastapi run
  2. 若某
    .py
    文件中存在
    if __name__ == "__main__":
    → 使用
    python <file>.py
  3. 其他情况 → 使用
    uvicorn main:app --host 0.0.0.0 --port 8080
    (若缺失则安装
    uvicorn
dockerfile
FROM python:3.10
LABEL "language"="python"
LABEL "framework"="fastapi"
WORKDIR /src
COPY . .
RUN pip install -r requirements.txt
EXPOSE 8080
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]
通用Python — 若适用WSGI,使用
gunicorn
;若不确定,直接使用
python <file>.py

Go

Go

dockerfile
FROM golang:1.23 AS build
WORKDIR /src
COPY . .
RUN go build -o /app .

FROM debian:bookworm-slim
LABEL "language"="go"
COPY --from=build /app /app
EXPOSE 8080
CMD ["/app"]
dockerfile
FROM golang:1.23 AS build
WORKDIR /src
COPY . .
RUN go build -o /app .

FROM debian:bookworm-slim
LABEL "language"="go"
COPY --from=build /app /app
EXPOSE 8080
CMD ["/app"]

PHP (Laravel / Symfony / Generic)

PHP(Laravel / Symfony / 通用)

Uses NGINX + PHP-FPM. Adjust PHP version and extensions as needed.
dockerfile
FROM php:8.3-fpm
LABEL "language"="php"
WORKDIR /var/www
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && sync
RUN apt update && apt install -y cron curl gettext git grep libicu-dev nginx pkg-config unzip && rm -rf /var/lib/apt/lists/*
RUN install-php-extensions @composer apcu bcmath gd intl mysqli opcache pcntl pdo_mysql sysvsem zip
RUN cat <<'NGINX' > /etc/nginx/sites-enabled/default
server {
    listen 8080;
    root /var/www;
    index index.php index.html;
    charset utf-8;
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt { access_log off; log_not_found off; }
    error_page 404 /index.php;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }
    location ~ /\.(?!well-known).* { deny all; }
    error_log /dev/stderr;
    access_log /dev/stderr;
}
NGINX
RUN chown -R www-data:www-data /var/www
COPY --chown=www-data:www-data . /var/www
USER www-data
RUN if [ -f composer.json ]; then composer install --optimize-autoloader --classmap-authoritative --no-dev; fi && if [ -f package.json ]; then npm install; fi
USER root
EXPOSE 8080
CMD ["sh", "-c", "php-fpm -D && nginx -g 'daemon off;'"]
For Laravel, add optimization after
composer install
:
dockerfile
RUN php artisan config:cache && php artisan route:cache && php artisan view:cache
使用NGINX + PHP-FPM,根据需要调整PHP版本和扩展。
dockerfile
FROM php:8.3-fpm
LABEL "language"="php"
WORKDIR /var/www
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && sync
RUN apt update && apt install -y cron curl gettext git grep libicu-dev nginx pkg-config unzip && rm -rf /var/lib/apt/lists/*
RUN install-php-extensions @composer apcu bcmath gd intl mysqli opcache pcntl pdo_mysql sysvsem zip
RUN cat <<'NGINX' > /etc/nginx/sites-enabled/default
server {
    listen 8080;
    root /var/www;
    index index.php index.html;
    charset utf-8;
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt { access_log off; log_not_found off; }
    error_page 404 /index.php;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }
    location ~ /\.(?!well-known).* { deny all; }
    error_log /dev/stderr;
    access_log /dev/stderr;
}
NGINX
RUN chown -R www-data:www-data /var/www
COPY --chown=www-data:www-data . /var/www
USER www-data
RUN if [ -f composer.json ]; then composer install --optimize-autoloader --classmap-authoritative --no-dev; fi && if [ -f package.json ]; then npm install; fi
USER root
EXPOSE 8080
CMD ["sh", "-c", "php-fpm -D && nginx -g 'daemon off;'"]
对于Laravel,在
composer install
后添加优化步骤:
dockerfile
RUN php artisan config:cache && php artisan route:cache && php artisan view:cache

3. Handle Existing Dockerfiles

3. 处理已存在的Dockerfile

  • Analyze the existing Dockerfile first
  • Use it as-is if it looks correct
  • Suggest improvements only if there are issues (wrong port, missing dependencies, etc.)
  • Always add Zeabur-specific labels (
    language
    ,
    framework
    ) if missing
  • 先分析已有的Dockerfile
  • 如果看起来正确则直接使用
  • 仅当存在问题(端口错误、依赖缺失等)时建议改进
  • 如果缺少Zeabur特定标签(
    language
    framework
    ),请务必添加

CLI Commands

CLI命令

After generating the Dockerfile, deploy with:
bash
npx zeabur@latest deploy --project-id <project-id> --json
For redeployment (must pass service ID to avoid creating duplicates):
bash
npx zeabur@latest deploy --project-id <project-id> --service-id <service-id> --json
Use the
zeabur-deploy
skill for the full deployment workflow.
生成Dockerfile后,使用以下命令部署:
bash
npx zeabur@latest deploy --project-id <project-id> --json
重新部署时(必须传入服务ID以避免创建重复服务):
bash
npx zeabur@latest deploy --project-id <project-id> --service-id <service-id> --json
完整部署流程请使用
zeabur-deploy
技能。

Error Handling

错误处理

If the build or runtime fails:
  1. Check build logs with the
    zeabur-deployment-logs
    skill
  2. Common issues:
    • Missing dependencies — add to
      RUN
      install step
    • Wrong port — verify
      EXPOSE
      matches what the app listens on; check with
      zeabur-port-mismatch
      skill
    • Wrong start command — verify
      CMD
      matches the project's actual entry point
    • Static site served as SSR — switch to
      zeabur/caddy-static
      if the app produces static output
    • SSR served as static — switch to Node.js runtime if the app requires a server
  3. Fix the Dockerfile, then redeploy with
    --service-id
    to update the existing service
如果构建或运行失败:
  1. 使用
    zeabur-deployment-logs
    技能查看构建日志
  2. 常见问题:
    • 依赖缺失 — 在
      RUN
      安装步骤中添加缺失的依赖
    • 端口错误 — 验证
      EXPOSE
      与应用监听的端口是否匹配;使用
      zeabur-port-mismatch
      技能排查
    • 启动命令错误 — 验证
      CMD
      与项目实际入口是否一致
    • 静态站点被当作SSR部署 — 如果应用生成静态产物,切换为
      zeabur/caddy-static
    • SSR被当作静态站点部署 — 如果应用需要服务器,切换为Node.js运行时
  3. 修复Dockerfile后,使用
    --service-id
    参数重新部署以更新现有服务