Chef-soloを使用してUbuntuでDjangoアプリを構成する

ボックスの設定と構成のプロセスを自動化する方法はたくさんあります。何らかの理由で、この時点でシステム全体が1つのボックスのみで構成されている場合、完全なSCM(ソフトウェア構成管理)インフラストラクチャをセットアップするのはやりすぎです。シェルスクリプトは1つのオプションですが、SCMの一部を取り除いたバージョンを使用して、そこにあるいくつかのツールで使用することもできます。Chefは人気のあるオプションの1つであり、「chef-solo」はChefのスタンドアロン構成モードであり、「chef-server」として機能するために追加のノードを必要としません。必要なのは、シェフのクックブックを含むtarballパッケージへのURLまたはパスです。シェルスクリプトと比較して、このタイプのアプローチは、宣言的で効率的であり、SCMまたはIaC(Infrastructure as Code)プロセスを開始するための優れた入門でもあります。

chef-soloを使用する他のいくつかの利点:

  • 構成可能性:シェフのスーパーマーケットやその他の場所にあるコミュニティクックブックを使用します。
  • フリーでオープンソース。寛容なApache 2.0ライセンスの下でライセンスされています。
  • Chefの残りのエコシステム(InSpec、ChefSpec、Cookstyle、Foodcritic、chef-shellなど)へのアクセス
  • クックブックとレシピは、後でクライアント/サーバーモードに適合させることができます。

そしていくつかの欠点:

  • シェフのスーパーマーケットにあるいくつかのコミュニティクックブックは古く、壊れていて、メンテナンスされていません。
  • chef-soloは、それ自体では依存関係を解決できません。

シェフ「クックブック」内の「レシピ」には、「リソース」がノード上で特定の状態になることを説明するルビベースのDSLがあります。chef-soloにも適用できるいくつかのChefの概念を理解するために、ウォークスルーに進みましょう。私たちの目標は、GunicornとNGINXを使用してPython / Django Webアプリを実行するUbuntuノードをセットアップすることです。

注:ChefDKを「Chefワークステーション」(私たちのマシン)にインストールする必要はありませんが、「chef generate」コマンドを使用して、クックブックやレシピなどを作成するためのディレクトリ構造から始めることができます。この記事では、ChefDKがワークステーションにインストールされていると想定します。コマンドはChefDKのバージョン4.7.26-1を使用して実行されました。


(この時点以降は、特に指定のない限り、すべて「Chef Workstation」とも呼ばれる私たちのマシンで実行されます)

クックブックを作成する

chefのクックブックは、構成シナリオをサポートするために必要なすべてを含む再利用可能なユニットです。クックブックには複数の「レシピ」を含めることができ、「レシピ」は主にリソースパターンで構成されます。default.rbは、クックブックがrun-listで参照されるときに実行されるデフォルトのレシピです。さまざまなレシピで問題を分離できます。ただし、このチュートリアルでは、すべてのリソース宣言を1つのメインレシピファイルであるに追加しますdefault.rb

「my-chef-project」という名前のフォルダーを作成し、その中に「cookbooks」というフォルダーを作成します。から./my-chef-project/cookbooks/、次を実行:

$ chef generate cookbook my-cookbook

ディレクトリ構造は次のようになります。

.
└── my-chef-project
└── cookbooks
└── my-cookbook
├── CHANGELOG.md
├── LICENSE
├── Policyfile.rb
├── README.md
├── chefignore
├── kitchen.yml
├── metadata.rb
├── recipes
│ └── default.rb
├── spec
│ ├── spec_helper.rb
│ └── unit
│ └── recipes
│ └── default_spec.rb
└── test
└── integration
└── default
└── default_test.rb

パッケージを追加する

ノードを設定する最初のステップは、アプリで必要なパッケージを識別することです。ノードはUbuntuとして選択されているため、APTパッケージマネージャーを使用して依存関係を収集できます。OSディストリビューションによって提供されるパッケージのインストールは簡単です。

