<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yuri Zinchenko</title>
    <description>The latest articles on DEV Community by Yuri Zinchenko (@zinchen).</description>
    <link>https://dev.to/zinchen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F579051%2F4a72bd5e-d726-4e75-9e99-4eea07babc63.jpeg</url>
      <title>DEV Community: Yuri Zinchenko</title>
      <link>https://dev.to/zinchen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zinchen"/>
    <language>en</language>
    <item>
      <title>Rails + VSCode + Docker. Разработка с devcontainer.</title>
      <dc:creator>Yuri Zinchenko</dc:creator>
      <pubDate>Sat, 13 Mar 2021 17:16:26 +0000</pubDate>
      <link>https://dev.to/zinchen/rails-vscode-docker-devcontainer-13h9</link>
      <guid>https://dev.to/zinchen/rails-vscode-docker-devcontainer-13h9</guid>
      <description>&lt;h2&gt;
  
  
  Содержание
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Введение&lt;/li&gt;
&lt;li&gt;Создание приложения в Docker контейнере&lt;/li&gt;
&lt;li&gt;Запуск Rails приложения в docker-compose&lt;/li&gt;
&lt;li&gt;Настройка контейнера для разработки&lt;/li&gt;
&lt;li&gt;Настройка Rubocop и Solargraph&lt;/li&gt;
&lt;li&gt;Добавляем немного кода&lt;/li&gt;
&lt;li&gt;Отладка с Byebug&lt;/li&gt;
&lt;li&gt;Отладка с Pry&lt;/li&gt;
&lt;li&gt;Подключение отладчика в VSCode&lt;/li&gt;
&lt;li&gt;Заключение&lt;/li&gt;
&lt;li&gt;Ссылки&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Введение
&lt;/h1&gt;

&lt;p&gt;Docker помогает разработчикам и девопсам, упрощая и автоматизируя шаги, необходимые для деплоя. Так же он часто используется разработчиками в повседневной работе, предоставляя изолированную среду, не зависимую от текущей ОС и окружения. Но переход на докер помимо упрощения добавляет и свои сложности. Например, при запуске приложения в докере использование линтера для подсветки синтаксиса становится недоступным, так как все зависимости и библиотеки приложения находятся в изолированном контейнере. И каким образом можно отлаживать приложение?&lt;/p&gt;

&lt;p&gt;Ответы на эти вопросы я постарался собрать в этой статье. Эти советы будут полезны и для работы с кодом на удалённой машине через ssh, так как методы взаимодействия будут схожи.&lt;/p&gt;

&lt;p&gt;Основными инструментами для разработки в докере у нас будут редактор VSCode и расширение &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers" rel="noopener noreferrer"&gt;Remote Containers&lt;/a&gt;. Это расширение позволит нам запускать редактор в таком же контейнере, что и приложение.&lt;/p&gt;

&lt;p&gt;Докер будет использоваться в качестве сервера с приложением, а так же как контейнер для разработки (devcontainer), в котором содержатся необходимые плагины VSCode, настройки редактора и зависимости проекта. Общая схема выглядит так:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fop1zwiynjgh6pb5eha9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fop1zwiynjgh6pb5eha9a.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Создание приложения в Docker контейнере
&lt;/h1&gt;

&lt;p&gt;В вашей системе должен быть установлен &lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; и &lt;a href="https://docs.docker.com/compose/install/" rel="noopener noreferrer"&gt;Docker-compose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Создайте файл &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ruby:2.7.2&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;curl https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb https://dl.yarnpkg.com/debian/ stable main"&lt;/span&gt; | &lt;span class="nb"&gt;tee&lt;/span&gt; /etc/apt/sources.list.d/yarn.list
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="nt"&gt;-qq&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; postgresql-client

&lt;span class="k"&gt;RUN &lt;/span&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;bundler

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Так как нам нужно создать новое приложение с помощью команды &lt;code&gt;rails new&lt;/code&gt;, создадим контейнер с гемом rails.&lt;/p&gt;

