- 投稿日:2020-11-24T23:09:12+09:00
Docker環境でNodeJSのライブラリsharpを使用するときの darwin-x64 エラー
MacでNode.jsのライブラリsharpを使用するときに darwin-x64 エラーが発生しました。
Docker環境のため、sharpの公式ドキュメントで書いた対処方法ですぐ解決できなかったのではまりました。/var/www/xxxxx/node_modules/sharp/lib/libvips.js:68 throw new Error(`‘${vendorPlatformId}’ binaries cannot be used on the ‘${currentPlatformId}’ platform. Please remove the ‘node_modules/sharp/vendor’ directory and run ‘npm install’.`); Error: ‘darwin-x64’ binaries cannot be used on the ‘linux-x64’ platform. Please remove the ‘node_modules/sharp/vendor’ directory and run ‘npm install’. at Object.hasVendoredLibvips (/var/www/xxxxx/node_modules/sharp/lib/libvips.js:68:13) at Object.<anonymous> (/var/www/xxxxx/node_modules/sharp/lib/constructor.js:7:22) at Module._compile (internal/modules/cjs/loader.js:1200:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10) at Module.load (internal/modules/cjs/loader.js:1049:32) at Function.Module._load (internal/modules/cjs/loader.js:937:14) at Module.require (internal/modules/cjs/loader.js:1089:19) at require (internal/modules/cjs/helpers.js:73:18) at Object.<anonymous> (/var/www/xxxxx/node_modules/sharp/lib/index.js:3:15) at Module._compile (internal/modules/cjs/loader.js:1200:30)下記のように解決しました。
OS:macOS Catalina1. nodeのバージョンを揃えます。
MacのnodeのバージョンとDocker環境のnodeバージョンとメジャーバージョンを揃えます。
例えば、
プロジェクトのnodeのバージョンが v14.xx.xx であれば、DockerfileでFROM node:14
を指定。
※nodeのバージョンの制御にプロジェクト単位で設定できるnodenvの利用がおすすめです。2. Dockerコンテナに入ってsharpを再インストール
$ docker ps $ docker exec -it xxxxx bash $ rm -rf node_modules/sharp $ npm install --arch=x64 --platform=linux sharp自分の環境では、targetの指定が不要でした。
$ npm install --arch=x64 --platform=linux --target=xx.xx.x sharp
参考:
https://github.com/lovell/sharp/blob/master/docs/install.md
https://sharp.pixelplumbing.com/install#common-problems
https://qiita.com/mame_daifuku/items/1dbdfbd4897b34df0d9f
- 投稿日:2020-11-24T22:33:40+09:00
【ConoHa VPS,Vue-cli,Docker】Vue CLIで作成したSPAをConoHaで公開するまで①(ConoHa登録~VPSにログイン)
初投稿です。よろしくお願い致します。
新卒入社して半年、「エンジニアなら自分のプロダクトを公開したい!」という思いから、学生自体にお世話になったバイト先のWEBサイトを公開することにしました。その際の作業ログを共有いたします。
前提条件
Vue Cliで作成したアプリケーションがあること
もし作成していない場合は、下記URLなどを参考に作成してみましょう。
https://qiita.com/yuucu/items/189945f984e5e53117ea環境
PC: MacBookPro
VPS: ConoHa
CentOS: 8.2.2004
docker-compose: 1.27.4
Docker: 19.03.13
nginx: 1.19.4
vue-cli: 4.5.8
npm: latest(作業時:15.2.0)ConoHa登録
新規登録
登録後
私は下から二番目のグレードの「memory:1GB」を選択
OSはCentOS8にしました。
右側の値段は、デフォルトでは、三ヶ月分まとめ払いが選択されていますが、
一ヶ月ごとの支払いに変更することもできます。
しかし、まとめ払いがお得みたいです。
ここで、rootパスワードとネームタグを入力しましょう。
※rootパスワードはVPSに接続するために必要です。必ずメモしましょう!
※また、この時SSH Keyを作成できるはずだったのですが、私は作成し損ねてしまったので、自力で作成していきます。
コントロールパネル
コントロールパネルはこんな感じです。
自分が作成したVPSが一覧で確認できます。
ネームタグをクリックすると、サーバの詳細が確認できます。
ここで、VPSのIPアドレスを確認しておきましょう。
VPSにリモートアクセス
rootでSSH接続していきます。
今回はMacのTerminalでの接続を想定しております。
Windowsの方は、Teratermなどで接続されることをお勧めします。ssh root@ipアドレス The authenticity of host '(IPAddress) ((IPAddress))' can't be established. ECDSA key fingerprint is (...). Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '(IPAddress)' (ECDSA) to the list of known hosts. root@(IPAddress)'s password: #初めに設定したrootパスワードを入力※基本的に、パスワード入力をしても、画面上に表示されません。
しかし、文字は見えないだけで入力されています。
注意して入力しましょう。このように表示されれば、リモートアクセス成功です。
[root@(IPアドレス) ~]#次回:セキュリティ対策
サーバに接続して、早速アプリケーションの環境を立ち上げたいところですが、
まずはセキュリティ対策をします。とはいえ、新卒研修でも行うぐらい作業自体は難しいものではありません。
(法人レベルになると、もっと高度な対策が求められると思われますが…)地道に進めていきます。
参考・引用
- 投稿日:2020-11-24T22:30:21+09:00
Vue 3.x (Vue CLI 5.x) 環境構築完全版 Docker + TypeScript + Yarn + Router
Vue 3 環境セットアップ手順
数ある記事から見ていただき有難うございます。
Vue 3 がリリースされてから2ヶ月ほど経過しましたが、
今回は会社でとりあえず採用している Vue 3 の環境構築をご紹介します。歓迎条件
- Docker の環境構築ができている。
- これまでに Vue (2.x) の環境を構築したことがある。
- とりあえず TypeScript で Vue3 触ってみたい!
- 完全版と書いていますがあくまで一つの環境に過ぎませんので構築したい環境の条件が合う方は使ってみてください。
プロジェクトの作成
自身のプロジェクトを作成します。
名前はお任せします。(どうしても決められない方は new-vue3-app とかで大丈夫です)プロジェクト直下に docker-compose.yml ファイルを作成
version: "2.4" services: node: image: node:latest ports: - 8080:8080 volumes: - .:/srv:cached working_dir: /srv command: yarn serveプロジェクトで以下のコマンドを実行
Vue CLI インストール
docker-compose run --rm node yarn add @vue/cliVue CLI バージョン確認
vue -V => @vue/cli 5.9 (2020/11/24)アプリケーションの初期化
docker-compose run --rm node ./node_modules/.bin/vue create . // 最後の . はカレントディレクトリを指すのでお忘れなく!? Your connection to the default yarn registry seems to be slow. Use https://registry.npm.taobao.org for faster installation? (Y/n) Y? Generate project in current directory? (Y/n) Yプロジェクトの作成方法を選択
? Please pick a preset: (Use arrow keys) Default ([Vue 2] babel, eslint) Default (Vue 3 Preview) ([Vue 3] babel, eslint) ❯ Manually select featuresプロジェクトへ導入するライブラリを選択
? Please pick a preset: Manually select features ? Check the features needed for your project: ◉ Choose Vue version ◉ Babel ◉ TypeScript ◯ Progressive Web App (PWA) Support ◉ Router ◯ Vuex ❯◉ CSS Pre-processors ◉ Linter / Formatter ◯ Unit Testing ◯ E2E Testing重要 : バージョンの選択 3.x を選択
? Choose a version of Vue.js that you want to start the project with 2.x ❯ 3.x (Preview)Class Style or Object Style の選択(基本的に No の Object Style で良い)
? Use class-style component syntax? (y/N) N自動検出されたポリフィルに Babel と TypeScript を使うか選択
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n) YVue RouterのHistoryモードを利用するかを設定
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) YCSS プリプロセッサの選択
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys) ❯ Sass/SCSS (with dart-sass) Sass/SCSS (with node-sass) Less StylusESLintのプリセットを選択
? Pick a linter / formatter config: ESLint with error prevention only ESLint + Airbnb config ❯ ESLint + Standard config ESLint + Prettier TSLint (deprecated)ESLintの実行タイミングを選択
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection) ❯◉ Lint on save ◯ Lint and fix on commitライブラリ(BabelやESLint)の設定ファイルの配置個所を選択
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys) ❯ In dedicated config files In package.json次回以降のcreate projectで利用できるプリセットに登録するか設定
? Save this as a preset for future projects? (y/N) NYarn or NPM を選択
? Pick the package manager to use when installing dependencies: (Use arrow keys) ❯ Use Yarn Use NPM完了時のログ
success Saved lockfile. Done in 80.73s. ⚓ Running completion hooks... ? Generating README.md... ? Successfully created project srv. ? Get started with the following commands: $ yarn serve WARN Skipped git commit due to missing username and email in git config, or failed to sign commit. You will need to perform the initial commit yourself.サーバを立てる
yarn serve yarn run v1.22.4 warning ../../../package.json: No license field $ vue-cli-service serve INFO Starting development server... 98% after emitting CopyPlugin DONE Compiled successfully in 2932ms 21:55:12 App running at: - Local: http://localhost:8081/ - Network: http://10.13.52.2:8081/ Note that the development build is not optimized. To create a production build, run yarn build. No issues found.構築完了です。
新生 Vue3 をお楽しみください。
お疲れ様でした!
- 投稿日:2020-11-24T22:24:30+09:00
Railsプロジェクトをdocker-composeで環境ごとに構築
Railsのプロジェクト(Redmine)をdocker-composeを用いて、
環境ごとに管理していきます
今回はdockerを用いた環境構築を主軸としたため、
webサーバーなどの詳しい説明は省きます作成:2020年11月24日
環境
Ubuntu18.04
Rails 5
Ruby 2.6.5
Redmine 4.0
nginx 1.15.8
Docker 19.03.13
docker-compose 3
MySQL 5.7必要なもの
Dockerとdocker-compsoeが動く環境(今回はUbuntu18.04で実行)
Redmineのソース
やる気ざっくりとした方法
環境ごとにcomposeファイルを作成
環境変数COMPOSE_FILEを環境ごとに指定するコンテナ構成
- 開発環境
app(rails), db(mysql)- 本番環境
app(rails, puma), db(mysql), web(nginx)フォルダ構成
docker-compose.develop.ymlが開発環境とテスト環境
docker-compose.prod.ymlが本番環境となる
開発環境のDockerファイルはDockerfile
本番環境はDockerfile.prodとなるredmine(プロジェクトroot) ├── app ├── bin ├── etc.... ├── config │ ├── database.yml(追加) │ ├── puma.rb(追加) │ └── etc... ├── container(追加) │ ├── app │ │ ├── Dockerfile │ │ └── Dockerfile.prod │ ├── db │ │ └── multibyte.cnf │ └── web │ ├── Dockerfile.prod │ └── nginx.conf ├── docker-compose.develop.yml(追加) └── docker-compose.prod.yml(追加)初期設定
環境に応じて、環境変数を設定する
docker-composeの仕様により、
COMPOSE_FILE環境変数を設定すると、設定した環境すべてにおいて、
docker-composeコマンドに適応されるので注意。
direnvの導入をおすすめする開発環境 $ export COMPOSE_FILE=docker-compose.develop.yml 本番環境 $ export COMPOSE_FILE=docker-compose.prod.ymlGemfile修正
pumaを本番環境に適応させる
Gemfilegroup :test, :production do gem 'puma', '~> 3.7' # 追加 end group :test do gem "rails-dom-testing" gem 'mocha', '>= 1.4.0' gem "simplecov", "~> 0.14.1", :require => false # For running system tests gem "capybara", '~> 2.13' gem "selenium-webdriver" # gem 'puma', '~> 3.7' 削除 endpuma.rb作成
config/puma.rbthreads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i threads threads_count, threads_count port ENV.fetch("PORT") { 3000 } plugin :tmp_restart app_root = File.expand_path("../..", __FILE__) bind "unix://#{app_root}/tmp/sockets/puma.sock" stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", truedatabase.yml作成(DB設定)
redmine公式ドキュメントに基づきdatabase.yml.exampleをもとに
database.ymlを作成database.yml# Default setup is given for MySQL with ruby1.9. # Examples for PostgreSQL, SQLite3 and SQL Server can be found at the end. # Line indentation must be 2 spaces (no tabs). production: adapter: mysql2 database: redmine host: db username: hoge password: "fugafuga_1" encoding: utf8 development: adapter: mysql2 database: redmine_development host: db username: root password: "" encoding: utf8 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: mysql2 database: redmine_test host: db username: root password: "" encoding: utf8 # 省略、、、、、本番環境以外、パスなしrootで良ければproduction関連以外編集しなくてもよい
各ファイル詳細
開発、本番環境共用
実際の本番環境ではDBサーバーを別途用意するとは思いますが、、
cotainers/db/multibyte.cnf# 文字コードを設定しないとエラーとなるため [mysqld] character-set-server=utf8 collation-server=utf8_general_ci開発環境
appコンテナ
containers/app/DockerfileFROM ruby:2.6.5 RUN apt-get update -qq && apt-get install -y build-essential \ libpq-dev \ nodejs RUN mkdir /redmine WORKDIR /redmine COPY . /redmine RUN gem install bundler && bundle installcompose
docker-compose.develop.yml# DBを永続化したい場合、コメントを外す version: '3' services: app: build: context: ./ dockerfile: containers/app/Dockerfile command: bundle exec rails s -p 3000 -b 0.0.0.0 volumes: - .:/redmine ports: - "3000:3000" depends_on: - db db: image: mysql:5.7 environment: MYSQL_ALLOW_EMPTY_PASSWORD: "yes" ports: - 3306:3306 volumes: - ./containers/db/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf #- db-store:/var/lib/mysql #volumes: #db-store:本番環境
appコンテナ
containers/app/Dockerfile.prodFROM ruby:2.6.5 RUN apt-get update -qq && apt-get install -y build-essential \ libpq-dev \ nodejs RUN mkdir /redmine WORKDIR /redmine COPY . /redmine RUN gem install bundler && bundle install --without development testwebコンテナ
Dockerfile.prodFROM nginx:1.15.8 # インクルード用のディレクトリ内を削除 RUN rm -f /etc/nginx/conf.d/* # Nginxの設定ファイルをコンテナにコピー ADD nginx.conf /etc/nginx/myapp.conf # ビルド完了後にNginxを起動 CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/myapp.confcontainers/db/nginx.confuser root; worker_processes 1; events{ worker_connections 512; } # ソケット接続 http { upstream redmine{ server unix:///redmine/tmp/sockets/puma.sock; } server { # simple load balancing listen 80; server_name localhost; #ログを記録しようとするとエラーが生じます #root /redmine/public; #access_log logs/access.log; #error_log logs/error.log; location / { proxy_pass http://redmine; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; } } }compose
docker-compose.prod.yml# DBコンテナはdatabase.ymlをもとに設定 # DBを永続化したい場合、コメントを外す version: '3' services: app: build: context: ./ dockerfile: containers/app/Dockerfile.prod command: bash -c "rm -f /redmine/tmp/pids/server.pid && bundle exec puma -e production -C config/puma.rb" volumes: - .:/redmine - public-data:/redmine/public - tmp-data:/redmine/tmp depends_on: - db web: build: context: containers/web/ dockerfile: Dockerfile.prod ports: - 80:80 volumes: - public-data:/redmine/public - tmp-data:/redmine/tmp depends_on: - app db: image: mysql:5.7 environment: MYSQL_USER: hoge MYSQL_PASSWORD: fugafuga_1 MYSQL_ROOT_PASSWORD: rootdayo MYSQL_DATABASE: redmine ports: - 3306 volumes: - ./containers/db/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf #- db-store:/var/lib/mysql volumes: #db-store: public-data: tmp-data:実行手順
開発環境
$ docker-compose build # DBを永続化した場合は最初だけ---------- # db作成(appはコンテナ名) $ docker-compose run app rake db:create # テーブル設定 $ docker-compose run app rake db:migrate # --------------------------------------- # 起動 $ docker-compose up -d # http://localhost:3000本番環境
$ docker-compose build # Redmine公式ドキュメントに基づき、シークレットトークン作成 # 実行は最初の一回だけでよい $ docker-compose run -e RAILS_ENV=production app bundle exec rake generate_secret_token # DBを永続化した場合は最初だけけ--------- # テーブル設定 $ docker-compose run -e RAILS_ENV=production app bundle exec rake db:migrate # --------------------------------------- # $ 起動 $ docker-compose up -d参考
Redmine GitHub
https://github.com/redmine/redmine
Redmineインストール
http://guide.redmine.jp/RedmineInstall/
docker-compose.ymlが環境別に複数ある場合はCOMPOSE_FILEを定義しておくと幸せになれる
https://suin.io/535GitHub
ソースをgithubにあげているので良かったら参考にしてください
https://github.com/kinako555/redmine_managed_docker.git
- 投稿日:2020-11-24T21:18:26+09:00
Rails on Dockerのgemの永続化について
背景
Dockerを利用したアプリ開発を行っていて、ログイン機能を搭載したくbcryptをGemfileに追加したが以下のエラーが出続け解決不能に。
22: from /usr/local/bundle/gems/spring-2.1.1/bin/spring:49:in `<main>' 21: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/client.rb:30:in `run' 20: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/client/command.rb:7:in `call' 19: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/client/server.rb:9:in `call' 18: from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require' 17: from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require' 16: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/server.rb:9:in `<top (required)>' 15: from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require' 14: from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require' 13: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/commands.rb:4:in `<top (required)>' 12: from /usr/local/bundle/gems/spring-2.1.1/lib/spring/commands.rb:33:in `<module:Spring>' 11: from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require' 10: from /usr/local/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require' 9: from /usr/local/lib/ruby/2.6.0/bundler/setup.rb:20:in `<top (required)>' 8: from /usr/local/lib/ruby/2.6.0/bundler.rb:107:in `setup' 7: from /usr/local/lib/ruby/2.6.0/bundler/runtime.rb:20:in `setup' 6: from /usr/local/lib/ruby/2.6.0/bundler/runtime.rb:108:in `block in definition_method' 5: from /usr/local/lib/ruby/2.6.0/bundler/definition.rb:226:in `requested_specs' 4: from /usr/local/lib/ruby/2.6.0/bundler/definition.rb:237:in `specs_for' 3: from /usr/local/lib/ruby/2.6.0/bundler/definition.rb:170:in `specs' 2: from /usr/local/lib/ruby/2.6.0/bundler/spec_set.rb:85:in `materialize' 1: from /usr/local/lib/ruby/2.6.0/bundler/spec_set.rb:85:in `map!' /usr/local/lib/ruby/2.6.0/bundler/spec_set.rb:91:in `block in materialize': Could not find bcrypt-3.1.16 in any of the sources (Bundler::GemNotFound)
解決方法
こちらのサイトの方法を試したが、一向に解決せず。。。
https://qiita.com/totto357/items/1741da83bf642dab99df
問題は実はDockerのgem一覧が永続化されていなかったからということが発覚。
https://nishinatoshiharu.com/datavolume-for-gem/gemの永続化を行なっていないとコンテナ上でbundle installを実行してもDockerイメージにはgemが保存されないためエラーが発生していたようです。
gemを永続化していないと新しいgemを入れるたびに、ビルドを実行しコンテナを起動しなければならないというわけです。
しかし、永続化を行えばコンテナ上でgemをインストールした際にイメージの再ビルドを行わなくて済むということのようです。
永続化の方法については上記のサイトがわかりやすいため参照ください。
- 投稿日:2020-11-24T21:17:11+09:00
コンテナ間通信ができない場合の原因について
docker-composeを使っていて、GoのコンテナからMySQLのコンテナに接続できずにハマった。 dial tcp 172.20.0.2:3306: connect: connection …
- 投稿日:2020-11-24T17:09:38+09:00
WSL2 上の Docker で wp-env が起動できない問題
Docker を Windows で動かしている場合は問題ありませんが、WSL2 上の Ubuntu で動かしているといろいろと壁にぶつかります。
今回の問題は、
wp-env
で WordPress のコンテナから MySQL のコンテナにアクセスできない問題です。エラー内容は以下の通り。yarn wp-env start ... mysqlcheck: Got error: 1130: Host '192.168.0.5' is not allowed to connect to this MariaDB server when trying to connect error Command failed with exit code 2. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
192.168.0.5
には MySQL にアクセスする権限がないとエラー。コンテナ自体は立ち上がっているので、mysql のコンテナに入って権限の設定を行います。コンテナ名は
docker ps | grep mariadb
で調べて置き換えてください。docker exec -it 3c9213646ddda6dbba714e3a7744fdfb_mysql_1 bashmysql のコンテナに入ったら、デフォルトの
root
ユーザー(パスワードなし)で mysql に接続します。root@f122f108eb2e:/# mysql -u rootユーザーの一覧を確認
MariaDB [(none)]> SELECT host, user FROM mysql.user; +--------------+-------------+ | Host | User | +--------------+-------------+ | 127.0.0.1 | root | | ::1 | root | | a1842b624a31 | root | | localhost | mariadb.sys | | localhost | root | +--------------+-------------+ 5 rows in set (0.001 sec)たしかに
192.168.0.5
ではアクセスできないようです。開発環境なのでどこからでも接続できるように Host%
を追加します。MariaDB [(none)]> CREATE USER 'root'@'%';権限の付与も忘れずに行います。
MariaDB [(none)]> GRANT ALL ON *.* TO 'root'@'%';追加できているか確認します。
MariaDB [(none)]> SELECT host, user FROM mysql.user; +--------------+-------------+ | Host | User | +--------------+-------------+ | % | root | | 127.0.0.1 | root | | ::1 | root | | a1842b624a31 | root | | localhost | mariadb.sys | | localhost | root | +--------------+-------------+ 6 rows in set (0.004 sec)無事に追加されています。
exit
を2回入力してコンテナから出ます。MariaDB [(none)]> exit Bye root@85afdca4b77e:/# exit exitそれでは、再度 wp-env をスタートしてみましょう。
yarn wp-env start yarn run v1.22.5 $ wp-env start ⚠ Warning: could not find a .wp-env.json configuration file and could not determine if 'プロジェクトディレクトリ名' is a WordPress installation, a plugin, or a theme. ✔ WordPress started. (in 22s 915ms) Done in 23.38s.無事に起動できたようです。
http://localhost:8888/ で動作が確認できます。
- 投稿日:2020-11-24T17:03:44+09:00
サーバーサイドエンジニアに知っておいてほしい文脈ごとのdockerコマンドとトラブルシューティング
これはなに
- docker自体は知っているし,「なんとなく起動と停止は使えるけどそれ以上はあまりやったことない」という人向け
- これらを抑えておけば普段の開発作業はもちろん,サーバー作業もおおよそ大丈夫でしょう!というのを想定作業ごとにまとめた
前提
- シェルスクリプトの構文がある程度頭に入っている
- dockerの環境整備が済んでいる
- dockerの基礎的な単語を抑えている
- dockerにおけるイメージ,コンテナの区別がついている
- buildをやったことはある
想定している作業
- dockerイメージの構築
- Dockerfileの作成および最適化
- CIでのdocker build
- 複数コンテナを利用したローカルでの環境の構築
- docker-compose.ymlの作成
- サーバー作業
- dockerコンテナのリソース利用率の確認
- コンテナに入って諸々の調査
それでは個別にみていきましょう.
作業ごとの解説
dockerイメージの構築作業
Dockerfileの作成および最適化
ここで想定しているのは,Dockerfileを編集しつつ,
docker build
とdocker run
を繰り返すような作業
使うコマンドとしては主に以下になる# build docker build . docker build -f /path/to/Dockerfile . docker build --build-arg HOGE=hoge docker build --no-cache # debugで使う docker run $IMAGE_ID docker run -it $IMAGE_ID sh docker exec -it $CONTAINER_ID sh # モリモリストレージ容量が食われるので適当なタイミングで片付ける docker images docker images -a docker images -aq docker rmi -f $(docker images -aq) docker system pruneDockerfileの作成
- docker buildで抑えておくべきなのは,コンテキストという概念である
docker build .
の最後の.
が,コンテキスト.この場合カレントディレクトリを指定している.- 一言でいえば,Dockerfileの実行はどのディレクトリで行われているとみなすのか?ということ.
- Dockerfileの配置場所と,コンテキストがずれる場合は理解必須.
- 参考: Dockerのビルドコンテキスト(build context)について確認したときのメモ
- docker build自体が失敗するとき
- docker buildでは
RUN
コマンドひとつ一つに対してimageが作成されている.- エラー直前に出力されたimage idに対して,
docker run
して,失敗したコマンドを実行&ログ確認して解決していく.- docker buildは成功するが,docker runが失敗するとき
- image idに対して,
docker run -it $IMAGE_ID sh
で起動してからコマンドを実行してエラーを確認する.- ENTRYPOINTを指定しているときは,
docker run -it --entrypoint='' $IMAGE_ID sh
としてentrypointを上書きすれば入れる.Dockerfileの最適化
--build-arg VAR=var
というオプションはDockerfileのARG構文と同時に理解すべき.
- 基本的に引数をDockerfileに渡せる,というだけ.それだけではdocker imageの中には記録されないので,注意.
- 記録したい場合は
ENV
構文を利用する.- ARGで気を付けるべきは,FROMとの位置関係.FROMよりあとに書かないと,うまく動かなくてハマる.
- 参考: Docker ARG vs ENV
- イメージサイズの削減にはmulti stage buildが効く
- わかっている人向けに端的にいえば,FROM句が二度でてきて,それぞれbuild時のイメージと実行時イメージに対応しており,buildが完了したら,実行時に必要なものだけ,実行時イメージにCOPYする手法.
- サービスやデプロイの規模によるが,イメージが1GBを超えないくらいなら優先度はまったく高くない.
- もしやるときにはdiveというコマンドが便利.
brew install dive
CIでのdocker build
ここでのコマンドはこれ
docker pull $PREV_IMAGE_ID docker build --cache-from $PREV_IMAGE_ID .
- CIでのポイントはとてもシンプル.buildキャッシュを効かせるだけ!
- ローカル環境でのbuildとは違って,CI環境ではなにもしないとキャッシュが基本効かない.
- ただし,通信コストが発生するので依存を一からダウンロードするコストとの比較にはなる.
複数コンテナを利用したローカルでの環境の構築
docker-compose.ymlの作成
ここでよく使うコマンドは以下の通り
docker-compose up docker-compose up --build docker-compose down docker-compose restart docker-compose exec [service] sh
- ymlの細かい解説はしない.公式docを読むべし.
- ローカル環境構築のポイントは下記.これらの項目を理解すればだいたいやりたいことはやれるはず.
- ポート転送設定(
posts:
)- コンテナとの共有ストレージの設定(
volumes:
)- コンテナ間ネットワークの設定(
links:
とdepends_on:
)- コンテナ間の通信ができないとき
- コンテナ間はサービス名(
services:
配下のkey)をホスト名として指定すれば通信できる- もちろん,ポートをEXPOSEなどしていることなどは確認が必要
- 環境変数を渡したい
environments:
での定義はもちろん,コミットしたくないような秘匿情報も,.env
形式のファイルを渡すことで解決できる!便利!- 変更が反映されない
- ymlファイル自体を更新したときは,
docker-compose down
もしくはdocker-compose restart
をおこなったほうがよい.- dockerにはイメージやコンテナとは別にネットワークの設定があり,一度落とさないと反映されない.
サーバー作業
基本はこちら
# 稼働コンテナ一覧表示 docker container ls docker ps docker ps -a # 稼働中コンテナへ入る docker exec -it $CONTAINER_ID sh # 稼働コンテナの強制停止 docker kill $CONTAINER_ID docker rm -f $(docker ps -aq)dockerコンテナのリソース利用率の確認
docker statsdockerコンテナでの作業後のファイル取得
地味に便利.
docker cp $CONTAINER_ID:/path/from/root/ ./
- 投稿日:2020-11-24T14:57:13+09:00
DockerでLaravelを構築してみた
Laradockとは
Docker環境でLaravel環境を簡単に構築できるDockerイメージです。
Laradockのプロジェクトは大きくなり、SymfonyやWordpress環境までも構築出来るようになりました。機能としては、Nginx, Apacheなどのwebサーバー、PHPの各バージョン、Mysql, PostgreSQL等の各データベースを自由に選択できます。
今回はNginx、PHP-FPMが動く環境を作り、Laravelを立ち上げるまでを記載します。
前提
・dockerインストールしていること
・docker-composeコマンドが実行できるようになっていることが必要。環境
Windows10 Pro
手順
[1] CMD開く。作業ディレクトリを作成してそこまで移動する
cd C:\Users\user[2] フォルダ内でLaradockをgithubからcloneします。
git clone https://github.com/laradock/laradock.git[3] Laravel環境を構築するまでの下準備
nginx(webサーバー。Apacheでも良いが、今回はLaradockの公式マニュアルに沿いました)
php-fpm(PHPを実行する環境。いわゆるfastCGI).envの作成
copy env-example .envdockerコンテナの立ち上げ
docker-compose up -d nginxコンテナが立ち上がっているかを確認する
docker-compose psworkspaceにログインし、Laravelをセットアップする
docker-compose exec workspace bash
workspaceにログインすると、最初の状態では/var/wwwにいる。この場所は、Windows側のprojectsフォルダ直下と同様の場所を表している。(laradockディレクトリ直下ではない)
/var/wwwの位置でLaravelをセットアップする
composer create-project laravel/laravel app01
現時点でディレクトリ構成は以下のようになっているかと思います。
親:projects
子1:laradock … Dockerコンテナ
子2:app1 … Laravel本体Dockerダッシュボード状態
ブラウザで動作確認する
ginx(webサーバー)の設定をします。設定ファイルを編集するため、一度、dockerコンテナを停止します。Windows側のlaradockディレクトリ直下で以下のコマンドを叩く
dockerコンテナが全てストップします。
コンテナを再度立ち上げる
docker-compose up -d nginxコンテナが立ち上がったら、ブラウザでhttp://localhost へアクセス
参考
- http://laradock.io
- http://laradock.io/introduction/
- 環境作成時に次のエラーが出た場合
UnexpectedValueException
The stream or file "/var/www/storage/logs/laravel.log" could not be opened:
failed to open stream: Permission deniedlaravel.logに書き込もうとして権限がなかった時に発生します。
sudo chmod 777 -R storage/参考になったURL
https://teratail.com/questions/236475
- 投稿日:2020-11-24T14:31:33+09:00
DockerでNode.js環境構築
概要
Dockerfile
とDocker-compose
を使って簡単にnode.jsの環境を作る。ディレクトリ構造
node_app ├─ Dockerfile └─ docker-compose.ymlDockerfile の記載
Dockerfile#イメージを指定 FROM node:12.4.0-alpine # 環境変数を定義 ENV NODE_ENV=development # 雛形パッケージのインストール RUN npm install -g express-generator # 初期カレントディレクトリ WORKDIR /app # 開放ポート EXPOSE 3000docker-compose.yml の記載
docker-compose.ymlversion: '3.7' services: app: build: context: . dockerfile: Dockerfile container_name: node volumes: - ./app:/app ports: - "8080:3000"
context
ディレクトリの指定 「 . 」 で同じディレクトリ
container_name
コンテナネームの指定
volumes
データーのマウント共有の指定 左がホスト 右がコンテナ
ports
コンテナとホストのポートをつなげる指定Dockerfile からイメージのビルド
$ docker-compose buildコンテナを生成、起動
-d (デタッチ オプション)でバックグラウンドで起動
$ docker-compose up -dコンテナに接続
-i(--interactive)標準入力を設定させ、コマンドを対話的にする
-t(--tty)疑似ターミナルの割り当て$ docker exec -it [CONTAINER_ID] bashexpress-generator で雛形の作成
今回はテンプレートエンジンはejsを使用
# express --view=ejs /appパッケージのインストール
# npm installサーバーを起動
# npm startlocal hostに接続して Welcome to Express! と表示されれば完成です。
参考本
Docker ドキュメント
Docker/Kubernetes 実践コンテナ開発入門
- 投稿日:2020-11-24T12:26:12+09:00
【AWSアカウント不要】ローカル環境でAWS CDKのデプロイ&動作確認をするチュートリアル
1. はじめに
1-1. この記事で行うこと
- LocalStackコンテナをセットアップし、動作確認
- Node.js環境コンテナ内にAWS CDKプロジェクトを作成
- AWS CDKプロジェクトをLocalStackへデプロイし、動作確認
1-2. この記事の対象者
- AWS CDKを本物のAWSを使わずに動かしたい方
- AWS CDKをすぐに捨てられる環境で色々と試してみたい方
- AWS CDKをブラウザのみで気軽に始めてみたい方
1-3. 動作環境
このチュートリアルはブラウザだけでDockerを使用可能なPlay with Dockerを使用しております。詳細な説明は以下の記事をご参考ください。
Docker 入門にはインストールなしで使える「Play with Docker」がいいと思うまた、Play with DockerではなくてもDockerが動く環境ならおそらく同じようにチュートリアル可能だと思います (が、この記事では手順等ございませんのでご了承ください)。
- 共通して必要なもの
- Docker Hubアカウント
- Play with Dockerで試す場合、必要なもの
- Play with Dockerを操作可能なブラウザ
- Play with Docker以外で試す場合、必要なもの
- Dockerをセットアップ済のPC等
1-4. 各種のバージョン
2020年11月24日時点で動作確認済のバージョンは以下の通りです。
- docker
- Docker version 19.03.11, build 42e35e61f3
- localstack
- 0.12.2
- aws-cli
- aws-cli/2.1.3 Python/3.7.3 Linux/4.4.0-189-generic docker/x86_64.amzn.2
- aws-cdk
- 1.74.0
- aws-cdk-local
- 1.65.0
2. チュートリアル
このチュートリアルではLocalStackというローカルでAWSを擬似的に使用できるツールを用います。詳しい説明は以下の記事をご参考ください。
LocalStack を使って無料で AWS を学ぶこのLocalStackのDockerコンテナ内に擬似的なAWS環境を立て、そこへAWS CDKをデプロイし、動作確認を行っていきます。
2-1. 最終的なファイル構成
いきなりですが、このチュートリアルが完了した状態のファイル構成です。
以下の「▶︎ 詳細」をクリックしてご確認ください。
$ tree -L 5 -I node_modules . ├── localstack │ ├── CHANGELOG.md │ ├── Dockerfile │ ├── LICENSE.txt │ ├── MANIFEST.in │ ├── Makefile │ ├── README.md │ ├── bin │ │ └── 略 │ ├── doc │ │ └── 略 │ ├── docker-compose.yml │ ├── localstack │ │ └── 略 │ ├── requirements.txt │ ├── setup.py │ └── tests │ └── 略 ├── node_workdir │ ├── Dockerfile │ ├── app │ │ └── sample │ │ ├── README.md │ │ ├── bin │ │ │ ├── sample.d.ts │ │ │ ├── sample.js │ │ │ └── sample.ts │ │ ├── cdk.json │ │ ├── cdk.out │ │ │ ├── SampleStack.template.json │ │ │ ├── cdk.out │ │ │ ├── manifest.json │ │ │ └── tree.json │ │ ├── jest.config.js │ │ ├── lib │ │ │ ├── sample-stack.d.ts │ │ │ ├── sample-stack.js │ │ │ └── sample-stack.ts │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── test │ │ │ ├── sample.test.d.ts │ │ │ ├── sample.test.js │ │ │ └── sample.test.ts │ │ └── tsconfig.json │ └── docker-compose.yml └── s3.txt
2-2. LocalStackのセットアップ
2-2-1. LocalStackをダウンロードする
[node1] (local) root@192.168.0.18 ~ $ git clone https://github.com/localstack/localstack Cloning into 'localstack'... remote: Enumerating objects: 44, done. remote: Counting objects: 100% (44/44), done. remote: Compressing objects: 100% (39/39), done. remote: Total 14028 (delta 15), reused 13 (delta 5), pack-reused 13984 Receiving objects: 100% (14028/14028), 5.75 MiB | 9.78 MiB/s, done. Resolving deltas: 100% (9762/9762), done.2-2-2. LocalStackコンテナを起動する
[node1] (local) root@192.168.0.18 ~ $ cd localstack [node1] (local) root@192.168.0.18 ~/localstack $ docker-compose up -d WARNING: The TMPDIR variable is not set. Defaulting to a blank string. Pulling localstack (localstack/localstack:)... latest: Pulling from localstack/localstack 1cff8f8f4790: Pull complete Digest: sha256:0e85ea6d44e3bf69a415298e72be46d06500ac038faebd98ea7bd9bcbcaab614 Status: Downloaded newer image for localstack/localstack:latest Creating localstack_main ... done [node1] (local) root@192.168.0.18 ~/localstack $ cd ..2-2-3. LOCALHOST_IP_ADDRESS変数を設定する
[node1] (local) root@192.168.0.18 ~ $ LOCALHOST_IP_ADDRESS=192.168.0.18 # 各自の環境によって異なります!後ほど、様々なコンテナ内からホストのIPアドレスを使用することになるので、先に変数として
LOCALHOST_IP_ADDRESS
を設定しておきます。
Play with Dockerの場合、root@192.168.0.18
の@
以降の192.168.0.18
を設定します (Play with Dockerでも毎回IPアドレスが固定ではないのでお気をつけください)。
それ以外の環境で試されている方は、各自で調べていただけると幸いです。2-2-4. LocalStackのステータスを確認する
[node1] (local) root@192.168.0.18 ~ $ curl "http://${LOCALHOST_IP_ADDRESS}:4566" {"status": "running"}https://github.com/localstack/localstack
2020-09-15: A major (breaking) change has been merged in PR #2905 - starting with releases after v0.11.5, all services are now exposed via the edge service (port 4566) only! Please update your client configurations to use this new endpoint.
(DeepLによる翻訳)
PR #2905 に主要な (壊すような) 変更がマージされました - v0.11.5 以降のリリースから、すべてのサービスがエッジサービス (ポート 4566) のみを介して公開されるようになりました! この新しいエンドポイントを使用するために、クライアントの設定を更新してください。公式githubにport 4566のみで動いてると書いてあるので、curlのポートに
:4566
を指定しています。
上手く動いていると{"status": "running"}
が返ってきます。2-2-5. Docker版aws-cliをaliasに登録する
[node1] (local) root@192.168.0.18 ~ $ alias awsd='docker run --rm -ti -v ~/.aws:/root/.aws -v $(pwd):/aws amazon/aws-cli'LocalStackは基本的にはGUIで操作できないのでaws-cliを使用する必要があります。
以下の記事を参考に設定しました。
AWS公式さんがDocker Hubで aws-cli のイメージを公開してくれた!
ちなみにawsd
(AWS Dockerの意味) は各自好きなように変更していただいても大丈夫です。2-2-6. Docker版aws-cliを起動し、バージョンを確認する
[node1] (local) root@192.168.0.18 ~ $ awsd --version Unable to find image 'amazon/aws-cli:latest' locally latest: Pulling from amazon/aws-cli 37373184fe69: Pull complete fc9d36ec628d: Pull complete 2ddf91b98617: Pull complete 9504c29fa015: Pull complete 21fd79a0d708: Pull complete Digest: sha256:8f8283ee998f26145569d411f986f1bdf0c56b1f4005077a22d94c7ed4561fb3 Status: Downloaded newer image for amazon/aws-cli:latest aws-cli/2.1.3 Python/3.7.3 Linux/4.4.0-189-generic docker/x86_64.amzn.2初回のDocker版aws-cli実行時にはDockerイメージのプルがまず実行されます。
そして、aws-cliのバージョンが表示されます。
ちなみに、2回目以降は以下のようにDockerイメージのプルが実行されずにDocker版aws-cliを使用できるようになります。[node1] (local) root@192.168.0.18 ~ $ awsd --version aws-cli/2.1.3 Python/3.7.3 Linux/4.4.0-189-generic docker/x86_64.amzn.22-2-7. LocalStack用のaws-cliのconfigureを設定する
[node1] (local) root@192.168.0.18 ~ $ awsd configure --profile=localstack AWS Access Key ID [None]: dummy AWS Secret Access Key [None]: dummy Default region name [None]: ap-northeast-1 Default output format [None]: json上記のように入力してください。
LocalStack用なのでAWS Access Key ID
とAWS Secret Access Key
は適当な値 (dummy
等) で大丈夫です。2-2-8. LocalStack用の情報入力を省略するaliasを設定する
[node1] (local) root@192.168.0.18 ~ $ alias awsdl="awsd --endpoint-url=http://${LOCALHOST_IP_ADDRESS}:4566 --profile=localstack"毎回
awsd --endpoint-url=http://${LOCALHOST_IP_ADDRESS}:4566 --profile=localstack
を入力しなくてもすむように、aliasを設定します。
ちなみにawsdl
(AWS Docker Localstackの意味) は各自好きなように変更していただいても大丈夫です。
なお、この記事ではこれ以降のawsコマンドはawsdl
となっています。2-3. LocalStackの動作確認
Amazon Simple Storage Service (以降、S3) へバケットを登録し、テキストファイルをアップロードできるかを確認します。
2-3-1. S3にバケットを登録する
[node1] (local) root@192.168.0.18 ~ $ awsdl s3 mb s3://test-s3 make_bucket: test-s32-3-2. S3のバケット一覧を取得する
[node1] (local) root@192.168.0.18 ~ $ awsdl s3 ls 2020-11-23 07:04:37 test-s32-3-3. S3へファイルをコピーする
[node1] (local) root@192.168.0.18 ~ $ echo "test text" > s3.txt [node1] (local) root@192.168.0.18 ~ $ awsdl s3 cp ./s3.txt s3://test-s3 upload: ./s3.txt to s3://test-s3/s3.txt2-3-4. 指定したS3のバケットのファイル一覧を取得する
[node1] (local) root@192.168.0.18 ~ $ awsdl s3 ls test-s3 2020-11-23 07:05:43 10 s3.txt2-4. Node.js環境のセットアップ
今回はAWS CDKをTypeScriptを使用して作成するので、Node.js環境が必要となります。
特別な理由はないですが、Node.js環境もDockerで準備していきます。2-4-1. Node.js環境作業ディレクトリを作成する
[node1] (local) root@192.168.0.18 ~ $ mkdir node_workdir && cd node_workdir [node1] (local) root@192.168.0.18 ~/node_workdir $ mkdir app2-4-2. Dockerfileを作成する
[node1] (local) root@192.168.0.18 ~/node_workdir $ vi Dockerfile以下のファイルの中身をコピペしてください。
DockerfileFROM node:14-alpine WORKDIR /app CMD ["sh"]2-4-3. docker-compose.ymlを作成する
[node1] (local) root@192.168.0.18 ~/node_workdir $ vi docker-compose.yml以下のファイルの中身をコピペしてください。
docker-compose.ymlversion: '3' services: app: build: . image: my-node-image volumes: - ./app:/app environment: - LOCALSTACK_HOSTNAME=${LOCALHOST_IP_ADDRESS} tty: trueenvironmentの
LOCALSTACK_HOSTNAME
は後ほど出てくるaws-cdk-localライブラリ内で必要となります。aws-cdk-local/bin/cdklocalから一部抜粋const getLocalEndpoint = () => { const port = process.env.EDGE_PORT || DEFAULT_EDGE_PORT; const host = process.env.LOCALSTACK_HOSTNAME || DEFAULT_HOSTNAME; return `http://${host}:${port}`; };2-4-4. Node.js環境作業ディレクトリの中身を確認する
[node1] (local) root@192.168.0.18 ~/node_workdir $ ls Dockerfile app docker-compose.yml3つの項目が表示されていたら、次の工程へ移りましょう。
2-4-5. Node.js環境コンテナを起動する
[node1] (local) root@192.168.0.18 ~/node_workdir $ LOCALHOST_IP_ADDRESS=$LOCALHOST_IP_ADDRESS docker-compose up -d Creating network "node_workdir_default" with the default driver Building app Step 1/3 : FROM node:14-alpine 14-alpine: Pulling from library/node cbdbe7a5bc2a: Pull complete f2ffd52523c3: Pull complete 48a445fb9d78: Pull complete 7a27e63388b2: Pull complete Digest: sha256:d41417bb7fd04744cd159a40632f918c13bc1af3486a848782e1f68af2c3e6cb Status: Downloaded newer image for node:14-alpine ---> 7f1893c3ede0 Step 2/3 : WORKDIR /app ---> Running in 47b57683cdda Removing intermediate container 47b57683cdda ---> 71423a0bee1b Step 3/3 : CMD ["sh"] ---> Running in e23e65a6f1f7 Removing intermediate container e23e65a6f1f7 ---> c695ce33957e Successfully built c695ce33957e Successfully tagged my-node-image:latest WARNING: Image for service app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Creating node_workdir_app_1 ... done
docker-compose up -d
コマンドの前にLOCALHOST_IP_ADDRESS=$LOCALHOST_IP_ADDRESS
の指定を忘れないようにお気をつけください。
コンテナの起動に成功するとCreating node_workdir_app_1 ... done
のように生成されたコンテナの名前が出力されます。2-4-6. Node.js環境コンテナの中に入る
[node1] (local) root@192.168.0.18 ~/node_workdir $ docker exec -it node_workdir_app_1 sh /app #先ほど生成されたコンテナの名前を指定して
docker exec
コマンドを実行します。
オプションに-it
を、コマンドにsh
を指定しているので、コンテナの中に入ることができます。
Dockerコンテナに入る方法については以下の記事をご参考ください。
docker exec -itって実際は何をしてるの?【90日目】なお、「2-5. AWS CDKプロジェクトの作成〜デプロイ」は、このコンテナの中に入っている状態で進めていきます。
2-5. AWS CDKプロジェクトの作成〜デプロイ
aws-cdkでプロジェクトを作成し、aws-cdk-localでLocalStackへデプロイしていきます。
2-5-1. aws-cdkとaws-cdk-localをグローバルインストールする
/app # npm install -g aws-cdk /usr/local/bin/cdk -> /usr/local/lib/node_modules/aws-cdk/bin/cdk + aws-cdk@1.74.0 added 188 packages from 186 contributors in 12.617s /app# npm install -g aws-cdk-local /usr/local/bin/cdklocal -> /usr/local/lib/node_modules/aws-cdk-local/bin/cdklocal + aws-cdk-local@1.65.0 added 189 packages from 187 contributors in 7.703s2-5-2. サンプルcdkプロジェクト用ディレクトリを作成し、移動する
/app # mkdir sample && cd sample2-5-3. サンプルcdkプロジェクトを作成する
/app/sample # cdk init sample-app --language=typescript Applying project template sample-app for typescript # Welcome to your CDK TypeScript project! You should explore the contents of this project. It demonstrates a CDK app with an instance of a stack (`SampleStack`) which contains an Amazon SQS queue that is subscribed to an Amazon SNS topic. The `cdk.json` file tells the CDK Toolkit how to execute your app. ## Useful commands * `npm run build` compile typescript to js * `npm run watch` watch for changes and compile * `npm run test` perform the jest unit tests * `cdk deploy` deploy this stack to your default AWS account/region * `cdk diff` compare deployed stack with current state * `cdk synth` emits the synthesized CloudFormation template Initializing a new git repository... /bin/sh: git: not found Unable to initialize git repository for your project. Executing npm install... npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 npm WARN deprecated request-promise-native@1.0.9: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 npm WARN deprecated har-validator@5.1.5: this library is no longer supported npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^2.1.2 (node_modules/jest-haste-map/node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.2.1: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) npm WARN sample@0.1.0 No repository field. npm WARN sample@0.1.0 No license field. ✅ All done!
cdk init
コマンドで--language=typescript
を指定してTypeScriptでファイルが生成されるようにしています。
また、sample-app
と指定すると、簡単なサンプルを含んだプロジェクトが生成されます。出力の中に簡単なサンプルについての説明があります。You should explore the contents of this project. It demonstrates a CDK app with an instance of a stack (`SampleStack`) which contains an Amazon SQS queue that is subscribed to an Amazon SNS topic.(DeepLによる翻訳)
このプロジェクトの内容を探ってみてください。スタック (SampleStack
) のインスタンスを持つ CDK アプリのデモを行います。
これは、Amazon SNSのトピックにサブスクライブされているAmazon SQSキューを含んでいます。生成された簡単なサンプルのソースコードを、ちょっとだけ見てみましょう。
/app/sample # vi ./lib/sample-stack.ts./lib/sample-stack.tsimport * as sns from '@aws-cdk/aws-sns'; import * as subs from '@aws-cdk/aws-sns-subscriptions'; import * as sqs from '@aws-cdk/aws-sqs'; import * as cdk from '@aws-cdk/core'; export class SampleStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const queue = new sqs.Queue(this, 'SampleQueue', { visibilityTimeout: cdk.Duration.seconds(300) }); const topic = new sns.Topic(this, 'SampleTopic'); topic.addSubscription(new subs.SqsSubscription(queue)); } }Amazon Simple Queue Service (以降、SQS) のキューとAmazon Simple Notification Service (以降、SNS)のトピックとサブスクリプションが定義されています。SNSトピックからメッセージを発行すると、サブスクリプションとして登録されているキューに登録されるようになっています。
2-5-4. TypeScriptファイルをJavaScriptファイルにトランスパイルする
/app/sample # npm run build > sample@0.1.0 build /app/sample > tscブラウザやNode.js環境はJavaScriptしか実行できないため、TypeScriptファイルをJavaScriptファイルへ必ず変換しましょう。
2-5-5. 初めてデプロイする場合、デプロイ用のS3バケットを作成する
/app/sample # cdklocal bootstrap ⏳ Bootstrapping environment aws://000000000000/us-east-1... CDKToolkit: creating CloudFormation changeset... [··························································] (0/3) ✅ Environment aws://000000000000/us-east-1 bootstrapped.2-5-6. LocalStackへデプロイする
/app/sample # cdklocal deploy This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening). Please confirm you intend to make the following modifications: IAM Statement Changes ┌───┬─────────────────────────┬────────┬─────────────────┬─────────────────────────┬───────────────────────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼─────────────────────────┼────────┼─────────────────┼─────────────────────────┼───────────────────────────┤ │ + │ ${SampleQueue.Arn} │ Allow │ sqs:SendMessage │ Service:sns.amazonaws.c │ "ArnEquals": { │ │ │ │ │ │ om │ "aws:SourceArn": "${Sam │ │ │ │ │ │ │ pleTopic}" │ │ │ │ │ │ │ } │ └───┴─────────────────────────┴────────┴─────────────────┴─────────────────────────┴───────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Do you wish to deploy these changes (y/n)? y SampleStack: deploying... SampleStack: creating CloudFormation changeset... [··························································] (0/6) ✅ SampleStack Stack ARN: arn:aws:cloudformation:us-east-1:000000000000:stack/SampleStack/3b39e2b2-bb7d-42d0-9b36-d53e069c1451途中で
Do you wish to deploy these changes (y/n)?
と入力を求められるので、問題がなければy
を入力しましょう。2-5-7. Node.js環境コンテナから抜け出す
/app/sample # exit [node1] (local) root@192.168.0.18 ~/node_workdir $2-6. AWS CDKからLocalStackへデプロイされたリソースの動作確認
「リソースが生成されているか」と「SNSトピックからメッセージを発行し、サブスクリプションとして登録されているキューに登録されるか」を確認していきます。
2-6-1. SQSキューの一覧を取得する
[node1] (local) root@192.168.0.18 ~/node_workdir $ awsdl sqs list-queues { "QueueUrls": [ "http://localhost:4566/000000000000/queue-7f6ead47" ] }SQSキューがちゃんと生成されていますね。
ちなみに、QueueUrls
に表示されている値は各自の環境で異ります。2-6-2. 指定したSQSキューの詳細を取得する
[node1] (local) root@192.168.0.18 ~/node_workdir $ awsdl sqs get-queue-attributes --queue-url http://localhost:4566/000000000000/queue-7f6ead47 { "Attributes": { "ApproximateNumberOfMessages": "0", "ApproximateNumberOfMessagesDelayed": "0", "ApproximateNumberOfMessagesNotVisible": "0", "CreatedTimestamp": "1606116190.41501", "DelaySeconds": "0", "LastModifiedTimestamp": "1606116190.41501", "MaximumMessageSize": "262144", "MessageRetentionPeriod": "345600", "QueueArn": "arn:aws:sqs:us-east-1:000000000000:queue-7f6ead47", "ReceiveMessageWaitTimeSeconds": "0", "VisibilityTimeout": "300" } }
--queue-url
に指定する値は「2-6-1. SQSキューの一覧を取得する」で取得した各自の値を指定してください。
今回はとりあえず出力結果のうち、次の一項目だけ確認します。ApproximateNumberOfMessages
(キューから取得可能なメッセージのおおよその数) が"0"
になっていることが確認できましたでしょうか。2-6-3. SNSトピックの一覧を取得する
[node1] (local) root@192.168.0.18 ~/node_workdir $ awsdl sns list-topics { "Topics": [ { "TopicArn": "arn:aws:sns:us-east-1:000000000000:topic-cac07a20" } ] }SNSトピックもちゃんと生成されていますね。
TopicArn
も同様に表示されている値は各自の環境で異ります。2-6-4. 指定したSNSトピックへメッセージを発行する
[node1] (local) root@192.168.0.18 ~/node_workdir $ awsdl sns publish --message "test message" --topic-arn "arn:aws:sns:us-east-1:000000000000:topic-cac07a20" { "MessageId": "d06d6c48-fba9-4b8b-ab09-5f96e0784aef" }
--topic-arn
に指定する値は「2-6-3. SNSトピックの一覧を取得する」で取得した各自の値を指定してください。
発行に成功するとMessageId
が入ったJSONが返ってきます。2-6-5. 指定したSQSキューの詳細を取得し、ApproximateNumberOfMessagesを確認する
[node1] (local) root@192.168.0.18 ~/node_workdir $ awsdl sqs get-queue-attributes --queue-url http://localhost:4566/000000000000/queue-7f6ead47 { "Attributes": { "ApproximateNumberOfMessages": "1", "ApproximateNumberOfMessagesDelayed": "0", "ApproximateNumberOfMessagesNotVisible": "0", "CreatedTimestamp": "1606116190.41501", "DelaySeconds": "0", "LastModifiedTimestamp": "1606116190.41501", "MaximumMessageSize": "262144", "MessageRetentionPeriod": "345600", "QueueArn": "arn:aws:sqs:us-east-1:000000000000:queue-7f6ead47", "ReceiveMessageWaitTimeSeconds": "0", "VisibilityTimeout": "300" } }「2-6-2. 指定したSQSキューの詳細を取得する」と同じコマンドを実行しましょう。
ApproximateNumberOfMessages
(キューから取得可能なメッセージのおおよその数) が"1"
になっていたら、SNSトピックから発行されたメッセージがSQSキューに登録される処理がうまくいった証拠です!
- 投稿日:2020-11-24T10:36:14+09:00
gem install: SSL verification error at depth 1: unable to get local issuer certificate
状況
GitHub Actionsを利用した
Docker buildx
中のgem install
で以下のエラーが発生。#24 [linux/arm/v7 7/10] RUN gem install iconv #24 2.493 ERROR: SSL verification error at depth 1: unable to get local issuer certificate (20) #24 2.495 ERROR: You must add /C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA to your local trusted storeベースコンテナはDocker Hubの
httpd:2.4.46
とhttpd:2.4.43
(2020年11月時点のlatest)のlinux/arm/v7
です。
linux/arm64
とlinux/amd64
では発生していません。詳しくはレポジトリを参照してください。
後述の通りその後対処が不要になったのでDockerfile
等は当時の版を参照。原因
原因は書いてある通り証明書エラーです。
GlobalSign Root CA
の証明書が入っていません。対処
証明書を追加すれば解決します。
Bundlerのページにあるトラブルシュートに従い、pemファイルへの直接リンクからダウンロードします。
署名の追加方法はLife with ITさんの記事と@msiさんの記事に従いました。ただし、証明書が不足している/古い場合はcurlが動作しないことがあります、
Dockerfile
内ではなく外部でcurlから取得し、COPY
した方が良いでしょう。.github/workflows/docker.yml- name: Download GlobalSignRootCA.pem run: curl https://raw.githubusercontent.com/rubygems/rubygems/master/lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem -o GemCert.pemDockerfileCOPY GemCert.pem /tmp/GemCert.pem RUN mkdir /usr/share/ca-certificates/Gem && \ cp /tmp/GemCert.pem /usr/share/ca-certificates/Gem && \ echo "Gem/GemCert.pem" >> /etc/ca-certificates.conf && \ update-ca-certificates && \ rm /tmp/GemCert.pemなお、
apt-get install ca-certificates
では解決しませんでした。
他には、$ curl -Lks 'https://git.io/rg-ssl' | ruby # SSLのチェック $ gem install bundler # Bundlerの更新 $ gem update --system # RubyGemsの更新が推奨されていました。私の場合更新は必要ありませんでしたが、チェックスクリプトは便利です。
懸念点
SSLの証明書をGitHubからダウンロードするというのはセキュリティ上心配です。
GitHubでなくとも将来ずっとURLが維持されるか、証明書自体が今後も信用できるのかなど不安が残ります。
特に定期実行もするGitHub Actionsで現時点で動作するだけのワークアラウンドも避けた方が良いでしょう。私の場合は、この後ソースコードを修正し
gem install
自体が不要になり、この対処を削除しました。参考記事
- Lief with IT (2019) 「Amazon Linux 2上でcurl実行時に「SSL certificate problem: unable to get local issuer certificate」というエラーが出る場合の対応」 https://l-w-i.net/t/aws/ec2_100.txt
- Bundler 「How to troubleshoot RubyGems and Bundler TLS/SSL Issues」https://bundler.io/v2.0/guides/rubygems_tls_ssl_troubleshooting_guide.html
- @msi (2020)「独自(root)CA のインストール方法」Qiita https://qiita.com/msi/items/9cb90271836386dafce3
- 投稿日:2020-11-24T10:36:14+09:00
Docker buildでのSSL証明書エラー対処 【GitHub Actions】
状況
GitHub Actionsを利用した
Docker buildx
中のgem install
で以下のエラーが発生。#24 [linux/arm/v7 7/10] RUN gem install iconv #24 2.493 ERROR: SSL verification error at depth 1: unable to get local issuer certificate (20) #24 2.495 ERROR: You must add /C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA to your local trusted storeベース・イメージはDocker Hubの
httpd:2.4.46
とhttpd:2.4.43
(2020年11月時点のlatest)のlinux/arm/v7
です。
linux/arm64
とlinux/amd64
では発生していません。詳しくはレポジトリを参照してください。
後述の通りその後対処が不要になったのでDockerfile
等は当時の版を参照。原因
原因は書いてある通り証明書エラーです。
GlobalSign Root CA
の証明書が入っていません。対処
証明書を追加すれば解決します。
Bundlerのページにあるトラブルシュートに従い、pemファイルへの直接リンクからダウンロードします。
署名の追加方法はLife with ITさんの記事と@msiさんの記事に従いました。ただし、証明書が不足している/古い場合はcurlが動作しないことがあります、
Dockerfile
内ではなく外部でcurlから取得し、COPY
した方が良いでしょう。.github/workflows/docker.yml- name: Download GlobalSignRootCA.pem run: curl https://raw.githubusercontent.com/rubygems/rubygems/master/lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem -o GemCert.pemDockerfileCOPY GemCert.pem /tmp/GemCert.pem RUN mkdir /usr/share/ca-certificates/Gem && \ cp /tmp/GemCert.pem /usr/share/ca-certificates/Gem && \ echo "Gem/GemCert.pem" >> /etc/ca-certificates.conf && \ update-ca-certificates && \ rm /tmp/GemCert.pemなお、
apt-get install ca-certificates
では解決しませんでした。
他には、$ curl -Lks 'https://git.io/rg-ssl' | ruby # SSLのチェック $ gem install bundler # Bundlerの更新 $ gem update --system # RubyGemsの更新が推奨されていました。私の場合更新は必要ありませんでしたが、チェックスクリプトは便利です。
なお、今回は証明書をインストールしましたが、SSLなしに設定するという選択肢もあります。お勧めしません。
懸念点
SSLの証明書をGitHubからダウンロードするというのはセキュリティ上心配です。
GitHubでなくとも将来ずっとURLが維持されるか、証明書自体が今後も信用できるのかなど不安が残ります。
特に定期実行もするGitHub Actionsで現時点で動作するだけのワークアラウンドも避けた方が良いでしょう。ここではやりませんでしたが、追加し処理が終わった後証明書を削除するのも一つのやり方でしょう。
私の場合は、この後ソースコードを修正し
gem install
自体が不要になり、この対処を削除しました。参考記事
- Lief with IT (2019) 「Amazon Linux 2上でcurl実行時に「SSL certificate problem: unable to get local issuer certificate」というエラーが出る場合の対応」 https://l-w-i.net/t/aws/ec2_100.txt
- Bundler 「How to troubleshoot RubyGems and Bundler TLS/SSL Issues」https://bundler.io/v2.0/guides/rubygems_tls_ssl_troubleshooting_guide.html
- @msi (2020)「独自(root)CA のインストール方法」Qiita https://qiita.com/msi/items/9cb90271836386dafce3
- 投稿日:2020-11-24T09:13:12+09:00
【ほぼ無料】FreenomとLet's Encryptを使って0円でドメインとSSL証明書を手に入れて、AWS EC2にdockerを入れてnginxコンテナを起動してドメインで繋がるHTTPS WEBサービスを立ち上げる方法
経緯
何か業務で使う技術や新しい技術を試したいときにAWS上にWebサーバーを立ててAPIとかテストページとか用意して、ローカルのChromeやAndroid端末からhttpで繋いでごにょごにょやるってのを結構やる。
RestAPIの疎通確認ぐらいならそれでいいんだけど、WebRTCやWebSocketの検証で使いたい場合、SSL化されたサイトでないとエラーになって接続できないため動作確認が出来ない問題があった。
どうにかこうにか安価でオレオレ証明書じゃないWebサーバーを立てられないかなーと調べたところ、FreenomとLet's Encryptを使えばほぼ無料で独自ドメインのhttpsサーバーを立てられそうだと判明。Freenomでのドメイン取得方法やLet's EncryptでのSSL証明書取得方法、それらをAWSで設定するやり方等は探せば断片的にはあるけど、全部まとまった記事は無かったので、備忘録もかねてここに残しておく。
やること
- 【無料】Freenomで無料ドメインを取得する
- 【条件付無料】AWS EC2インスタンスを作成してdockerをインストールする
- 【条件付無料】AWS Elastic IPで静的IPアドレスを発行してEC2インスタンスに関連付ける
- 【ほぼ無料】AWS Route53でDNS設定を行いドメイン名でEC2インスタンスに繋がるようにする
- 【無料】dockerでEC2インスタンスにnginxコンテナを立ち上げる
- 【無料】Let's Encryptで無料SSL証明書を取得してhttpsで繋がるようにする
無料の条件とほぼ無料の詳細
- AWS EC2インスタンスは無料利用枠を使用する
- 無料利用枠と記載のあるAmazonマシンイメージ(AMI)は月に750時間無料で使える。今回はそれを使うことで無料とする
- ElasticIPで割り当てたEC2インスタンスは起動したままにしておく
- ElasticIPで発行したIPアドレスがEC2インスタンスに関連付けされていない場合は課金が発生する。いくら課金されるかは調べていないがわずかであるらしい。こういう仕組みになっているのは無駄にIPアドレスを確保されるのを防ぐためだろう。
- AWS Route53では月に0.5$課金される
1. 【無料】Freenomで無料ドメインを取得する
早速やっていきます。ドメインはFreenomというサービスを使って取得します。Freenomとは、ドメインを無料で取得出来る海外のサービスです。ドメイン名は、XXXX.tkやXXXX.ml、XXXX.ga等が無料で取得できます。
https://www.freenom.com/ja/index.htmlドメインが使えることを確認し、チェックアウトする
好きなドメインを取得することが出来ますので、取得したいドメインを入力しましょう。利用可能か調べてくれて利用可能であれば以下のような画面になりますので「今すぐ入手!」を押下した後、「チェックアウト」を押下します。
使用期間を選択する
12ヵ月まで無料で使えるようですので、最大限使用させていただきましょう。Periodで「12 Months @ FREE」を選択して「Continue」を押下します。
ユーザー登録 or ログイン
金額が$0.00USD(無料)なのを確認します。問題なければ購入のためログインします。
私の場合は既に登録済みなので、普通にGoogleでログインします。
初回登録してないと、いろいろ登録しないといけないかもしれません。
規約に同意して購入
再度、金額が$0.00USD(無料)なのを確認してから、規約に同意のチェックを入れ、「Complete Order」を押下します。
これにてドメインの取得は完了しました。
2. 【条件付無料】AWS EC2インスタンスを作成してdockerをインストールする
こちらは私が書いた別の記事がそのまま使用できますので、こちら↓を参照ください。
AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法
3. AWS Elastic IPで静的IPアドレスを発行してEC2インスタンスに関連付ける
静的IPアドレス(固定IPアドレス)を取得し、上記で起動したEC2インスタンスにそのIPアドレスを割り当てます。こうすることで、EC2を再起動したりしてもIPアドレスが変わることは無くなります。
静的IPアドレスを取得する
まずは画面操作して静的IPアドレスを取得します。
「Elastic IP」を押下し、
次の画面で「Elastic IP アドレスの割り当て」を押下します。
次の画面で「割り当て」を押下します。
静的IPアドレスが取得できました。
EC2インスタンスに静的IPアドレスを関連付ける
割り当てられたIPアドレスを選択状態にして「アクション」内の「Elastic IPアドレスの関連付け」を押下します。
インスタンスには、先ほど作成したEC2のインスタンスIDを入力します。
入力したら「関連付ける」を押下します。
EC2インスタンスと静的IPアドレスの関連付けが完了しました。
4. 【ほぼ無料】AWS Route53でDNS設定を行いドメイン名でEC2インスタンスに繋がるようにする
ドメイン名で繋がるようにDNS設定を行います。
ホストゾーン作成→Aレコード登録→FreenomでNameserver設定という手順になります。ホストゾーンの作成
Route53の画面に行き、
「ホストゾーン」を押下します。
「ホストゾーンの作成」を押下します。
Freenomで取得したドメインを入力して「ホストゾーンの作成」を押下します。
ホストゾーンの作成が完了しました。
Aレコードの作成
「レコードの作成」を押下します。
シンプルルーティングがデフォルト選択されているのを確認して「次へ」を押下します。
「シンプルなレコードを定義」を押下します。
値/トラフィックのルーティング先で「レコードタイプに応じたIPアドレスまたは別の値」を選択した後、先ほど取得した静的IPアドレスを入力して、「シンプルなレコードを定義」を押下します。
レコードの作成を押下します。
レコードの作成が完了しました。
Nameserverの設定
今度はFreenomでNameserverの設定を行います。
「My Domains」を押下し、次の画面で「Manage Domain」を押下します。
「Management Tools」の「Nameservers」を押下します。
「Use custom nameservers(enter below)」を選択、Nameserver欄にはRoute53 ホストゾーンのNSレコードの値をコピペします。
入力したら「Change Nameservers」を押下します。
この時点で数分経過すると、DNSが浸透して行って「http://ドメイン名」でサイトが表示されるようになっているかと思います。
5. 【無料】dockerでEC2インスタンスにnginxコンテナを立ち上げる
6. 【無料】Let's Encryptで無料SSL証明書を取得してhttpsで繋がるようにする
5と6は一気にやっちゃいます。
いろいろやり方はあるかと思いますが、以下構成でdockerを使用してやってみます。
- reverse-proxyコンテナをインターネットに公開し、https通信を受け付けます。
- reverse-proxyコンテナからwebコンテナへ通信を転送、webコンテナではreverse-proxyからhttp通信を受け付けます。
全てのdockerを停止しておく
誤動作防止のため、作業前に一度全てのdockerコンテナを止めて、dockerオブジェクトも全部削除しておくといいでしょう。
docker stop $(docker ps -q) docker system prune -awebコンテナの作成と起動
homeディレクトリ配下にwebディレクトリを作成し、必要な構成ファイルを作成します。
cd mkdir web
ディレクトリ配下とファイルの内容は以下のような構成にしました。
ディレクトリ構成web - html - index.html # hogeとでも書いておく - docker-compose.ymldocker-compose.ymlversion: '3' services: web: image: nginx:latest container_name: web volumes: - ./html:/usr/share/nginx/html作成が終わったらdockerコンテナを起動します。
docker-compose up -d --build起動したことを確認します。
docker-compose ps Name Command State Ports ------------------------------------------------------ web /docker-entrypoint.sh ngin ... Up 80/tcp
reverse-proxyコンテナの作成と起動
homeディレクトリ配下にreverse-proxyディレクトリを作成し、必要な構成ファイルを作成します。
cd mkdir reverse-proxy
ディレクトリ配下とファイルの内容は、悪戦苦闘の結果、以下のような構成にしました。
ディレクトリ構成reverse-proxy - reverse-proxy - default.conf - Dockerfile - entrypoint.sh - docker-compose.ymldefault.confserver{ server_name y-do.tk; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location / { proxy_pass http://web/; } }DockerfileFROM nginx COPY default.conf /etc/nginx/conf.d/default.conf RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime RUN apt-get update && apt-get install -y \ wget cron && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /usr/local/bin/wait-for-it.sh RUN chmod +x /usr/local/bin/wait-for-it.sh ADD https://dl.eff.org/certbot-auto /usr/local/bin/certbot-auto RUN chmod a+x /usr/local/bin/certbot-auto RUN certbot-auto --os-packages-only -n COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"]entrypoint.sh#!/bin/bash # hogehoge@example.comはメールアドレス certbot-auto --nginx -d y-do.tk -m hogehoge@example.com --agree-tos -n certbot-auto renew # cron job settings # Let's Encrypt automatic Renew echo '0 8 * * * certbot-auto renew --post-hook "nginx -s reload"' >> /cron-tmpfile crontab /cron-tmpfile rm /cron-tmpfile # cron start /etc/init.d/cron start /bin/bashdocker-compose.ymlversion: '3' services: reverse-proxy: build: ./reverse-proxy tty: true container_name: reverse-proxy logging: driver: "json-file" options: max-size: "10m" max-file: "3" ports: - "80:80" - "443:443" volumes: - '/srv/letsencrypt:/etc/letsencrypt' command: ["wait-for-it.sh", "web:80"] networks: - default - web_default networks: web_default: external: true作成が終わったらdockerコンテナを起動します。
docker-compose up -d --build起動したことを確認します。
docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------- reverse-proxy entrypoint.sh wait-for-it. ... Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
インターネットからhttpsで繋がるようにAWSでセキュリティグループを更新する
FWで弾かれているため、まだインターネットからhttps通信を受け付けることが出来ません。
AWSのセキュリティグループのインバウンドルールを修正します。ルールを追加して、タイプ「HTTPS」、ソースは「0.0.0.0/0」を入力します。
入力したら「ルールを保存」を押下します。動作確認
ここまでやってやっとhttpsで通信が出来るようになっているはずです。アクセスしてみます。
アクセス出来た!!!
結果
月額0.5USDで独自ドメインのSSLサイトが運用できる。
ただし、ドメインは12ヵ月、SSL証明書は3か月で有効期限が切れる(無料だから文句は言えない)ので、今後は自動更新の仕組みを導入したい
- 投稿日:2020-11-24T00:57:29+09:00
WSL2 + Ubuntu18.04 + Docker環境構築
はじめに
アドベントカレンダー11日目の記事です。
今回は、WindowsでWSL2環境のセットアップ方法を紹介します。巷に記事はたくさんありますが、情報が古くエラーが発生して上手く動作しなかったり。。。
記事とターミナルを行ったり来たりで時間がかかったりと、セットアップに煩わしさを感じることが多いのではないでしょうか本記事では、そんな大変な設定をシェルスクリプトで大部分を構築する方法を紹介します。
環境
- Ubuntu18.04LTS(64bit)を想定しています。
※ Ubuntu 20.04の場合は、適宜置き換えてください。- Windows OSビルド 19041以上
Ubuntu 18.04のインストール
Microsoft StoreからUbuntu 18.04LTSをインストールします
WSL1の設定
インストールしたUbuntu 18.04をスタートメニューから開いてユーザ名やパスワードを設定します
Ubuntu18.04ターミナル# 初回起動時は初期設定が必要 Installing, this may take a few minutes... Please create a default UNIX user account. The username does not need to match your Windows username. For more information visit: https://aka.ms/wslusers Enter new UNIX username: # <= ログインユーザ名を設定 Enter new UNIX password: # <= ログインパスワードを設定(sudo コマンド実行時等に必要なため忘れないようにする) Retype new UNIX password: # <= ログインパスワードをもう一度入力 # 初期設定を行うと WSLにUbuntu 18.04 ディストロが追加される # ここで一旦終了する $ exitWSL2有効化
PowerShellを管理者権限で開いて下記コマンドを入力します。
# WSL2 を使うために、Windows仮想化機能(Hyper-V)を有効化 > Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform この操作を完了するために、今すぐコンピューターを再起動しますか? [Y] Yes [N] No [?] ヘルプ (既定値は "Y"): # そのままENTERして再起動 # 再起動が完了したらWSLのバージョン確認 ## 現状の Ubuntu 18.04はVersion 1 になっているはずです > wsl -l -v NAME STATE VERSION * Ubuntu-18.04 Stopped 1 # 先にインストールしていたUbuntu 18.04をWSL2環境に変換する > wsl --set-version Ubuntu-18.04 2 # 「WSL 2 を実行するには、カーネル コンポーネントの更新が必要です。」というエラーが出た場合 ## => https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi をインストールして再実行する # 変換が完了したらバージョン確認 ## Ubuntu 18.04がVersion 2になっていればOK > wsl -l -v NAME STATE VERSION * Ubuntu-18.04 Stopped 2WSL2の有効化が完了しました。
次は、WSL2を開いて基本設定を行います。基本設定
Ubuntu環境を一括で設定するためのシェルスクリプトを用意しました。
記事を見ながらコピペすることなく基本的なものは一括でインストールすることができます。やること
- ミドルウェアのインストール
- 動作に必要な基本ミドルウェアのインストール
- PythonやNode.jsをビルドするために必要なミドルウェアをインストール
カラーテーマの設定
Linuxbrewのインストール
- MacでおなじみのHomebrewのLinux版です
Dockerのインストール
- Windows版DockerクライアントをインストールすることなくWSL内で完結するDocker環境を構築します
- メリットとしては、Dockerクライアントを常時起動しなくても良いのでリソースの節約に繋がります
シェルスクリプトで実行
~/init.sh
を作成し、下記の全文をコピー
スクリプト中の[USER_NAME]
を自身のWindowsのユーザ名に変更します~/init.sh#!/bin/bash install_colortool() { echo 'カラーテーマの適用' # ColorToolのダウンロード先 ## [USER_NAME]はWindowsのユーザ名に適宜変更 DOWNLOAD_PATH="/mnt/c/Users/[USER_NAME]/Downloads" # 適用したいカラーテーマ(今回はOneHalfDarkを選択) # 変えたい場合は、ColorTool.exe -s で選択可能なテーマを確認して置き換える COLOR_THEME="OneHalfDark.itermcolors" echo 'ColorTool.zipのダウンロード' wget -P "${DOWNLOAD_PATH}" https://github.com/microsoft/terminal/releases/download/1904.29002/ColorTool.zip echo 'zipファイルの解凍' unzip "${DOWNLOAD_PATH}/ColorTool.zip" -d "${DOWNLOAD_PATH}/ColorTool" echo 'zipファイルの削除' rm "${DOWNLOAD_PATH}/ColorTool.zip" echo 'カラーテーマの種類' `echo ${DOWNLOAD_PATH}/ColorTool/ColorTool.exe -s` echo 'OneHalfDarkテーマの選択' # その他のテーマを変更したい場合は-dオプションの後を置き換える `echo ${DOWNLOAD_PATH}/ColorTool/ColorTool.exe -d ${COLOR_THEME}` echo '解凍したフォルダの削除' rm -r "${DOWNLOAD_PATH}/ColorTool" } install_linuxbrew() { echo 'Linuxbrew (Linux版の Homebrew パッケージマネージャ) 導入' ## Linuxbrew を使うことで最新の開発ツール等を導入しやすくなる sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)" echo 'PATHを通す' echo 'export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"' >> ~/.bashrc source ~/.bashrc echo 'Linuxbrew で各種開発ツールを導入' ## curl や git などは、最新版を使う方が良いため、改めて Linuxbrew で導入しなおす brew install curl git wget gcc zlib libzip bzip2 readline openssl pkg-config autoconf } install_anyenv() { echo 'Linuxbrewでanyenv導入' brew install anyenv anyenv install --init echo 'anyenv初期化スクリプトを.bashrc に記述' echo 'eval "$(anyenv init -)"' >> ~/.bashrc source ~/.bashrc echo 'anyenv update plugin の導入' mkdir -p $(anyenv root)/plugins git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update anyenv update echo 'バージョン確認' anyenv -v } install_docker() { echo 'Docker (Community Edition) インストール' curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable" sudo apt update && sudo apt install -y docker-ce echo 'WSL2再起動時dockerデーモンをスタートアップに登録するための設定' echo 'service docker start を /sbin/mount.rc に追記' echo 'service docker start' | sudo tee -a /sbin/mount.rc # WSL2にはcgroup用ディレクトリがデフォルトで作られていないため、以下もスタートアップスクリプトに登録しておく ## これをしておかないと Docker でプロセスのグループ化が必要になったときにエラーが起きる echo 'mkdir -p /sys/fs/cgroup/systemd && mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd' | sudo tee -a /sbin/mount.rc echo 'docker-compose 導入' sudo curl -L https://github.com/docker/compose/releases/download/1.26.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose echo 'Dockerをsudoなしで実行可能に' echo '※ カレントユーザーをdockerグループに所属させた上で docker.sock へのグループ書き込み権限を付与すればよい' sudo gpasswd -a $USER docker sudo chgrp docker /var/run/docker.sock sudo service docker restart echo '設定を反映するためにターミナル再起動' exec $SHELL -l } echo 'Linuxシステムアップデート' sudo apt update && sudo apt upgrade -y echo 'Linuxbewの動作に必要なパッケージのインストール' sudo apt install -y vim curl git ruby echo 'openjdkは個人開発で必要なため一応インストール' sudo apt install -y openjdk-11-jdk echo 'Pythonビルドに必要なミドルウェアのインストール' sudo apt install -y zlib1g-dev libssl-dev libbz2-dev libsqlite3-dev libffi-dev \ build-essential libreadline-dev tk-dev liblzma-dev libgdbm-dev libdb-dev echo 'https通信を可能にするためのミドルウェアをインストール' sudo apt install -y software-properties-common apt-transport-https ca-certificates echo '==========color toolのインストール=========' install_colortool echo '==========color toolのインストール完了=========' echo '==========linux brewのインストール=========' install_linuxbrew echo '==========linux brewのインストール完了=========' echo '==========anyenvのインストール=========' install_anyenv echo '==========anyenvのインストール完了=========' echo '==========Dockerのインストール=========' install_docker echo '==========Dockerのインストール完了========='実行属性を与えて実行する。
# 実行属性の付与 $ chmod +x init.sh # シェルの実行 $ ./init.shPythonやNode.jsのインストール
基本設定でインストールした
anyenv
を使ってPythonとNode.jsをインストールします。
これらをシェルスクリプトに含めなかった理由としては、exec $SHELL -l
を実行するときプログラムが終了してしまうためです。
ステップは多くないので、必要であればインストールしましょう。Pythonのインストール
pyenvを使って
Python 3.9
をインストールします# anyenv を使って pyenv 導入 $ anyenv install pyenv $ exec $SHELL -l # pyenvでPython 3.9をインストール $ pyenv install 3.9.0 # pyenvによるPythonのバージョン指定 $ pyenv global 3.9.0 # 現在選択されているバージョンを確認 $ pyenv versions # Pythonのバージョン確認 $ python --version # pipパッケージマネージャを更新しておく $ pip3 install --upgrade pip setuptools # pipのバージョン確認 $ pip3 --versionNode.jsのインストール
nodenvを使って
Node.js 15.2.0
をインストールします。# anyenvを使ってnodenv導入 $ anyenv install nodenv $ exec $SHELL -l # nodenv-yarn-install プラグイン導入: nodenv install 時にyarnもインストールする $ mkdir -p "$(nodenv root)/plugins" $ git clone https://github.com/pine/nodenv-yarn-install.git "$(nodenv root)/plugins/nodenv-yarn-install" $ export PATH="$HOME/.yarn/bin:$PATH" >> ~/.bashrc # Node.js 15.2.0インストール $ touch $(nodenv root)/default-packages $ nodenv install 15.2.0 # Node.js 15.2.0 に切り替え $ nodenv global 15.2.0 # 現在選択されているバージョンを確認 $ nodenv versions # シェルの再起動 $ exec $SHELL -l # Node.jsバージョン確認 $ node -v # yarnバージョン確認 $ yarn -vおわりに
今回は、WSL2のセットアップを紹介しました。
Docker環境がWSL内で完結するので、本当にLinuxに近い形で利用できそうです。
明日は、@tadahayaさんによる記事です。お楽しみに?