とーますメモ

Ruby on Rails / Goなどの学習メモ

【Ubuntu】セキュリティアップデートを自動で行う方法

unattended-upgradesパッケージを入れて、自動設定を行えば、セキュリティ更新が自動アップデートされる。

1)インストール

$ sudo apt install unattended-upgrades

2)自動設定

コマンド後、Yes/Noの選択画面が表示されるので「Yes」を選択

$ sudo dpkg-reconfigure -plow unattended-upgrades

3)ブラックリストパッケージの設定

時として、勝手にアップデートされては困るものもあるため、そういったものはブラックリストとして設定できる。

「/etc/apt/apt.conf.d/50unattended-upgrades」ファイルの以下の箇所を変更

// List of packages to not update (regexp are supported)
Unattended-Upgrade::Package-Blacklist {
      "vim";
      "mysql-server"; 
      "mysql-client"; 
//      "libc6";
//      "libc6-dev";
//      "libc6-i686";
};


システムアップデートには、再起動が必要な場合があるが
デフォルトだと自動的に再起動は行われない。

設定ファイルである、「/etc/apt/apt.conf.d/50unattended-upgrades」ファイルの以下の箇所を
コメント解除し、値を「true」にする。

Unattended-Upgrade::Automatic-Reboot "true"

その他、メールで通知するなどの設定も可能。

自動アップデートのログは「/var/log/unattended-upgrades/」に保存される。


[参考]
Debian 系で unattended-upgrades を有効にする場合の追加設定 (メール通知, autoremove, autoclean, 再起動)
Ubuntu 16.04: 自動アップデート / アップグレードの設定をする - Narrow Escape
Ubuntuでsecurity updateのみ自動的に適用する
Ubuntu 16.04で自動セキュリティアップデートをセットアップする方法

【Docker】VPSにDockerをインストールし、リモート操作を行ってみた

VPSは格安VPSのDigitalOceanで検証。

ローカルからVPSにDockerをインストールするには「docker-machine」を使用する。
※docker-machineは、色んなクラウドサービスに対応したドライバを搭載しており、AWSやAzuruなどにも対応している。

「digitalocean」ドライバを使用する場合

この場合、新しいドロップレット(デフォルトだとubuntu-16-04-x64)が作成され、docker-machineコマンドで起動や停止ができる。
DigitalOceanの管理画面からAPIのトークンを発行し、以下の記述でDockerをインストールできる。

$ docker-machine create --driver digitalocean --digitalocean-access-token=<DigitalOceanAPIトークン> <ホスト名(任意)>

「generic」ドライバを使用する場合

$ docker-machine create --driver generic --generic-ip-address <対象とするホストのIPアドレス> --generic-ssh-user <ログインに使用するユーザー> <ホスト名(任意)>

これだけで、リモート環境にDockerがインストールされる。
※「generic」ドライバは、docker-machineコマンドで起動や停止はサポートしていない。

[参考]
さくら VPS を docker-machine のホストとして使う
非Linux環境でもDockerの実行環境を簡単に構築できる「Docker Machine」 | さくらのナレッジ
Digital Ocean | Docker Documentation

【Docker】よく使うコマンドまとめ

バージョン確認

$ docker version

index.docker.ioからイメージ取得

$ docker pull イメージ名[:タグ名]

イメージ一覧

$ docker images

イメージ詳細

$ docker inspect [イメージ名]

イメージ検索(※前方一致で検索される)

$ docker search ubuntu

// 人気のあるイメージの検索
$ docker search --stars=30 ubuntu

イメージの削除

$ docker rmi [イメージ名]

※イメージに基づくコンテナが存在する場合「-f」オプションを指定しないと削除できない。

コンテナ生成/起動

$ docker run [オプション] イメージ名[:タグ名] [引数]

// 「nginx」イメージから「my_nginx」というコンテナ名を生成し、バックグランドで動作するよう設定する。
またコンテナの80ポートに、ホストの8080ポートからアクセスできるように設定する。
$ docker run -d -p 8080:80 --name my_nginx nginx

// コンテナ起動後、bashを使用する場合は -iおよび-tを使用する必要がある。オプションの説明は以下。
$ docker run -it コンテナ名 /bin/bash