&lt;p&gt;Сначала сделаем том докера, чтобы сохранить в нём установленные гемы. Это не обязательный шаг, но сохранит время в дальнейшем. При изменении Dockerfile или Gemfile гемы не будут удалятся вместе с контейнером, а останутся в отдельном томе(volume).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker volume create ruby-2.7.2-gems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Теперь создадим образ из файла Dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; rails-docker-debug &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Для создания приложения создадим одноразовый контейнер и запустим в нём терминал&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; ruby-2.7.2-gems:/usr/local/bundle &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/app rails-docker-debug bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--rm&lt;/code&gt; удалит контейнер после его остановки&lt;br&gt;
&lt;code&gt;-it&lt;/code&gt; позволит запустить команду в контейнере, в нашем случае bash&lt;br&gt;
&lt;code&gt;-v&lt;/code&gt; смонтируем текущую директорию в WORKDIR контейнерa, чтобы файлы при создании попали в неё. Если у вас Windows, замените $(pwd) на полный путь до директории проекта&lt;br&gt;
&lt;code&gt;-v&lt;/code&gt; смонтируем том, где будут храниться гемы&lt;br&gt;
В Windows вместо &lt;code&gt;$(pwd)&lt;/code&gt; нужно будет указать полный путь до папки проекта.&lt;/p&gt;

&lt;p&gt;Внутри контейнера установим rails и создадим новое приложение:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;rails
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rails new &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; postgresql &lt;span class="nt"&gt;--api&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-d postgresql&lt;/code&gt; будем использовать PostgresQL в качестве базы данных&lt;br&gt;
&lt;code&gt;--api&lt;/code&gt; пропускаем установку вебпака, так как он требует node.js. При желании его установку можно добавить в Dockerfile&lt;/p&gt;

&lt;p&gt;Теперь можно закрыть контейнер&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Дополнение:&lt;/p&gt;

&lt;p&gt;В unix системах (Mac и Linux) файлы созданные в контейнере будут созданы от имени рут пользователя и у нас не будет прав на изменение этих файлов вне докера. Выполним &lt;code&gt;chown&lt;/code&gt; команду, чтобы иметь возможность редактировать эти файлы.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &amp;lt;username&amp;gt;:&amp;lt;group&amp;gt; &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Название группы можно увидеть, выполнив &lt;code&gt;ls -al&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Запуск Rails приложения в docker-compose
&lt;/h1&gt;

&lt;p&gt;Создадим файл &lt;code&gt;docker-compose.yml&lt;/code&gt;. Docker-compose делает работу с контейнерами заметно удобнее, чем просто Docker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rails s -b 0.0.0.0&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ruby-2.7.2-gems:/usr/local/bundle&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/app&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;3000:3000&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:10&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db-data:/var/lib/postgresql&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yourpassword&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ruby-2.7.2-gems&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;db-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Параметром &lt;code&gt;POSTGRES_PASSWORD&lt;/code&gt; мы задаём пароль для БД, это можно сделать только в момент создания базы, чтобы это повторить, нужно удалить volume с БД.&lt;br&gt;
В раздел &lt;code&gt;volumes&lt;/code&gt; мы подключаем внешний том с гемами.&lt;/p&gt;

&lt;p&gt;Изменим конфиг подключения к базе &lt;code&gt;config/database.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgresql&lt;/span&gt;
  &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unicode&lt;/span&gt;
  &lt;span class="c1"&gt;# For details on connection pooling, see Rails configuration guide&lt;/span&gt;
  &lt;span class="c1"&gt;# https://guides.rubyonrails.org/configuring.html#database-pooling&lt;/span&gt;
  &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yourpassword&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;здесь db это название сервиса из docker-compose.yml. Оно по сути выступает адресом в сети, наподобие домена нулевого уровня или localhost. Эту сеть создаёт docker-compose для общения между контейнерами.&lt;/p&gt;

