I end up using a docker image of mailcatcher.
I use the default docker-compose.yml, but use this docker-compose.override.yml:
version: '3' services: mailcatcher: image: yappabe/mailcatcher ports: - "1025:1025" - "1080:1080" networks: - mailcatcher search: image: docker.elastic.co/elasticsearch/elasticsearch:7.8.1 environment: cluster.name: fusionauth bootstrap.memory_lock: "true" discovery.type: single-node FUSIONAUTH_SEARCH_MEMORY: ${FUSIONAUTH_SEARCH_MEMORY} ES_JAVA_OPTS: ${ES_JAVA_OPTS} # Un-comment to access the search service directly # ports: # - 9200:9200 # - 9300:9300 networks: - search restart: unless-stopped ulimits: memlock: soft: -1 hard: -1 volumes: - es_data:/usr/share/elasticsearch/data fusionauth: depends_on: - search - mailcatcher environment: SEARCH_SERVERS: http://search:9200 SEARCH_TYPE: elasticsearch networks: - mailcatcher - search networks: search: driver: bridge mailcatcher: driver: bridge volumes: es_data:Then I configure the SMTP settings to use the hostname mailcatcher and the port 1025. I can then send email and view it in the mailcatcher interface, at localhost:1080.
Here's the relevant dockerfile: https://github.com/yappabe/docker-mailcatcher/blob/master/Dockerfile
Here's more about mailcatcher: https://mailcatcher.me/