[RUBY] Créez une API REST avec Apache2 + Passenger + Sinatra.

Politique de construction de l'API REST

J'exécute déjà le service principal sur Apache2, je ne souhaite donc pas modifier les paramètres réseau de l'API REST. Je lance donc Sinatra sur Apache2. Dans le cas peu probable où il y aurait un problème de performances, j'appellerai la fonction Rust via FFI. Sinatra publie l'API REST en parallèle avec l'application principale publiée par Apache2. Rendez-le appelable sous la forme suivante.

http://localhost:8080/main_app
http://localhost:8080/sinatra

Matériel de référence

  1. [Installing Passenger + Apache on Ubuntu 18.04 LTS (with APT)] (https://www.phusionpassenger.com/library/install/apache/install/oss/bionic/)
  2. [Deploying an app to a sub-URI or subdirectory] (https://www.phusionpassenger.com/library/deploy/apache/deploy/ruby/#deploying-an-app-to-a-sub-uri-or-subdirectory)
  3. Autres articles de personnes qui ont relevé des défis similaires (merci!)

Installation basique

Construisez un environnement expérimental avec Vagrant. Les éléments d'installation sont les suivants.

  1. Apache2
  2. Ruby
  3. bundler
  4. Sinatra
  5. sinatra-contrib
  6. Passenger

S'il fonctionne avec 1024 Mo de mémoire, la charge de travail sur le serveur de production doit être légère. Puisque vagrant ssh peut provoquer une erreur, ssh est défini au début de l'installation.

Vagrantfile


# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/bionic64"

  config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

  config.vm.synced_folder "./data", "/vagrant_data"

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
  end

  config.vm.provision "shell", inline: <<-SHELL
    # To solve the issue of "[email protected]: permission denied (publickey)."
    sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config; \
    sudo systemctl restart sshd;

    apt-get update
    # Installing Apache2
    apt-get install -y apache2

    # Installing Ruby & sinatra
    apt-get install -y ruby
    gem install bundler
    gem install sinatra
    gem install sinatra-contrib
    
    # [Installing Passenger + Apache on Ubuntu 18.04 LTS (with APT)]
    # (https://www.phusionpassenger.com/library/install/apache/install/oss/bionic/)
    sudo apt-get install -y dirmngr gnupg
    sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
    sudo apt-get install -y apt-transport-https ca-certificates

    sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list'
    sudo apt-get update

    sudo apt-get install -y libapache2-mod-passenger
    
    sudo a2enmod passenger
    sudo a2enmod headers
    sudo apache2ctl restart
  SHELL
end

Vérification de la version d'installation

Connectez-vous avec vagrant ssh pour vérifier. Le mot de passe est «vagrant».

Apache2

La version d'Apache2 détermine s'il faut écrire les paramètres Apache2 (`Exiger tout accordé ').

$ apache2 -v
Server version: Apache/2.4.29 (Ubuntu)
Server built:   2020-08-12T21:33:25

Ruby

La version Ruby est également confirmée ici pour être utilisable normalement.

$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]

L'emplacement du fichier exécutable Ruby sera reflété dans les paramètres Apache2 (PassengerRuby / usr / bin / ruby2.5).

Ruby Gems (bundler,sinatra,sinatra-contrib)

Ce qui suit est ce qui a été installé par le travail jusqu'à présent.

$gem list
backports (3.18.2)
bigdecimal (default: 1.3.4)
bundler (2.1.4)
cmath (default: 1.0.0)
csv (default: 1.0.0)
date (default: 1.0.0)
dbm (default: 1.0.0)
did_you_mean (1.2.0)
etc (default: 1.0.0)
fcntl (default: 1.0.0)
fiddle (default: 1.0.0)
fileutils (default: 1.0.2)
gdbm (default: 2.0.0)
io-console (default: 0.4.6)
ipaddr (default: 1.2.0)
json (default: 2.1.0)
minitest (5.10.3)
multi_json (1.15.0)
mustermann (1.1.1)
net-telnet (0.1.1)
openssl (default: 2.1.1)
power_assert (0.2.7)
psych (default: 3.0.2)
rack (2.2.3, 1.6.4)
rack-protection (2.0.8.1)
rake (12.3.1)
rdoc (default: 6.0.1)
ruby2_keywords (0.0.2)
scanf (default: 1.0.0)
sdbm (default: 1.0.0)
sinatra (2.0.8.1)
sinatra-contrib (2.0.8.1)
stringio (default: 0.0.1)
strscan (default: 1.0.0)
test-unit (3.2.5)
tilt (2.0.10)
webrick (default: 1.4.2)
zlib (default: 1.0.0)

Passenger

Vérifiez le fonctionnement en vous reportant à Étape 3: vérification de l'installation.

$ sudo /usr/bin/passenger-config validate-install
What would you like to validate?
Use <space> to select.
If the menu doesn't display correctly, press '!'

 . ●  Passenger itself
   ○  Apache

-------------------------------------------------------------------------

 * Checking whether this Passenger install is in PATH... ✓
 * Checking whether there are no other Passenger installations... ✓

Everything looks good. :-)

Même si je coche ʻApache`, il n'est pas reconnu. Il n'est pas nécessaire de reconnaître Apache2 de Passenger, donc il n'y a pas de problème.

Vérifiez l'état d'utilisation de la mémoire.

$ sudo /usr/sbin/passenger-memory-stats
Version: 6.0.6
Date   : 2020-09-03 00:07:00 +0000

--------- Apache processes ----------
PID   PPID  VMSize     Private  Name
-------------------------------------
4238  1     153.9 MB   0.5 MB   /usr/sbin/apache2 -k start
4483  4238  1268.4 MB  0.7 MB   /usr/sbin/apache2 -k start
4484  4238  1268.4 MB  0.6 MB   /usr/sbin/apache2 -k start
### Processes: 3
### Total private dirty RSS: 1.78 MB


-------- Nginx processes --------

### Processes: 0
### Total private dirty RSS: 0.00 MB


---- Passenger processes -----
PID   VMSize    Private  Name
------------------------------
4468  389.7 MB  2.3 MB   Passenger watchdog
4471  946.3 MB  3.4 MB   Passenger core
### Processes: 2
### Total private dirty RSS: 5.64 MB

Assurez-vous que Passager reconnaît Ruby. Reportez-vous à Déterminer la commande Ruby que Passenger doit utiliser.

$ passenger-config about ruby-command
passenger-config was invoked through the following Ruby interpreter:
  Command: /usr/bin/ruby2.5
  Version: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
  To use in Apache: PassengerRuby /usr/bin/ruby2.5
  To use in Nginx : passenger_ruby /usr/bin/ruby2.5
  To use with Standalone: /usr/bin/ruby2.5 /usr/bin/passenger start

The following Ruby interpreter was found first in $PATH:
  Command: /usr/bin/ruby
  Version: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
  To use in Apache: PassengerRuby /usr/bin/ruby
  To use in Nginx : passenger_ruby /usr/bin/ruby
  To use with Standalone: /usr/bin/ruby /usr/bin/passenger start

## Notes for RVM users
Do you want to know which command to use for a different Ruby interpreter? 'rvm use' that Ruby interpreter, then re-run 'passenger-config about ruby-command'.

N'oubliez pas que / usr / bin / ruby2.5 est défini dans Apache2.

Configuration de l'application Sinatra

Il y a quelques précautions dans la configuration de l'application pour exécuter l'application Sinatra dans la configuration Apache2 + Passenger. Les répertoires public et tmp sont requis pour le répertoire d'application. Le contenu peut être vide.

/home/vagrant/sinatra$ $ ls -al
total 32
drwxr-xr-x 4 vagrant vagrant 4096 Sep  3 00:59 .
drwxr-xr-x 7 vagrant vagrant 4096 Sep  3 00:46 ..
-rw-r--r-- 1 vagrant vagrant   79 Sep  3 00:50 Gemfile
-rw-r--r-- 1 vagrant vagrant   83 Sep  3 00:59 app.rb
-rw-r--r-- 1 vagrant vagrant   63 Sep  3 00:31 config.ru
drwxr-xr-x 2 vagrant vagrant 4096 Sep  3 00:31 public
drwxr-xr-x 2 vagrant vagrant 4096 Sep  3 00:31 tmp

/home/vagrant/sinatra/Gemfile


source 'https://rubygems.org/'

gem 'sinatra'
gem 'sinatra-contrib'
gem 'rack'

/home/vagrant/sinatra/app.rb


Bundler.require

  get '/' do
    "I did it my way"
  end

/home/vagrant/sinatra/config.ru


require File.absolute_path("app.rb")

run Sinatra::Application

Exécutez le bundler et définissez les dépendances des applications.

~/sinatra$ bundler install
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Using backports 3.18.2
Following files may not be writable, so sudo is needed:
  /usr/local/bin
  /var/lib/gems/2.5.0
  /var/lib/gems/2.5.0/build_info
  /var/lib/gems/2.5.0/cache
  /var/lib/gems/2.5.0/doc
  /var/lib/gems/2.5.0/extensions
  /var/lib/gems/2.5.0/gems
  /var/lib/gems/2.5.0/specifications
Using bundler 2.1.4
Using multi_json 1.15.0
Using ruby2_keywords 0.0.2
Using mustermann 1.1.1
Using rack 2.2.3
Using rack-protection 2.0.8.1
Using tilt 2.0.10
Using sinatra 2.0.8.1
Using sinatra-contrib 2.0.8.1
Bundle complete! 3 Gemfile dependencies, 10 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

OK si Gemfile.lock est créé.

/home/vagrant/sinatra/Gemfile.lock


GEM
  remote: https://rubygems.org/
  specs:
    backports (3.18.2)
    multi_json (1.15.0)
    mustermann (1.1.1)
      ruby2_keywords (~> 0.0.1)
    rack (2.2.3)
    rack-protection (2.0.8.1)
      rack
    ruby2_keywords (0.0.2)
    sinatra (2.0.8.1)
      mustermann (~> 1.0)
      rack (~> 2.0)
      rack-protection (= 2.0.8.1)
      tilt (~> 2.0)
    sinatra-contrib (2.0.8.1)
      backports (>= 2.8.2)
      multi_json
      mustermann (~> 1.0)
      rack-protection (= 2.0.8.1)
      sinatra (= 2.0.8.1)
      tilt (~> 2.0)
    tilt (2.0.10)

PLATFORMS
  ruby

DEPENDENCIES
  rack
  sinatra
  sinatra-contrib

BUNDLED WITH
   2.1.4

Liez un répertoire reconnu par Apache2.

$ sudo ln -s /home/vagrant/sinatra sinatra
$ ls -l
total 4
drwxr-xr-x 2 root root 4096 Sep  2 23:30 html
lrwxrwxrwx 1 root root   21 Sep  3 00:35 sinatra -> /home/vagrant/sinatra

Paramètres dans /etc/apache2/mods-available/passenger.conf

[Deploying an app to a sub-URI or subdirectory] Modifiez le fichier de configuration en vous référant à (https://www.phusionpassenger.com/library/deploy/apache/deploy/ruby/#deploying-an-app-to-a-sub-uri-or-subdirectory). Puisque ### Begin to ### End sont décrits lors de l'installation de Passenger, ajoutez les paramètres après cela. Les éléments de réglage diffèrent selon la version de Passenger, soyez donc prudent lorsque vous utilisez différentes versions de Passenger. Spécifiez l'emplacement du fichier exécutable ruby dans PassengerRuby. Si la version d'Apache2 est 2.4 ou supérieure, décrivez «Exiger tout accordé». Il n'y a qu'un seul endroit pour écrire RackBaseURI, ce qui est correct.

/etc/apache2/mods-available/passenger.conf


### Begin automatically installed Phusion Passenger config snippet ###
<IfModule mod_passenger.c>
  PassengerRoot /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini
  PassengerDefaultRuby /usr/bin/passenger_free_ruby
</IfModule>
### End automatically installed Phusion Passenger config snippet ###

PassengerRuby /usr/bin/ruby2.5
RackBaseURI /sinatra

Alias /sinatra /var/www/sinatra/public
<Location /sinatra>
  PassengerBaseURI /sinatra
  PassengerAppRoot /var/www/sinatra
</Location>
<Directory /var/www/sinatra/public>
  Allow from all
  Options -MultiViews
  Require all granted
</Directory>

Redémarrage Apache2

$ sudo service apache2 restart

Vérifiez l'état au cas où.

$ sudo service apache2 status
● apache2.service - The Apache HTTP Server
   Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
  Drop-In: /lib/systemd/system/apache2.service.d
           └─apache2-systemd.conf
   Active: active (running) since Thu 2020-09-03 00:25:40 UTC; 47s ago
  Process: 4811 ExecStop=/usr/sbin/apachectl stop (code=exited, status=0/SUCCESS)
  Process: 4817 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
 Main PID: 2595 (code=exited, status=0/SUCCESS)
    Tasks: 73 (limit: 1152)
   CGroup: /system.slice/apache2.service
           ├─4871 /usr/sbin/apache2 -k start
           ├─4874 Passenger watchdog
           ├─4878 Passenger core
           ├─4892 /usr/sbin/apache2 -k start
           └─4893 /usr/sbin/apache2 -k start

Sep 03 00:25:40 ubuntu-bionic systemd[1]: Starting The Apache HTTP Server...
Sep 03 00:25:40 ubuntu-bionic apachectl[4817]: AH00558: apache2: Could not reliably determine the server's fully qualified d
Sep 03 00:25:40 ubuntu-bionic systemd[1]: Started The Apache HTTP Server.

Le passager court également.

Contrôle de fonctionnement

Tout d'abord, l'application principale. 20200903_main_app.png

Confirmation de l'opération Sinatra. 20200903_sinatra_1.png

Si cela ne fonctionne pas, un écran d'erreur apparaîtra. 20200903_error.png

Si vous ne voyez même pas l'écran d'erreur Passager, vous n'avez pas atteint Passager en premier lieu. Il existe une possibilité de mauvaise configuration d'Apache2 lui-même. Si vous obtenez une erreur, vérifiez / var / log / apache2 / error.log.

Tâche

Les points qui n'ont pas été résolus en raison du manque d'étude sont les suivants.

  1. Je ne connais pas Bundler. Vous n'êtes pas obligé de faire gem install sinatra.
  2. Sinatra ne se recharge pas automatiquement. N'est-il pas suffisant d'écrire simplement "inatra-contrib" dans le Gemfile?
  3. Placement de l'application Sinatra. Faites attention à la sécurité des services publics.
  4. Processus d'authentification de l'application Sinatra.
  5. Comment appeler les fonctions Rust de Sinatra (Ruby) sur FFI.

Recommended Posts

Créez une API REST avec Apache2 + Passenger + Sinatra.
Hello World (API REST) avec Apache Camel + Spring Boot 2
Test de l'API REST avec REST Assured
Test de l'API REST à l'aide de REST Assured Part 2
FileUpload avec Rest sur Apache Wicket
L'application Sinatra avec ActiveRecord est morte dans Passenger 6.0.5
Comment créer une API avec GraphQL et Rails
[Spring Boot] Obtenez des informations utilisateur avec l'API Rest (débutant)
Personnalisez la réponse aux erreurs de l'API REST avec Spring Boot (Partie 2)
Environnement Build Rails (API) x MySQL x Nuxt.js avec Docker
Personnalisez la réponse aux erreurs de l'API REST avec Spring Boot (Partie 1)
Compatible avec Android 10 (API 29)
Construire Doma1 avec Ant
Construisez Growai avec Centos7
À propos de l'API Apache Inference
Construire Java avec Wercker
Construisez bazel avec alpin
Implémenter l'API REST avec Spring Boot et JPA (Application Layer)
Implémenter l'API REST avec Spring Boot et JPA (couche d'infrastructure)
Opération Elasticsearch via l'API REST à l'aide d'Apache HttpClient en Java
Ce à quoi j'étais accro avec l'API REST Redmine
Implémenter l'API REST avec Spring Boot et JPA (Domain Layer Edition)
Implémentez une API Rest simple avec Spring Security & JWT avec Spring Boot 2.0
Parlez du téléchargement de fichiers à l'aide de l'API Slack avec Apache HttpPost