&lt;p&gt;Осталось только создать базу и можно работать с приложением&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose build
docker-compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; web rails db:create
docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Дополнение:&lt;/p&gt;

&lt;p&gt;Если возникли ошибки в процессе создания базы данных, рекомендую прежде всего удалить volume:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose down &lt;span class="nt"&gt;--volumes&lt;/span&gt;
docker volume &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; rails-docker-debug_db-data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;и проверить, совпадают ли пароли для базы в &lt;code&gt;database.yml&lt;/code&gt; и &lt;code&gt;docker-compose.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Так же можно посмотреть логи контейнеров&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose logs web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;web&lt;/code&gt; - имя сервисa в docker-compose.yml&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Настройка контейнера для разработки
&lt;/h1&gt;

&lt;p&gt;Для использования контейнера для разработки установим плагин &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers" rel="noopener noreferrer"&gt;Remote Containers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;В качестве линтера для руби будем использовать &lt;strong&gt;rubocop&lt;/strong&gt; и &lt;strong&gt;solargraph&lt;/strong&gt;. Для создания девконтейнера мы возьмём тот же самый Dockerfile, который сделали раньше. Так как гемы у нас лежат в отдельном томе, то устанавливать rubocop и solargraph надо так же в этот том. Для этого запустим docker-compose с командой установки.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose run web bundle add solargraph rubocop rubocop-rails rubocop-rspec rubocop-performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Создадим в директории нашего проекта папку &lt;code&gt;.devcontainer&lt;/code&gt;, в ней создадим файл конфигурации контейнера для vscode. Этот файл содержит информацию о контейнере для разработки, наборе плагинов и настройках, которые будет использовать vscode внутри этого контейнера.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.devcontainer/devcontainer.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rails Api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dockerFile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"../Dockerfile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mounts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"source=ruby-2.7.2-gems,target=/usr/local/bundle,type=volume"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"[ruby]"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"editor.insertSpaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"editor.tabSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"solargraph.commandPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/bundle/bin/solargraph"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"solargraph.bundlerPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/bin/bundle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ruby.rubocop.executePath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/bundle/bin/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ruby.linter.executablePath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/bundle/bin/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"rebornix.Ruby"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"castwide.solargraph"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"misogi.ruby-rubocop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"hoovercj.ruby-linter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"miguel-savignano.ruby-symbols"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"wingrunr21.vscode-ruby"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"kaiwood.endwise"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'forwardPorts'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;make&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ports&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;inside&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;container&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;available&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;locally.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"forwardPorts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Uncomment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;commands&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;after&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;container&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;created&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;installing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;curl.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"postCreateCommand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apt-get update &amp;amp;&amp;amp; apt-get install -y curl"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Uncomment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;when&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ptrace-based&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;debugger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;like&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;C++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Go&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Rust&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"runArgs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--cap-add=SYS_PTRACE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--security-opt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"seccomp=unconfined"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Uncomment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CLI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;inside&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;container.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;See&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://aka.ms/vscode-remote/samples/docker-from-docker.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mounts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Uncomment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;connect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;non-root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;you've&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;added&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;one.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;See&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://aka.ms/vscode-remote/containers/non-root.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"remoteUser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vscode"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;В этом файле помимо настроек редактора и списка плагинов есть строка подключения к контейнеру тома с гемами, который мы создали ранее.&lt;/p&gt;

&lt;p&gt;После сохранения этого файла можно запустить команду, чтобы перейти в разработку внутри дев контейнера. Для этого в палитре команд (ctrl+shift+p) выбираем &lt;code&gt;Rebuild and Reopen in Container&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;После запуска команды редактор перезапустится и построит дев контейнер. После успешного завершения откроется обычное окно vscode, но уже с плагинами и настройками, указанными в &lt;code&gt;devcontainer.json&lt;/code&gt;. Так же в этом окне не будет доступна файловая система хоста. При необходимости можно вернуться в редактор без запуска дев контейнера: &lt;code&gt;ctrl+shift+p&lt;/code&gt; -&amp;gt; &lt;code&gt;Reopen Locally&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Настройка Rubocop и Solargraph
&lt;/h1&gt;

