Dockerizar una aplicación Flutter Web con la construcción de Flutter dockerizada y Nginx
Construya y aloje una aplicación web de Flutter con contenedores de Docker
Varias ejemplos de Dockerfiles para construir y alojar aplicaciones web Flutter, Imagen de construcción de Flutter basada en Ubuntu + imagen de aplicación web en Nginx.
Dockerfile todo en uno
Un Dockerfile típico para construir aplicaciones web Flutter podría parecerse al que se muestra a continuación.
Utiliza ubuntu:latest
como imagen base de construcción, instala Flutter, construye la aplicación web y la copia a la imagen nginx:alpine
.
La imagen resultante de la aplicación web alojada en nginx sería un poco más de 73 MB, gracias al tamaño de nginx:alpine de 48,2 MB.
FROM ubuntu:latest AS builder
# Instalar dependencias
RUN apt-get update && apt-get install -y \
curl \
git \
unzip \
xz-utils \
zip \
libglu1-mesa
# Instalar 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
# Agregar argumento de construcción
ARG MY_MEGA_API_URL
ENV MY_MEGA_API_URL=${MY_MEGA_API_URL}
# Copiar código fuente de la aplicación
WORKDIR /app
COPY . .
# Obtener dependencias de la aplicación
RUN flutter pub get
# Limpiar cualquier construcción existente y construir para web
RUN flutter clean
RUN flutter build web --release --verbose --dart-define=MY_MEGA_API_URL=${MY_MEGA_API_URL}
# Etapa 2 - Crear la imagen final con nginx para servir los archivos estáticos
FROM nginx:alpine
# Copiar la construcción de la etapa de construcción
COPY --from=builder /app/build/web /usr/share/nginx/html
# Copiar configuración de nginx
RUN echo 'server { \
listen 80; \
server_name localhost; \
root /usr/share/nginx/html; \
index index.html; \
\
# Manejar activos estáticos con tipos MIME adecuados \
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; \
} \
\
# Manejar enrutamiento de Flutter web \
location / { \
try_files $uri $uri/ @fallback; \
} \
\
location @fallback { \
rewrite ^.*$ /index.html last; \
} \
\
# Encabezados de seguridad \
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
# Exponer puerto
EXPOSE 80
# Iniciar Nginx
CMD ["nginx", "-g", "daemon off;"]
Flutter dockerizado
Pero si tienes varias aplicaciones web Flutter en las que estás trabajando, esos archivos temporales para la imagen de construcción intermedia consumirían algo de espacio en tu disco duro. Tiene sentido crear una sola imagen para la construcción de Flutter y reutilizarla en los proyectos. La siguiente imagen ocupa 3,47 GB en mi PC solo una vez.
Aquí hay un sencillo Dockerfile para la imagen de construcción de Flutter. Guárdalo como Dockerfile.flutter
.
FROM ubuntu:latest AS builder
# Instalar dependencias
RUN apt-get update && apt-get install -y \
curl \
git \
unzip \
xz-utils \
zip \
libglu1-mesa
# Instalar 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
Vamos a construirlo con
docker build -f Dockerfile.flutter -t rg-flutter:1.0 .
Dockerfile simplificado para aplicación web Flutter
FROM rg-flutter:1.0 AS builder
# Agregar argumento de construcción
ARG MY_MEGA_API_URL
ENV MY_MEGA_API_URL=${MY_MEGA_API_URL}
# Copiar código fuente de la aplicación
WORKDIR /app
COPY . .
# Obtener dependencias de la aplicación
RUN flutter pub get
# Limpiar cualquier construcción existente y construir para web
RUN flutter clean
RUN flutter build web --release --verbose --dart-define=MY_MEGA_API_URL=${MY_MEGA_API_URL}
# Etapa 2 - Crear la imagen final con nginx para servir los archivos estáticos
FROM nginx:alpine
# Copiar la construcción de la etapa de construcción
COPY --from=builder /app/build/web /usr/share/nginx/html
# Copiar configuración de nginx
RUN echo 'server { \
listen 80; \
server_name localhost; \
root /usr/share/nginx/html; \
index index.html; \
\
# Manejar activos estáticos con tipos MIME adecuados \
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; \
} \
\
# Manejar enrutamiento de Flutter web \
location / { \
try_files $uri $uri/ @fallback; \
} \
\
location @fallback { \
rewrite ^.*$ /index.html last; \
} \
\
# Encabezados de seguridad \
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
# Exponer puerto
EXPOSE 80
# Iniciar Nginx
CMD ["nginx", "-g", "daemon off;"]