apt_update
package 'python3'
package 'python3-pip'
package 'nginx'
package 'pkg-config'
package 'libcairo2-dev'
package 'libjpeg-dev'
package 'libgif-dev'
package 'libgirepository1.0-dev'

これらはほとんど自明です。最初の行はaptリポジトリを更新し、次の行はそれらのパッケージをインストールします。

注: 'nginx'に続くパッケージは、pipを介して一部のpython依存関係をコンパイルするために必要です。これらは、で指定されたpython / djangoプロジェクトの依存関係に基づいて異なる場合がありますrequirements.txt。試行錯誤の方法を使用して、クックブックに含める必要があるこれらのパッケージを決定できます。これを行うには、sudo pip install -r requirements.txt新しくインスタンス化されたubuntuマシンで手動で(注:これによりパッケージがシステム全体にインストールされます!)実行して、正常に実行されるかどうかを確認します。そうでない場合、stderrはどのパッケージが不足しているかについてのヒントを提供するはずです。

Linuxユーザーの作成

必要なパッケージを追加したら、アプリケーションのソースコードを所有する非特権Linuxユーザーを作成する必要があります。

user 'bob' do
  uid 1212
  gid 'users'
  home '/home/bob'
  shell '/bin/bash'
  password '$1$alilbito$C83FsODuq0A1pUMeFPeR10'
end

パスワードはLinuxで使用されているシャドウハッシュ形式であることに注意してください。OpenSSLを使用して導出できます。

$ openssl passwd -1 -salt alilbitof mypassword

アプリのソースを含める

次に、Djangoアプリケーションのソースコードをクックブックに含めます。ソースコードが存在しない場合./my-chef-project/cookbooks/my-cookbook/files/default/myapp/ は、Create ./my-chef-project/cookbooks/my-cookbook/files/defaultdirectory 内にソースコードを配置します。

これらのファイルをノードのリモートの場所にコピーする手順は、remote_directoryリソースを使用して説明されています。

remote_directory '/home/bob/myapp' do
  source 'myapp' # This is the name of the folder containing our source code that we kept in ./my-cookbook/files/default/
  owner 'bob'
  group 'users'
  mode '0755'
  action :create
end

Pythonの依存関係を取り込む

Pythonパッケージをにインストールするにはrequirements.txtexecuteリソースを使用して任意のコマンドを実行します。この場合、pip installコマンドを実行する必要があります。

execute 'install python dependencies' do
  command 'pip3 install -r requirements.txt'
  cwd '/home/bob/myapp'
end

注:これはrootユーザーとして実行され、Pythonライブラリはシステム全体にインストールされることに注意してください。私たちのノードがこの単一のpythonアプリを排他的に実行するように指定されている場合は、それほど問題にはなりません。それにもかかわらず、物事をクリーンで正気に保つためのより良いオプションは、Pythonのインストールまたは「virtualenvs」を管理するコミュニティクックブックを見つけて使用することです。(少なくとも、これを複製するための一連の実行ブロックを記述します)。Pythonでvirtualenvsを使用すると、Pythonベースのシステムツールやその他のPythonプロジェクトが影響を受けないことが保証されます

GunicornとNGINXのセットアップ

次に、NGINXをリバースプロキシとして使用して、Gunicorn WSGI HTTPサーバーを準備します。Nginxは、Djangoからのすべての静的アセットを処理するためにも使用されます。

UbuntuのサービスとしてGunicornをストラップするには、Systemdを使用できます。systemd_unitのリソースは、バージョン12.11以降シェフに含まれています。

systemd_unit 'gunicorn.service' do
  content({
  Unit: {
    Description: 'Django on Gunicorn',
    After: 'network.target',
  },
  Service: {
    ExecStart: '/usr/local/bin/gunicorn --workers 3 --bind localhost:8080 myapp.wsgi:application',
    User: 'bob',
    Group: 'www-data',
    WorkingDirectory: '/home/bob/myapp'
    Restart: 'always',
  },
  Install: {
    WantedBy: 'multi-user.target',
  }
  })
  action [:create, :enable, :start]
