Guide d’installation de HAPI FHIR sur AWS EC2

Version personnalisée pour Amazon Linux 2023.11.20260526

Note

Décision technique retenue : L’installation se base directement sur Amazon Linux 2023. Ubuntu n’est pas nécessaire pour ce déploiement, car Docker est disponible sur Amazon Linux 2023 et convient à l’exécution de HAPI FHIR sous forme de conteneurs.

Accès via navigateur : http://13.247.174.189/

Objectif du document

Ce guide décrit les étapes nécessaires pour installer un serveur HAPI FHIR JPA sur une instance AWS EC2 utilisant Amazon Linux 2023.11.20260526. Il inclut la préparation de l’instance, les prérequis système, Docker, Docker Compose, PostgreSQL, HAPI FHIR, Nginx, HTTPS et les vérifications de fonctionnement.

1. Architecture cible

L’architecture proposée privilégie une installation simple, maintenable et adaptée à une instance EC2 unique. HAPI FHIR et PostgreSQL sont exécutés dans Docker. Nginx est installé directement sur Amazon Linux 2023 pour jouer le rôle de reverse proxy public.

Composant

Rôle

Port recommandé

AWS EC2

Serveur applicatif sous Amazon Linux 2023

22, 80, 443

Docker Engine

Exécution des conteneurs HAPI FHIR et PostgreSQL

Interne

HAPI FHIR

Serveur FHIR JPA exposé localement

127.0.0.1:8080

PostgreSQL

Base de données persistante de HAPI

Réseau Docker uniquement

Nginx

Reverse proxy public et terminaison HTTPS

80 et 443

Avertissement

Bonne pratique : Le port 8080 ne doit pas être ouvert publiquement dans le Security Group. L’accès externe doit passer par Nginx en HTTP/HTTPS.

2. Prérequis AWS

2.1 Instance EC2 recommandée

Élément

Recommandation

AMI

Amazon Linux 2023.11.20260526

Type minimal

t3.small pour test ; t3.medium ou supérieur pour usage plus sérieux

Stockage

Au moins 20 à 30 Go EBS gp3, davantage si beaucoup de ressources FHIR

Adresse IP

Elastic IP recommandée pour stabiliser l’adresse publique

DNS

Un nom de domaine ou sous-domaine pointant vers l’Elastic IP

2.2 Règles du Security Group

Créer ou modifier le Security Group associé à l’instance EC2. Le Security Group agit comme un pare-feu virtuel AWS qui contrôle le trafic entrant et sortant de l’instance.

Type

Port

Source

Utilisation

SSH

22

Votre adresse IP publique uniquement

Administration serveur

HTTP

80

0.0.0.0/0 et ::/0

Redirection vers HTTPS et validation Let’s Encrypt

HTTPS

443

0.0.0.0/0 et ::/0

Accès public sécurisé

Danger

À éviter : Ne pas ouvrir PostgreSQL 5432 ni HAPI 8080 au public. Ces services restent internes au serveur ou au réseau Docker.

2.3 Connexion SSH à l’instance

Depuis votre poste local, se connecter avec l’utilisateur par défaut d’Amazon Linux, généralement ec2-user :

ssh -i /chemin/vers/votre-cle.pem ec2-user@ADRESSE_IP_PUBLIQUE

3. Mise à jour et prérequis système Amazon Linux 2023

Les commandes suivantes sont adaptées à Amazon Linux 2023. Elles utilisent dnf/yum, pas apt. Il n’est donc pas nécessaire d’installer Ubuntu.

sudo dnf update -y
sudo dnf install -y git curl wget vim nano unzip tar jq htop

Configurer le fuseau horaire si nécessaire :

timedatectl
sudo timedatectl set-timezone Indian/Antananarivo

Créer l’arborescence de travail :

sudo mkdir -p /opt/hapi-fhir
sudo chown -R ec2-user:ec2-user /opt/hapi-fhir
cd /opt/hapi-fhir

4. Installation de Docker sur Amazon Linux 2023

Sur Amazon Linux 2023, Docker s’installe directement depuis les dépôts système. La commande officielle pour AL2023 est yum install -y docker. dnf peut également être utilisé, car Amazon Linux 2023 est basé sur un gestionnaire de paquets de type RPM.

sudo dnf install -y docker
sudo systemctl enable --now docker
sudo usermod -aG docker lalaina   # optionnel

Important

Après l’ajout de ec2-user au groupe docker, fermer la session SSH puis se reconnecter. Cela permet d’utiliser docker sans sudo.

Vérifier Docker :

docker --version

Résultat attendu

Docker version 25.0.14, build 0bab007
sudo docker ps

5. Installation de Docker Compose sur Amazon Linux 2023

