Docker、GitLab、無料のSSL証明書、およびその他の最新のWeb開発ツール

こんにちは! ほぼ5年間、私はここで新しい記事を書いていませんが、正直なところ、遅かれ早かれ、私は再びそれをやり始めるといつも知っていました。 私はあなたのことは知りませんが、同じことですが、このビジネスはいつも私にとって魅力的でした。







このビジネスからの長い休憩の後に新しい素材を書くことは最も難しいです。 しかし、目標が設定されたら、最後まで行かなければなりません。 私は遠くから少し始めます。







私の意識的な生涯を通して、ウェブ開発は今日まで私の活動の主な種類であり続けています。 だからこそ、この資料は、アマチュアシステム管理者からDockerクラスターを構築する試みとして正確に認識されるべきであり、専門家としてではないことをすぐに告白します。 この記事では、クラスタリングの専門家の意見を主張することはできません。さらに、自分自身の経験の信頼性を確認したいのです。







habrakatの下には、仮想化の「ジャングル」やその他の関連トピックに深く入ることなく、以下に概説する特定のタスクを解決するために必要なレベルでDocker使用するクイックスタートがあります。 それでもこの最新のテクノロジーの使用を成功させ、それによってWeb製品の開発から最新の機器への展開および転送までの多くのプロセスを大幅に簡素化したい場合は、カットをお願いします!







オプリングインラスト-Docker







前文



もちろん、問題の説明と、ガイドで使用されている主な技術/技術の定義から始めます。







当初から、私は自分のプロジェクト(仕事、トレーニングなど)のために、小さくてもかなり普遍的なクラスターをすばやく作成するためにDockerに興味を持ちました。 システム管理を専門的に扱うつもりはなかったので、Webプロジェクトに人気のあるソフトウェアスタックを特別な問題なく展開できるようになるまで、クラスタリングの基本を学ぶ必要があると判断しました。 次に、次の構成をDockerにデプロイすることを検討します。









最初の2つは、導入する必要はないと思います。 3番目は、 MongoDBExpress.jsNode.jsで構成されています 私はほとんどの場合、 MEANを使用してRESTful APIを記述し、たとえば、それに基づいたモバイルアプリケーションをさらに開発しました。







その後、私自身が次の要件を追加してタスクを少し複雑にしました。







  1. 仮想ホストの原則に基づいて)個々のコンテナーごとに異なるドメイン (または、多くの場合、サブドメイン) を簡単に使用する機能
  2. デフォルトのHTTPSプロトコルを使用します。 さらに、有料のアナログに劣らないSSL証明書の無料生成を整理したいと思います。
  3. 同じGitLab CEサーバーへの展開 -単独でだけでなくチームとしてもプロジェクトに取り組むためのメインCVSシステムとして。


基本的な定義:





インストールとセットアップ



Dockerおよびその他のパッケージのインストールに関する問題は発生しません。 公式ウェブサイトでは、このプロセスが詳細に説明されています。 次に、初期セットアップに必要なコマンドの一般的なリストを作成します。







この記事では、 CentOS 7ディストリビューターでDockerおよびすべての関連プログラムをセットアップすることを検討していることをすぐに明確にします。このOSでは、メインサーバーシステムでの作業に長い間慣れているからです。 一般に、他のLinuxディストリビューションでもアクションはほぼ同じですが、唯一の違いは、たとえばUbuntuの場合はyum / dnf (CentOS / Fedoraの代わり)の代わりにapt-getを使用することです。







Docker + Docker Compose:



準備:







$ sudo yum update





$ sudo tee /etc/yum.repos.d/docker.repo <<-'EOF'





[dockerrepo]





name=Docker Repository





baseurl=https://yum.dockerproject.org/repo/main/centos/7/





enabled=1





gpgcheck=1





gpgkey=https://yum.dockerproject.org/gpg





EOF









Docker Engineをインストールします。







$ sudo yum install docker-engine





$ sudo systemctl enable docker.service





$ sudo systemctl start docker









