Comment déployer des applications Elixir-Phoenix avec MySQL sur Ubuntu 16.04

_L’auteur a sélectionné Code.org pour recevoir un don de 300 $ dans le cadre du programme Write for DOnations. _

introduction

Dans le tutoriel Comment automatiser Elixir Phoenix Déploiement avec Distillery et edeliver, vous avez créé une application Phoenix sans base de données et l’avez déployée sur un serveur de production à l’aide de edeliver. La plupart des applications réelles nécessitent une base de données nécessitant quelques modifications du processus de déploiement.

Vous pouvez utiliser edeliver pour transmettre simultanément les modifications apportées aux applications et à la base de données sur votre serveur de production afin de pouvoir gérer les modifications apportées à la base de données lors de déploiements.

Dans ce guide, vous allez configurer votre application Phoenix existante pour qu’elle se connecte à une base de données MySQL à l’aide de Phoenix-Ecto et Mariaex. . Ecto est un wrapper de base de données largement utilisé pour les applications Phoenix. Mariaex est un pilote de base de données qui s’intègre à Ecto et communique avec les bases de données MySQL et MariaDB.

Vous créerez également sur votre ordinateur de développement un simple carnet d’adresses utilisant une base de données et utilisant edeliver pour déployer les modifications sur votre serveur de production. Les utilisateurs de votre site pourront créer, lire, mettre à jour et supprimer des entrées de ce carnet d’adresses.

Conditions préalables

Pour compléter ce tutoriel, vous aurez besoin de:

Étape 1 - Ajout de Mariaex et Ecto à votre application

En règle générale, les applications Phoenix n’établissent pas directement de connexions aux bases de données et n’exécutent pas de requêtes SQL. Au lieu de cela, un pilote de base de données _ est utilisé pour se connecter à la base de données souhaitée et un wrapper_ de base de données est ensuite utilisé pour interroger la base de données.

Un pilote de base de données est une application Elixir qui prend en charge les tâches courantes d’utilisation d’une base de données, telles que l’établissement de connexions, la fermeture de connexions et l’exécution de requêtes. Le wrapper de base de données est une couche au-dessus du pilote de base de données qui permet aux programmeurs Elixir de créer des requêtes de base de données avec du code Elixir et fournit des fonctionnalités supplémentaires telles que la composition de requête (chaînage de requêtes).

Cette séparation permet une application modulaire. Le wrapper de la base de données, et donc le code de l’application permettant d’interagir avec la base de données, est en grande partie identique, quelle que soit la base de données utilisée. En modifiant simplement le pilote de la base de données, les applications Phoenix peuvent utiliser un logiciel de base de données différent.

Puisque vous avez fourni le drapeau + - no-ecto + lors de la création de votre application dans https://www.digitalocean.com/community/tutorials/how-to-automate-elixir-phoenix-deployment-with-distillery-and -edeliver-on-ubuntu-16-04 [tutoriel précédent], l’application n’a ni Ecto ni Mariaex installée. Vous allez maintenant ajouter Ecto et Mariaex comme dépendances de votre projet.

Commencez par basculer vers le répertoire contenant votre projet Phoenix.

cd ~/

Ouvrez ensuite le fichier + mix.exs +, qui contient la liste des dépendances de votre application.

nano mix.exs

Recherchez le bloc de code suivant:

~ / myproject / mix.exs

 defp deps do
   [
     {:phoenix, "~> 1.3.0"},
     {:phoenix_pubsub, "~> 1.0"},
     {:phoenix_html, "~> 2.10"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.11"},
     {:cowboy, "~> 1.0"},
     {:edeliver, "~> 1.4.3"},
     {:distillery, "~> 1.4"}
   ]
 end

Ajoutez Mariaex et Phoenix-Ecto comme dépendances:

~ / myproject / mix.exs

 defp deps do
   [
     {:phoenix, "~> 1.3.0"},
     {:phoenix_pubsub, "~> 1.0"},
     {:phoenix_html, "~> 2.10"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.11"},
     {:cowboy, "~> 1.0"},
     {:edeliver, "~> 1.4.3"},
     {:distillery, "~> 1.4"}


   ]
 end

Enregistrez et fermez + mix.exs +. Ensuite, exécutez la commande suivante pour télécharger les dépendances que vous venez d’ajouter au projet.

mix deps.get

Vous verrez cette sortie lorsque vos dépendances sont installées:

OutputRunning dependency resolution...
...
* Getting phoenix_ecto (Hex package)
 Checking package (https://repo.hex.pm/tarballs/phoenix_ecto-3.3.0.tar)
 Fetched package
* Getting mariaex (Hex package)
 Checking package (https://repo.hex.pm/tarballs/mariaex-0.8.3.tar)
 Fetched package
...

La sortie montre que Mix a vérifié la compatibilité entre les packages et obtenu les packages avec leurs dépendances à partir du référentiel Hex. Si cette commande échoue, assurez-vous que Hex est installé et que vous avez correctement modifié + mix.exs +.

Avec Ecto et Mariaex en place, vous pouvez configurer le référentiel Ecto.

Étape 2 - Configuration d’un référentiel Ecto dans votre application

Les applications Phoenix accèdent à la base de données via un wrapper appelé Ecto. Le wrapper de base de données est implémenté sous la forme d’un module Elixir dans votre projet. Vous pouvez importer ce module chaque fois que vous avez besoin d’interagir avec la base de données et d’utiliser les fonctions fournies par le module. La base de données encapsulée est appelée repository.

Ce module de référentiel doit inclure la macro + Ecto.Repo + pour donner accès aux fonctions de requête définies par Ecto. De plus, il doit contenir le code pour initialiser les options transmises à l’adaptateur de base de données dans une fonction nommée + init +.

Si vous n’aviez pas utilisé l’indicateur + - no-ecto + lors de la création de votre projet Phoenix, Phoenix aurait automatiquement généré ce module pour vous. Mais depuis que vous l’avez fait, vous devrez le créer vous-même.

Créons le module dans un fichier nommé + repo.ex + dans le répertoire + lib / +. Créez d’abord le fichier:

nano lib//repo.ex

Ajoutez le code suivant dans le fichier pour définir le référentiel:

~ / monprojet / lib / monprojet / repo.ex

defmodule .Repo do
 use Ecto.Repo, otp_app: :

 @doc """
 Dynamically loads the repository url from the
 DATABASE_URL environment variable.
 """
 def init(_, opts) do
   {:ok, Keyword.put(opts, :url, System.get_env("DATABASE_URL"))}
 end
end

Par défaut, les projets Phoenix définissent la fonction + init + de telle sorte que si la variable d’environnement + DATABASE_URL + existe, Ecto utilisera alors la configuration dans la variable d’environnement pour se connecter à la base de données au lieu d’utiliser les informations d’identification dans les fichiers de configuration de Phoenix ( comme nous le ferons plus tard dans ce tutoriel).

Enregistrez et fermez + repo.ex +.

Les projets Phoenix utilisent des processus Elixir légers pour la concurrence et la tolérance aux pannes. Les superviseurs gèrent ces processus et les redémarrent, s’ils se bloquent. Les superviseurs peuvent également superviser d’autres superviseurs, et cette structure s’appelle un «arbre de supervision».

Le module + Myproject.Repo + que vous venez d’ajouter implémente un superviseur qui gère les processus se connectant à la base de données. Pour démarrer ce superviseur, vous devez l’ajouter à l’arbre de supervision du projet.

Ouvrez le fichier + application.ex + dans le dossier + lib / +.

nano lib//application.ex

Recherchez le bloc de code suivant qui définit l’arbre de supervision:

~ / monprojet / lib / monprojet / application.ex

...
   children = [
     # Start the endpoint when the application starts
     supervisor(.Endpoint, []),
     ...
   ]
...

Vous pouvez voir que le noeud final de l’application, + MyprojectWeb.Endpoint +, est démarré en tant que superviseur. Ajoutez + Myproject.Repo + à cette liste:

~ / monprojet / lib / monprojet / monprojet.ex

   children = [


     # Start the endpoint when the application starts
     supervisor(MyprojectWeb.Endpoint, []),
     ...
   ]

Si vous ignorez cette étape, Ecto ne créera pas de processus pour interagir avec la base de données et toute tentative d’interaction avec la base de données entraînera le blocage de l’application.

Enregistrez et fermez + application.ex + avant de continuer.

Enfin, spécifiez le référentiel Ecto dans la configuration de l’application afin de pouvoir utiliser des tâches de mixage telles que + ecto.create + et + + ecto.migrate + pour créer et gérer votre base de données.

Ouvrez le fichier de configuration sous + config / config.exs +.

nano config/config.exs

Recherchez la ligne suivante à la fin du fichier:

~ / myproject / config / config.exs

import_config "#{Mix.env}.exs"

Cette ligne permet aux fichiers de configuration spécifiques à l’environnement, tels que + prod.exs + et + test.exs +, de remplacer les paramètres de + config.exs + si nécessaire. Ajoutez le code suivant * ci-dessus * cette ligne pour configurer le référentiel Ecto:

~ / myproject / config / config.exs

...

config :,
 ecto_repos: [.Repo]
...

Enregistrez vos modifications et fermez le fichier.

Maintenant que vous avez configuré Ecto, continuez en ajoutant vos informations d’identification de base de données à l’application.

Étape 3 - Configuration de votre application avec les informations d’identification MySQL

Votre application se connecte à une base de données dans trois situations: pendant le développement, les tests et la production.

De même, Phoenix fournit trois fichiers de configuration spécifiques à l’environnement contenant les informations d’identification pertinentes pour l’environnement dans lequel l’application est exécutée. Ces fichiers sont situés dans le répertoire + config + à la racine du projet. Vous allez modifier ces trois fichiers à cette étape.

Commençons par configurer l’environnement de développement. Ouvrez + dev.exs +.

nano config/dev.exs

Ajoutez les lignes suivantes pour configurer l’adaptateur de base de données sur + Ecto.Adapters.MySQL puisque nous utilisons MySQL.

~ / myproject / config / dev.exs

config :, .Repo,
 adapter:

Ensuite, spécifiez le nom souhaité de la base de données dans le même bloc de code.

~ / myproject / config / dev.exs

config :myproject, Myproject.Repo,
 adapter: Ecto.Adapters.MySQL

Ici, nous définissons le nom de la base de développement comme étant + _dev +. Il s’agit d’une convention d’appellation utilisée par les applications Phoenix pour les bases de données. Suivant cette convention, la base de production sera appelée + _prod + et la base de test + _test +. Vous pouvez utiliser votre propre schéma de nommage à la place.

Maintenant, indiquez le nom d’hôte, le nom d’utilisateur et le mot de passe de votre serveur de base de données de développement.

~ / myproject / config / dev.exs

config :myproject, Myproject.Repo,
 adapter: Ecto.Adapters.MySQL,
 database: "myproject_dev"

Enfin, définissez la taille du pool sur un nombre approprié. La taille du pool correspond au nombre maximal de connexions à la base de données que l’application peut avoir. Ces connexions seront partagées entre les demandes. La taille optimale dépend de votre matériel, mais vous pouvez utiliser + 10 + pour commencer.

~ / myproject / config / dev.exs

config :myproject, Myproject.Repo,
 adapter: Ecto.Adapters.MySQL,
 username: "root",
 password: "password",
 database: "myproject_dev",
 hostname: "localhost"

Enregistrez et fermez + dev.exs +.

Ensuite, configurez votre environnement de test. Ouvrez le fichier de configuration de l’environnement de test + test.exs +.

nano config/test.exs

Dans ce didacticiel, nous hébergerons la base de données de test sur le serveur de base de données local à côté de la base de données de développement. En tant que tels, les configurations pour la base de données de test sont presque identiques.

Cependant, au lieu de la taille du pool, nous spécifions + Ecto.Adapters.SQL.Sandbox + pour la valeur du pool. Cela exécutera des tests en mode bac à sable. C’est-à-dire que toutes les transactions effectuées avec la base de données de test lors d’un test seront annulées. Et cela signifie que les tests unitaires peuvent être exécutés dans un ordre aléatoire car la base de données est réinitialisée à l’état initial après chaque test.

Et nous utiliserons + myproject_test + comme nom de base de données.

Ajoutez la configuration suivante au fichier + test.exs +:

~ / myproject / config / test.exs

config :, .Repo,
 adapter: Ecto.Adapters.MySQL,
 username: "",
 password: "",
 database: "",
 hostname: "",
 pool: Ecto.Adapters.SQL.Sandbox

Enregistrez et fermez + test.exs +.

Enfin, pour configurer les informations d’identification de votre application en production, ouvrez votre fichier secret de production, + prod.secret.exs +.

nano config/prod.secret.exs

Ajoutez ce code dans le fichier + prod.secret.exs +. Notez que nous utilisons le nom d’utilisateur * myproject * ici avec le mot de passe + password +. . Nous allons bientôt créer cet utilisateur sur le serveur de base de données de production, en utilisant le mot de passe spécifié ici. Vous voudrez utiliser un mot de passe plus sécurisé ici.

~ / myproject / config / prod.secret.exs

config :, .Repo,
 adapter: Ecto.Adapters.MySQL,
 username: "",
 password: "",
 database: "",
 hostname: "",
 pool_size: 10

Enregistrez vos modifications et fermez le fichier.

Ce fichier n’est pas suivi par Git pour des raisons de sécurité. Vous devez donc le transférer manuellement au serveur. Pour plus d’informations sur ce processus, consultez l’étape 3 de la configuration requise https://www.digitalocean.com/community/tutorials/how-to-automate-elixir-phoenix-deployment-with-distillery-and-edeliver-on-ubuntu. -16-04 [tutoriel sur le déploiement d’applications Phoenix].

scp ~/myproject/config/prod.secret.exs @:/home//app_config/prod.secret.exs

Appelez ensuite la tâche de mixage + ecto.create + pour créer la base de développement. Notez qu’il n’est pas nécessaire de créer la base de données de tests, car Phoenix le fera pour vous lors de l’exécution de vos tests.

mix ecto.create

La sortie suivante indique qu’Ecto a créé la base de données avec succès:

Output...
The database for .Repo has been created

Si vous ne voyez pas cette sortie, assurez-vous que vos détails de configuration sont corrects et que MySQL est en cours d’exécution. Ecto refuserait également de créer la base de données si la compilation de votre application échouait à cause d’erreurs.

Maintenant que vous avez configuré le projet pour se connecter à une base de données et que vous avez même utilisé Ecto pour créer une base de données sur la machine de développement, vous pouvez maintenant modifier la base de données sur le serveur.

Étape 4 - Configuration de la base de données de production

Avec la tâche de mixage + ecto.create +, vous avez créé une base de données vide sur votre machine de développement. Maintenant, vous ferez la même chose pour votre serveur de production. Malheureusement, il n’existe aucune tâche Mix ou commande edeliver pour nous aider à atteindre cet objectif. Vous devez donc vous connecter manuellement au serveur et créer une base de données vide avec des commandes SQL à l’aide de la console MySQL.

Connectez-vous au serveur via SSH.

ssh @

Accédez maintenant à la console MySQL en utilisant l’utilisateur * root * et le mot de passe que vous avez configuré.

mysql -u  -p

Une fois connecté, créez la base de données de production:

CREATE DATABASE ;

Vous verrez le résultat suivant, vous indiquant que la base de données a été créée:

OutputQuery OK, 1 row affected (0.00 sec)

Ensuite, créez un utilisateur pour l’application, en utilisant le nom d’utilisateur * myproject * et le mot de passe que vous avez spécifié à l’étape précédente:

CREATE USER ''@'localhost' IDENTIFIED BY '';

Puis, donnez à l’utilisateur * myproject * l’accès à la base de données que vous avez créée:

GRANT ALL PRIVILEGES ON .* to ''@'localhost';

Enfin, appliquez les modifications d’autorisation:

FLUSH PRIVILEGES;

Quittez la console MySQL en tapant + exit +. Terminez la connexion SSH en tapant + exit + à nouveau.

À partir de maintenant, vous devrez rarement toucher à la base de données de production, car vous effectuerez presque toutes les opérations, telles que la création et la modification de tables à partir de votre ordinateur local.

Avec la base de données de production maintenant prête, vous pouvez redéployer votre application sur le serveur.

Étape 5 - Déploiement du projet sur le serveur

Dans cette étape, vous allez remplacer l’application en cours qui n’a pas de connexion à une base de données par votre application récemment configurée et son nouveau référentiel Ecto. Cette étape vous permettra de vous assurer que l’application est configurée correctement et qu’elle fonctionne toujours comme prévu.

Ouvrez + mix.exs + et incrémentez la version de l’application. Le numéro de version facilite le suivi des versions et la restauration des versions précédentes si nécessaire. Edeliver l’utilise également pour mettre à niveau votre application sans temps d’arrêt.

nano mix.exs

Incrémenter le champ de version à une valeur appropriée.

~ / myproject / mix.exs

 def project do
   [
     app: :myproject,
     version: "",
     elixir: "~> 1.4",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix, :gettext] ++ Mix.compilers,
     start_permanent: Mix.env == :prod,
     deps: deps()
   ]
 end

Pour utiliser edeliver pour effectuer des migrations de bases de données, edeliver doit être la dernière application à démarrer dans votre projet. Recherchez le bloc de code suivant:

~ / myproject / mix.exs

 def application do
   [
     mod: {.Application, []},
     extra_applications: [:logger, :runtime_tools]
   ]
 end

Ajoutez + edeliver + à la fin de la liste + extra_applications +:

~ / myproject / mix.exs

 def application do
   [
     mod: {.Application, []},
     extra_applications: [:logger, :runtime_tools]
   ]
 end

Enregistrez et fermez + mix.exs +.

Lancez l’application pour vous assurer que tout fonctionne et qu’il n’y a pas d’erreur de compilation:

mix phx.server

Visitez http: // localhost: 4000 [http: // localhost: 4000 / adresses] pour vous assurer que l’application fonctionne toujours. S’il ne démarre pas ou si vous constatez des erreurs de compilation, passez en revue les étapes de ce didacticiel et résolvez-les avant de poursuivre.

Si tout fonctionne comme prévu, appuyez deux fois sur les touches + CTRL + C + de votre terminal pour arrêter le serveur.

Ensuite, validez les modifications avec Git. Vous devez le faire à chaque fois que vous apportez des modifications à votre projet, car edeliver utilise Git pour transmettre le code du dernier commit au serveur de construction pour une action ultérieure.

git add .
git commit -m "Configured application with database"

Enfin, utilisez edeliver pour mettre à jour l’application sur le serveur de production. La commande suivante permet de créer et de déployer la dernière version de votre projet avant de mettre à niveau l’application s’exécutant sur la machine de production sans temps d’arrêt.

mix edeliver upgrade production

Vous verrez le résultat suivant:

OutputEDELIVER MYPROJECT WITH UPGRADE COMMAND

-----> Upgrading to revision 2512398 from branch master
-----> Detecting release versions on production hosts
-----> Deploying upgrades to 1 online hosts
-----> Checking whether installed version 0.0.2 is in release store
-----> Building the upgrade from version 0.0.2
-----> Authorizing hosts
-----> Validating * version 0.0.2 is in local release store
-----> Ensuring hosts are ready to accept git pushes
-----> Pushing new commits with git to: @
-----> Resetting remote hosts to 2512398838c2dcc43de3ccd869779dded4fd5b6b
-----> Cleaning generated files from last build
-----> Checking out 2512398838c2dcc43de3ccd869779dded4fd5b6b
-----> Fetching / Updating dependencies
-----> Compiling sources
-----> Checking version of new release
-----> Uploading archive of release 0.0.2 from local release store
-----> Extracting archive myproject_0.0.2.tar.gz
-----> Removing old releases which were included in upgrade package
-----> Generating release
-----> Removing built release 0.0.2 from remote release directory
-----> Copying release 0.0.3 to local release store
-----> Copying myproject.tar.gz to release store
-----> Upgrading production hosts to version 0.0.3
-----> Authorizing hosts
-----> Uploading archive of release 0.0.3 from local release store
-----> Upgrading release to 0.0.3

UPGRADE DONE!

Bien que la mise à niveau se soit déroulée avec succès, vous ne pourrez pas exécuter les tâches edeliver relatives à la base de données tant que vous n’avez pas redémarré l’application.

mix edeliver restart production

Vous verrez cette sortie:

OutputEDELIVER  WITH RESTART COMMAND

-----> restarting production servers

production node:

 user    :
 host    :
 path    : /home//app_release
 response: ok

RESTART DONE!

edeliver nous dit qu’il a redémarré avec succès le serveur de production.

Pour vous assurer que votre application a été mise à niveau, exécutez la commande edeliver suivante pour récupérer la version de l’application en cours d’exécution en production.

mix edeliver version production
OutputEDELIVER MYPROJECT WITH VERSION COMMAND

-----> getting release versions from production servers

production node:

 user    :
 host    :
 path    : /home//app_release
 response:

VERSION DONE!

La sortie nous indique que le serveur de production exécute la version de l’application ++.

Vous pouvez également visiter votre application sur + https: // + pour s’assurer de son bon fonctionnement. Il ne devrait y avoir aucune modification observable dans l’application car nous n’avons pas touché le code de l’application elle-même.

Si la mise à niveau réussit mais ne réussit pas à mettre à jour l’application, assurez-vous que vous avez bien validé votre code et modifié la version de votre application. Si la commande de mise à niveau échoue, edeliver affichera le code bash qu’il était en train d’exécuter sur le serveur lorsque l’erreur s’est produite et le message d’erreur lui-même. Vous pouvez utiliser ces indices pour résoudre votre problème.

Maintenant que vous avez ajouté le support de base de données à votre application et que vous l’avez déployé en production, vous êtes maintenant prêt à ajouter certaines fonctionnalités qui utilisent MySQL.

Étape 6 - Création du carnet d’adresses

Pour montrer comment déployer les modifications de la base de données, construisons un simple carnet d’adresses dans notre application et déployez-le en production.

Au lieu d’écrire le code du carnet d’adresses à partir de rien, nous utiliserons Phoenix generators pour créer le carnet d’adresses. Les générateurs Phoenix sont des utilitaires qui génèrent du code pour une simple fonctionnalité CRUD (Créer, Lire, Mettre à jour, Supprimer). Cela constitue un bon point de départ pour de nombreuses fonctionnalités d’application que vous pouvez créer.

Le carnet d’adresses nécessitera également une table dans la base de données pour stocker les entrées. Pour ajouter cette table à la base de données, vous pouvez construire et exécuter une requête SQL, mais nous utiliserons la fonctionnalité de migration d’Ecto pour modifier la base de données à la place. Cette approche présente quelques avantages. Premièrement, il est indépendant de la base de données. les commandes sont les mêmes que vous utilisiez une base de données PostgreSQL, MySQL ou une autre base de données. Ensuite, les fichiers de migration constituent un moyen pratique de suivre l’évolution de votre schéma de base de données. Enfin, vous pouvez également annuler les dernières migrations sur votre ordinateur de développement si vous en avez besoin.

Heureusement, vous n’avez pas à écrire un fichier de migration à partir de zéro, car les générateurs Phoenix vous en créeront un pour vous, sauf indication contraire.

Pour utiliser le générateur, spécifiez le contexte, le nom au singulier de l’entité, le nom au pluriel de l’entité et tous les autres champs avec leurs types respectifs.

Le * contexte * est un module qui contiendra des fonctions pour les ressources associées. Par exemple, si vous prévoyez de conserver une liste des utilisateurs qui se sont inscrits sur votre site et un journal des sessions lorsque les utilisateurs se connectent, il est judicieux de placer les utilisateurs et les sessions dans un seul module de contexte appelé «Compte».

Notez que, par convention, Phoenix suppose que le nom au pluriel de l’entité est le nom de la table de base de données pour cette ressource.

Créons le carnet d’adresses avec le générateur. Pour que le carnet d’adresses reste simple, nous n’incluerons que trois champs pour chaque enregistrement: nom, e-mail et code postal. Nous nous référerons à chaque entrée en tant que + Address +, à plusieurs entrées en tant que + adresses + et au contexte dans lequel le carnet d’adresses doit résider en tant que + AddressBook +.

Exécutez cette commande pour générer le carnet d’adresses:

mix phx.gen.html
Output* creating lib/myproject_web/controllers/.ex
...
* creating priv/repo/migrations/_create_address.exs

Add the resource to your browser scope in web/router.ex:

   resources "/",

Remember to update your repository by running migrations:

   $ mix ecto.migrate

Phoenix nous indique qu’il a généré automatiquement les fichiers de modèle, les fichiers de test, le modèle, le contrôleur et le fichier de migration. Il nous indique également d’ajouter la ressource au fichier du routeur et de mettre à jour le référentiel.

Vous pouvez suivre les instructions que vous voyez dans le résultat, mais vous regrouperez ainsi la mise à niveau du code de l’application et la migration de la base de données dans une seule version. Cela peut entraîner l’échec de certaines parties de l’application en production à partir du moment où l’application est déployée sur le serveur de production jusqu’au moment de la migration de la base de données de production. Pendant cet intervalle, le code de l’application peut référencer des tables ou des colonnes inexistantes dans la base de données.

Pour éviter les temps d’arrêt et les erreurs, déployez les modifications en deux étapes:

  1. Ajoutez un fichier de migration de base de données contenant les modifications nécessaires à la base de données sans modifier le code de l’application. Créez une version, mettez à niveau le serveur de production et migrez la base de données de production.

  2. Apportez des modifications au code de l’application, puis créez et déployez une autre version.

Si nous ne prenons pas cette approche, le code du carnet d’adresses essaiera de référencer la table d’adresses que nous n’avons pas encore créée et notre application se bloquera.

Avant de migrer la base de données de production, examinons le fichier de migration. Il se trouve dans + priv / repo / migrations / _create_addresses.exs +, bien que le nom du fichier ait un horodatage différent en fonction du moment de sa création. Ouvrez le fichier dans votre éditeur:

nano priv/repo/migrations/*_create_addresses.exs

Le fichier de migration généré par Phoenix est un module Elixir doté d’une fonction unique appelée + change +. Lorsque vous effectuerez la migration ultérieurement, cette fonction sera appelée.

~ / myproject / priv / repo / migrations / 20180501040548_create_addresses.exs

defmodule Myproject.Repo.Migrations.CreateAddresses do
 use Ecto.Migration

 def change do
   create table(:addresses) do
     add :name, :string
     add :email, :string
     add :zip_code, :integer

     timestamps()
   end

 end
end

Dans cette fonction, le générateur Phoenix a écrit le code pour créer la table + adresses + avec les champs que vous avez fournis. De plus, le générateur a également inclus la fonction + timestamps () + qui ajoute deux champs supplémentaires pour vous: + Insert_at + et + updated_at +. Les valeurs stockées dans ces champs sont mises à jour automatiquement lorsque vous insérez ou mettez à jour des données.

Fermez le fichier sans apporter de modifications; le code généré est tout ce dont vous avez besoin.

Pour déployer uniquement le fichier de migration sans inclure le code de l’application, nous utiliserons le fait qu’edeliver utilise Git pour transférer notre projet sur le serveur de construction. Plus précisément, nous allons simplement organiser et valider le fichier de migration tout en laissant le reste des fichiers générés non suivi.

Mais avant de pouvoir le faire, incrémentez la version de l’application dans + mix.exs +. Edeliver utilise le numéro de version pour préparer les mises à niveau à chaud. Vous devez donc incrémenter le numéro de version pour chaque mise à jour.

Ouvrez + mix.exs +.

nano mix.exs

Incrémentez la version de votre application à une valeur appropriée.

~ / myproject / mix.exs

 def project do
   [
     app: :myproject,
     version: "",
     ...

Enregistrez et fermez le fichier.

Maintenant, utilisez Git pour organiser le fichier + mix.exs + et le fichier de migration.

git add mix.exs priv/repo/migrations/*_create_addresses.exs

Ensuite, validez les fichiers mis en scène.

git commit -m "Adding addresses table to the database"

Avec cela, mettez à niveau votre application de production avec edeliver.

mix edeliver upgrade production

Une fois la mise à niveau terminée, exécutez la commande edeliver suivante pour migrer la base de production.

mix edeliver migrate production

La sortie indique que la migration a été exécutée avec succès et affiche l’horodatage du fichier de migration:

OutputEDELIVER  WITH MIGRATE COMMAND

-----> migrateing production servers

production node:

 user    :
 host    :
 path    : /home//app_release
 response: []

MIGRATE DONE!

La base de production a maintenant une table vide nommée + adresses +.

Le champ + response + afficherait + [] + si aucune migration n’était exécutée. Si tel est le cas, assurez-vous que vous avez validé votre code avec Git avant de procéder à la nouvelle mise à niveau. Si le problème persiste, redémarrez l’application de production en tapant + mix edeliver restart production +, puis réexécutez la tâche de migration de la base de données.

Avec le tableau + adresses + en place, nous pouvons continuer à suivre les instructions émises par Phoenix lorsque nous avons généré le carnet d’adresses et créé une nouvelle version.

Commencez par ouvrir le fichier + lib / myproject_web / router.ex +:

nano lib/myproject_web/router.ex

Recherchez le bloc de code suivant:

~ / myproject / lib / myproject_web / router.ex

 scope "/",  do
   pipe_through :browser

   get "/", PageController, :index
 end

Insérez la route pour la ressource + adresses +:

~ / myproject / lib / myproject_web / router.ex

 scope "/",  do
   pipe_through :browser

   get "/", PageController, :index

 end

Enregistrez et fermez + router.ex +.

Ensuite, demandez à Ecto d’apporter des modifications à la base de données locale.

mix ecto.migrate

La sortie montre que la fonction du fichier de migration a été appelée, ce qui a permis de créer la table + adresses +.

Output...
[info] == Running .Repo.Migrations.CreateAddresses.change/0 forward
[info] create table addresses
[info] == Migrated in 0.0s

Maintenant, démarrez le serveur de développement local pour tester votre nouvelle fonctionnalité:

mix phx.server

Pointez votre navigateur sur http: // localhost: 4000 / adresses pour voir la nouvelle fonctionnalité en action.

Lorsque vous êtes certain que les choses fonctionnent localement, retournez sur votre terminal et appuyez deux fois sur les touches + CTRL + C + pour mettre fin au serveur.

Maintenant que les choses fonctionnent, vous pouvez déployer les modifications en production. Ouvrez + mix.exs + pour mettre à jour la version de l’application.

nano mix.exs

Incrémenter le champ de version à une valeur appropriée.

~ / myproject / mix.exs

 def project do
   [
     app: :myproject,
     version: "",
     elixir: "~> 1.4",
     elixirc_paths: elixirc_paths(Mix.env),
     compilers: [:phoenix, :gettext] ++ Mix.compilers,
     start_permanent: Mix.env == :prod,
     deps: deps()
   ]
 end

Enregistrez et fermez + mix.exs +.

Commettez vos modifications avec Git. Cette fois, mettez en scène tous les fichiers.

git add .
git commit -m "Added application code for address book"

Mettez à niveau l’application de production avec edeliver.

mix edeliver upgrade production

Une fois la mise à jour terminée, vous pouvez accéder à la nouvelle fonctionnalité à partir de + https: /// adresses +.

Avec cela, vous avez mis à niveau avec succès l’application de production et la base de données.

Conclusion

Dans cet article, vous avez configuré votre application Phoenix pour utiliser une base de données MySQL et utilisé les migrations edeliver et Ecto pour modifier la base de production. Avec cette méthode, vous n’avez pas besoin de toucher à la base de données de production et les modifications que vous souhaitez apporter à la base de données de production sont effectuées via les fichiers de migration Ecto. Cela facilite l’annulation des modifications et le suivi des modifications apportées à la base de données au fil du temps.

Pour en savoir plus sur les migrations Ecto et sur la manière de manipuler des bases de données complexes, reportez-vous au official document officiel sur les migrations Ecto.