&lt;p&gt;Чтобы настроить линтеры для работы с rails, добавим им конфиг файлы&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.solargraph.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;**/*.rb"&lt;/span&gt;
&lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;spec/**/*&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test/**/*&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;vendor/**/*&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.bundle/**/*"&lt;/span&gt;
&lt;span class="na"&gt;require&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;actioncable&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;actionmailer&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;actionpack&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;actionview&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;activejob&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;activemodel&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;activerecord&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;activestorage&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;activesupport&lt;/span&gt;
&lt;span class="na"&gt;domains&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;span class="na"&gt;reporters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rubocop&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;require_not_found&lt;/span&gt;
&lt;span class="na"&gt;require_paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;span class="na"&gt;max_files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.rubocop.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;require&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rubocop-rails&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rubocop-rspec&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rubocop-performance&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Следуя совету из &lt;a href="https://solargraph.org/guides/rails" rel="noopener noreferrer"&gt;гайдов solargraph&lt;/a&gt; запустим команду для генерации кэша с документацией. Запускать нужно внутри контейнера, например в терминале vscode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solargraph bundle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;и создадим файл, который поможет solargraph анализоровать rails приложение&lt;/p&gt;

&lt;p&gt;&lt;code&gt;definitions.rb&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The following comments fill some of the gaps in Solargraph's understanding of&lt;/span&gt;
&lt;span class="c1"&gt;# Rails apps. Since they're all in YARD, they get mapped in Solargraph but&lt;/span&gt;
&lt;span class="c1"&gt;# ignored at runtime.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# You can put this file anywhere in the project, as long as it gets included in&lt;/span&gt;
&lt;span class="c1"&gt;# the workspace maps. It's recommended that you keep it in a standalone file&lt;/span&gt;
&lt;span class="c1"&gt;# instead of pasting it into an existing one.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# @!parse&lt;/span&gt;
&lt;span class="c1"&gt;#   class ActionController::Base&lt;/span&gt;
&lt;span class="c1"&gt;#     include ActionController::MimeResponds&lt;/span&gt;
&lt;span class="c1"&gt;#     extend ActiveSupport::Callbacks::ClassMethods&lt;/span&gt;
&lt;span class="c1"&gt;#     extend AbstractController::Callbacks::ClassMethods&lt;/span&gt;
&lt;span class="c1"&gt;#   end&lt;/span&gt;
&lt;span class="c1"&gt;#   class ActiveRecord::Base&lt;/span&gt;
&lt;span class="c1"&gt;#     extend ActiveRecord::QueryMethods&lt;/span&gt;
&lt;span class="c1"&gt;#     extend ActiveRecord::FinderMethods&lt;/span&gt;
&lt;span class="c1"&gt;#     extend ActiveRecord::Associations::ClassMethods&lt;/span&gt;
&lt;span class="c1"&gt;#     extend ActiveRecord::Inheritance::ClassMethods&lt;/span&gt;
&lt;span class="c1"&gt;#     include ActiveRecord::Persistence&lt;/span&gt;
&lt;span class="c1"&gt;#   end&lt;/span&gt;
&lt;span class="c1"&gt;# @!override ActiveRecord::FinderMethods#find&lt;/span&gt;
&lt;span class="c1"&gt;#   @overload find(id)&lt;/span&gt;
&lt;span class="c1"&gt;#     @param id [Integer]&lt;/span&gt;
&lt;span class="c1"&gt;#     @return [self]&lt;/span&gt;
&lt;span class="c1"&gt;#   @overload find(list)&lt;/span&gt;
&lt;span class="c1"&gt;#     @param list [Array]&lt;/span&gt;
&lt;span class="c1"&gt;#     @return [Array&amp;lt;self&amp;gt;]&lt;/span&gt;
&lt;span class="c1"&gt;#   @overload find(*args)&lt;/span&gt;
&lt;span class="c1"&gt;#     @return [Array&amp;lt;self&amp;gt;]&lt;/span&gt;
&lt;span class="c1"&gt;#   @return [self, Array&amp;lt;self&amp;gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Добавляем немного кода
&lt;/h1&gt;