end

次に示すように、このGunicornサーバーに標準のNGINXプロキシ構成を含める必要があります。このスニペットはに入ることができます./my-cookbook/templates/nginx.conf.erb。テンプレートディレクトリが存在しない場合は作成します。

注:Chefのテンプレートは、変数、ルビ式、およびステートメントを含めることができる埋め込みルビファイルをサポートしています。このファイルには「erb」拡張子が付いていますが、ルビのステートメントや式は使用していません。また、簡単にするために、ここではHTTPS以外のnginx設定のみを使用しています(注意してください。本番環境ではこれを行わないでください)。

server {
  listen 80;
  server_name http://example.com/;

  location = /favicon.ico { access_log off; log_not_found off; }
  location /static/ {
    root /home/bob/myapp/myapp/static;
  }

  location / {
  include proxy_params;
    proxy_pass http://localhost:8080/;
  }
}

注:また、GunicornサーバーがTCPループバック接続の代わりにUNIXドメインソケットにバインドされている場合など、より適切な構成もあります。パフォーマンス上の理由から、これを検討する価値があります。

この構成をノード上のサイト対応フォルダーにコピーするには、Chefのテンプレートリソースを使用します。

template '/etc/nginx/sites-available/example.com.conf' do
  source 'nginx.conf.erb'
  owner 'root'
  group 'root'
  mode '0744'
end

nginxでの設定のアクティブ化は、通常sites-available、nginxのsites-enabledフォルダーにある設定を指すシンボリックリンクを作成することによって行われます。シンボリックリンクは、以下に示すように、リンクリソースを使用してシェフのクックブックで宣言できます。

link '/etc/nginx/sites-enabled/example.com.conf' do
  to '/etc/nginx/sites-available/example.com.conf'
end

デフォルトの設定シンボリックリンクを削除するには:

link '/etc/nginx/sites-enabled/default' do
  action :delete
end

NGINXの起動

そして最後に、nginxサービスを起動するには:

service 'nginx' do
  action :enable
  action :start
end

ランリスト

chefの実行リストは、ノードで順番に実行されるクックブックのロールまたはレシピの順序付きリストです。Ubuntuボックスで実行する必要があるクックブック「my-cookbook」と「デフォルト」レシピが1つあるので、プロジェクトディレクトリ(./my-chef-project/runlist.json)のrunlist.jsonは次のようになります。

{
  "run_list": [
    "recipe[my-cookbook::default]"
  ]
}

最後のステップ

Chef soloの料理本が出ました。Ubuntu 18.04マシンをプロビジョニングして、それにChefDKをインストールします。

$ ssh [email protected] 'apt-get update && yes | apt-get install curl && curl https://packages.chef.io/files/current/chefdk/4.7.45/ubuntu/18.04/chefdk_4.7.45-1_amd64.deb -o chefdk.deb && yes | dpkg -i chefdk.deb && rm chefdk.deb'

ゴーイングシェフのワークステーションに背中を、私たちが行う必要があるすべては、tarボール、転送内のフォルダ料理を入れていることに加えてtarボールrunlist.json我々は上記のプロビジョニングとシェフ・ソロのコマンドを実行して、リモート・ノードへ:

(以下のコマンドは、Chef Workstationではなく、ノードまたは「chefクライアント」内で実行されます)

$ chef-solo --recipe-url $(pwd)/chef-solo.tar.gz -j $(pwd)/runlist.json --chef-license=accept

または、ここにワンライナーがあります(./my-chef-project/Chef WorkstationのCWD から実行されます):

tar zvcf chef-solo.tar.gz ./cookbooks &&\
scp chef-solo.tar.gz runlist.json [email protected]:~/ &&\
ssh [email protected] 'chef-solo --recipe-url $(pwd)/chef-solo.tar.gz -j $(pwd)/runlist.json --chef-license=accept'

