Ruby: Usages avancés

Aller plus loin avec vos déploiements Ruby

👋 Bienvenue sur la documentation de Stackhero !

Stackhero propose une solution Ruby cloud prête à l'emploi qui offre de nombreux avantages, notamment :

  • Déployez votre application en quelques secondes avec un simple git push.
  • Utilisez votre propre nom de domaine et bénéficiez de la configuration automatique des certificats HTTPS pour une sécurité renforcée.
  • Profitez de la tranquillité d'esprit avec des sauvegardes automatiques, des mises à jour en un clic, et une tarification simple, transparente et prévisible.
  • Obtenez des performances optimales et une sécurité robuste grâce à une VM privée et dédiée.

Gagnez du temps et simplifiez-vous la vie : il ne faut que 5 minutes pour essayer la solution Ruby cloud hosting de Stackhero !

Jusqu'à présent, nous avons déployé notre application Ruby en poussant la branche main en utilisant :

git push stackhero main

Si vous souhaitez déployer une autre branche, vous pouvez utiliser cette commande. Remplacez <BRANCH> par le nom de la branche que vous voulez déployer :

git push stackhero <BRANCH>:main

Par exemple, pour déployer une branche nommée production, exécutez :

git push stackhero production:main

Dans certains cas, vous pouvez souhaiter déployer un tag plutôt qu'une branche. Pour ce faire, exécutez la commande suivante. Remplacez <TAG> par le tag que vous souhaitez déployer :

git push stackhero '<TAG>^{}:main'

Par exemple, pour déployer le tag v1.0.0, exécutez :

git push stackhero 'v1.0.0^{}:main'

La syntaxe ^{} est utilisée pour référencer le commit auquel le tag pointe.

En plus des branches ou des tags, vous pouvez déployer un commit spécifique. Remplacez <COMMIT_HASH> dans la commande ci-dessous par le hash du commit désiré :

git push -f stackhero <COMMIT_HASH>:main

Par exemple, pour déployer un commit avec le hash abcde, exécutez :

git push -f stackhero abcde:main

Si votre déploiement en production ne fonctionne pas comme prévu, vous pouvez revenir en arrière en déployant un ancien commit. Utilisez d'abord la commande ci-dessous pour voir votre historique de commits :

git log

Cette commande affiche la date, le hash du commit et la description pour chaque commit de votre dépôt. Par exemple, vous pourriez voir une sortie comme :

commit cccc8b3ebdccb9abc1926ef49ee589dae5c5fe06 (HEAD -> main, stackhero/main)
Author: Developer
Date:   Fri Apr 28 09:36:18 +0000

    Break the code

commit bbbb622301772072c3d82f3cc0d91e29e6e84901
Author: Developer
Date:   Wed Apr 26 12:49:28 +0000

    Update the code

commit aaaa1d8b06535b413e0df8298ccf52339dfef3ff
Author: Developer
Date:   Wed Apr 26 12:44:50 +0000

    Improve the code

Si le commit avec le message "Break the code" (hash cccc...) est en cours d'exécution en production, et que vous décidez de revenir au commit précédent "Update the code" (hash bbbb...), exécutez :

git push -f stackhero bbbb622301772072c3d82f3cc0d91e29e6e84901:main

Pour éviter de déployer du code défectueux et augmenter la stabilité de votre production, il est fortement recommandé d'avoir un environnement "staging".

Situé entre les environnements "development" et "production", l'environnement "staging" fournit une réplique quasi exacte de l'environnement de production. Cela vous permet de tester votre code et d'assurer sa qualité avant de le déployer en production.

En utilisant un environnement de staging, vous pouvez être plus confiant dans la fonctionnalité et la performance de votre code, assurant un déploiement en production plus fiable et robuste.

Ce type d'environnement sera discuté plus tard dans la documentation.

Un environnement staging est une bonne pratique à utiliser en parallèle de vos environnements development et production. Il réplique votre environnement de production pour que vous puissiez tester les mises à jour et les changements avant qu'ils ne soient mis en ligne.

Un environnement de staging doit refléter de près l'environnement de production.

Cependant, assurez-vous que l'environnement de staging utilise un clone de la base de données de production plutôt que la base de données de production elle-même.

Si votre service Ruby est lié à une base de données ou à d'autres services, recréez-les dans le nouveau stack <Project> - Staging.

Pour configurer un environnement de staging sur Stackhero, suivez ces étapes :

  1. Sur le tableau de bord Stackhero, renommez votre stack existant de <Project> à <Project> - Production. Par exemple, si votre projet s'appelle Chat Bot, renommez le stack en Chat Bot - Production.
  2. Créez un nouveau stack appelé <Project> - Staging. En utilisant l'exemple précédent, cela serait Chat Bot - Staging.
  3. Démarrez un service Ruby dans le stack de staging.
  4. Récupérez la valeur de la commande git remote et suivez les instructions dans la section Déployer dans l'environnement de staging.

En suivant ces étapes, vous obtiendrez un environnement de staging correctement configuré pour tester et vérifier les mises à jour avant qu'elles n'atteignent la production.