&lt;p&gt;Создадим модель и контроллер с книгами и сгенерируем несколько записей:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;db/seeds.rb&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"War and Peace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="s2"&gt;"Leo Tolstoy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;publication_year: &lt;/span&gt;&lt;span class="mi"&gt;1869&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"Hamlet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="s2"&gt;"William Shakespeare"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;publication_year: &lt;/span&gt;&lt;span class="mi"&gt;1870&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"Crime and Punishment"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="s2"&gt;"Fyodor Dostoevsky"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;publication_year: &lt;/span&gt;&lt;span class="mi"&gt;1866&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose run web rails g scaffold books title:string author:string publication_year:integer
docker-compose run web rails db:migrate
docker-compose run web rails db:seed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Отладка с Byebug
&lt;/h1&gt;

&lt;p&gt;Этот гем позволяет запустить простой отладчик в терминале, достаточно написать слово &lt;code&gt;byebug&lt;/code&gt; в коде и это станет брейкпоинтом. В консоли будет возможность посмотреть содержимое переменных или пошагово выполнить код. Он входит в набор гемов, которые устанавливаются при создании rails приложения, а значит мы уже можем им воспользоваться.&lt;br&gt;
Для запуска Byebug в докере необходимо включить интерактивный режим консоли. Для этого в сервис &lt;code&gt;web&lt;/code&gt; в &lt;code&gt;docker-compose.yml&lt;/code&gt; добавим параметры.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;stdin_open&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;tty&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;В итоге получится&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rails s -b 0.0.0.0&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ruby-2.7.2-gems:/usr/local/bundle&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/app&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;3000:3000&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
    &lt;span class="na"&gt;stdin_open&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;tty&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Попробуем Byebug в деле, добавим строчку с &lt;code&gt;byebug&lt;/code&gt; в контроллер книг&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app/controllers/books_controller.rb&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="c1"&gt;# GET /books&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;

    &lt;span class="n"&gt;byebug&lt;/span&gt;

    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="vi"&gt;@books&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Теперь запустим приложение&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;И в другом терминале подключимся к консоли сервиса web, в ней мы сможем управлять отладкой.&lt;br&gt;
Найдём имя контейнера сервиса web.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Обычно это имя папки плюс название сервиса и цифра: &lt;code&gt;rails-docker-debug_web_1&lt;/code&gt;. Подключимся к нему:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker attach rails-docker-debug_web_1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Теперь при открытии страницы &lt;a href="http://localhost:3000/books" rel="noopener noreferrer"&gt;http://localhost:3000/books&lt;/a&gt; произойдёт вызов byebug и в окне терминала появится интерактивный режим, как если бы мы открыли консоль пользователя. Здесь мы можем вывести любую переменную, которая была объявлена в коде, выполнить следующую строку (&lt;code&gt;step&lt;/code&gt;) или продолжить выполнение кода (&lt;code&gt;continue&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9leea12nsab9ksiadnge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9leea12nsab9ksiadnge.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Чтобы отключить терминал от докера нужно выполнить комбинацию клавиш &lt;code&gt;Ctrl+P&lt;/code&gt; и &lt;code&gt;Ctrl+Q&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Отладка с Pry
&lt;/h1&gt;