Docker Compose v2 s’utilise avec la commande docker compose. Sur Amazon Linux 2023, le paquet docker-compose-plugin peut ne pas être disponible selon les dépôts activés. La méthode ci-dessous installe le plugin Compose manuellement pour tous les utilisateurs.

sudo mkdir -p /usr/local/lib/docker/cli-plugins
sudo curl -SL https://github.com/docker/compose/releases/download/v2.29.7/docker-compose-linux-x86_64 \
    -o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
docker compose version

Résultat attendu

Docker Compose version v2.29.7

Note

Architecture ARM : Si l’instance est de type Graviton/ARM64, remplacer docker-compose-linux-x86_64 par docker-compose-linux-aarch64.

6. Préparation des fichiers HAPI FHIR

6.1 Création du fichier .env

Le fichier .env centralise les paramètres sensibles et évite de laisser les mots de passe directement dans docker-compose.yml.

cd /opt/hapi-fhir
sudo nano .env

Contenu du fichier .env :

POSTGRES_DB=hapi
POSTGRES_USER=hapi_user
POSTGRES_PASSWORD=CHANGER_CE_MOT_DE_PASSE_SOLIDE
HAPI_PORT=8080

6.2 Création du fichier docker-compose.yml

Cette configuration lance PostgreSQL et HAPI FHIR. Le port HAPI est lié uniquement à 127.0.0.1 afin d’empêcher un accès direct depuis Internet.

sudo nano docker-compose.yml
services:
  hapi-postgres:
    image: postgres:16-alpine
    container_name: hapi-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - hapi-postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - hapi-net

  hapi-fhir:
    image: hapiproject/hapi:latest
    container_name: hapi-fhir
    restart: unless-stopped
    depends_on:
      hapi-postgres:
        condition: service_healthy
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://hapi-postgres:5432/${POSTGRES_DB}
      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER}
      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
      SPRING_DATASOURCE_DRIVER_CLASS_NAME: org.postgresql.Driver
      HIBERNATE_DIALECT: ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgresDialect
      hapi.fhir.server_address: http://13.247.174.189/fhir
      hapi.fhir.tester.home.server_address: http://13.247.174.189/fhir
      hapi.fhir.tester.home.name: HAPI FHIR AWS
    ports:
      - "127.0.0.1:${HAPI_PORT}:8080"
    networks:
      - hapi-net

volumes:
  hapi-postgres-data:

networks:
  hapi-net:
    driver: bridge

Note

À personnaliser : Remplacer fhir.votre-domaine.com par le sous-domaine réel qui pointera vers l’instance EC2.

6.3 Démarrage des conteneurs

cd /opt/hapi-fhir
sudo docker compose pull
sudo docker compose up -d

Vérifier l’état des conteneurs :

sudo docker compose ps
sudo docker logs -f hapi-fhir

7. Vérifications locales de HAPI FHIR

Depuis l’instance EC2, vérifier que HAPI répond localement :

curl -I http://127.0.0.1:8080/
curl http://127.0.0.1:8080/fhir/metadata

Astuce

Résultat attendu : La première commande doit retourner une réponse HTTP. La seconde doit retourner le CapabilityStatement FHIR, ce qui confirme que l’API FHIR répond.

Vérification PostgreSQL :

sudo docker compose exec -it postgres psql -U hapi_user -d hapi

Vérification des bases de données et tables :

sudo docker exec -it hapi-postgres psql -U hapi_user -l
sudo docker exec -it hapi-postgres psql -U hapi_user -d hapi -c "\dt"

8. Installation et configuration de Nginx sur Amazon Linux 2023

Nginx sera utilisé comme reverse proxy. Il recevra les requêtes sur 80/443 et les transmettra vers HAPI sur 127.0.0.1:8080.

sudo dnf install -y nginx

Résultat attendu

nginx version: nginx/1.30.1
sudo systemctl enable --now nginx
sudo systemctl status nginx --no-pager

8.1 Configuration reverse proxy HTTP

sudo nano /etc/nginx/conf.d/hapi-fhir.conf
server {
    listen 80;
    server_name fhirpivot;
    client_max_body_size 50M;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Tester puis recharger Nginx :

sudo nginx -t
sudo systemctl reload nginx

9. Exemples de requêtes FHIR

# Lister les locations de type STATE
curl -X GET "http://13.247.174.189/fhir/Location?type=STATE"

# Lister les locations rattachées à Location/1001
curl -X GET "http://13.247.174.189/fhir/Location?partof=Location/1001"

# Lister les locations rattachées à Location/1006
curl -X GET "http://13.247.174.189/fhir/Location?partof=Location/1006"

# Lister les villages rattachés à Location/1009
curl -X GET "http://13.247.174.189/fhir/Location?partof=Location/1009&type=VILLAGE"

10. Sources consultées