Gérer des environnements séparés tels que staging et production est fortement recommandé. Comme expliqué dans Configurer un environnement de staging, vous pouvez déployer dans chaque environnement avec différents remotes Git.

Commencez par renommer le dépôt distant actuel. Par exemple, renommez le remote "stackhero" en "stackhero-production" avec cette commande :

git remote rename stackhero stackhero-production

Ensuite, créez un nouveau service Ruby pour l'environnement de staging. Utilisez la commande "git remote add" fournie et modifiez-la comme suit (remplacez <XXXXXX> par le domaine de votre service) :

  • Commande originale :

    git remote add stackhero ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git
    
  • Commande modifiée :

    git remote add stackhero-staging ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git
    

Vous pouvez maintenant déployer sur staging en utilisant :

git push stackhero-staging main

Ou déployer en production avec :

git push stackhero-production main

Pour simplifier davantage le processus de déploiement, envisagez d'utiliser la version améliorée du Makefile.

Avec ce Makefile amélioré, le déploiement en production ou en staging peut être effectué facilement en utilisant make deploy-production ou make deploy-staging.

Ci-dessous se trouve un Makefile amélioré qui prend en charge plusieurs règles pour les tâches courantes :

  • make dev (ou simplement make) : Démarre l'application en mode développement.
  • make deploy : Déploie l'application sur le remote nommé stackhero (idéal lorsque vous avez une seule instance Stackhero).
  • make deploy-production : Déploie l'application sur le remote nommé stackhero-production.
  • make deploy-staging : Déploie l'application sur le remote nommé stackhero-staging.

Ce Makefile est conçu pour gérer les cas où le code a déjà été déployé, évitant l'erreur "Everything up-to-date".

Copiez et collez le contenu suivant dans votre nouveau Makefile :

# Règle à exécuter par défaut lors de l'invocation de "make" sans argument
.DEFAULT_GOAL := dev


# Stackhero pour Ruby exécutera la règle "run" sur votre instance.
# C'est la commande à exécuter sur les plateformes de production et de staging.
run:
  rake assets:precompile
  rake db:migrate RAILS_ENV=production
  RAILS_ENV=production bundle exec puma -C config/puma.rb


# Commande à exécuter dans l'environnement de développement
dev:
  RAILS_ENV=development rails server -b 0.0.0.0


# La règle "deploy" déploie sur l'instance "stackhero".
# Convient lorsque vous n'avez qu'une seule instance.
deploy:
  @$(MAKE) -s deploy-script DEPLOY_REMOTE=stackhero DEPLOY_BRANCH=main


# La règle "deploy-*" déploie sur l'instance "stackhero-*".
# Par exemple, exécutez "make deploy-production" pour déployer sur "stackhero-production",
# ou "make deploy-staging" pour déployer sur "stackhero-staging".
deploy-%:
  @$(MAKE) -s deploy-script DEPLOY_REMOTE=stackhero-$* DEPLOY_BRANCH=main


# Règle de déploiement interne. Ne pas modifier.
deploy-script:
  @echo "Déploiement de la branche \"${DEPLOY_BRANCH}\" vers \"${DEPLOY_REMOTE}\"..."
  @echo

  @if [ -n "$$(git status --porcelain)" ]; then \
    echo "Impossible de déployer car il y a des modifications non validées :"; \
    echo "\e[0m"; \
    git status -s; \
    echo ""; \
    echo "\e[0;31m"; \
    echo "Vous pouvez utiliser cette commande pour valider les modifications :"; \
    echo "git add -A . && git commit -m \"Votre message\""; \
    echo "\e[0m"; \
    exit 1; \
  fi

  @git push --dry-run ${DEPLOY_REMOTE} ${DEPLOY_BRANCH} 2>&1 | grep -q -F "Everything up-to-date"; \
  EXIT_CODE=$$?; \
  if [ $$EXIT_CODE -eq 0 ]; then \
    echo -n "Rien de nouveau à déployer... Forcer le déploiement (cela créera un nouveau commit) ? (y/N) "; \
    read answer && \
    case $$answer in \
      y|Y|yes|YES) \
      git commit --allow-empty -m "Force update for deploy purpose to \"${DEPLOY_REMOTE}\"" ; \
      ;; \
      *) \
      echo "Rien à déployer !"; \
      exit 1; \
      ;; \
    esac \
  fi

  git push ${DEPLOY_REMOTE} ${DEPLOY_BRANCH}

À un moment donné, vous devrez gérer des secrets tels que des tokens ou des mots de passe pour les bases de données et les services tiers. Il est essentiel de stocker ces secrets de manière sécurisée. Évitez d'intégrer directement les secrets dans votre dépôt ou votre code car cela représente un risque de sécurité sérieux.

Les variables d'environnement offrent deux avantages significatifs :

  1. Vos secrets ne seront pas stockés dans votre dépôt Git, réduisant le risque si quelqu'un accède à votre code source.
  2. Vous pouvez utiliser des identifiants différents pour différents environnements. Par exemple, se connecter à votre base de données de production en production tout en utilisant une base de données de développement pendant le développement.

