20201204のdockerに関する記事は14件です。

DockerでRails6(MySQL, Webpacker)を動かす。

Docker練習第二弾。Rails5は結構やっていたのでRails6を動かしてみようと思います。

環境

  • Docker 19.03.13
  • docker-compose 1.27.4
  • Windows10 Pro

ディレクトリ構成

rails_test/
    ┝ Dockerfile
    ┝ docker-compose.yml
    ┝ Gemfile
    ┝ Gemfile.lock
    ┝ environments/
              └ db.env

Dockerfile

Dockerfile
FROM ruby:2.6

RUN apt-get update -qq && \
    apt-get install -y build-essential \
                       nodejs

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
    echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
    apt-get update && apt-get install yarn

RUN mkdir /rails_test
WORKDIR /rails_test

ADD Gemfile /rails_test/Gemfile
ADD Gemfile.lock /rails_test/Gemfile.lock

RUN bundle install

ADD . /rails_test
  • FROM Ruby2.6をプルします。
  • RUN Railsに必要なNode.jsとyarnをインストール。 作業ディレクトリの作成。
  • WORKDIR 作業ディレクトリの指定をします。
  • ADD ローカルのGemfileとGemfile.lockをコンテナにコピーします。
  • RUN バンドルインストールをします。
  • ADD Gemfileをローカルに反映します。

今回webpackerを使うためにyarnをインストールするのポイントでした。

docker-compose.yml

今回のメインのdocker-compose.ymlの設定です。

docker-compose.yml
version: '3'
services: 
  app:
    build: .
    volumes: 
      - .:/rails_test
    command: bash -c "rm -f tmp/pids/server.pid && rails s -b 0.0.0.0"
    ports:
      - 3000:3000
    environment:
      WEBPACKER_DEV_SERVER_HOST: webpacker
    env_file: 
      - ./environments/db.env
    depends_on: 
      - db
  webpacker:
    build: .
    environment:
      NODE_ENV: development
      RAILS_ENV: development
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
    volumes: 
      - .:/rails_test
    command: ./bin/webpack-dev-server
    ports:
      - 3035:3035
  db:
    image: mysql:5.7
    volumes: 
      - rails-db:/var/lib/mysql
    env_file: 
      - ./environments/db.env
volumes: 
  rails-db:

各コンテナの設定を説明します。

app
app:
  build: .
  volumes: 
    - .:/rails_test
  command: bash -c "rm -f tmp/pids/server.pid && rails s -b 0.0.0.0"
  ports:
    - 3000:3000
  environment:
    WEBPACKER_DEV_SERVER_HOST: webpacker
  env_file: 
    - ./environments/db.env
  depends_on: 
    - db

Railsの設定です。

  • volumes ローカルのディレクトリとマウントします。これによりコンテナ作成時にローカルでの変更点が反映されます。
  • command サーバーを立ち上げています。ポイントとしてdocker-compose downでコンテナを削除した際にserver.pidがローカルに残るため再度コンテナを作成した際にサーバーが立ち上げられなくなるため最初にserver.pidを削除します。
  • depends_on MySQLのコンテナとの起動順序を定義します。Railsが先に立ち上がるとDBと接続できないと怒られます。
  • env_file ここではDBのユーザーネームなど定義します。今回はrootユーザーで行うためルートユーザーのパスワードだけ設定しておきます。
  • environment webpackerの設定です。
webpacker
webpacker:
  build: .
  environment:
    NODE_ENV: development
    RAILS_ENV: development
    WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
  volumes: 
    - .:/rails_test
  command: ./bin/webpack-dev-server
  ports:
    - 3035:3035

Webpackerの設定です。ほとんど公式に書いてある通り(Github)にしただけなので、特に言うこともありませんがここでもvolumesをRailsと合わせておかないとwebpack-dev-serverが見つけられなくなります。

db
db:
  image: mysql:5.7
  volumes: 
    - rails-db:/var/lib/mysql
  env_file: 
    - ./environments/db.env
volumes: 
  rails-db:

MySQLの設定です。rails-dbという名前付きボリュームにてDBのデータを永続化しています。また設定は別に用意(db.env)しています。もしrootユーザーでなく新しいユーザーを作りたい場合にはdb.envに書き加えます。

/environments/db.env
MYSQL_ROOT_PASSWORD=password

とりあえずこれだけ書いておきます。

Gemfile

この二行だけ書き加えます。Gemfile.lockは何も書きません。

Gemfile
source 'https://rubygems.org'
gem 'rails', '6.0'

アプリ作成

まずはrails newをしてアプリを作ります。

$ docker-compose run --rm app rails new . --force -d mysql

ディレクトリを新たに作らずにDBはMySQLを使い、Gemfileのオーバーライドをするコマンドを入力しています。ここで自分はyarnを入れていなかったためにwebpackerが途中でインストールが止まりました。

database.ymlの設定

ローカルにできたdatabase.ymlファイルにdocker-compose.ymlで設定したものに書き換えます。

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch('MYSQL_USER') { 'root' } %>
  password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %>
  host: db

development:
  <<: *default
  database: rails_test_development

test:
  <<: *default
  database: rails_test_test

production:
  <<: *default
  database: rails_test_production
  username: rails_test
  password: <%= ENV['RAILS_TEST_DATABASE_PASSWORD'] %>

defaultのところを書き換えています。今回MYSQL_USERとMYSQL_PASSWORDは設定していないのでrootとpasswordになりますが、db.envにて設定できるようにしています。

コンテナ起動

これでRailsがMySQLに接続できるようになりました。コンテナを全て起動しましょう。

$ docker-compose up -d

コンテナが3つ(app, db, webpacker)停止していなければ成功かと思われます。

$ docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                    NAMES
ab56f7caf110        rails_test_app         "bash -c 'rm -f tmp/…"   2 minutes ago       Up 2 minutes        0.0.0.0:3000->3000/tcp   rails_test_app_1
eb345957801c        mysql:5.7              "docker-entrypoint.s…"   3 minutes ago       Up 2 minutes        3306/tcp, 33060/tcp      rails_test_db_1
a64c29f979c1        rails_test_webpacker   "./bin/webpack-dev-s…"   13 minutes ago      Up 2 minutes        0.0.0.0:3035->3035/tcp   rails_test_webpacker_1

DB作成

最後にdb:createして http://localhost:3000 にてデフォルト画面が見れたら成功です。

$ docker-compose exec app rails db:create

所感

Qiitaの記事を見ながらコピペでやってできた気になっていましたが、改めて自分で書いてみるとMySQLに接続できなかったりWebpackerが起動できなかったりとトラブル続出でした。
また、node_modulesをコンテナの中に置いておくのってセンスが無い気もしました。何かいいアイデアがありそう。

とはいえひと月前までコピペでなんとなくやっていたところも大分自分の言葉で説明できるようになりました。
次は本番環境想定してnginxとの連携とかですかね...。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaのWebアプリケーションをDockerのマルチステージビルドでデプロイする

本記事は東京学芸大学 櫨山研究室 Advent Calendar 2020の四日目の記事になります.

概要

  • Javaで作成したWebアプリケーションをDockerを使ってデプロイする

本記事のコードは以下のGitHubリポジトリで公開しています.

動作させるアプリケーション

Building Java Web Applications, https://guides.gradle.org/building-java-web-applications/
Building Java Web Applications, https://medium.com/@tutorialspointexamples/building-java-web-applications-760d656061e4

にあるサンプルアプリケーションをDockerで動作させてみます.

※Gradleの公式ドキュメントがリンク切れだったので同じコードを紹介している別のリンクを載せています.

マルチステージビルド

コンテナを用いた開発では本番環境向けにサイズの小さいDockerイメージを作成することは重要になります.
よってビルド後の生成物だけを含んだイメージを作成するのが理想となります.