ユーザーグループ「docker」を作成し、そこに現在のユーザーを追加します(これは、「sudo」またはルートアクセスを使用せずにDockerで作業するために必要です):







$ sudo groupadd docker





$ sudo usermod -aG docker your_username









インストールの成功の確認:







$ docker run --rm hello-world









Docker Compose(複数のコンテナを1つのWebアプリケーションに結合するためのユーティリティ)のインストール:







$ sudo curl -L "https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose





$ sudo chmod +x /usr/local/bin/docker-compose





$ docker-compose --version









Certbot( 公式サイト ):



LetsencryptからSSL証明書を自動的に受信/更新するユーティリティ:







インストールする前に、EPELリポジトリを有効にする必要があります (これがまだ行われていない場合)。







$ sudo yum install certbot









Docker Engineの基本



Dockerエンジン







基本原則:



Dockerは抽象化の追加レイヤーです。 オペレーティングシステムレベルで仮想化を自動化するシステム







オペレーティングシステムレベルの仮想化は、オペレーティングシステムのカーネルが1つではなく、ユーザー空間の複数の隔離されたインスタンスをサポートする仮想化手法です。これらのインスタンス(多くの場合、 コンテナーまたはゾーンと呼ばます)は、ユーザーの観点から実サーバーと完全に同一です。異なるコンテナのプログラムが互いに影響することはできません。」



ウィキペディアから

Dockerを使用する主な利点:









次に、クラスターを作成するために必要な基本コマンドを検討します。







$ docker run



実際、新しいコンテナを起動するメインコマンド。







主なパラメーター:







  1. --name :UUID識別子:コンテナの一意の名前。
  2. --volume(-v) :コンテナに関連付けられたボリューム:ディレクトリへの絶対パスの形式で指定されます。
  3. --env(-e) :環境変数:起動されたコンテナーの追加構成を許可します。
  4. --publish(-p) :コンテナーが機能するために必要な特定のポートを構成します(たとえば、httpの場合は80、httpsの場合は443)。


$ docker ps



実行中のコンテナのリストを取得できるコマンド。







$ docker stop container-name



コンテナを停止するコマンド。







$ docker rm container-name



特定のコンテナを削除します。







注意 :コンテナを取り外す前に、コンテナを停止する必要があります( docker stop )!







公式文書で各チームの作業をより詳細に理解できます 。 この記事では、Dockerでの作業を正常に開始するために必要な基本的なコマンドのみに注目しました。







この記事では、 docker run



の使用の具体例をもう少し詳しく説明します。







仮想ホストを構成する



Nginxリバースプロキシ







問題:さまざまなコンテナーで仮想ホストを使用してクラスターを実装する際の特定の難点は、1つのポートが1つのコンテナー(--publishで構成)でのみ「タップ」できることです。 デフォルトでは、ポート80および/または443(それぞれ、httpおよびhttpsプロトコル)を介してサーバーへの要求に応答するコンテナーを1つだけ作成できます。







ソリューション:原則として、ポート80および443で「リッスン」する1つのコンテナにカプセル化されたリバースプロキシを使用することは非常に明白です。この問題を解決するために、このコンテナの機能は使用される仮想ホストに従ってリクエストを自動的にリダイレクトします。







このようなコンテナは、Docker Hub- nginx-proxyのパブリックドメインに存在します。







仮想ホストの問題を解決することに加えて、デフォルトでSSL証明書の使用をサポートしています。これにより、サイトへの安全なHTTPSアクセスのサポートを展開できます。







このリバースプロキシコンテナを開始する前に、仮想ホストとして使用するドメインのSSL証明書を取得しましょう。







無料のSSL証明書の取得



SSL証明書を取得するには、無料のletsencryptサービスを使用します。 これを行うには、前の手順で、 certbotユーティリティを既にインストールしました 。 このユーティリティの使用の詳細については説明しません(これはすべて公式ドキュメントにあります )。







ドメインの無料のSSL証明書を自動的に受信する既製のコマンドを提供します。







