使用 Docker 化的 Flutter 构建和 Nginx 将 Flutter Web 应用 Docker 化

使用 Docker 容器构建和托管 Flutter Web 应用

目录

几个 Dockerfile 示例用于构建和托管 Flutter Web 应用 的示例,包括基于 Ubuntu 的 Flutter 构建镜像 + Web 应用镜像在 Nginx 上的部署。

docker+flutter logos

一体化 Dockerfile

构建 Flutter Web 应用的典型 Dockerfile 可能如下所示。 它使用 ubuntu:latest 作为基础构建镜像,安装 Flutter,构建 Web 应用,并将其复制到 nginx:alpine 镜像中。 由于 nginx:alpine 的大小为 48.2MB,托管在 nginx 上的 Web 应用镜像大小将略大于 73 MB。

FROM ubuntu:latest AS builder

# 安装依赖
RUN apt-get update && apt-get install -y \
    curl \
    git \
    unzip \
    xz-utils \
    zip \
    libglu1-mesa

# 安装 Flutter
RUN git clone https://github.com/flutter/flutter.git /flutter
ENV PATH="/flutter/bin:${PATH}"
RUN flutter doctor
RUN flutter channel stable
RUN flutter upgrade


# 添加构建参数
ARG MY_MEGA_API_URL
ENV MY_MEGA_API_URL=${MY_MEGA_API_URL}


# 复制应用源代码
WORKDIR /app
COPY . .

# 获取应用依赖
RUN flutter pub get

# 清理任何现有构建并为 Web 构建
RUN flutter clean
RUN flutter build web --release --verbose --dart-define=MY_MEGA_API_URL=${MY_MEGA_API_URL}

# 第二阶段 - 创建最终镜像,使用 Nginx 提供静态文件服务
FROM nginx:alpine

# 从构建阶段复制构建结果
COPY --from=builder /app/build/web /usr/share/nginx/html

# 复制 Nginx 配置
RUN echo 'server { \
    listen 80; \
    server_name localhost; \
    root /usr/share/nginx/html; \
    index index.html; \
    \
    # 处理静态资源并使用正确的 MIME 类型 \
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|json)$ { \
        expires 1y; \
        add_header Cache-Control "public, immutable"; \
        try_files $uri =404; \
    } \
    \
    # 处理 Flutter Web 路由 \
    location / { \
        try_files $uri $uri/ @fallback; \
    } \
    \
    location @fallback { \
        rewrite ^.*$ /index.html last; \
    } \
    \
    # 安全头信息 \
    add_header X-Frame-Options "SAMEORIGIN" always; \
    add_header X-Content-Type-Options "nosniff" always; \
    add_header X-XSS-Protection "1; mode=block" always; \
}' > /etc/nginx/conf.d/default.conf

# 暴露端口
EXPOSE 80

# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"] 

Docker 化的 Flutter

如果你正在处理多个 Flutter Web 应用,那么用于中间构建镜像的临时文件会占用一些磁盘空间。因此,创建一个用于 Flutter 构建的单一镜像并在多个项目中重复使用是有意义的。在我电脑上,这个镜像仅占用 3.47GB 的空间。

以下是一个简单的 Flutter 构建镜像的 Dockerfile。将其保存为 Dockerfile.flutter

FROM ubuntu:latest AS builder

# 安装依赖
RUN apt-get update && apt-get install -y \
    curl \
    git \
    unzip \
    xz-utils \
    zip \
    libglu1-mesa

# 安装 Flutter
RUN git clone https://github.com/flutter/flutter.git /flutter
ENV PATH="/flutter/bin:${PATH}"
RUN flutter doctor
RUN flutter channel stable
RUN flutter upgrade

使用以下命令构建它:

docker build -f Dockerfile.flutter -t rg-flutter:1.0 .

简化版 Flutter Web 应用 Dockerfile

FROM rg-flutter:1.0 AS builder

# 添加构建参数
ARG MY_MEGA_API_URL
ENV MY_MEGA_API_URL=${MY_MEGA_API_URL}


# 复制应用源代码
WORKDIR /app
COPY . .

# 获取应用依赖
RUN flutter pub get

# 清理任何现有构建并为 Web 构建
RUN flutter clean
RUN flutter build web --release --verbose --dart-define=MY_MEGA_API_URL=${MY_MEGA_API_URL}

# 第二阶段 - 创建最终镜像,使用 Nginx 提供静态文件服务
FROM nginx:alpine

# 从构建阶段复制构建结果
COPY --from=builder /app/build/web /usr/share/nginx/html

# 复制 Nginx 配置
RUN echo 'server { \
    listen 80; \
    server_name localhost; \
    root /usr/share/nginx/html; \
    index index.html; \
    \
    # 处理静态资源并使用正确的 MIME 类型 \
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|json)$ { \
        expires 1y; \
        add_header Cache-Control "public, immutable"; \
        try_files $uri =404; \
    } \
    \
    # 处理 Flutter Web 路由 \
    location / { \
        try_files $uri $uri/ @fallback; \
    } \
    \
    location @fallback { \
        rewrite ^.*$ /index.html last; \
    } \
    \
    # 安全头信息 \
    add_header X-Frame-Options "SAMEORIGIN" always; \
    add_header X-Content-Type-Options "nosniff" always; \
    add_header X-XSS-Protection "1; mode=block" always; \
}' > /etc/nginx/conf.d/default.conf

# 暴露端口
EXPOSE 80

# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"] 

有用的链接