Dockerのマルチステージビルドはこのような要求をを簡単に実現する方法になります.

今回のJavaのWebアプリケーションをマルチステージビルドの流れを図に起こすと以下のようになります.

はじめにビルドステージと命名したステージでソースコードをビルドしwarファイルを生成します.
その次の本番用ステージと命名したステージでwarファイルをjettyに配備します.

Dockerfile

この流れを記述したDockerfileは以下のようになります.

# ビルドステージ
FROM adoptopenjdk/openjdk8:alpine as builder
WORKDIR /webapp

# プロジェクトの配置とビルド
ADD ./ ./
RUN ./gradlew war

# 本番用ステージ
FROM jetty:9-jdk8

EXPOSE 8080

COPY --from=builder ./webapp/build/libs/sample-app.war /var/lib/jetty/webapps

公式のjettyイメージでは/var/lib/jetty/webapps/配下にwarファイルを配備することでデプロイが完了します.

Dockerイメージのビルドとコンテナの起動

dockerイメージのビルドし,コンテナを起動しアプリケーションが正常に動作しているかを確認します.

docker image build -t sample-app:latest .
docker container run -p 8080:8080 sample-app:latest

正常に起動したら,http://localhost:8080/sample-app/ にアクセスをします.
以下の画面になっていたら成功です.

テキストフィールドにworldと入力しSay Helloボタンをクリックしましょう.

きちんとHello, world!と出力されました.
これで正常に動作していることが確認できました.

Docker Imageのサイズを確認

サンプルアプリケーションでそもそものアプリケーションのサイズがとても小さいので比較にもなりませんがDockerのイメージサイズを確認しておきます.

# ベースのjettyのイメージサイズ
$ docker image ls jetty            
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jetty               9-jdk8              12fc9041849d        10 days ago         525MB

# アプリケーションを配備したイメージサイズ
$ docker image ls sample-app
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample-app          latest              4096cac4f49a        10 minutes ago      525MB

本格的な開発ではDockerイメージの大きさがどの程度の確認する癖をつけると良いでしょう?‍♂️

参考文献

マルチステージビルドの利用,https://matsuand.github.io/docs.docker.jp.onthefly/develop/develop-images/multistage-build/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ElixirでIoT#4.1.2:Docker(とVS Code)だけ!でNerves開発環境を整備する

この記事は fukuoka.ex Elixir/Phoenix Advent Calendar 2020 の4日目です.
3日目は,@torifukukaiouさんの「ElixirでAtCoderのABC123を解いてみる!」でした.awesome!!:tada::tada::tada:

はじめに

どうも最近は開発環境厨みが増してきている気がします.
ElixirでIoT!の連載記事も久々な気がするんですが,今回も開発環境な記事です^^;

これまでの実績はこんな感じです.

なんか新しいものを導入するたびにホスト環境はいろいろ汚れるわけですが,それを解消するために最近はDockerにハマりつつあります.
@matsujirushi さんがこんな記事を公開していました!

こんなcoolなsolution,もうちょい綺麗にできそう!ってことで, @matsujirushi さんにリポジトリの権限をいただきつつ,Docker(とVS Code)だけで素敵な開発環境を整えてみました!!

この記事では整備した環境について,ユーザ目線での使い方を主に紹介します.
中身の解説はまた機会を改めて^^;

つくったもの