$ sudo certbot certonly -n -d yourdomain.com --email your@email.com --standalone --noninteractive --agree-tos









--standalone --noninteractive --agree-tos



これらのパラメーターは、certbotがバックグラウンドで実行され、特定のWebサーバーへの特定のバインドなしで証明書を生成するために必要です。







このコマンドが正常に実行された結果、次の2つのファイルが生成されます。







/etc/letsencrypt/live/yourdomain.com/fullchain.pem









/etc/letsencrypt/live/yourdomain.com/privkey.pem









nginx-proxyが正しく機能するためには、 yourdomain.com.crt (証明書ファイル)とyourdomain.com.key (秘密鍵)の形式で各ドメイン名に2つのファイルを使用して、すべての証明書ファイルを1つのディレクトリに配置する必要があります。







この場合、シンボリックリンクを使用するのが論理的です。 例:







$ mkdir ssl-certs









$ cd ssl-certs









$ ln -s /etc/letsencrypt/live/yourdomain.com/fullchain.pem ./yourdomain.com.crt









$ ln -s /etc/letsencrypt/live/yourdomain.com/privkey.pem ./yourdomain.com.key









.pem拡張子にあまり注意を払ってはいけません-ファイルの本質はこれから変わりません。







同様に、私たちが所有するドメイン名の証明書を取得し、それらを引き続き仮想ホストとして使用できます。 唯一の要件は、これらのドメイン名のAレコードが、 certbot certonly ...



を実行するサーバーの外部IPアドレスに向けられる必要があることですcertbot certonly ...









各ドメインの証明書を生成したら、 nginx-proxyコンテナーを起動する準備ができました。







 $ docker run -d -p 80:80 -p 443:443 \ ​-v /full/path/to/ssl-keys:/etc/nginx/certs \ ​-v /var/run/docker.sock:/tmp/docker.sock:ro \ ​jwilder/nginx-proxy
      
      





このコマンドをさらに詳しく検討してください。







  1. -p 80:80 -p 443:443



    ポート80および443をコンテナにバインドしますさらに、サーバーの80番目のポートは、コンテナ内の80番目のポートに対応し、ポート443と同様になります。別の仮想コンテナ内のマシン全体とポート。
  2. -v /full/path/to/ssl-keys:/etc/nginx/certs



    このコンテナの設定に必要な最初のボリューム。 ここでは、コンテナ自体の内部の標準ディレクトリ/ etc / nginx / certsを、ドメインの証明書と秘密キーファイルへのシンボリックリンクを手動で配置したディレクトリにリンクします(前の段階で)。
  3. jwilder/nginx-proxy



    -Dockerハブ内のコンテナー識別子。 Docker Engineは、まだダウンロードされていない場合、このコンテナのイメージを自動的にダウンロードします。


それだけです-最初のコンテナが起動します! そして、このコンテナはリバースプロキシであり、これを介してアプリケーションコンテナをVIRTUAL_HOSTにさらに設定できます。







さまざまなスタックの使用例



ランプ



それで、最後に、すでにWebアプリケーションを開発できるコンテナーの起動に移ることができます。







Docker Hubデータベースには、LAMPコンテナー用のさまざまなオプションがあります。 個人的には、 tutum-docker-lampを使用しました。







以前は、Docker Engineに加えて、 Docker Composeユーティリティをインストールしました。 そして、この瞬間から使用を開始します。 Docker Composeは、複数のコンテナが組み合わされ、開発中のアプリケーションを正確に表すアプリケーションを作成するのに便利です。







このコンテナをnginx-proxyと組み合わせて実行するには、次を行う必要があります。







  1. tutum-docker-lampのソースを別のディレクトリにダウンロードします(これはgit clone



    を使用すると最も便利です)。







  2. この作業ディレクトリに、次の内容のdocker-compose.ymlファイルを作成します。


 web: ​build: . volumes: - ./www:/var/www/html environment: - MYSQL_PASS=yourmysqlpassword - VIRTUAL_HOST=yourdomain.com
      
      





  1. docker-composeを使用して起動します。







    $ docker-compose up