Pour le développement, créez un fichier .env à la racine de votre projet. Ce fichier sera exclu de Git pour qu'il ne soit jamais validé. Utilisez la gem dotenv pour charger automatiquement le fichier .env.

Tout d'abord, ajoutez la gem dotenv-rails à votre Gemfile :

# Gemfile
gem 'dotenv-rails', groups: [:development, :test]

Ensuite, installez la gem :

bundle install

Ensuite, créez un fichier .env à la racine de votre projet et ajoutez vos variables :

RAILS_ENV="development"
DATABASE_PASSWORD="secretPassword"
THIRD_API_PRIVATE_KEY="secretKey"
# ...

Enfin, assurez-vous que le fichier .env est ignoré par Git :

echo '.env*' >> .gitignore

Pour le staging et la production, le fichier .env n'est pas sécurisé ni pratique car il ne peut pas être stocké dans un dépôt Git. Au lieu de cela, Stackhero fournit une solution sécurisée pour gérer les variables d'environnement directement dans la configuration de votre service Ruby.

Vous pouvez définir ces variables via le tableau de bord Stackhero en sélectionnant votre service Ruby et en cliquant sur le bouton "Configurer".

En Ruby, vous pouvez facilement accéder aux variables d'environnement en utilisant ENV. Par exemple, pour récupérer DATABASE_PASSWORD, utilisez :

ENV['DATABASE_PASSWORD'] # => 'secretPassword'

Voici un exemple de connexion à un serveur RabbitMQ en utilisant des variables d'environnement :

require 'bunny'

class RabbitMQClient
  def initialize
    @connection = Bunny.new(hostname: ENV['RABBITMQ_HOST'],
                            username: ENV['RABBITMQ_USERNAME'],
                            password: ENV['RABBITMQ_PASSWORD'])
    @connection.start
  end

  def publish(queue_name, message)
    channel = @connection.create_channel
    queue = channel.queue(queue_name)
    channel.default_exchange.publish(message, routing_key: queue.name)
  end

  def close
    @connection.close
  end
end

Sur la plateforme de développement, votre fichier .env pourrait inclure :

RABBITMQ_HOST='127.0.0.1'
RABBITMQ_USERNAME='developmentUser'
RABBITMQ_PASSWORD='developmentPassword'

Pour la production et le staging, définissez vos variables d'environnement dans le tableau de bord Stackhero sous la configuration du service Ruby comme indiqué ci-dessous :

RABBITMQ_HOST='<XXXXXX>.stackhero-network.com'
RABBITMQ_USERNAME='production'
RABBITMQ_PASSWORD='secretProductionPassword'

Les applications Ruby utilisent souvent le protocole HTTP sur les ports 80 (HTTP) et 443 (HTTPS). Si votre application nécessite des ports supplémentaires ou des protocoles différents (TCP ou UDP), configurez les paramètres "Ports Redirections" dans votre service Ruby via le tableau de bord Stackhero.

Vous devrez spécifier le port d'entrée (ouvert publiquement), le port de destination (ouvert au sein de votre service Ruby), et le protocole (TCP ou UDP).

Pour stocker des fichiers tels que des photos d'utilisateurs ou des documents, il est fortement recommandé d'utiliser une solution d'object storage. L'object storage vous permet de partager des fichiers entre plusieurs services et instances et découple la couche de stockage de votre code. C'est considéré comme une bonne pratique.

Nous recommandons MinIO comme solution simple, rapide et puissante compatible avec le protocole Amazon S3.

Si vous choisissez le stockage de fichiers local, vous pouvez utiliser le stockage persistant fourni avec votre instance Ruby. Ce stockage local est disponible sous le répertoire /persistent/storage/.

Cependant, le stockage de fichiers local n'est généralement pas recommandé car il peut ne pas être la meilleure pratique pour une évolutivité et une fiabilité à long terme.

ATTENTION : Ne stockez jamais de données en dehors du dossier /persistent/storage/ !

Stocker des données dans un emplacement autre que le dossier de stockage persistant peut entraîner une perte de données lorsque votre instance est redémarrée, mise à jour ou lorsque vous poussez du nouveau code.

Si vous utilisez macOS, vous pourriez trouver gênant de taper le mot de passe de votre clé privée SSH à chaque fois que vous poussez votre code. Bien que la sécurité soit essentielle, vous pouvez améliorer la commodité en stockant votre mot de passe en toute sécurité dans le Trousseau d'accès d'Apple.

Il peut être tentant de supprimer le mot de passe de votre clé privée SSH, mais cela n'est pas conseillé.

Au lieu de cela, stockez le mot de passe de votre clé dans le Trousseau d'accès en utilisant la commande suivante pour une clé nommée id_ed25519 :

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Après avoir exécuté cette commande, vous ne devriez plus être invité à entrer le mot de passe de votre clé. Si vous utilisez une clé RSA, remplacez id_ed25519 par id_rsa comme indiqué ci-dessous :

ssh-add --apple-use-keychain ~/.ssh/id_rsa