なにが嬉しいの?いつ使うの?

  • Dockerを使えば,数ステップだけでNervesの開発環境が整います.ElixirでIoT#4.1で紹介したみたいに,Nervesの開発環境の準備って,いろいろライブラリを入れたり,いろいろErlangインストールにハマったり,いろいろ大変なんですよね,,, そんなシチュエーションが気楽に回避できます.
  • 特に入門者にとっては嬉しいですし,知り合いにすぐ試してもらいたい!場合にも紹介しやくなるかと思います.
  • ハンズオンの開催を計画する時にすごく頭を悩ませるのが,参加者の環境を揃えることです.DockerfileとかVS Codeの各種設定ファイルを調整すれば,これもお手軽に解消できます!!
  • すでにNervesを導入済みの方でも,最新のバージョンや機能を味見で試してみたいことは多いです.そんなときにDockerを使えば,ホストの環境は汚さずにお手軽に最新版を試すことができます.asdfでErlang/Elixirのバージョンを切り替えて mix archive.install hex nerves_bootstrap のバージョンも,,, って煩わしさも無くなります.
  • Docker Hubにビルド済みのイメージを公開しています.これを使えば,さらに効率よくNerves開発環境が手に入ります(ただし最新版じゃないことがありますので,ご注意ください.全てはメンテナの @takasehideki の頑張り次第です^^;

ツラいことは??

  • Dockerを動かすので,CPU/メモリの負荷がそれなりに掛かります.あとイメージ展開のためのディスク容量も必要です.
  • mix burn でNervesファームウェアをmicroSDカードに書き込む作業ができません,,, ホスト上で fwup を実行する必要があります:fire::fire::fire:

導入手順

インストールが必要なものは下記です.

DockerとVS Codeの詳しい導入方法は「ALGYAN x Seeed x NervesJPハンズオン!に向けた開発環境の準備方法」の記事を参照してください.

Docker単体で動かす

Docker Hubリポジトリから

ビルド済みのDockerイメージを使用します.pullしてrunするだけです.

$ docker pull nervesjp/nerves
$ docker run -it -w /workspace nervesjp/nerves
root@6e304327bd2e:/workspace# 

GitHubリポジトリから

GitHubで公開しているDockerfileを使ってローカルでビルドします.自分好みにDockerfileをカスタマイズすることもできます.

$ git clone https://github.com/NervesJP/docker-nerves
$ cd docker-nerves

$ docker build -t docker-nerves .
$ docker run -it -w /workspace docker-nerves 
root@9bc88d0fc7b8:/workspace# pwd
/workspace
root@9bc88d0fc7b8:/workspace# echo ${HOME}
/root
root@9bc88d0fc7b8:/workspace# ls ~/.mix/*
/root/.mix/rebar  /root/.mix/rebar3

/root/.mix/archives:
hex-0.20.6  nerves_bootstrap-1.10.0

Tips:ファイルシステムのマウント

Dockerはイメージの再構築時/実行時に,そのファイルシステムが消えてしまいます.このため,Nervesプロジェクトのファイルを保持するためにホストにボリュームをマウントしておくのが便利です.
-v $ {PWD}:/ workspace によって,ホスト上の現在のディレクトリをDockerイメージにマウントできます.

$ docker run -it -w /workspace -v ${PWD}:/workspace docker-nerves 

Elixir/Nervesに関連する設定ファイルをマウントしておくのも効率的です. ~/.hex~/.nerves.ssh/ があります.
以下は,ホストとイメージ間で設定ファイルを共有する例です.

$ docker run -it -w /workspace -v ${PWD}:/workspace \\
  -v ~/.hex:/root/.hex -v ~/.nerves:/root/.nerves -v ~/.ssh:/root/.ssh \\
  docker-nerves 

VS Codeでより便利に!

みんな大好きVisual Studio Codeを使うと,さらに快適な開発環境が手に入ります.
通称dev-containerという拡張機能 Remote - Containers を利用します.
詳しくは下記の記事などをご参照ください〜

使用方法

1. リポジトリをclone

git clone https://github.com/NervesJP/nerves-devcontainer

Gitに慣れていなければ,下記から直接ダウンロードもできます.
https://github.com/NervesJP/nerves-devcontainer/archive/main.zip

2. VS Codeをdev-container機能で開く

VS Codeを起動して,クイックアクションのステータスバー項目(左下の緑の >< となっているところ)かF1をクリックします.
コマンドパレットが開きますので,Remote-Containers: Open Folder in Container...を選択し,手順1でcloneしてきたディレクトリを選択します.

image.png

image.png

3. コーヒーを淹れる:coffee:

Dockerイメージのダウンロードと展開がよしなに始まります.PCスペックとネットワーク環境によっては10分くらい掛かるかもしれません.コーヒーでも呑みながら,落ち着いてお待ちください

うまくいかない?場合は,Docker Desktopのアプリが起動していないことが考えられます.
Windowsだと,デスクトップ右下のタスクトレイにこんな感じのクジラのアイコンが表示されているか確認してください(Macだとメニューバーにいてます)

image.png

ちゃんと進んでいるか気になる方は, 右下の青字の "Starting Dev Container (show log)" をクリックすると,進捗のログが表示できます.

ということで,こんな感じに出来上がりっ♪
左下の緑色なところが
>< Dev Container: Nerves
な表示になっていることを確認してください.
(画像は途中で "Starting Dev Container (show log)" をクリックして進捗を表示した場合のものです)

image.png

メニューの [ターミナル] > [新しいターミナル](ショートカットキーは Ctrl+Shift+`)でターミナルを開くと, Dockerイメージ内でNerves開発環境の整ったターミナルを良い感じに利用できます.
(起動直後は[新しいターミナル]が選択できないことがあるようです.その場合は左側[エクスプローラー]で右クリックして[統合ターミナルで開く]を選択してみてください)

root@ebc5e1a19ae3:/workspaces/nerves-devcontainer# ls 
LICENSE.txt  README.md
root@ebc5e1a19ae3:/workspaces/nerves-devcontainer# ls ~/.mix/*
/root/.mix/rebar  /root/.mix/rebar3

/root/.mix/archives:
hex-0.20.6  nerves_bootstrap-1.10.0
root@ebc5e1a19ae3:/workspaces/nerves-devcontainer# elixir --version 
Erlang/OTP 23 [erts-11.1.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Elixir 1.11.2 (compiled with Erlang/OTP 23)
root@ebc5e1a19ae3:/workspaces/nerves-devcontainer# iex 
Erlang/OTP 23 [erts-11.1.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Interactive Elixir (1.11.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 

4. SSH鍵を作成する

Nervesのファームウェア開発とネットワーク接続には,SSH鍵交換方式が使われます.
下記のように,いちばん代表的であるRSA鍵を作成しておきます.

ssh-keygen -t rsa -N "" -f .ssh/id_rsa

Tips a.k.a コダワリどころ

ローカルでのイメージの手動ビルド

GitHubで公開しているVS Codeのディレクトリは,Docker Hubでビルド済みのイメージのを使用しています.
手元でカスタマイズしてビルドしたい場合は,もともとのDockerfile./.devcontainer に配置して, ./.devcontainer/devcontainer.json//"dockerFile": "Dockerfile", の行のコメントを解除してください.

.devcontainer/devcontainer.json
{
    "name": "Nerves",
    // Pull Docker image from DockerHub  https://hub.docker.com/r/nervesjp/nerves
    //"image": "nervesjp/nerves:0.1.1",
    // NOTE: original Dockerfile is maintained at https://github.com/NervesJP/docker-nerves/blob/main/Dockerfile
    // You can also build Docker image locally by locating above file to here and uncomment next line 
    "dockerFile": "Dockerfile",

〜〜(省略)〜〜

Nerves設定に関するファイルのマウント

先ほどのTIPSと同じく,イメージの再構築時/実行時に,そのファイルシステムが消えてしまいます.
VS Code/GitHubでは docker run 時のオプションも統一できるので,これらのファイルが含まれるディレクトリをカレントに保持するようにしました.
(これらはどこにマウントするのがいいのか,割りと悩ましかったです.${HOME} のほうがええんちゃうかという気もします.ご意見いただけたら嬉しいです)

1つめは,Dockerコンテナ内の ~/.hex にマウントされる ${PWD}/.hex です.ElixirのHexパッケージが保持されます.

2つめは,Dockerコンテナ内の ~/.nerves にマウントされる ${PWD}/.nerves です.このディレクトリでは,Nervesのツールチェーンとnerves_system_brのアーカイブが保持されます.

Dockerコンテナの再起動のたびに mix deps.get でこのアーカイブのダウンロード/展開は面倒ですし時間が掛かります.なので,このディレクトリをマウントするようにしています.
ホストとコンテナのファイルシステム間のバインディングはパフォーマンスが悪いため,最初の mixdeps.get の実行時には多少の時間が掛かります.ですが,Docker起動のたびにダウンロード/展開に待たされるよりはマシじゃね?と判断しました.

最後に ${PWD}/.ssh です.
ステップ4で作成した id_rsaid_rsa.pub のSSHキーペアが含まれます.これらは,Nervesファームウェアの構築とNervesデバイスへのSSH接続のために使用されます.

さらに,VS Code拡張機能の自動設定で,Nervesのプロジェクトファイルも現在のディレクトリに保持されます.

fwupのインストール a.k.a 制約事項,,,

すっげー便利やん!と思うのですが,冒頭にも挙げている欠点がひとつだけあります.
Docker環境からはmicroSDカードへのアクセスができません,,, このため,せっかくDocker内でビルドしたNervesファームウェアを,mix burnでそのままmicroSDカードに書き込めません.

代案として,Nervesファームウェアの書込みのためのユーティリティである fwup をホストにインストールして実行します.
https://github.com/fhunleth/fwup

Windowsの場合

Chocolateryを使われている方は,下記でインストールできます.

choco install fwup

そうでない方は,下記からバイナリを直接ダウンロードして,ダウンロード先にPath環境変数を設定してください.
https://github.com/fhunleth/fwup/releases/download/v1.8.2/fwup.exe

macOSの場合

brewでインストールできます.

brew install fwup

Linuxの場合

プラットフォームに合わせて,パッケージのダウンロードとインストールを行ってください.
https://github.com/fhunleth/fwup#installing

fwupの実行

インストールが完了したら,ターミナルを開いてNervesのプロジェクトのディレクトリに移動して,下記のとおり実行してください.
Windowsの方は,PowerShellを「管理者として実行する」で開く必要があります.

$ cd <your_nerves_project_dir>
$ fwup _build/${MIX_TARGET}_dev/nerves/images/<project_name>.fw

Dockerだから仕方ない話しではあるのですが,なんかうまいことできたら嬉しいところです.
例えばmicroSDの /dev/diskX を書き込み可能でアクセスできたり,ホストにシェルプロセスの立ち上げをそこで実行したり,,, (WSL 2ではそんな機能があるらしい??

良い方法をご存じの方がいましたら,ここのissue#1かコメント欄で教えてください〜

おわりに

この記事の初稿は,実は英語で書きました.
よっしゃElixir Forumに投稿してやんぜ!世界のみんなを楽にしてやんぜ!Advent Calendarも英語記事を登録やっ!!
って息巻いていたんですが,どうもElixir ForumはModeratorsの審査承認作業があるらしく,,,
敢えなく日本語で書き直す,そんな不毛な作業の果てでした^^;

↓ この1時間後,,, 無事にapprovedされて公開されました!! :grin:


fukuoka.ex Elixir/Phoenix Advent Calendar 2020 の5日目は @hisaway さんによる「[Elixir]匿名関数をパターンマッチする」です.ASTの世界をチラ見しましょっ:eyes:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【re:Invent】AWS Lambda コンテナ試して見た

AWS Lambda Container Support が発表されました。最大 10GB のサイズのコンテナイメージがデポロイできます。現時点サポートされている、全てのランタイム(Python、Node.js、Java、.NET、Go、Ruby)のベースイメージを提供します。

全体像

従来は Lambda コンソールからソース編集かアップロードできますが、コンテナイメージ使う場合、一旦 Amazon ECR に保存し、Lambda コンソールからデポロイを行います。

Lambda (1).png

コンテナイメージ

Amazon ECR (Amazon Elastic Container Registry)

コンテナイメージを AWS に保管しますので、まず ECR 作ります。

aws ecr create-repository \
  --repository-name lambda-repo \
  --region ap-northeast-1

下記結果が返ってきます、repositoryUri をメモしておきましょう。

Output
{
  "repository": {
    "repositoryArn": "arn:aws:ecr:ap-northeast-1:[ACCOUNT_ID]:repository/lambda-repo",
    "registryId": "[ACCOUNT_ID]",
    "repositoryName": "lambda-repo1",
    "repositoryUri": "[ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/lambda-repo",
    "createdAt": "2020-12-04T08:03:18+00:00",
    "imageTagMutability": "MUTABLE",
    "imageScanningConfiguration": {
      "scanOnPush": false
    },
    "encryptionConfiguration": {
      "encryptionType": "AES256"
    }
  }
}

Dockerfile

イメージビルド用の Dockerfileを準備します。テストコードも含めて作ります。
Base image は AWS が提供する amazon/aws-lambda-nodejs:12 を使用します。

Dockerfile
# AWS Docker Image
FROM amazon/aws-lambda-nodejs:12

WORKDIR /usr/local/app

# Port
EXPOSE 8000

# Application
RUN echo $'\n\
  exports.handler = async (event) => { \n\
    const response = { \n\
      statusCode: 200, \n\
      body: JSON.stringify(\'Hello from Lambda!\'), \n\
    }; \n\
    return response; \n\
  }; \n\
  ' > index.js

CMD [ "/usr/local/app/index.handler" ]

最終的に ECR に保存して使うなので、${repositoryUri}:${tag} のフォーマットでタグを付けます。

ACCOUNT_IDは環境に合わせて修正する
# docker build
docker build -t [ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/lambda-repo:latest .

# ECR login (Linux)
aws ecr get-login-password | docker login --username AWS --password-stdin [ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com

# docker push
docker push [ACCOUNT_ID].dkr.ecr.ap-northeast-1.amazonaws.com/lambda-repo:latest

AWS Lambda デポロイ

AWS Lambda のコンソールで [Create Function] をクリックします。 [Container image] を選択し、[Browse images] をクリックします。

image.png

先ほど作った ECR Repository から、 latest タグ付けたコンテナイメージを選択し、[Select image] をクリックします。
image.png

最後は [Function name] を入れて、他の設定は全部デフォルトのままで、[Create function] をクリックします。
image.png

テスト

Lambda コンソールでテストしましょう。想定通りの結果が返ってきました。

image.png

パフォーマンス

コンテナイメージ大きいため、やはりコードスタート気になりますね。

イメージサイズ (MB) Lambdaメモリ (MB) コードスタート 正常コール (5回平均)
146.71 128 Duration (11.20 ms)
Billed duration (619 ms)
Duration (7.6ms)
Billed duration (8 ms)
146.71 640 Duration (2.28 ms)
Billed duration (584 ms)
Duration (1.84ms)
Billed duration (2 ms)
146.71 1280 Duration (1.98ms)
Billed duration (459 ms)
Duration (0.95ms)
Billed duration (1 ms)

結果から見ると、メモリを積めば、ある程度改善できます。

おまけに

Lambda コンテナベースイメージの自作方法は、公式ドキュメントに Python のみの記載があります。
日本語の翻訳またなので、英語のみとなります。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images-create.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker+ActiveDirectory+nginx(certbot)でKeycloakを使いたい!

Windows Server上に構築したActiveDirectoryの認証情報を使って、OIDCなどを使用したかったのですが、その際Keycloakの構築に結構手間取ったので備忘録として

後から再構築するのを楽にするために、Docker環境を使用しています

サーバーの準備

ConoHaを使います。(学割があるのがいいですよね)

image.png

普通に、Docker環境が使えるイメージがあるので、そのまま使います(その場からDocker環境が使えるのいいですよね)

証明書の書き出し

Keycloakは、公式のDockerイメージが提供されています(サクッと構築できるの以下略
ActiveDirectoryは、オンプレで構築していて、イマドキ暗号化されていないとかあり得ない時代なので、接続はLDAPSを使用します(LDAP over SSLです、困ってググってもLDAPSではなくLDAPが引っかかったりするので注意しましょう)

AD側は、証明機関の機能をインストールして、CA証明書を発行してください(その時点で、ADもLDAPS接続が利用可能になるはずです)

本当であれば、ADに使用する証明書も、ちゃんとしたCAから発行されているものが望ましいのですが、個人レベルなので、オレオレ証明書もとい自己署名証明書を使用します

Keycloakで正しくSSL接続できるよう、ルート証明書を書き出して、トラストします

ツール→証明機関→発行した証明書から、一番要求IDが若く、証明書テンプレートが「クロス証明機関(CrossCA)」になっているものをダブルクリック
image.png
image.png
image.png

Base64 encoded X.509でエクスポートします
image.png
image.png
image.png

Dockerfileを書きます
(4行目でADDしているファイルがADを構築しているWindows Serverで書き出したクロスルート証明書です)

Dockerfile
FROM jboss/keycloak

WORKDIR /opt/jboss/keycloak/standalone
ADD cert.pem /usr/share/pki/ca-trust-source/anchors/cert.pem
USER root
RUN keytool -import -noprompt -alias selfsigned -cacerts -file /usr/share/pki/ca-trust-source/anchors/cert.pem  -storepass changeit

JREがデフォルトで使用している(ので合ってましたっけ、オプションなしのものは)keystoreにインストールしてあげれば大丈夫です
ストアのパスワードは changeit です(変えたほうがいいんでしょうかね)

デプロイします
そういえば、GitLabに実はContainer Registryの機能があったんですね・・・初めて知りました・・・

nginxの設定

Certbot(Let's Encrypt)を使いたいのと、個人的に圧倒的信頼があるのでnginxでリバースプロキシを行い、nginxより外はHTTPS、nginxより内側はHTTPな環境を準備します

この際、注意する点としては、実際にはHTTPSでも、Keycloakから見たらHTTPであるというところです
そのため、リソースがHTTPで埋め込まれ、Chromeなどに怒られるため、対策の設定も加えます

proxy.conf
server{
    listen 80;
    server_name YOUR_DOMAIN_NAME;

    location / {
            # プロキシ先のサーバアドレスとポート番号を指定
            return 301 https://$host$request_uri;
    }
}


# HTTPSの設定
server{
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name    YOUR_DOMAIN_NAME;

    # SSL認証キーの参照先。certbotで自動的に生成されるファイルを指定する。
    ssl_certificate     /etc/letsencrypt/live/YOUR_DOMAIN_NAME/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN_NAME/privkey.pem;

    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;
    proxy_set_header X-Forwarded-Proto $scheme;

    add_header Access-Control-Allow-Origin *;

    location / {
        # プロキシ先のサーバアドレスとポート番号を指定
        proxy_pass http://localhost:8080;
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-compose up --buildができないときの対処

環境

・Windows10Pro
・Docker for windows 19.03.13

概要

〇コマンドで以下を実行したが、MySQLでエラーが出てbuildできない
 docker-compose up --build

〇エラーメッセージ
 ERROR: for web Cannot create container for service web1: Conflict.
 ~中略~
 havCreating mysql ... error

解決策

 ①以下のコマンドを実行しコンテナを一括削除する
 \$ docker rm $(docker ps -aq)
 ②以下のコマンドを実行し再度buildする
 \$ docker-compose up --build
 ③立ち上げることができる

参考

https://qiita.com/kabi5/items/9e2090da22ffd6c7ad2a

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CensOS6のサポートが切れてyum updateでError: Cannot retrieve repository metadata (repomd.xml) for repository: base. Please verify its path and try againが出た時の対処法

起こったこと

2020-11-30でCentOS6のサポートが終了した。
Dockerfileでyum updateしてるところがあってエラーになってしまった。
今回はその対処法を残しておく。

Dockerfile
FROM centos:6.6

RUN yum update -y
実行したコマンドとエラー
$ docker build -t centos6.6 .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos:6.6
 ---> 368c96d786ae
Step 2/2 : RUN yum update -y
 ---> Running in 7daac25d2959
Loaded plugins: fastestmirror
Setting up Update Process
Error: Cannot retrieve repository metadata (repomd.xml) for repository: base. Please verify its path and try again
YumRepo Error: All mirror URLs are not using ftp, http[s] or file.
 Eg. Invalid release/repo/arch combination/
removing mirrorlist with no valid mirrors: /var/cache/yum/x86_64/6/base/mirrorlist.txt
The command '/bin/sh -c yum update -y' returned a non-zero code: 1

対処法

Dockerfileを修正

Dockerfile
FROM centos:6.6

RUN sed -i "s|#baseurl=|baseurl=|g" /etc/yum.repos.d/CentOS-Base.repo \
  && sed -i "s|mirrorlist=|#mirrorlist=|g" /etc/yum.repos.d/CentOS-Base.repo \
  && sed -i "s|http://mirror\.centos\.org/centos/\$releasever|https://vault\.centos\.org/6.6|g" /etc/yum.repos.d/CentOS-Base.repo

RUN yum update -y

まとめ

本当はCentOSのバージョンを上げるべきだよ

参考

yumコマンド実行時に Cannot retrieve repository metadata と出て失敗する(CentOS 6.4)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerイメージが削除できない

事象

不要となったDockerイメージを削除しようとしたところ、エラーとなり削除することができなかった。

発生したエラー内容

$ docker rmi <IMAGE_ID>
Error response from daemon: conflict: unable to delete 86ec02f67a26 (must be forced) - image is being used by stopped container 9d75bcc06a43

エラーの原因

Dockerイメージを削除するには、コンテナが停止している必要がある。
また、停止されていてもコンテナとしては存在しているので、コンテナを削除してからでないとDockerイメージを削除することができない。

対応策

psコマンド(-aオプションで停止中のコンテナも全て表示)で、停止中のコンテナのIDを確認し、
コンテナを削除後に、再度Dockerイメージを削除する。

$ docker ps -a
$ docker rm <CONTAINER_ID>
$ docker rmi <IMAGE_ID>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ERROR: Service 'web' failed to build : The command '/bin/sh -c apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs' returned a non-zero code: 100

Udemyのゼロからはじめる Dockerによるアプリケーション実行環境構築にて

レクチャーと同じコードでrubyのverを2.6.3に変えてRUN apt-get update -qq && apt-get install -y build-essentialを行うとこのエラーがでてしまいます。

Step 2/8 : RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

---> Running in 36ea4384800f

E: Failed to fetch http://deb.debian.org/debian/dists/buster/main/binary-amd64/by-hash/SHA256/e8455b55666b3c399ac4605281f20a90fa86617fd75c3a9f26a1efa5c0687a5b File has unexpected size (13341 != 7906408). Mirror sync in progress? [IP: 151.101.90.132 80]

Hashes of expected file:

- Filesize:7906408 [weak]

- SHA256:e8455b55666b3c399ac4605281f20a90fa86617fd75c3a9f26a1efa5c0687a5b

- MD5Sum:ecae7a32cc589c20b7895517deda55e5 [weak]

Release file created at: Sat, 26 Sep 2020 09:54:48 +0000

E: Failed to fetch http://security.debian.org/debian-security/dists/buster/updates/main/binary-amd64/by-hash/SHA256/695dc865096aea89c8019fd5c2eb1d60be9d26c9a274c1261851a845e5144f08 File has unexpected size (13391 != 253900). Mirror sync in progress? [IP: 151.101.90.132 80]

Hashes of expected file:

- Filesize:253900 [weak]

- SHA256:695dc865096aea89c8019fd5c2eb1d60be9d26c9a274c1261851a845e5144f08

- MD5Sum:735dc48c9149a23603b4a8e6b5b21628 [weak]

Release file created at: Fri, 04 Dec 2020 02:01:41 +0000

E: Failed to fetch http://deb.debian.org/debian/dists/buster-updates/main/binary-amd64/by-hash/SHA256/e26b70071e36b418e8b95c6b7ec6d0a733973708aa308f856b0c9ebb2d884fcf File has unexpected size (13357 != 7856). Mirror sync in progress? [IP: 151.101.90.132 80]

Hashes of expected file:

- Filesize:7856 [weak]

- SHA256:e26b70071e36b418e8b95c6b7ec6d0a733973708aa308f856b0c9ebb2d884fcf

Release file created at: Thu, 03 Dec 2020 20:30:16 +0000

E: Some index files failed to download. They have been ignored, or old ones used instead.

ERROR: Service 'web' failed to build : The command '/bin/sh -c apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs' returned a non-zero code: 100

解決方法

RUN printf "deb http://archive.debian.org/debian/ jessie main\ndeb-src http://archive.debian.org/debian/ jessie main\ndeb http://security.debian.org jessie/updates main\ndeb-src http://security.debian.org jessie/updates main" > /etc/apt/sources.list

をDockerfileのRUN apt-get update -qq && apt-get install -y build-essentialの前に追加

最後に

解決するのに時間がかかりました。node.jsのupdateも要求されたので下記参考
https://qiita.com/kodai_0122/items/795438d738386c2c1966

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WindowsServer2019 Proxy環境でWSL+Dockerを使う

目次

動作環境

OS Name: Microsoft Windows Server 2019 Standard
OS Version: 10.0.17763 N/A Build 17763

Domain参加していてProxy環境です。

きっかけ

WindowsServer2019にはWindowsContainerという機能がありますが、Dockerhubにはpullできるものが少なく勝手が悪い。
Hyper-VでLinaxの仮想を立てても良いですが、ドメイン参加や手続きが面倒です。
そんな中でWSLという機能を見つけたのでそれを使ってやってみようと思いました。
※以前はWSLではDockerは動かなかったようですが、今は動くようです。

WSLでUbuntu18.04を使えるようにする

Ubuntu18.04でsudo apt updateができるところまでやります。
参考 https://docs.microsoft.com/ja-jp/windows/wsl/install-on-server

※WSLだとUbuntu20.04はDockerがうまく動かなかったので、Ubuntu18.04のディストリビューションを選択
参考 https://qiita.com/AumyF/items/eaf42dd3345a2285ff9e
※GUIでポチポチやる場合は以下が参考になります。
https://pswork.jp/wsl/windows-2019-wsl-install/

PowerShell
# 機能有効化
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
# ディストリビューションのDL
$url = "https://wslstorestorage.blob.core.windows.net/wslblob/Ubuntu_1804.2019.522.0_x64.appx"
Invoke-WebRequest $url -OutFile Ubuntu1804.zip
# 展開
Expand-Archive .\Ubuntu1804.zip .\Ubuntu1804
# Ubuntu18.04の実行
.\Ubuntu1804\ubuntu1804.exe

上記を実行して4,5分待つとusername、passwordを聞かれるので適当に入力します。
次にUbuntu側でProxyの設定を行って、sudo apt updateします。

以下のshファイルを作成して、上記で作成したユーザのホームディレクトリに配置します。
エクスプローラーから配置できます。(Ubuntuからexitしておかないとエラーになる場合がある)
参考 https://qiita.com/quzq/items/1096c638c0d86795be13

proxysetting.sh
#!/bin/bash

# setting bash proxy
cat <<'EOF' >> /etc/profile.d/proxy.sh
export http_proxy="http://[proxy_ip]:[proxy_port]"
export https_proxy="http://[proxy_ip]:[proxy_port]"
EOF

# setting apt proxy
cat <<'EOF' >> /etc/apt/apt.conf
Acquire::http::proxy "http://[proxy_ip]:[proxy_port]";
Acquire::https::proxy "http://[proxy_ip]:[proxy_port]";
EOF

作成したファイルを実行して、一度exitします。

Bash
cd ~/
sudo sh proxysetting.sh
exit

もう一度ubuntuに入りなおすときはwslまたはubuntu1804.exeを実行します。
参考 https://qiita.com/mizutoki79/items/f6ba08b7f73133102c91

PowerShell
wsl 

sudo apt updateして、エラーなく動けば完了です。

Bash
sudo apt update && sudo apt upgrade

Ubuntu18.04でDockerを実行できるようにする

以下のshファイルを作成して、上記で作成したユーザのホームディレクトリに配置します。

※Dockerは最新のバージョンだとエラーがでて動きませんでした。
※以下のスクリプトでは18.06.1でインストールしています。

installdockerce.sh
#!/bin/bash

# 必要なもののインストール
sudo apt install -y \
   apt-transport-https \
   ca-certificates \
   gnupg-agent \
   software-properties-common
# gpgキーの追加 sudoでcurlは-E付けないとProxyでとまる
sudo -E 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 $(lsb_release -cs) stable"
sudo apt update
# version指定してインストール
sudo apt install docker-ce=18.06.1~ce~3-0~ubuntu
# sudo付けないでdockerコマンド使えるようにする
sudo usermod -aG docker $USER
  • 環境変数を引き継いでdockerdをバックグラウンドで起動させるshファイルの作成
    ※サービスのところにProxyのコンフィグファイルを追加するやり方だとproxy設定が反映されませんでした。
    参考 https://qiita.com/dkoide/items/ca1f4549dc426eaf3735
startdockerd.sh
#!/bin/bash

# proxy用の環境変数
export http_proxy=http://[proxy_ip]:[proxy_port]
export https_proxy=http://[proxy_ip]:[proxy_port]
# これないとdockerdの起動でエラー
sudo cgroupfs-mount
# バックグラウンドで上記の環境変数引き継いで実行
sudo -bE dockerd

Ubuntuでinstalldockerce.shを実行してDockerをインストールします。

Bash
cd ~/
sudo sh installdockerce.sh
# ~~~
# 出力をみて、エラーなくインストールできていることを確認
# ~~~
exit

wslコマンドでstartdockerd.shを実行し、Ubuntuに入ります。

PowerShell
wsl sudo sh startdockerd.sh
wsl

dockerコマンドを実行して、エラーなどがなければ完了です。

Bash
docker info
# これでエラーの表示がでず、設定したproxyの環境変数が表示されていればok
docker run hello-world
# 実行して下記がでれば完了
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS SAMをローカルDockerコンテナ上で動かす

目標

前回のAWS SAM CLIによるサーバレス環境構築に引き継ぎ、SAM環境構築で直接にローカルPCにインストールではなく、Docker内に入れます。Docker導入の良いところは、個人開発環境のパッケージのバージョンを統一できるメリットがもちろん、MysqlやElasticSearchなどの導入も迅速できます。

ちなみに、エキサイトの「開発現場でAWSサーバーレスを導入しました」記事も紹介しました。

前提

入門編に紹介している知識を把握していることが前提です。また、Dockerの基礎知識があり、ローカルPCにDockerインストールしておく必要。

構築

アプリケーションのひな形生成

初回だけ雛形生成が必要なので、前回みたいsam init実行します。

$ sam init \
    --runtime python3.8 \
    --name excite-serverless-project \
    --app-template hello-world

excite-serverless-projectプロジェクトが作成されました。

ディレクトリ構造を再編

最終的にこのようなフォルダー構成を作ります

├── README.md
├── __init__.py
├── bin
│   ├── build.sh
│   └── deploy.sh
├── docker
│   └── Dockerfile
├── docker-compose.yml
├── src
│   ├── hello_world
│   │   ├── __init__.py
│   │   ├── app.py
│   │   └── requirements.txt
│   └── template.yaml
└── tests
    ├── __init__.py
    └── unit
        ├── __init__.py
        └── test_handler.py

とりあえず、Events不要なので削除します

$ rm -rf events/

実際にAPIエンドポイントが複数あるので、もう1段を下げます

$ mkdir src
$ mv hello_world template.yaml src

Docker環境構築

  • AWSの認証設定 AWSへデプロイのため、アクセスキーIDとシークレットキー設定が必要です。
$ mkdir .aws

保存フォルダーだけ先に作成しておきます。

  • docker管理フォルダー作成
$ mkdir docker

Dockerfileファイル作成、以下の内容を追加します

FROM python:3.8

# create local bin directory
RUN mkdir -p /root/.local/bin
ENV PATH $PATH:/root/.local/bin

# Install awscli and aws-sam-cli
RUN pip install -U pip setuptools wheel --no-cache-dir && \
  pip install pipx --no-cache-dir && \
  pipx install virtualenv && \
  pipx install pipenv && \
  pipx install awscli==1.* && \
  pipx install aws-sam-cli==1.9.0

WORKDIR /usr/src

最後にdocker-compose.yml作成します

version: "3"

services:
  sam_instance:
    container_name: excite-sam-instance
    image: excite-sam-instance
    build:
      context: .
      dockerfile: ./docker/Dockerfile
    networks:
      - excite-sam-network
    volumes:
      - .:/usr/src
networks:
  excite-sam-network:
    driver: bridge

コマンド省略化のために、bashファイルにまとめる

まず、スクリプト保存フォルダーを作成します

$ mkdir bin

build.shファイル作成、以下の内容を追加します。

#!/bin/bash
set -o errexit

# aws profile
echo -n "AWS_ACCESS_KEY_ID:"
read -r AWS_ACCESS_KEY_ID
echo -n "AWS_SECRET_ACCESS_KEY:"
read -r AWS_SECRET_ACCESS_KEY

# aws credentials
echo "[default]" > .aws/credentials
echo "aws_access_key_id = $AWS_ACCESS_KEY_ID" >> .aws/credentials
echo "aws_secret_access_key = $AWS_SECRET_ACCESS_KEY" >> .aws/credentials

# aws config
echo "[default]" > .aws/config
echo "output = json" >> .aws/config
echo "region = ap-northeast-1" >> .aws/config

# build docker
docker-compose build "${@}"

次にdeploy.shファイル作成、以下の内容を追加します。

#!/bin/bash
set -o errexit

TEMPLATE_FILE=$1
DOCKER_IMAGE_NAME=excite-sam-instance
STACK_NAME=excite-api-lambda-deploy-stack
S3_BUCKET_NAME=excite-api-lambda-deploy-bucket

# build SAM template
docker run \
  -v $(pwd):/usr/src \
  -v $(pwd)/.aws:/root/.aws --rm $DOCKER_IMAGE_NAME \
  sam build -t "$TEMPLATE_FILE"

# SAM deploy
docker run \
  -v $(pwd):/usr/src \
  -v $(pwd)/.aws:/root/.aws --rm $DOCKER_IMAGE_NAME \
  sam deploy --template-file .aws-sam/build/template.yaml --stack-name "$STACK_NAME" \
    --s3-bucket "$S3_BUCKET_NAME" --capabilities CAPABILITY_NAMED_IAM  --no-fail-on-empty-changeset

# remove unnecessary folder
rm -rf .aws-sam

AWSへデプロイしてみる

まず、ビルド実施

$ ./bin/build.sh

個別でテンプレートをAWSへデプロイ

$ ./bin/deploy.sh src/template.yaml 

API Gatewayのアクセスポイントでアクセスしてみる

$ curl https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello
{"message": "hello world"}

と返ってくれば成功です。

最後に

実際の開発現場でdockerが非常に便利です。ローカルでAPIの開発・デバッグ・デプロイの一連作業ができます。次の単体テスト編は実際にコードを書いて、単体テストを実施してみます。

エキサイト株式会社では随時に仲間を募集しております。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

snapのdockerを使ってみての感想

概要

ここ数か月、snapでインストールしたdockerを使っているので感想などを書きます。

snapについて軽く解説

https://snapcraft.io/

linux向けのパッケージマネージャーです。
色んなディストリビューションに対応していてます。
ちなみにubuntuならプリインストールされているので最初から使えるはずです。

dockerをインストール

https://github.com/docker-snap/docker-snap

snapで普通にinsltallするだけでOKです。
docker-composeも一緒にインストールされます。

sudo snap install docker

sudoなしでdockerコマンドを使う方法について

ユーザーをdockerグループに追加した後にsnapでdockerを再起動します。

sudo snap disable docker
sudo snap enable docker

ssh経由でdockerコマンドが使えない

ssh経由でコマンドを実行する時は /snap/bin にPATHが通っていないのが原因でした。
.bashrc などに書いても読み込まれないので、結局 /etc/environment に追加して解決しました。

ディレクトリの制約

dockerがアクセスするファイルはホームディレクトリ配下に置く必要があります。
今のところ問題になっていませんが特定のケースで困るかもしれません。

docker-composeでsnapのvolumeが使われてしまう

~/.config などをマウントしたくてもsnap側のディレクトリがマウントされてしまいます。
今のところキャッシュ用途に使っているだけなので問題になっていませんが、これも特定のケースで困るかもしれません。
しかもvオプションで指定した時は、ちゃんと指定したディレクトリがマウントされるので混乱しました。

versionが最新ではない

dockerもdocker-composeもちょっと古いバージョンがインストールされます。
現状だとdockerはpatchバージョン、docker-composeはminorバージョンくらいの遅れがあります。

おわり

備忘録として色々書きましたが実際のところ普通に使えているのでこのまま使用を継続しようと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

クラウドから撤退して自前サーバに自分でwebアプリを建てるおはなし

はじめに

クラウド全盛の昨今ですが、あえてクラウドに逆らうセルフホスティングの話をします。クラウドに任せるのではなく、自分のサーバの中に自分で使うサービスをたる、そういう記事です。

Self-hosting (web services) - Wikipedia

今回はそんなself-hostingにおすすめのwebアプリケーションをドドーンと14個紹介します。

計算機の歴史は常に振り子でした。
集中処理と分散処理、逐次処理と並列処理、同期処理と非同期処理、RISCとCISC...
これらは決して排他的に対立するということもないのですが、どちらが主流かというのは時代のトレンドとともに振り子のように揺れ動いてきました。
「クラウドとオンプレ」「所有と非所有」というのもまたその一つですね。

利点と欠点

まず利点はなんといっても、自分のデータを自分の手元においておけることです。
クラウド事業者が技術的問題でデータを消したり中身を見ることも、契約的・法的問題でデータを消したり見ることもありません。
すべてのデータは手元にあり、(適切に設定して運用していれば)他人が見ることも消すこともありません。

また、クラウド事業者の気ままな変更に付き合う必要がないということも挙げられます。
たとえばEvernoteは度々、大幅なサービスの変更を行っいています。
これに追従できていればいいのですが、「余計な改定しやがっておかげで使えないぜ!」と憤慨しているユーザもたくさんいます。
Self-hostingであれば、ある時点で動くコードを永遠に死守することができます。とくにコンテナ環境であれば古いライブラリを封入しておくことも簡単(脆弱性対策は自分でする必要はあります)。
「〇〇が使えないサービスになったから次は△△に引っ越し」などといっても、△△が第2の〇〇にならない保証はどこにもありません。
EvernoteからNotionに引っ越したところで、Notionが未来永劫安住の地となることはなく、サービス終了や値上げの心配だって残ってしまいます。
これを自前化することにより、Evernote朝からNotion朝への王朝交代ではなく、権利を自らに取り戻すことができます。

欠点はその「適切に設定して運用」「脆弱性対策は自分で」する責任は常に自分にあり、バックアップも自分でやる必要があるということです。
「ふくいナビ」事件を笑っていることはできません。そのような事件が起きたら自分で自分のデータのバックアップを探してきて自分で復旧しないといけないのです。
自由と自立にはそれなりの責任と手間、時には苦労が伴います...

構成

  1. httpsを解釈するreverse proxy
  2. httpで動くアプリケーション(docker内)

基本的には上記の構成でしょう。
httpsを終端する場所でクライアント証明書を請求・検証することで、他人のアクセスを排除することも簡単にできます。
1をnginxやapacheを使わずに以下のような構成にすることも可能です。

  1. sslhやstunnelでSNIを解釈して、SNIのホスト名で割り振る先のポートを変更する(sslhはconfigファイルを使うとSNIで割り振りができる。stunnelは比較的新しいバージョンでSNI対応可能)
  2. sslhを使う場合、sslhからの接続をstunnelで受け取り、サーバ側証明書処理やクライアント証明書の処理をおこなって平文のTCPとしてトンネルする
  3. httpで動くアプリケーション(docker内)

SSLHでHTTPS, SSH, OpenVPNを443番ポートに共存させる - Qiita
1つのアドレス・ポートを SSH (over SSL) と HTTPS で使う - Qiita

1〜2はバーチャルサーキットを暗号化するレイヤ(TCPより上でHTTPより下、OSI参照モデルでL6あたり)のみ扱うので、websocketだろうが未知のHTTP拡張だろうが関与せず何でも通るという利点があります。
欠点はログ類も乏しく、セキュリティ上のヘッダー追加などの加工も不可能ということでしょうか。

これらのうち、露出する頭だけVPSにおいておき、背後のアプリケーションは自宅においてVPNでつなげるということも可能です。
これならVPSにかかるお金は最小限ですみますし、自宅サーバなのでバックアップなども簡単です。

なお、クライアント証明書を使う場合はその証明書がはいった端末が必要ですが、iOS Safariではwebsocketには証明書をつけてくれません。
他のアプリでもつけてくれないことがあります。
その場合はクライアント証明書以外の方法で守ってあげる必要があります。

デスクトップ用アプリもほしい!

Evernoteのver.10からが使っているのがElectronですが、そこまでしなくても以下のようなものを使えばこれらwebサービスはだいたいデスクトップアプリになります。

GitHub - jiahaog/nativefier: Make any web page a desktop application
Unite for macOS
Fluid – Turn any webpage into a real Mac App

使えるソフト

ということで...
以下、GPLなのかBSDなのか等は別として、すべてオープンソースです。

特にここでリンクしていませんが、すべてDockerfileがgithubにあります。
OpenStackを自分で建ててAWSを代替するほど大変ではありませんのでご安心を!

NextCloud

代替対象: Dropbox, Google Drive, One Drive

Nextcloud

ファイルをどんどんおいて、共有したり共有しなかったり、プラグインで遊んだりと様々なことができます。

PHPで動いているせいかちょっと重いこともあるのですが、安定稼働するとかなり便利です。

OnlyOfficeを追加すると、Google DocumentsやOffice 365の代わりにもなります。
どこまで使えるかどうかは人によるとはおもいますが、たいして複雑なオフィス文書の機能を使っていな私にとってはこれで十分です。

DAVも話せるので、DAVに写真をバックアップするようなアプリをスマホにいれておけば、Google PhotoやiCloud Photoの代わりにもなります。
画像認識のような賢いことはしてくれませんが、そのへんは自分でqiitaにたくさんあるAI関連記事に従って頑張りましょう。

nextcloud - Qiita

gitbucket

代替対象: github

GitHub - gitbucket/gitbucket: A Git platform powered by Scala with easy installation, high extensibility & GitHub API compatibility

恥ずかしいコードも秘密のコードもgithubに置かなくてOK!

GitBucketをdockerで構築 - Qiita

wallabag

代替対象: Pocket

GitHub - wallabag/wallabag: wallabag is a self hostable application for saving web pages: Save and classify articles. Read them later. Freely.

以下に細かいお話があるのでどうぞ。

「後で読む」サービスのwallabagを自分で建てよう - Qiita

freshrss

代替対象: Feedly

FreshRSS, a free, self-hostable aggregator…

RSSリーダです。

ちなみにうちでは、ファームウェア更新告知や声優さん等のwebのhtmlをとってきて、xpathや正規表現でゴミを捨ててからgitbucketにdiffを蓄積し、差分とスクショをfreshrssに出す自前プログラムを動かしています。
「はてなアンテナ」の代替ですね。
転売屋はこういうのを真剣にやって、在庫復活を捉えているんでしょうね...

Leanote

代替対象: Evernote, Notion, Google Note

Leanote - open source alternative to Evernote · GitHub

日本ではあまり知られていないソフトですが、中国の人が開発しているようです。
Evernoteの代わりになります。
デスクトップアプリやiOSアプリもあります。
かなりよく出来ていて、お陰様で最近の私はEvernoteへの依存度がかなりヘリました。

markdownも使えますし、ビジュアルなエディッタも使えます。
デスクトップアプリからはenmlのインポートができます。
REST APIもあります。

標準ですといわゆる中華フォントなのですが、ソースのある場所で、

grep -l Hiragino -r . | xargs perl -i.bak -pe 's/Hiragino Sans GB/Hiragino Sans/g;'

という呪文を唱えるとあら不思議、日本語フォントになります(一部追加修正が必要)。
githubも中国語が多いですが、日本語話者でもだいたい何書いてあるかくらいはわかるし英語での質問には英語で答えてくれているのでそんなに困りません。
排外主義者・国粋主義者・右翼にはおすすめできないかもしれませんが、普通の人には普通におすすめできるソフトです。

myTinyTodo

代替対象: todoist, wondrlist

myTinyTodo - simple open source to-do list script written in PHP and jQuery

ToDo管理です。
課金Todoistのような細かいことはできないので、Todoistのカルマを大量に貯めるような生活をしている私にとってはあまり使えないのですが...

wekan

代替対象: Trello

Wekan — Open-Source kanban

カンバン型タスク管理ツールです。
左にある「未着手」を右にある「進行中」にすすめていくあれです。

WekanをDockerで立てる! - Qiita

vimflowy

代替対象: workflowy

GitHub - WuTheFWasThat/vimflowy: An open source productivity tool drawing inspiration from workflowy and vim
Vimflowy

ただひたらす箇条書きするものです。
日本語は環境によってはちょっと挙動が怪しいことがあります。
githubにパッチがあるので当てましょう。

開発が止まっていますが、Hackflowyというものもあります。
こちらはwebsocketを大量に生成する、日本語のキーイベント(229)が遅い等の問題が多くて実用できませんでした?

GitHub - abhshkdz/HackFlowy: Workflowy clone, built using Backbone.js & Socket.io

agendav

代替対象: Googleカレンダー

GitHub - agendav/agendav: A CalDAV web client similar to Google Calendar

caldavのwebインターフェイスです。
なので背後にcaldavサーバを置くと、なんとgoogleカレンダーのようなものができます。
caldavサーバにはbaikalが使えます。

Baïkal - baikal

rainloop

代替対象: gmail

GitHub - RainLoop/rainloop-webmail: Simple, modern & fast web-based email client

imapのwebインターフェイスです。
なので背後にimapサーバをおくと、なんと(以下略

RainLoop - Qiita

jitsi

代替対象: Zoom, WebEX

Jitsi Meet

Mattermost

代替対象: Slack

Mattermost: Open-source, high-trust, developer-centric collaboration platform

私はまだこれらを建てたことがないのですが、今どきのブラウザならカメラもマイクも使えるわけで...

overleaf

代替対象: overleaf

GitHub - overleaf/overleaf: A web-based collaborative LaTeX editor

代替もなにももとからですので、これをここにリストするのは問題があるかもしれませんが(笑)。

Overleafを使った日本語論文の作成 - Qiita

webssh

代替対象: ssh

GitHub - huashengdun/webssh: Web based ssh client

webサービス代替というのとは少し違いますが、ブラウザからsshできるようになります。
便利なのかセキュリティホールなのかは微妙な気もしますが、何かあったときに便利かもしれません...

おわりに

と、これらのソフトの作者の皆様のおかげで、我々はプライバシーと財布をサブスク課金クラウドから取り返すことができます。
企業で建てたいけど面倒・管理が心配、という方は弊社までご連絡ください(嘘です... あ、大金つまれればやりますよw それで「プライバシーと財布」が戻ってくるかどうかは知りませんw)。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

よさげな動画配信プラットフォームOSS「Streama」を紹介します

Streamaとは

https://github.com/streamaserver/streama

Ever had a huge bookshelf full of shows and movies? Ever wanted to digitalize them, but didn't have a good way of organizing the files? Worry no more! Streama is your own personal Netflix for just such a purpose!

ショーや映画の巨大な本棚を持っていたことはありますか?今までそれらをデジタル化したいと思ったが、ファイルを整理する良い方法を持っていませんでしたか?もう心配しないでください! Streamaはちょうどそのような目的のためのあなた自身の個人的なNetflixです!
※DeepLによる翻訳

つまり、NetFlix風の動画配信プラットフォーム!!

デモ環境

こちらから
以下のユーザー名とパスワードを入力して利用してください
credentials: username: demoUser | password: demoUser

想定される利用者

  • 個人が所有する動画を管理、閲覧したい方
  • 組織で利用する動画を管理、配信したい方
  • 動画配信プラットフォームとして商用利用したい方

※2020/12/04時点では商用利用可と記載されている

推奨実行環境

https://docs.streama-project.com/getting-started/installing/

公式より以下

  • Ubuntu (バージョン指定無し)
    • Ubuntuを推奨
    • Linuxであれば問題無いとのこと
  • Java8
    • Java7とJava10だと動かない可能性がある

ですが、公式がdocker-compose.ymlを用意してくれているので、
そちらを利用することも可能です

構築手順

  1. 公式リポジトリをクローンする
$ git clone https://github.com/streamaserver/streama
  1. クローンしたディレクトリから/streama/dockerへ移動する
$ cd ./streama/docker
  1. コンテナを立ち上げる
$ docker-compose up -d
  1. http://localhostへブラウザからアクセスする image.png

所感

このStreamaの細かい仕様は公式HPよりご確認ください

これまでは

上記の選択肢が有名であったが

  • 導入がヘビー
  • 高機能すぎる

などの障壁を感じていた

しかし、Streamaは簡易なカスタマイズも簡単そうな印象がある

日本ではほぼ無名のアプリケーションではあるが
リモートや非同期の情報共有が多い時代になってきたので
この手のアプリケーションの需要も高まっているはず

今後の発展と普及を期待しつつ
今後も経過を見ていきたい

編集後記

今回たまたま、幼稚園や学校のイベントの動画共有の相談を受け調べてみたところStreamaを見つけた

数年前だとPHPTubeが本命かと思ったがアンテナ高くしておくと良いものと巡り合う機会も増えるなーと思ったところです

今後も便利そうなOSSを紹介できればと思います

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む