diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c9702bc2cc946d28290f5e4fb15396dea7cd96d1..cab890e9058007f8509c0dc202c5e99a7c872923 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,35 +1,56 @@
+stages:
+  - without-vendors
+  - with-vendors
 
-.defaults: &defaults
+.without-vendors: &without-vendors
   tags: [ docker ]
+  stage: without-vendors
   image: isdevtools.irstea.fr/poleis/php-analysis:7.1
+  dependencies: []
 
 phploc:
-  <<: *defaults
+  <<: *without-vendors
   script: phploc src tests
 
 lint:
-  <<: *defaults
+  <<: *without-vendors
   script:
     - parallel-lint -j $(nproc) src tests
     - twig-lint lint src
     - yaml-lint src
 
 php-cs-fixer:
-  <<: *defaults
+  <<: *without-vendors
   script: php-cs-fixer fix --dry-run --verbose
 
 phpcpd:
-  <<: *defaults
+  <<: *without-vendors
   script: phpcpd --fuzzy src tests
 
-.with-vendors: &with-vendors
-  <<: *defaults
-  before_script:
-    - composer install --prefer-dist --no-progress --no-suggest
+install-vendors:
+  <<: *without-vendors
+  image: isdevtools.irstea.fr/poleis/php-apache2:stretch-7.1
+  variables:
+    S6_TARGET: none
+    COMPOSER_NO_INTERACTION: "1"
+  script:
+    - phpenmod iconv
+    - composer validate
+    - composer install -n --prefer-dist --no-suggest --no-progress --no-scripts --ignore-platform-reqs
   cache:
-    key: "$CI_COMMIT_REF_NAME"
+    key: "$CI_COMMIT_REF_NAME-composer-cache"
     paths:
       - /composer/cache
+  artifacts:
+    name: vendors
+    paths:
+      - vendor
+    expire_in: "1 day"
+
+.with-vendors: &with-vendors
+  <<: *without-vendors
+  stage: with-vendors
+  dependencies: [ install-vendors ]
 
 phpunit:
   <<: *with-vendors
@@ -42,3 +63,4 @@ composer-require-checker:
 phpmd:
   <<: *with-vendors
   script: phpmd src,tests text ./phpmd-ruleset.xml --suffixes=php
+