&lt;p&gt;Pry - аналог irb, интерактивная среда выполнения со множеством дополнительных функций. Основные особенности pry:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;отображение с цветной подсветкой синтаксиса и форматированием, это первое, что сразу добавляет удобства&lt;/li&gt;
&lt;li&gt;возможность поставить брейкпоинт, аналогично гему byebug&lt;/li&gt;
&lt;li&gt;удобная навигация по коду, быстрые переходы по состояниям (cd, ls)&lt;/li&gt;
&lt;li&gt;отображение документации из кода
и множество других команд и возможностей
&lt;a href="https://github.com/pry/pry" rel="noopener noreferrer"&gt;https://github.com/pry/pry&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Установим pry&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose run web bundle add pry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Теперь при вызове команды &lt;code&gt;rails c&lt;/code&gt; откроется интерактивная среда pry вместо irb. Если у вас в консоли написано &lt;code&gt;irb&lt;/code&gt; то можно переключиться на pry командой &lt;code&gt;pry&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxm0keexqwcegxibrnzj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxm0keexqwcegxibrnzj.png" alt="image"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose run web rails c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Так же pry можно использовать во время отладки. Сделаем аналогично примеру с &lt;code&gt;byebug&lt;/code&gt;, для этого в начало файла &lt;code&gt;app/controllers/books_controller.rb&lt;/code&gt; добавим&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'pry'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;и добавим &lt;code&gt;binding.pry&lt;/code&gt; в метод &lt;code&gt;index&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="c1"&gt;# GET /books&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;

    &lt;span class="nb"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pry&lt;/span&gt;

    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="vi"&gt;@books&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;После этого можно так же запустить сервер и подключиться к докеру&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up
docker attach rails-docker-debug_web_1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;и открыть &lt;a href="http://localhost:3000/books" rel="noopener noreferrer"&gt;http://localhost:3000/books&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8hfqo5ez598st60tdz5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8hfqo5ez598st60tdz5.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Теперь в консоли можно посмотреть доступные методы и переменные: &lt;code&gt;ls&lt;/code&gt;, исходный код метода или класса: &lt;code&gt;show-source render&lt;/code&gt; покажет код метода &lt;code&gt;render&lt;/code&gt; и многое другое.&lt;br&gt;
Для выхода введите &lt;code&gt;exit&lt;/code&gt;.&lt;br&gt;
Подробнее про методы pry можно почитать в репозитории &lt;a href="https://github.com/pry/pry" rel="noopener noreferrer"&gt;https://github.com/pry/pry&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Подключение отладчика в VSCode
&lt;/h1&gt;

&lt;p&gt;Так же имеется возможность отладки приложения напрямую из VSCode. Для этого нужно сделать несколько шагов&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Добавим гемы &lt;code&gt;ruby-debug-ide&lt;/code&gt; &lt;code&gt;debase&lt;/code&gt;, чтобы к нашему приложению можно было подключиться для отладки
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; docker-compose run web bundle add ruby-debug-ide debase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Создадим папку и в ней файл &lt;code&gt;.vscode/launch.json&lt;/code&gt;. Добавим туда конфиг для подключения отладчика VSCode к приложению.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"configurations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Listen for rdebug-ide"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ruby"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"attach"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"remoteHost"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"remotePort"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"remoteWorkspaceRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/app"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Создадим новый docker-compose файл для дебага &lt;code&gt;docker-compose.debug.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rdebug-ide --host 0.0.0.0 --port 9000 -- bin/rails s -p 3000 -b 0.0.0.0&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;9000:9000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Чтобы наш контейнер для разработки имел доступ к порту отладки, сделаем внутри контейнера ту же самую сеть, что и на хосте. Для этого добавим в файл &lt;code&gt;devcontainer.json&lt;/code&gt; строчку с параметром запуска.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"runArgs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--network=host"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;После изменений нужно сделать ребилд контейнера:&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;Command Palette -&amp;gt; Rebuild Container&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Выполним команду запуска проекта в режиме дебага.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yml &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.debug.yml up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;На этом этапе адрес сайта &lt;code&gt;http://localhost:3000/&lt;/code&gt; будет не доступен до тех пор, пока мы не включим режим отладки в редакторе VSCode.&lt;/p&gt;