それでおしまい!クックブックで指定したものにノードを収束させようとするChefアクティビティで標準出力がいっぱいになるのを観察します。Chef-soloはすべての料理本に必要なすべての宝石をインストールします。chef-soloコマンドが成功すると、Ubuntuボックスのnginxの背後で動作するDjangoアプリケーションが動作します。ドメイン/ IPに移動してテストします。

注:djangoでは、このドメイン/ IPをのALLOWED_HOSTSリストに設定する必要がある場合がありますsettings.py

変化への対応

プロジェクトディレクトリの内容(レシピ、テンプレート、アプリケーションのソースコードなど)を変更するときはいつでも、プロジェクトディレクトリから上記の1行を実行するだけです。

ヒント:クックブックがgitでバージョン管理されている場合(必要に応じて)、1つのライナーを実行するようにgitフックを設定することをお勧めします。

tarballのホスティング(オプション)

最後のchef-soloコマンドをよく見ると、--recipe-urlはURLを取得するためのものであることに注意してください。つまり、CIがchef-solo tarballを構築し、どこかにアップロードし、定期的にそこからプルするようにノードを構成するワークフローを使用できます。

ヒント:curlを使用して、変更されたtarballを定期的にcronjobとしてプルします。既存のローカルのタイムスタンプ以降にリモートファイルが変更された場合にのみ、ヘッダーcurl -z $fileを尊重しIf-Modified-Sinceてtarボールをダウンロードします$file



Leave a Comment

CentOS 7にApacheをインストールする方法

CentOS 7にApacheをインストールする方法

CentOS 7サーバーにApache 2.4をインストールする方法を説明します。安定したウェブサーバーを構築するための前提条件と手順を解説します。

FreeBSD 11.1にBlacklistdをインストールする方法

FreeBSD 11.1にBlacklistdをインストールする方法

FreeBSD 11.1におけるBlacklistdのインストール方法について詳しく解説します。この方法を通じて、強力なセキュリティ対策を実装できます。

Windows Serverのサーバーマネージャーを使用した複数サーバーの管理

Windows Serverのサーバーマネージャーを使用した複数サーバーの管理

サーバーマネージャーを使用して、Windows Serverの管理が向上します。セキュリティリスクを軽減し、効率的な管理を実現します。

CentOS 7にSeafileサーバーをインストールする方法

CentOS 7にSeafileサーバーをインストールする方法

CentOS 7にSeafileサーバーをインストールする方法。Seafile(コミュニティバージョン)は、ownCloudに似た無料のオープンソースファイル同期および共有ソリューションです。

DebianでSnortを設定する方法

DebianでSnortを設定する方法

Snortは無料のネットワーク侵入検知システムです。最新の方法で、SnortをDebianにインストールし、設定する手順を紹介します。ネットワークのセキュリティを強化しましょう。

CentOS 7にGraylogサーバーをインストールする方法

CentOS 7にGraylogサーバーをインストールする方法

CentOS 7にGraylogサーバーをインストールし、ログ管理を行う方法を学びます。

WindowsでhMailServerを使用してメールサーバーを構築する

WindowsでhMailServerを使用してメールサーバーを構築する

WindowsサーバーでWebサイトを実行している場合、電子メールも受信できるようにするためにhMailServerを使用する方法を解説します。

Ubuntu 19.04にFiveMサーバーをインストールする方法

Ubuntu 19.04にFiveMサーバーをインストールする方法

FiveMサーバーをUbuntu 19.04にインストールするための詳細なガイド。必要条件からインストール、起動、トラブルシューティングまで、すべてのステップを含みます。

WsgiDAVを使用してDebian 10にWebDAVをデプロイする

WsgiDAVを使用してDebian 10にWebDAVをデプロイする

Debian 10にWebDAVをデプロイする方法を学び、WsgiDAVとSSL証明書で安全な接続を実現しましょう。

ヘルスケア2021における人工知能の影響

ヘルスケア2021における人工知能の影響

ヘルスケアにおけるAIは、過去数十年から大きな飛躍を遂げました。したがって、ヘルスケアにおけるAIの未来は、日々成長を続けています。