この例でわかるように、仮想ホストは、1つの環境変数VIRTUAL_HOSTのみを使用してnginx-proxyを使用して管理されます。







./www:/var/www/html



注意して./www:/var/www/html



。 明らかに、wwwフォルダーはサイトの作業ディレクトリーになります(手動で作成する必要があります)。 このディレクトリ内のすべてのファイルは、実行中のコンテナ内の/var/www/html



自動的に分類されます。







docker-compose.yml設定ファイルの構文については、 公式ドキュメントで詳しく理解できます







レンプ



LEMPコンテナの起動は、基本的に上記の例と変わりません。







まず、Docker Hubでコンテナーを見つけます。 例: docker-lemp







コンテナーのソースをダウンロードし、 docker-compose.ymlを追加します。 カスタムコンテナのこの設定ファイル内では、環境変数VIRTUAL_HOSTを設定できるだけでなく、 Dockerfileが許可するすべてを設定できます。 たとえば、 Dockerfile以下を定義します。







VOLUME /var/www/









したがって、次のようにdocker-compose.ymlでこのボリュームにリンクできます。







volumes:





- ./www:/var/www









NodeJS + ExpressJS + MongoDB



そのような構成の例: docker-nodejs-mongodb-example







docker-compose.ymlファイルは次のようになります。







 web:​ build: .​ volumes:​ - "./api:/src/app"​ environment:​ - VIRTUAL_HOST=yourdomain.com​ links:​ - "db:mongo" db: ​image: mongo ​ports:​ - "27017:27017" ​volumes:​ - ./data/db:/data/db
      
      





この場合、2つのリンクされたコンテナが作成されます。 1つはベース(mongoDB)用、2つ目はNodeJSアプリケーション自体用です。







このコンテナのバンドルを実行するには、同じdocker-compose up



ます。







gitlab / gitlab-ceでの作業の微妙さ



Docker Engine上のGitLab CE







より複雑なコンテナの中には、nginx-proxyを使用して実行するために追加の設定が必要なものがあります。 これらのコンテナにはgitlab-ceが含まれます。







この記事で説明されている構成を考慮に入れて、このコンテナーを実行するコマンドの完全に機能するバージョンを最初に提供し、次にこのコマンドの詳細を説明します。







だから:







 $ docker run --detach \ --hostname gitlab.yourdomain.com \ --publish 2289:22 \ --restart always \ --name custom-gitlab \ --env GITLAB_OMNIBUS_CONFIG="nginx['listen_port'] = 80; nginx['listen_https'] = false; nginx['proxy_set_headers'] = { \"X-Forwarded-Proto\" => \"https\", \"X-Forwarded-Ssl\" => \"on\" }; gitlab_rails['gitlab_shell_ssh_port'] = 2289; external_url 'https://gitlab.yourdomain.com'; gitlab_rails['smtp_enable'] = true; gitlab_rails['smtp_address'] = 'smtp.mailgun.org'; gitlab_rails['smtp_port'] = 2525; gitlab_rails['smtp_authentication'] = 'plain'; gitlab_rails['smtp_enable_starttls_auto'] = true; gitlab_rails['smtp_user_name'] = 'postmaster@mg.yourdomain.com'; gitlab_rails['smtp_password'] = 'password'; gitlab_rails['smtp_domain'] = 'mg.yourdomain.com';" \ --env VIRTUAL_HOST="gitlab.yourdomain.com" \ --volume /srv/gitlab/config:/etc/gitlab \ --volume /srv/gitlab/logs:/var/log/gitlab \ --volume /srv/gitlab/data:/var/opt/gitlab \ gitlab/gitlab-ce:latest
      
      





NGINXリバースプロキシ+ HTTPS経由で起動