&lt;p&gt;Для этого зайдем в окно отладки. И начнём отладку.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjgwb17eoymwcjs02o09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjgwb17eoymwcjs02o09.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;После запуска отладки наш проект заработает как обычно.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhnle71g3e3zgbuzw912u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhnle71g3e3zgbuzw912u.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;А в редакторе мы сможем поставить точку остановки.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe08jx7h19vzvz4v4snqu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe08jx7h19vzvz4v4snqu.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;При открытии страницы &lt;a href="http://localhost:3000/books" rel="noopener noreferrer"&gt;http://localhost:3000/books&lt;/a&gt; в браузере редактор отобразит текущее состояние приложения в данной точке.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdoulu3p3tu04ngzwj2gb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdoulu3p3tu04ngzwj2gb.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Дополнение&lt;/p&gt;

&lt;p&gt;В случае ошибки &lt;code&gt;A server is already running. Check /app/tmp/pids/server.pid.&lt;/code&gt; удалите файл &lt;code&gt;server.pid&lt;/code&gt; командой&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; docker-compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; web &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; tmp/pids/server.pid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;или в файле &lt;code&gt;docker-compose&lt;/code&gt; значение свойства &lt;code&gt;command&lt;/code&gt; оберните следующим кодом&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"rm -f tmp/pids/server.pid &amp;amp;&amp;amp; &amp;lt;здесь_исходная_команда&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;В этом случае удаление файла будет происходить автоматически при запуске.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Заключение
&lt;/h1&gt;

&lt;p&gt;Мы рассмотрели основные способы создания и отладки приложения и адаптировали их использование для Docker окружения. Использование Docker в разработке вносит удобства запуска, но так же и повышает сложность настройки и взаимодействия с приложением в контейнере. Как по мне, использование Docker позволяет лучше понять принципы  работы разных компонентов приложения. Сделаем выводы, какие достоинства и недостатки есть у использования Docker в разработке.&lt;/p&gt;

&lt;p&gt;Достоинства:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker-compose изолирует приложение и позволяет запускать его независимо от вашей ОС или от того, какие версии Ruby или Postgres установлены на вашей хост машине.&lt;/li&gt;
&lt;li&gt;Devcontainer изолирует плагины VSCode и необходимое для них окружение, это удобно если вы работаете в VSCode с разными языками или фреймворками.&lt;/li&gt;
&lt;li&gt;В случае необходимости запуска проекта на новой машине это пройдёт быстрее, благодаря автоматизации деплоя.&lt;/li&gt;
&lt;li&gt;Все шаги деплоя задокументированы в файлах докера.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Недостатки:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Контейнеризация усложняет процесс взаимодействия компонентов приложения.&lt;/li&gt;
&lt;li&gt;Необходимо иметь представление об устройстве докера, чтобы правильно его использовать.&lt;/li&gt;
&lt;li&gt;Докер приложение будет использовать больше системных ресурсов, чем запущенное локально.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Ссылки
&lt;/h1&gt;

&lt;p&gt;Код из этой статьи &lt;a href="https://github.com/ZinChen/rails-docker-debug" rel="noopener noreferrer"&gt;https://github.com/ZinChen/rails-docker-debug&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Статьи, которые помогли разобраться в данной теме и написать эту статью. Большое спасибо их авторам! :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/docs/remote/create-dev-container" rel="noopener noreferrer"&gt;Create a development container&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/imiked/starting-a-rails-app-using-vscode-containers-1gj9"&gt;Starting a Rails app using vscode containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stelligent.com/2020/04/10/development-acceleration-through-vs-code-remote-containers-setting-up-a-foundational-configuratio/" rel="noopener noreferrer"&gt;Development Acceleration Through VS Code Remote Containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/gogox-technology/debugging-rails-app-with-docker-compose-39a3767962f4" rel="noopener noreferrer"&gt;Debugging Rails App With Docker Compose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@GrantMercer/debugging-rails-on-docker-with-vscode-6f9d920413fd" rel="noopener noreferrer"&gt;Debugging Rails on Docker with VSCode&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>rails</category>
      <category>docker</category>
      <category>vscode</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
