Dockeriser une application Flutter Web avec une construction Flutter dockerisée et Nginx

Construire et héberger une application Flutter Web avec des conteneurs Docker

Sommaire

Plusieurs exemples de fichiers Dockerfile pour la construction et l’hébergement d’applications web Flutter,
Image de construction Flutter basée sur Ubuntu + Image d’application web sur Nginx.

logos Docker+Flutter

Dockerfile tout-en-un

Un Dockerfile typique pour la construction d’applications web Flutter pourrait ressembler à celui ci-dessous.
Il utilise ubuntu:latest comme image de base pour la construction, installe Flutter, construit l’application web et la copie dans l’image nginx:alpine.
L’image résultante de l’application web hébergée sur Nginx serait un peu plus de 73 Mo, grâce à la taille de 48,2 Mo de l’image nginx:alpine.

FROM ubuntu:latest AS builder

# Installer les dépendances
RUN apt-get update && apt-get install -y \
    curl \
    git \
    unzip \
    xz-utils \
    zip \
    libglu1-mesa

# Installer 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


# Ajouter un argument de construction
ARG MY_MEGA_API_URL
ENV MY_MEGA_API_URL=${MY_MEGA_API_URL}


# Copier la source de l’application
WORKDIR /app
COPY . .

# Obtenir les dépendances de l’application
RUN flutter pub get

# Nettoyer tout build existant et construire pour le web
RUN flutter clean
RUN flutter build web --release --verbose --dart-define=MY_MEGA_API_URL=${MY_MEGA_API_URL}

# Étape 2 - Créer l’image finale avec Nginx pour servir les fichiers statiques
FROM nginx:alpine

# Copier le build depuis l’étape de construction
COPY --from=builder /app/build/web /usr/share/nginx/html

# Copier la configuration Nginx
RUN echo 'server { \
    listen 80; \
    server_name localhost; \
    root /usr/share/nginx/html; \
    index index.html; \
    \
    # Gérer les actifs statiques avec les types MIME appropriés \
    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; \
    } \
    \
    # Gérer le routage web Flutter \
    location / { \
        try_files $uri $uri/ @fallback; \
    } \
    \
    location @fallback { \
        rewrite ^.*$ /index.html last; \
    } \
    \
    # En-têtes de sécurité \
    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

# Exposer le port
EXPOSE 80

# Démarrer Nginx
CMD ["nginx", "-g", "daemon off;"] 

Flutter Dockerisé

Mais si vous avez plusieurs applications web Flutter sur lesquelles vous travaillez, ces fichiers temporaires pour l’image de construction intermédiaire prendraient de l’espace disque. Il est donc logique de créer une seule image pour la construction Flutter et de la réutiliser sur plusieurs projets. L’exemple ci-dessous occupe uniquement 3,47 Go sur mon PC.

Voici un simple Dockerfile pour l’image de construction Flutter. Enregistrez-le comme Dockerfile.flutter.

FROM ubuntu:latest AS builder

# Installer les dépendances
RUN apt-get update && apt-get install -y \
    curl \
    git \
    unzip \
    xz-utils \
    zip \
    libglu1-mesa

# Installer 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

Exécutons la construction avec

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

Dockerfile simplifié pour une application web Flutter

FROM rg-flutter:1.0 AS builder

# Ajouter un argument de construction
ARG MY_MEGA_API_URL
ENV MY_MEGA_API_URL=${MY_MEGA_API_URL}


# Copier la source de l’application
WORKDIR /app
COPY . .

# Obtenir les dépendances de l’application
RUN flutter pub get

# Nettoyer tout build existant et construire pour le web
RUN flutter clean
RUN flutter build web --release --verbose --dart-define=MY_MEGA_API_URL=${MY_MEGA_API_URL}

# Étape 2 - Créer l’image finale avec Nginx pour servir les fichiers statiques
FROM nginx:alpine

# Copier le build depuis l’étape de construction
COPY --from=builder /app/build/web /usr/share/nginx/html

# Copier la configuration Nginx
RUN echo 'server { \
    listen 80; \
    server_name localhost; \
    root /usr/share/nginx/html; \
    index index.html; \
    \
    # Gérer les actifs statiques avec les types MIME appropriés \
    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; \
    } \
    \
    # Gérer le routage web Flutter \
    location / { \
        try_files $uri $uri/ @fallback; \
    } \
    \
    location @fallback { \
        rewrite ^.*$ /index.html last; \
    } \
    \
    # En-têtes de sécurité \
    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

# Exposer le port
EXPOSE 80

# Démarrer Nginx
CMD ["nginx", "-g", "daemon off;"] 

Liens utiles