Récemment je me suis demandé comment je pourrais mettre en ligne plusieurs instances de la même application Web sur une seule adresse et en servir une différente en fonction de l’utilisateur visitant le site. Je voulais une solution aussi transparente que possible. J’ai donc choisi d’utiliser un paramètre d’URL et un cookie pour rediriger l’utilisateur vers l’instance voulue.

Le problème

Il y a de nombreuses raisons pour lesquelles vous pourriez vouloir faire cela. Vous pourriez avoir une instance pour chaque langue ou par thème, ou vous pourriez vouloir tester différentes versions d’une même fonctionnalité (A/B testing). Dans mon cas, j’avais besoin d’avoir une version différente de mon site Web personnel et de mon CV en fonction de l’entreprise à laquelle je postulais. Je voulais le faire sans avoir à créer un sous-domaine ou un chemin spécifique pour chaque instance.

La solution

Vous avez deux versions différentes de votre site Web, version A et version B. Vous voulez montrer la version A par défaut et la version B lorsque l’utilisateur se connecte à votre site via https://yoursite.com/?version=B.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Version A</title>
    </head>
    <body>
        <h1>Bienvenue sur la Version A</h1>
    </body>
</html>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Version B</title>
    </head>
    <body>
        <h1>Bienvenue sur la Version B</h1>
    </body>
</html>

Les deux versions tournent sur la même machine mais sur des ports différents. Vous utilisez Nginx comme reverse proxy. Voici comment vous pouvez faire:

upstream versionA {
	server 127.0.0.1:4000;
}

upstream versionB {
	server 127.0.0.1:4001;
}

# Map pour choisir le backend en fonction de "backend_version"
map $backend_version $upstream {
	A       versionA;
	B       versionB;
	default versionA;
}

server {
	listen 80;
	server_name yoursite.com;

	location / {
		# Version par défaut
		set $backend_version A;

		# Vérifie si le paramètre "version" est dans l'URL
		if ($arg_version) {
			set $backend_version $arg_version;
			add_header Set-Cookie "version=$arg_version; Path=/";

			# Redirige l'utilisateur vers la racine pour supprimer le paramètre
			return 302 $uri;
		}

		# Vérifie si le cookie "version" est présent et met à jour la version
		if ($http_cookie ~* "version=(\d)") {
			set $backend_version $1;
		}

		# Si le cookie "version" n'est pas présent il est créé par défaut
		if ($http_cookie !~* "version=(\d)") {
			add_header Set-Cookie "version=$backend_version; Path=/";
		}

		# Redirige vers le backend approprié
		proxy_pass http://$upstream;
	}
}

Remplacez yoursite.com par votre nom de domaine et les ports 4000 et 4001 par les ports sur lesquels vos instances tournent.

Cette configuration doit être placée dans le répertoire /etc/nginx/sites-available et un lien symbolique doit être créé dans /etc/nginx/sites-enabled. Elle redirigera l’utilisateur vers l’instance appropriée en fonction du paramètre d’URL version. Si le paramètre n’est pas présent, elle vérifiera si le cookie version est défini. Si ce n’est pas le cas, elle le définira sur la version par défaut. Le cookie sera défini à la racine du site pour qu’il soit disponible sur toutes les pages.

Conclusion

Quand l’utilisateur visite https://yoursite.com/?version=B, il sera redirigé vers https://yoursite.com/ et naviguera sur la version B. Le cookie sera défini et il continuera à voir la version B jusqu’à ce qu’il efface ses cookies. Le routage est à la fois transparent et persistant.

Cette solution est simple et peut être facilement mise à jour pour inclure plus de versions différentes. C’est également un bon moyen de tester de nouvelles fonctionnalités de votre site Web sans affecter tous les utilisateurs. C’est une technique puissante à avoir à sa disposition.