この場合にリバースプロキシを使用するスキームを機能させるには、以下を追加する必要があります。







 nginx['listen_port'] = 80; nginx['listen_https'] = false; nginx['proxy_set_headers'] = { \"X-Forwarded-Proto\" => \"https\", \"X-Forwarded-Ssl\" => \"on\" };
      
      





その理由は、コンテナで作業する場合、nginx-proxyは、コンテナ内の443ではなくポート80にアクセスします。gitlab-ce( proxy_set_headersコンテナ内のnginx設定に追加のヘッダーがない場合、リクエストは通過しません。







さらに、以下を追加することが重要です。







external_url 'https://gitlab.yourdomain.com';









ポート22



一番下の行は次のとおりです。







--publish 2289:22









作業マシンでの作業がSSHプロトコルを介して行われる場合、ポート22がすでにsshdサービスによって占有されているため、バンドル「22:22」を直接作成することはできません。







この問題の解決策は、gitlab-ceの公式ドキュメントに記載されています。 簡単です。サーバー内の他の(22を除く)ポートをコンテナー内のポート22にバインドします。 この例では、ポート2289が使用されます。







これと並行して、追加することを忘れないことが重要です







gitlab_rails['gitlab_shell_ssh_port'] = 2289;









GitLab自体の設定。







したがって、gitlab-ceを起動してリポジトリを作成すると、次のスタイルのアドレスで作業が実行されます。







ssh://git@gitlab.yourdomain.com:2289/username/repository_name.git









SMTPサーバーのセットアップ



GitLab自体の特別な環境変数を使用することも必要です。







私の場合( Google Cloud Engineを使用)、ポート25、465はデフォルトで閉じられています(つまり、標準のSMTPプロトコルポート)。 この問題の解決策の1つは、SMTPサーバーとしてサードパーティサービス( MailGunなど)を使用することです。 これを行うには、設定を使用します。







 gitlab_rails['smtp_enable'] = true; gitlab_rails['smtp_address'] = 'smtp.mailgun.org'; gitlab_rails['smtp_port'] = 2525; gitlab_rails['smtp_authentication'] = 'plain'; gitlab_rails['smtp_enable_starttls_auto'] = true; gitlab_rails['smtp_user_name'] = 'postmaster@mg.yourdomain.com'; gitlab_rails['smtp_password'] = 'password'; gitlab_rails['smtp_domain'] = 'mg.yourdomain.com';
      
      





最後に、 --env VIRTUAL_HOST="gitlab.yourdomain.com" \



-proxy自体の環境変数を忘れないでください。







以上です。 この指示を完了すると、DockerはGitLab CEで完全に機能するコンテナーを起動します。







Gitlab-ce標準アップグレードプロセス



これが、このガイドで個別に強調したい最後の瞬間です。







Dockerを使用してGitLabを更新するプロセスは、いくつかのコマンドに簡略化されています。







  1. docker stop custom-gitlab



    実行中のコンテナーを停止します。







  2. docker rm custom-gitlab



    -GitLab CEコンテナーを削除します。







    重要な点:コンテナーを削除しても、システムの使用中に作成されたデータを削除することにはなりません。 したがって、このコマンドは問題なく実行できます。







  3. docker pull gitlab/gitlab-ce



    実際にコンテナーイメージを更新します。







  4. 長いコマンド(上記の例)を実行し、最初にコンテナーを起動しました。


以上です。 これらの4つのコマンドを完了すると、GitLabは自動的に最新バージョンにアップグレードし、Docker Engineを開始します。







まとめ



したがって、このガイドの結果として、NGINX Reverse Proxyに基づいたDockerクラスターを取得する必要があります。 各Webアプリケーションには独自の仮想ホストがあり、同時に安全なHTTPSプロトコルをサポートしています。







Webアプリケーションとともに、完全に構成されたGitLabクラスターは、SMTPサーバーへのアクセスまで機能します。







私のこの小さな研究が、HabrHabrの多くの読者にとって有用であるか、少なくとも興味深いものになることを本当に願っています。 もちろん、専門家からの批判、記事への追加または改善を聞いてうれしいです!







ご清聴ありがとうございました!








All Articles