Configuración de Apache para que las imágenes se almacenen en caché durante mucho tiempo

Configuración de Apache para que las imágenes se almacenen en caché durante mucho tiempo

Lo pregunto aquí ya que no importa lo que intento, sigo notando que las imágenes se siguen recargando después de un tiempo. Básicamente, quiero que las imágenes se almacenen en caché durante 11 meses, pero en todo caso parecen estar almacenadas en caché durante minutos u horas. Esta es una aplicación node.js con archivos estáticos servidos por Apache. Las imágenes están dentro del directorio público/estático. Esto es lo que tengo:

NameVirtualHost *:443

<VirtualHost *:443>
  ServerName app.site.com

  ProxyPreserveHost   On

  RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
  RequestHeader set "X-Forwarded-SSL" expr=%{HTTPS}

  Alias "/static/" "/home/node/app/public/static/"

  <Directory /home/node/app/public>

    Options FollowSymLinks
    AllowOverride None
    Require all granted

    ExpiresActive On
    ExpiresByType image/jpeg "access plus 11 months"
    ExpiresByType image/jpg "access plus 11 months"
    ExpiresByType image/png "access plus 11 months"
    ExpiresByType image/gif "access plus 11 months"

  </Directory>

  RewriteEngine On
  RewriteCond %{HTTP:Upgrade} =websocket [NC]
  RewriteRule /(.*)                  ws://localhost:3210/$1 [P,L]
  RewriteCond %{HTTP:Upgrade} !=websocket [NC]
  RewriteRule ^/(?!static/)(.*)$ http://localhost:3210/$1 [P,L]

  SSLCertificateFile /root/.lego/certificates/_.site.com.crt
  SSLCertificateKeyFile /root/.lego/certificates/_.site.com.key

</VirtualHost>

Tener la consola abierta y recargada para detectar la actividad de la red muestra esto en una imagen aleatoria:

200 OK

Response header:

HTTP/1.1 200 OK
Date: Wed, 12 Aug 2020 10:27:50 GMT
Server: Apache
Last-Modified: Mon, 01 Jun 2020 19:03:16 GMT
ETag: "3313-5a70a727f2500"
Accept-Ranges: bytes
Content-Length: 13075
Cache-Control: max-age=28512000
Expires: Thu, 08 Jul 2021 10:27:50 GMT
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: image/png

Request header:

GET /static/img/profile_5a914158141c9367e38c4d8a.png?ver=74 HTTP/1.1
Host: hue.merkoba.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:79.0) Gecko/20100101 Firefox/79.0
Accept: image/webp,*/*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Referer: https://app.site.com/
Cookie: connect.sid=s%3AUZb7Zopuy6LId0iMeMYVaKDtfuppIIxL.8F7Hx%2FeqrodOsS2fHPZjOqRDKTBM4RoBwcKiUu0PUUg; io=fbMMZAHDTJzbnoVvAAAo
Cache-Control: max-age=0
If-Modified-Since: Mon, 01 Jun 2020 19:03:16 GMT
If-None-Match: "3313-5a70a727f2500"

Algunas pruebas de rizo:

curl -vso /dev/null https://app.site.com/static/img/profile_5f192733805c646004ecf4c8.png?ver=1
*   Trying 196.83.125.124:443...
* TCP_NODELAY set
* Connected to app.site.com (192.81.135.159) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [112 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2391 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [147 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [37 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=*.site.com
*  start date: May 14 20:51:05 2020 GMT
*  expire date: Aug 12 20:51:05 2020 GMT
*  subjectAltName: host "app.site.com" matched cert's "*.site.com"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
} [5 bytes data]
> GET /static/img/profile_5f192733805c646004ecf4c8.png?ver=1 HTTP/1.1
> Host: app.site.com
> User-Agent: curl/7.68.0
> Accept: */*
> 
{ [5 bytes data]
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Wed, 12 Aug 2020 10:30:40 GMT
< Server: Apache
< Last-Modified: Thu, 23 Jul 2020 06:01:07 GMT
< ETag: "16f27-5ab15950eeec0"
< Accept-Ranges: bytes
< Content-Length: 93991
< Cache-Control: max-age=28512000
< Expires: Thu, 08 Jul 2021 10:30:40 GMT
< Content-Type: image/png
< 
{ [5 bytes data]
* Connection #0 to host app.site.com left intact

información relacionada