※主なrunオプションの意味

  • d, --detach(Run container in background and print container ID)・・・コンテナをバックグランドで起動する。その後コンテナIDを出力する。
  • i, --interactive(Keep STDIN open even if not attached)・・・標準入力を開く(バックグランド(デタッチド)モードの場合でも)
  • t, --tty(Allocate a pseudo-TTY)・・・仮想(tty)端末を割り当てる
  • p, --publish list(Publish a container's port(s) to the host)・・・ポートを割り当てる
  • v, --volume list(Bind mount a volume)・・・ホストのディレクトリをコンテナにマウントする。

run実行時にイメージのタグ名を指定しない場合、デフォルトで「latest」のタグが暗黙的につく。
また-pや-vなどの設定は、コンテナ作成後はできないようだ。
Docker - すでに作ったコンテナでホスト側ディレクトリをマウントするには?(60233)|teratail


コンテナ状態確認

// 現在動いているコンテナ一覧
$ docker ps

// 停止しているコンテナも全て含めたコンテナ一覧
$ docker ps -a

停止中のコンテナをスタート

$ docker start コンテナ名

起動中のコンテナを停止

$ docker stop コンテナ名

停止中のコンテナを削除

$ docker rm コンテナ名

起動中のコンテナでコマンド操作

$ docker exec -it コンテナ名 /bin/bash

起動中のコンテナのログ採取

$ docker logs -ft コンテナ名

※logsオプションの意味

  • f, --follow(Follow log output)・・・リアルタイムでログを監視。
  • t, --timestamps(Show timestamps)・・・ログの先頭にタイムスタンプがつく。

DockerfileからDockerイメージを構築

$ docker build [オプション] パス/URL

コンテナからイメージ作成

// docker commit [オプション] コンテナ識別子 [イメージ名[:タグ名]]
// (例)コンテナからイメージの作成
docker commit -a "TEST Commit" my_nginx thoames/webfront:1.0

【ShopifyApp × Rails】Embedded(埋め込み)方式じゃないアプリの作成方法

公式にも詳細が載っていないので調べてみた。

TL;DR

以下の3つの設定が必要。

① [必須] アプリ管理側画面で、「Embedded」設定をオフにする
② [必須] config/initializers/shopify_app.rbの「config.embedded_app」をfalseにする
③ [任意] layoutファイルを設定する

アプリ管理側画面で、「Embedded」設定をオフにする

以下の記事でも触れたが、
thoames.hatenadiary.jp
公式のgemを使用して、Railsアプリを作成する場合のデフォルトでは「埋め込みアプリ」として設定される。

そのため埋め込みを解除するには、アプリ管理側の画面から「Embedded app」設定をオフにする必要がある。
※詳細は上記の記事内。

config/initializers/shopify_app.rbの「config.embedded_app」をfalseにする

config.embedded_app = false

以下の設定をしない場合、埋め込みアプリのデフォルトテンプレートである「embedded_app.html.erb」が読み込まれ、
その中身のJavascriptでShopify内の画面にリダイレクトし、「画面が見つからない」というエラーが発生する。

layoutファイルを設定する

Railsはデフォルトでapplication.html.erbをレイアウトファイルとして読み込むが
shopify_appのgemを使用し、embedded(埋め込み)アプリを作成しない場合、レイアウトファイルが読み込まれない。
(※この辺の仕組みはよくわからない・・・もしご存知の方がいらっしゃればコメント下さい)

自分の場合は、明示的にデフォルトレイアウトを指定する親コントローラを作成し、アプリの全コントローラはこの親コントローラを継承することでレイアウトファイルが読み込まれる設定にした。

app/controllers/shopify_application_controller.rb

class ShopifyApplicationController < ShopifyApp::AuthenticatedController
  layout 'application'
end

※shopify_appを使用してアプリを作成する場合、コントローラは「ShopifyApp::AuthenticatedController」を継承する。


以上

【Capistrano】puma起動後に、systemdのpuma.serviceを起動させる方法

以下のタスクをcapistranoのdeploy.rmに追加するだけ。
puma.serviceはすでに/etc/systemd/system/puma.serviceに存在する前提。

namespace :puma do
  after :start, :start_systemd_puma_service do
    on roles(:web), in: :groups, limit: 3, wait: 10 do
      within release_path do
        execute "sudo systemctl daemon-reload"
        execute "sudo systemctl restart puma"
      end
    end
  end
end

もしくはpuma:startを上書きしてもよいか。。
こちらは試してない。

Rake::Task["puma:start"].clear

[参考]
deployment - Capistrano and systemd integration - Stack Overflow
rake taskを上書きする

【Rails5】Systemdを使用したPumaの自動起動設定

自分用メモ。

Systemctlは、Systemdを管理するためのコマンド。
Systemdは、デーモンプロセスを自動立ち上げるるために使用される。
以下のサイトが詳しい。
Systemd メモ書き
いまだにsysvinitの手癖が抜けない人のためのsystemd
Linux女子部 systemd徹底入門

前提

Capistrano3を使用し、デプロイしていることが前提。
公式を見ると、Systemd用の設定が載っていたので
以下のページを参考に設定する。
puma/systemd.md at master · puma/puma · GitHub

公式には、「Type=simple」での設定例、「Type=forking」での設定例が存在するが
「Type=forking」の場合は、サービスが落ちたときなど自動で再起動する機能が使用できないため、
ここでは「Type=simple」での設定を行うこととする。

but is not performing continuous restarts. Therefore running Puma in cluster mode, where the master can restart workers, is highly recommended.

by puma/systemd.md at master · puma/puma · GitHub

またこの設定を使用する場合、Capistranoで「capistrano/puma」を読み込んでいて、且つ「set :puma_daemonize, ture」を設定している場合は必ず「set :puma_daemonize, false」もしくは、設定自体を削除すること!

[参考]
Puma silently exits after "Daemonizing..." from systemd script · Issue #941 · puma/puma · GitHub


deploy.rb

# before
set :puma_daemonize, true
# after
set :puma_daemonize, false

これを設定していると、puma.serviceが動作せず、後述するjournalctlのログには「No Pid 'xxxxx' found」というエラーが表示される。

puma.serviceの作成

「/etc/systemd/system/」内に「puma.service」というファイルを作成

$ cd /etc/systemd/system/
$ vim puma.service

puma.serviceには以下の内容を設定。
{{ working_directory }}はcapistranoの「xxx/current」を指定
{{ shared_directory }}はcapistranoの「xxx/shared」を指定

またsystemdは.barshrcや.bash_profileを読み込まないので
ExecStartには「/bin/bash -lc」でログインシェルを読み込む、.bashrcを読み込む設定にした。
[SOLVED] Where to put environment vars regarding SystemD / System Administration / Arch Linux Forums

[Unit]
Description=Puma Application Server
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory={{ working_directory }}
ExecStart=/bin/bash -lc "/root/.rbenv/bin/rbenv exec bundle exec puma -C {{ shared_directory }}/puma.rb"
ExecStop=/root/.rbenv/bin/rbenv exec bundle exec pumactl -S {{ shared_directory }}/tmp/pids/puma.state stop
TimeoutSec=300
Restart=always

[Install]
WantedBy=multi-user.target

Restartをalwaysにすることで、サービスの再起動を行う。例えばサーバリスタート時や、何らかの理由でpumaが異常終了したとしても自動的に起動する。
※stopで止めた場合は、再起動しない。
WantedBy=multi-user.targetはランレベル3で動作することを意味する。

※forkingを使用する場合は、以下のようにPIDFileを設定する必要がある。

PIDFile={{ shared_directory }}/tmp/pids/puma.pid

systemctlコマンド

# puma.serviceを新規作成後または変更後はこのコマンドを叩かないと反映されない。
systemctl daemon-reload

# 有効化
systemctl enable puma.service

# 起動
systemctl start puma.service

# 停止
systemctl stop puma.service

# ステータス確認
systemctl status puma.service

# 再起動
systemctl restart puma.service

Journalctlコマンド

Systemdのログは、Journalctlコマンドを利用することで確認できる。

journalctl

  • u (Unit): 指定ユニットに関係するログのみ表示
  • b: 直前のサーバ起動以降のログを表示
  • f: tail -f のように、順次表示する
    • no-pager: less コマンドを使用しない
  • a : 長いメッセージを省略しない
    • since='YYYY-MM-DD hh:mm:ss': 指定日以降のログ表示
    • until='YYYY-MM-DD hh:mm:ss': 指定日までのログ表示

by
Systemd メモ書き

自分の場合は、よく以下を使用する。

pumaのログだけを、リアルタイムで確認

$ journalctl -f -u puma

その他所感

capistrano/pumaを読み込んだ状態で、Capistranoを利用しデプロイすると
以下のコマンドが流れる。

$HOME/.rbenv/bin/rbenv exec bundle exec puma -C /var/www/recipe_post/shared/puma.rb --daemon

見ての通り、「--daemon」がついているため、デーモン化されて動作する。
これを変更したりすることは現時点では無理そう。
なぜならpuma.rakeに固定して記述されているため。

以下ページのソースを参照。
capistrano-puma/puma.rake at master · seuros/capistrano-puma · GitHub


[その他参考]
Pumaをsystemdで起動するメモ
Manage Puma with systemd on Ubuntu 16.04 and rbenv · GitHub
「Systemd」を理解する ーシステム管理編ー | ギークを目指して
Systemd入門(4) - serviceタイプUnitの設定ファイル - めもめも
CentOS7系と6系のコマンドの違いについて