20201114のdockerに関する記事は18件です。

pythonをインストールしてるのにimportエラー

VScodeでpythonをインストールしているのにimportエラーが起きている。

スクリーンショット 2020-11-14 22.52.07.png

解決策

簡単な話、pythonをアンインストールしたら改善した。

これはおそらくdockerが原因だと思われる。

ようはdocker上でpythonをインストールしているにも関わらずVScode側にもPythonが存在しているため、干渉しあいエラーが引き起こされているのではないか。

少し調べてみると存在しているPythonのバージョンが違うとこのようなエラーが起きてしまうらしい。

dockerを使うさいにはご注意を。

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

MySQL操作でよく使うコマンド一覧

MySQLの操作で使用する事の多いコマンドを一覧形式でまとめます。

MySQLにログイン

mysql -u ユーザー名 -p

を入力した後パスワードを入力。
パスワードはCLI上には表示されないので打ち間違いに注意。

非推奨だが、-pの引数にパスワードを渡すと一発でログインもできる。

データベース一覧を表示

SHOW DATABASES;

こんな感じで一覧が表示される。

mysql> SHOW databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| myapp_development  |
| myapp_test         |
| mysql              |
| performance_schema |
| root               |
| sys                |
+--------------------+
7 rows in set (0.00 sec)

information_schemaとは?
performance_schemaとは

テーブル一覧を表示する

まずは使用するデータベースを選択します。

use データベース名;
ex)use users;

※コマンドの最後に「;」をつけ忘れないように注意。
データベースを選択したら、以下のコマンドを実行。

SHOW TABLES;

データベース内のテーブルを一覧で取得できます。

mysql> SHOW TABLES;
+----------------------+
| Tables_in_myapp_test |
+----------------------+
| posts                |
| schema_migrations    |
| users                |
+----------------------+
3 rows in set (0.01 sec)

※データベースを選択していない状態でも、

show tables from データベース名;

で取得できる。

テーブル内のカラム一覧を取得する。

先ほどと同じくデータベースを選択。
以下のコマンドを実行。

DESCRIBE テーブル名;
show columns from テーブル名;

ex)use users;

こんな感じでテーブル内のカラム一覧を取得できる。

mysql> show columns from users;
+-----------------------------+--------------+------+-----+---------+----------------+
| Field                       | Type         | Null | Key | Default | Extra          |
+-----------------------------+--------------+------+-----+---------+----------------+
| id                          | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| email                       | varchar(255) | NO   | UNI | NULL    |                |
| created_at                  | datetime     | NO   |     | NULL    |                |
| updated_at                  | datetime     | NO   |     | NULL    |                |
| name                        | varchar(255) | NO   |     | NULL    |                |
| image                       | varchar(255) | YES  |     | NULL    |                |
+-----------------------------+--------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)

Docker環境でMySQLと接続

・docker-compose upでコンテナを立ち上げる。
・docker-compose exec db bash
・mysql -u ユーザー名 -pでDBコンテナに接続

ECS/EC2コンテナからRDSに接続

・タスクを立ち上げ
・sshでEC2と接続
・docker exec -it コンテナID sh
・mysql -h エンドポイント -u ユーザー名 -pでRDSと接続

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

MySQL操作でよく使うコマンド

MySQLの操作における以下のコマンドをまとめます。

・MySQLにログイン
・データベース一覧を表示
・テーブル一覧を表示
・カラム一覧を表示

MySQLにログイン

mysql -u ユーザー名 -p

を入力した後パスワードを入力。
パスワードはCLI上には表示されないので打ち間違いに注意。

非推奨だが、-pの引数にパスワードを渡すと一発でログインもできる。

データベース一覧を表示

SHOW DATABASES;

こんな感じで一覧が表示される。

mysql> SHOW databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| myapp_development  |
| myapp_test         |
| mysql              |
| performance_schema |
| root               |
| sys                |
+--------------------+
7 rows in set (0.00 sec)

information_schemaとは?
performance_schemaとは
sysとは

テーブル一覧を表示する

まずは使用するデータベースを選択します。

use データベース名;
ex)use users;

※コマンドの最後に「;」をつけ忘れないように注意。
データベースを選択したら、以下のコマンドを実行。

SHOW TABLES;

データベース内のテーブルを一覧で取得できます。

mysql> SHOW TABLES;
+----------------------+
| Tables_in_myapp_test |
+----------------------+
| posts                |
| schema_migrations    |
| users                |
+----------------------+
3 rows in set (0.01 sec)

※データベースを選択していない状態でも、

show tables from データベース名;

で取得できる。

テーブル内のカラム一覧を取得する。

先ほどと同じくデータベースを選択。
以下のコマンドを実行。

DESCRIBE テーブル名;
show columns from テーブル名;

ex)show columns from users;

こんな感じでテーブル内のカラム一覧を取得できる。

mysql> show columns from users;
+-----------------------------+--------------+------+-----+---------+----------------+
| Field                       | Type         | Null | Key | Default | Extra          |
+-----------------------------+--------------+------+-----+---------+----------------+
| id                          | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| email                       | varchar(255) | NO   | UNI | NULL    |                |
| created_at                  | datetime     | NO   |     | NULL    |                |
| updated_at                  | datetime     | NO   |     | NULL    |                |
| name                        | varchar(255) | NO   |     | NULL    |                |
| image                       | varchar(255) | YES  |     | NULL    |                |
+-----------------------------+--------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)

Docker環境でMySQLと接続

・docker-compose upでコンテナを立ち上げる。
・docker-compose exec db bash
・mysql -u ユーザー名 -pでDBコンテナに接続

ECS/EC2コンテナからRDSに接続

・タスクを立ち上げ
・sshでEC2と接続
・docker exec -it コンテナID sh
・mysql -h エンドポイント -u ユーザー名 -pでRDSと接続

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

テンプレート: Docker コンテナで Ruby / Rails の開発環境を構築する (Mac版)

手軽に Ruby / Rails の開発環境を構築したいなら Docker が最適です。
ここでは、ホストOSとしてMac OSを使用しています。
(Ubuntuホストの場合はこちらを参照してください)

Dockerコンテナでは、ベースOSをUbuntu 20.04とし、Rails アプリケーションを実行するために必要なライブラリやRuby本体をインストールしていきます。
Railsアプリケーション本体はホストOS上のローカルディレクトリから参照できるようにします。
これはRailsアプリケーションの実行環境をDockerコンテナが担い、エディタによるRailsアプリケーションの編集やソースコード管理をホストOS上で実現するためのものです。

以下のようなメリットがあります。

1.ホストOS上にRubyやRailsを直接インストールする必要がない
2.必要に応じて異なるバージョンのRubyやRailsを別々のコンテナで実行させることも可能
3.RailsソースコードはホストOS上の好みのエディタで編集できる
4.Gitの管理対象をホストOS上のソースコードに限定できる
5.(以下のDockerfile.devもGitの管理対象とすべき)

コンテナの構築と起動

あらかじめDockerサービスをホストOS上にインストールしておいてください。

まずは、任意のディレクトリに以下のファイルを配置します。

Dockerfile.dev
# Docker による Ruby / Rails 開発環境の構築
#
# 任意バージョンの Ruby を Ubuntu ベースのコンテナ上にインストールする
# また、node.js をインストールする
# Rails アプリケーションは、コンテナ内ではなく、ホストOSのローカルディレクトリに生成する

From ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive

# Ubuntu にインストールされているソフトウェアを最新にする
RUN apt-get update -y
RUN apt-get upgrade -y

# Ruby のビルドに必要なパッケージを apt-get 経由でインストールする
RUN apt-get install -y build-essential
RUN apt-get install -y libssl-dev libreadline-dev zlib1g-dev
RUN apt-get install -y git wget 

# sqlite3 を利用する場合に必要なライブラリ
RUN apt-get install libsqlite3-dev

# MySQL or MariaDB を利用する場合に必要なライブラリ
RUN apt-get install -y libmysqlclient-dev

# その他の便利ツール
RUN apt-get install -y nano

# ruby-build を使って任意の Ruby バージョンをインストールする
RUN git clone --depth=1 https://github.com/rbenv/ruby-build
RUN PREFIX=/usr/local ./ruby-build/install.sh
RUN rm -rf ruby-build
RUN ruby-build 2.7.2 /usr/local

# node.js, npmをインストール
RUN apt-get install -y nodejs npm
# n packageをインストール
RUN npm install n -g
# n packageを使ってnodeをインストール
RUN n stable
# 最初に入れた古いnode.js, npmを削除
RUN apt-get purge -y nodejs npm
# yarn packageをインストール
RUN npm install yarn -g

以下はコンテナの生成方法
(your_app_nameをあなたのアプリケーション名に変更する)

$ export YOURAPP=your_app_name
$ docker build -t $YOURAPP -f Dockerfile.dev .

コンテナを起動する

$ export REPO=`pwd`
$ docker run -d --name $YOURAPP -v $REPO/:/$YOURAPP/ -p 4000:3000 -ti $YOURAPP

コンテナ内で Rails アプリケーションを生成する

コンテナ上のbashを起動し、Railsアプリケーションを構築していきます。

$ docker exec -ti $YOURAPP bash

あなたのアプリケーションディレクトリに移動する
(your_app_nameをあなたのアプリケーション名に変更する)

$ cd /your_app_name

bundle init を実行して Gemfile ファイルを作成

$ bundle init

Gemfile を編集する(以下ではnanoエディタを使用)

$ nano Gemfile

Gemfile内の # gem "rails" のコメントを外す
(# gem "rails" を gem "rails" に変更する)

bundle install により Rails 関連の Gem を vendor/bundle にインストールする

$ bundle config set path 'vendor/bundle'
$ bundle install

rails new により Rails アプリケーションをこのディレクトリで新規に生成する
Overwrite /example/Gemfile? (enter "h" for help) [Ynaqdhm] と尋ねられたら Y と返答する

$ bundle exec rails new .

Rails アプリケーションを起動する
ホスト OS からアクセスできるようにバインドする IP アドレスを 0.0.0.0 にしておく

$ bundle exec rails s -b 0.0.0.0

コンテナ上の作業が完了したので、改めてホスト OS のブラウザで http://localhost:4000 にアクセスする
ブラウザ上で Yay! You’re on Rails! が表示されたら成功です

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

Micronaut + Kotlin のプロジェクトにてMyBatisを使ってデータベースからデータ取得してみる

前回

Micronaut + KotlinでHelloWorld
前回のプロジェクトを拡張し、MyBatisを使ってデータベース接続をしてみます。

実際に作成したリポジトリはこちらになります。

データベースを用意

DockerでPostgreSQLのコンテナを用意します。
前回作成したプロジェクトと同階層に以下を作成しました。

  • DB環境作成用のdocker-compose.yml
docker-compose.yml
version: '3'
services: 
  db:
    image: postgres
    restart: always
    container_name: postgres
    environment: 
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: books
    volumes:
      - ./data/postgres/db-data:/var/lib/postgresql/data
      - ./database:/docker-entrypoint-initdb.d
    ports:
      - 5432:5432
  • テーブル作成用のSQLを格納するdataフォルダとSQL
database/init.sql
set client_encoding = 'UTF8';

CREATE TABLE book (
  id SERIAL,
  name VARCHAR(200) NOT NULL,
  publisher VARCHAR(200),
  publication_date DATE,
  created_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL,
  CONSTRAINT pk_book PRIMARY KEY (id)
);

-- 確認用の初期データ
INSERT INTO book (id, name, publisher, publication_date, created_at, updated_at) VALUES (1, 'テスト書籍1', 'テスト出版社A', null, current_timestamp, current_timestamp);
INSERT INTO book (id, name, publisher, publication_date, created_at, updated_at) VALUES (2, 'テスト書籍2', 'テスト出版社A', null, current_timestamp, current_timestamp);
  • DBデータをGitの管理対象から外すための.gitignore
.gitignore
data

docker-composeのあるフォルダに移動し、コンテナを起動します。

$ docker-compose up -d

これでDBの方の準備はOKです。

プロジェクトの改修

ライブラリの追加

build.gradleを編集し、ライブラリを追加します。

server/build.gradle
dependencies {
    // 省略
    implementation("org.mybatis:mybatis:3.4.6")
    implementation("io.micronaut.sql:micronaut-jdbc-hikari")
    runtimeOnly("org.postgresql:postgresql")
    // 省略
}

接続設定とか追加

application.ymlを編集します。

  • 接続先の追加
  • MyBatisの設定を追加
server/src/main/resources/application.yml
micronaut:
  application:
    name: helloworld
# 以下を追加
datasources:
  default:
    url: jdbc:postgresql://localhost:5432/books
    username: postgres
    password: postgres
    driverClassName: org.postgresql.Driver
mybatis:
  # mapperのxmlファイルを格納する位置を指定
  mapper-locations: classpath:example/mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true
    default-fetch-size: 100
    default-statement-timeout: 30
    cache-enabled: false

モデルの作成

DBから取得したデータを格納するクラスを作成します。

server/src/main/kotlin/example/model/Book.kt
package example.model

import io.micronaut.core.annotation.Introspected
import java.sql.Date

/**
 * 書籍データクラス
 */
@Introspected
data class Book(
        var id: Int?,
        var name: String,
        var publisher: String?,
        var publicationDate: Date?,
)

SqlSessionFactoryの作成

SqlSessionを用意するFactoryクラスを作成します。

server/src/main/kotlin/example/MybatisFactory.kt
package example

import io.micronaut.context.annotation.Factory
import org.apache.ibatis.mapping.Environment
import org.apache.ibatis.session.Configuration
import org.apache.ibatis.session.SqlSessionFactory
import org.apache.ibatis.session.SqlSessionFactoryBuilder
import org.apache.ibatis.transaction.TransactionFactory
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory
import javax.inject.Singleton
import javax.sql.DataSource

@Factory
class MybatisFactory(private val dataSource: DataSource) {

    @Singleton
    fun sqlSessionFactory(): SqlSessionFactory {
        val transactionFactory: TransactionFactory = JdbcTransactionFactory()

        val environment = Environment("dev", transactionFactory, dataSource)
        val configuration = Configuration(environment)
        // mapperをスキャンするパッケージを指定。
        configuration.addMappers("example")

        return SqlSessionFactoryBuilder().build(configuration)
    }
}

Mapperの作成

SQLとのインタフェースとなるMapperを作成します。

server/src/main/kotlin/example/mapper/BookMapper.kt
package example.mapper

import example.model.Book
import org.apache.ibatis.annotations.Mapper

@Mapper
interface BookMapper {
    fun findById(id: Int): Book
}

実行するSQL本体はXMLに記載します。

server/src/main/resources/example/mapper/BookMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="example.mapper.BookMapper">

    <select id="findById" resultType="example.model.Book">
        SELECT
        id,
        name,
        publisher,
        publication_date
        FROM book
        <where>
            id = #{id}
        </where>
    </select>

</mapper>

インタフェースの実装としてServiceクラスを作成します。

server/src/main/kotlin/example/service/BookService.kt
package example.service

import example.mapper.BookMapper
import example.model.Book
import org.apache.ibatis.session.SqlSessionFactory
import javax.inject.Singleton

@Singleton
class BookService(private val sqlSessionFactory: SqlSessionFactory) : BookMapper {

    override fun findById(id: Int): Book {
        sqlSessionFactory.openSession().use { session ->
            val bookMapper = session.getMapper(BookMapper::class.java)
            return bookMapper.findById(id)
        }
    }
}

Controllerの作成

データベースにアクセスするAPIを作成します。

server/src/main/kotlin/example/controller/BookController.kt
package example.controller

import example.mapper.BookMapper
import example.model.Book
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get


@Controller()
class BookController(private val bookMapper: BookMapper) {

    /**
     * 書籍情報の取得。
     * ID指定
     *
     * @param id 書籍ID
     *
     * @return HttpResponse
     */
    @Get("/book/{id}")
    fun readById(id: Int): HttpResponse<Book> {
        return HttpResponse.ok(bookMapper.findById(id))
    }
}

ひとまず完成

ここまで/book/{id}のエンドポイントにアクセスすればデータを取得する動きができました。
試してみます。

サーバを実行します。

$ cd server 
$ ./gradlew run

http://localhost:8080/book/1にアクセスします。

$ curl -X GET  http://localhost:8080/book/1
{"id":1,"name":"テスト書籍1","publisher":"テスト出版社A"}

データベースからデータを取得することができました。

参考

Access a database with MyBatis

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

認証代行プロキシサーバーをDockerを使って構築する

背景

社内の認証ありプロキシサーバーはソフトウェア開発を行う上では邪魔でしかありません.
認証ありプロキシに対応していないアプリ,パスワード変更による毎回の設定変更,開発メンバー間での設定差分……これらの問題にいつも頭を悩まされていました.
そこで調べてみると先人たちがSquidを使って認証代行プロキシサーバーを立てている1ことを知り,私もMac上にSquidを立てて使っていました.(とても便利!)

しかし,開発メンバーから「そんなの使っててセキュリティは大丈夫なの?」,「他のメンバーと環境変わっちゃうからそんなのだめだよ」みたいなことを言われうようになりました.

仕方がないのでMac用の認証代行プロキシ構築スクリプトをメンバーに展開して環境の統一には一応成功しました.
しかし,中身(特にSquid)の仕組みはあんまり展開していないので,もし問題があった場合は自分が見なきゃいけない状況になってしまっており,他プロジェクトへの展開があまりできていない状況です.

今回はDockerのみで極力シンプルに認証代行プロキシサーバーを構築できるようにしたので,その仕組みをSquidの設定を中心に紹介します.

つくったもの

今回は以下リポジトリを紹介します.
最新の情報はここを参照するようにしてください.

https://github.com/k-ishigaki/proxy-docker

前提条件

Docker(Docker Compose)がインストールされていれば動作するはずです.
私が使ったDockerのバージョンは以下でした.

$ docker version
(中略)
Server: Docker Engine - Community
 Engine:
  Version:          19.03.12
  API version:      1.40 (minimum version 1.12)
(後略)
$ docker --version
Docker version 19.03.9, build 9d988398e7
$ docker-compose --version
docker-compose version 1.26.2, build eefe0d31

全体像

Dockerコンテナ上に認証代行プロキシサーバー(Squid)を立てて,認証情報(Authorizationヘッダー)を付与するようにします.
こうすることでプロキシを利用するアプリケーションからは,認証なしでインターネットに接続できるようなります.

alt

Squidの設定

squid.conf.templateの設定を1つずつ説明していきます.

基本的な設定

待受ポートは8080に設定します.
visible_hostnameは設定しないと「未設定だよ」とエラーが表示されるためnoneに設定します2
DNSはONにします.これを設定しておくとドメイン名のプロキシサーバーを指定できるようになります.(ならない環境もあるみたいですが……要因わからずです)

http_port 8080
visible_hostname none
dns_defnames on

ACLの定義

SquidのACL(Access Control)を定義します.
localnetはローカルネットワークからのアクセス,to_localnet_fastはローカルネットワークへのアクセス,to_localhost_fastはローカルホストへのアクセス,to_direct_access_domainsは指定ドメインへのアクセスを定義しています.

dst(デスティネーション)のACLでは-nフラグを指定して,DNS Lookupを無効にしています.有効にしてしまうと,ネットワークアクセスがものすごく低速になります.
また,to_direct_access_domains.direct_access_domainsに指定されたドメインを取り込むように指定しています3

acl localnet src 0.0.0.1-0.255.255.255
acl localnet src 10.0.0.0/8
(中略)
acl to_localnet_fast dst -n 0.0.0.1-0.255.255.255
acl to_localnet_fast dst -n 10.0.0.0/8
(中略)
acl to_localhost_fast dst -n 127.0.0.0/8
acl to_direct_access_domains dstdomain -n "/.direct_access_domains"

Squidへのアクセス許可

Squidへのアクセスを許可するネットワークを指定します.
内部ネットワークからのアクセスのみを許可しています4

http_access allow localhost
http_access allow localnet

認証ありプロキシサーバーへの転送設定

認証ありプロキシサーバーへの転送を行うリクエストを指定します.
Squidはデフォルトでは「cache_peerで指定されたプロキシへの転送を試みて,無理なら直接接続を試みる」動作なので,never_direct allow <直接接続を許可する接続先以外の接続先>で直接接続を禁止する接続先を指定します5

cache_peerで親プロキシ(認証ありプロキシ)を指定します.
$proxy_portなどの変数はDockerコンテナの起動時にenvsubstで置き換えます.

never_direct allow !to_localhost_fast !to_localnet_fast !to_direct_access_domains
cache_peer $proxy_host parent $proxy_port 0 proxy-only no-digest no-netdb-exchange login=$proxy_auth

Squidを秘匿化する設定

SquidなどのプロキシサーバーはデフォルトではPROXY_VIAなどの「プロキシを通していますよ」という情報を乗せる動作となります.
環境によっては通信ヘッダが異なると通信できなくなってしまう可能性があるので,Squidが勝手に乗せる情報を削除します.
また,転送のみの動作とさせるため,cache deny allでSquidのキャッシュを無効化しています.

forwarded_for delete
via off
cache deny all
request_header_access Cache-Control deny all
request_header_access Connection deny all
request_header_add Proxy-Connection "Keep-Alive" all

Dockerでの認証代行プロキシ立ち上げ

Dockerイメージのビルドと起動はDocker Compose経由で行います.
ビルドするのにもプロキシの設定が必要なので,環境変数にHTTP_PROXY_FOR_PROXYを設定してビルド,起動を行うようにします.
ベースイメージ(Alpine)のpullを行うにはDocker Daemon側へのプロキシ設定が必要ですが,Docker実行環境によって設定方法が異なっているので,pullでダウンロードするのではなくloadでローカルのイメージを読み込むようにしています.

<proxy_user><proxy_password>に記号が入っている場合はURLエンコードした値を入れる必要があります.

cd proxy-docker
docker load ./alpine.tar
HTTP_PROXY_FOR_PROXY=http://<proxy_user>:<proxy_password>@<proxy_host>:<proxy_port> HOST_PORT=8080 docker-compose up -d

Docker Composeの設定

docker-compose.ymlにビルド,起動を行うときのパラメータを定義しています.
HTTP_PROXYHTTPS_PROXYargs(ビルド時の環境変数),environment(起動時の環境変数)に入れるようにしています.
また,HOST_PORTでホスト側のポートを設定できるようにしています.
8080ポートが既に埋まっている場合は別のポートを指定できます.

version: "3.4"

x-proxy_settings: &proxy_settings
    HTTP_PROXY: "${HTTP_PROXY_FOR_PROXY:?HTTP_PROXY_FOR_PROXY must be set. Prease read README}"
    HTTPS_PROXY: "${HTTP_PROXY_FOR_PROXY}"

services:
    proxy:
        build:
            context: .
            args:
                <<: *proxy_settings
        environment:
            <<: *proxy_settings
        ports:
            - "${HOST_PORT:-8080}:8080"

Dockerfileの設定

長いので中身は割愛しますが,以下を行っています.

  • ビルド時
    HTTP_PROXYに設定された値を使ってインターネットに接続し,Squidをインストール
  • 起動時
    HTTP_PROXYに設定された値を使ってSquidの設定ファイルを修正,Squidを立ち上げ

まとめ

Squidを使った認証代行プロキシサーバーの設定について,それをDockerで立ち上げる方法について簡単に紹介しました.
これらの情報を使って少しでも多くの方が認証ありプロキシの不便から脱却できることを願っています.


  1. 認証ありプロキシを認証なしにするDockerコンテナとか,squid で認証ありプロキシによるストレスを軽減するとか,mac上にHTTPプロキシを立てることで認証プロキシの認証をスキップするとか,他にもたくさんあります. 

  2. squidを久々に起動しようとしたらerrorになる、visible_hostnameを設定やて! 

  3. 社内ポータルサイトなどのプロキシ除外ドメインを簡単に設定できるように別ファイルから取り込むようにしています. 

  4. VirtualBoxなどの仮想環境からのアクセスを許可するために,localhostだけでなくlocalnetからのアクセスも許可しています. 

  5. always_direct allow <直接接続を許可する接続先>としないのはVPN経由で社内ネットワークに接続しているときはプロキシ経由で接続するからです. 

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

Docker コンテナで Ruby / Rails 開発環境を構築する

手軽に Ruby / Rails の開発環境を構築したいなら Docker が最適です。
ここでは、ホストOSとしてUbuntuを使用しています。
Dockerコンテナでは、ベースOSをUbuntu 20.04とし、Rails アプリケーションを実行するために必要なライブラリやRuby本体をインストールしていきます。
Railsアプリケーション本体はホストOS上のローカルディレクトリから参照できるようにします。
これはRailsアプリケーションの実行環境をDockerコンテナが担い、エディタによるRailsアプリケーションの編集やソースコード管理をホストOS上で実現するためのものです。

以下のようなメリットがあります。

1.ホストOS上にRubyやRailsを直接インストールする必要がない
2.必要に応じて異なるバージョンのRubyやRailsを別々のコンテナで実行させることも可能
3.RailsソースコードはホストOS上の好みのエディタで編集できる
4.Gitの管理対象をホストOS上のソースコードに限定できる
5.(ただし、以下のDockerfile.devもGitの管理対象とすべき)

コンテナの構築と起動

あらかじめDockerサービスをホストOS上にインストールしておいてください。

まずは、任意のディレクトリに以下のファイルを配置します。

Dockerfile.dev
# Docker による Ruby / Rails 開発環境の構築
#
# 任意バージョンの Ruby を Ubuntu ベースのコンテナ上にインストールする
# また、node.js をインストールする
# Rails アプリケーションは、コンテナ内ではなく、ホストOSのローカルディレクトリに生成する

From ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive

# ローカルと同じユーザを作成する
ARG uid=unknown
ARG user=unknown
RUN useradd -m -u ${uid} ${user}

# Ubuntu にインストールされているソフトウェアを最新にする
RUN apt-get update -y
RUN apt-get upgrade -y

# Ruby のビルドに必要なパッケージを apt-get 経由でインストールする
RUN apt-get install -y build-essential
RUN apt-get install -y libssl-dev libreadline-dev zlib1g-dev
RUN apt-get install -y git wget 

# sqlite3 を利用する場合に必要なライブラリ
RUN apt-get install libsqlite3-dev

# MySQL or MariaDB を利用する場合に必要なライブラリ
RUN apt-get install -y libmysqlclient-dev

# その他の便利ツール
RUN apt-get install -y nano

# ruby-build を使って任意の Ruby バージョンをインストールする
RUN git clone --depth=1 https://github.com/rbenv/ruby-build
RUN PREFIX=/usr/local ./ruby-build/install.sh
RUN rm -rf ruby-build
RUN ruby-build 2.7.2 /usr/local

# node.js, npmをインストール
RUN apt-get install -y nodejs npm
# n packageをインストール
RUN npm install n -g
# n packageを使ってnodeをインストール
RUN n stable
# 最初に入れた古いnode.js, npmを削除
RUN apt-get purge -y nodejs npm
# yarn packageをインストール
RUN npm install yarn -g

以下はコンテナの生成方法
(your_app_nameをあなたのアプリケーション名に変更する)

$ export YOURAPP=your_app_name
$ docker build -t $YOURAPP --build-arg uid=$(id -u $USER) --build-arg user=$USER -f Dockerfile.dev .

コンテナを起動する

$ export REPO=`pwd`
$ docker run -d --name $YOURAPP -v $REPO/:/$YOURAPP/ -p 4000:3000 -v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro -u $(id -u $USER):$(id -g $USER) -ti $YOURAPP

コンテナ内で Rails アプリケーションを生成する

$ docker exec -ti $YOURAPP bash

あなたのアプリケーションディレクトリに移動する
(your_app_nameをあなたのアプリケーション名に変更する)

$ cd /your_app_name

bundle init を実行して Gemfile ファイルを作成

$ bundle init

Gemfile を編集する(以下ではnanoエディタを使用)

$ nano Gemfile

Gemfile内の # gem "rails" のコメントを外す
(# gem "rails" を gem "rails" に変更する)

bundle install により Rails 関連の Gem を vendor/bundle にインストールする

$ bundle config set path 'vendor/bundle'
$ bundle install

rails new により Rails アプリケーションをこのディレクトリで新規に生成する
Overwrite /example/Gemfile? (enter "h" for help) [Ynaqdhm] と尋ねられたら Y と返答する

$ bundle exec rails new .

Rails アプリケーションを起動する
ホスト OS からアクセスできるようにバインドする IP アドレスを 0.0.0.0 にしておく

$ bundle exec rails s -b 0.0.0.0

コンテナ上の作業が完了したので、改めてホスト OS のブラウザで http://localhost:4000 にアクセスする
ブラウザ上で Yay! You’re on Rails! が表示されたら成功です

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

テンプレート: Docker コンテナで Ruby / Rails の開発環境を構築する(Ubuntu版)

手軽に Ruby / Rails の開発環境を構築したいなら Docker が最適です。
ここでは、ホストOSとしてUbuntuを使用しています。
(Macホストの場合はこちらを参照してください)

Dockerコンテナでは、ベースOSをUbuntu 20.04とし、Rails アプリケーションを実行するために必要なライブラリやRuby本体をインストールしていきます。
Railsアプリケーション本体はホストOS上のローカルディレクトリから参照できるようにします。
これはRailsアプリケーションの実行環境をDockerコンテナが担い、エディタによるRailsアプリケーションの編集やソースコード管理をホストOS上で実現するためのものです。

以下のようなメリットがあります。

1.ホストOS上にRubyやRailsを直接インストールする必要がない
2.必要に応じて異なるバージョンのRubyやRailsを別々のコンテナで実行させることも可能
3.RailsソースコードはホストOS上の好みのエディタで編集できる
4.Gitの管理対象をホストOS上のソースコードに限定できる
5.(以下のDockerfile.devもGitの管理対象とすべき)

コンテナの構築と起動

あらかじめDockerサービスをホストOS上にインストールしておいてください。

まずは、任意のディレクトリに以下のファイルを配置します。

Dockerfile.dev
# Docker による Ruby / Rails 開発環境の構築
#
# 任意バージョンの Ruby を Ubuntu ベースのコンテナ上にインストールする
# また、node.js をインストールする
# Rails アプリケーションは、コンテナ内ではなく、ホストOSのローカルディレクトリに生成する

From ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive

# ローカルと同じユーザを作成する
ARG uid=unknown
ARG user=unknown
RUN useradd -m -u ${uid} ${user}

# Ubuntu にインストールされているソフトウェアを最新にする
RUN apt-get update -y
RUN apt-get upgrade -y

# Ruby のビルドに必要なパッケージを apt-get 経由でインストールする
RUN apt-get install -y build-essential
RUN apt-get install -y libssl-dev libreadline-dev zlib1g-dev
RUN apt-get install -y git wget 

# sqlite3 を利用する場合に必要なライブラリ
RUN apt-get install libsqlite3-dev

# MySQL or MariaDB を利用する場合に必要なライブラリ
RUN apt-get install -y libmysqlclient-dev

# その他の便利ツール
RUN apt-get install -y nano

# ruby-build を使って任意の Ruby バージョンをインストールする
RUN git clone --depth=1 https://github.com/rbenv/ruby-build
RUN PREFIX=/usr/local ./ruby-build/install.sh
RUN rm -rf ruby-build
RUN ruby-build 2.7.2 /usr/local

# node.js, npmをインストール
RUN apt-get install -y nodejs npm
# n packageをインストール
RUN npm install n -g
# n packageを使ってnodeをインストール
RUN n stable
# 最初に入れた古いnode.js, npmを削除
RUN apt-get purge -y nodejs npm
# yarn packageをインストール
RUN npm install yarn -g

以下はコンテナの生成方法
(your_app_nameをあなたのアプリケーション名に変更する)

$ export YOURAPP=your_app_name
$ docker build -t $YOURAPP --build-arg uid=$(id -u $USER) --build-arg user=$USER -f Dockerfile.dev .

コンテナを起動する

$ export REPO=`pwd`
$ docker run -d --name $YOURAPP -v $REPO/:/$YOURAPP/ -p 4000:3000 -v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro -u $(id -u $USER):$(id -g $USER) -ti $YOURAPP

コンテナ内で Rails アプリケーションを生成する

コンテナ上のbashを起動し、Railsアプリケーションを構築していきます。

$ docker exec -ti $YOURAPP bash

あなたのアプリケーションディレクトリに移動する
(your_app_nameをあなたのアプリケーション名に変更する)

$ cd /your_app_name

bundle init を実行して Gemfile ファイルを作成

$ bundle init

Gemfile を編集する(以下ではnanoエディタを使用)

$ nano Gemfile

Gemfile内の # gem "rails" のコメントを外す
(# gem "rails" を gem "rails" に変更する)

bundle install により Rails 関連の Gem を vendor/bundle にインストールする

$ bundle config set path 'vendor/bundle'
$ bundle install

rails new により Rails アプリケーションをこのディレクトリで新規に生成する
Overwrite /example/Gemfile? (enter "h" for help) [Ynaqdhm] と尋ねられたら Y と返答する

$ bundle exec rails new .

Rails アプリケーションを起動する
ホスト OS からアクセスできるようにバインドする IP アドレスを 0.0.0.0 にしておく

$ bundle exec rails s -b 0.0.0.0

コンテナ上の作業が完了したので、改めてホスト OS のブラウザで http://localhost:4000 にアクセスする
ブラウザ上で Yay! You’re on Rails! が表示されたら成功です

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

OPcacheが有効になっているPHP-FPMをRead Onlyコンテナで動かす

環境

PHP7.3 opcache Docker php-fpm

前提

  • OPcache
    • キャッシュ有効化
    • file_cache_onlyが無効
    • lockfile_pathが/tmp
  • PHP-FPM
    • pidへのファイルパスなし
  • Docker
    • Read Only mode

方法

opcacheのロックファイルが作成される/tmpにvolumeをマウントします。

docker run -d -p 9000:9000 --read-only -v $(pwd)/tmp:/tmp php:7.3-fpm-alpine3.12

解説

なぜ/tmpにvolumeをマウントさせるのかを説明します。
opcacheは共有メモリにキャッシュするためにロックファイルが必要です。
zend_shared_alloc_create_lock関数内で、mkstempをコールして/tmpにロックファイルを作成します。
作成失敗の場合は、Unable to create lock fileというエラーメッセージを出力後に異常終了します。

ロックファイルの作成関数
void zend_shared_alloc_create_lock(char *lockfile_path)
{
    int val;

#ifdef ZTS
    zts_lock = tsrm_mutex_alloc();
#endif

    snprintf(lockfile_name, sizeof(lockfile_name), "%s/%sXXXXXX", lockfile_path, SEM_FILENAME_PREFIX);
    lock_file = mkstemp(lockfile_name);
    fchmod(lock_file, 0666);

    if (lock_file == -1) {
        zend_accel_error(ACCEL_LOG_FATAL, "Unable to create lock file: %s (%d)", strerror(errno), errno);
    }
    val = fcntl(lock_file, F_GETFD, 0);
    val |= FD_CLOEXEC;
    fcntl(lock_file, F_SETFD, val);

    unlink(lockfile_name);
}

zend_shared_alloc_create_lockはzend_shared_alloc_startupからコールされ、実行時設定のlockfile_pathを引数として渡します。

zend_shared_alloc_create_lockの呼び出し元
int zend_shared_alloc_startup(size_t requested_size)
{
/* 省略 */

#ifndef ZEND_WIN32
    zend_shared_alloc_create_lock(ZCG(accel_directives).lockfile_path);
#else
    zend_shared_alloc_create_lock();
#endif

Reference

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

Dockerについて理解した後、実際に導入してみました。

1 本記事について

明日から新しい職場でDockerというものを使うっぽいのですが、よく(というかほぼ何も)分からないので、調べてみました。

2 Dockerとは

そもそもDockerとは何なのか分からないので調べてみました。

Dockerとは、ひとことでいうと「Linux上で動作するシンプルで使いやすい軽量コンテナ環境」です。 LinuxというOS上にコンテナという箱を用意し、そのコンテナの中に必要なソフトウェアやライブラリ(ツール)などをインストールしてひとつのまとまりとしてパッケージングすることができます。

引用元:開発環境にDockerを導入し開発を効率化する話〜開発本部・TechLunch〜


Dockerは、インフラ関係やDevOps界隈で注目されている技術の一つで、Docker社が開発している、コンテナ型の仮想環境を作成、配布、実行するためのプラットフォームです。
Dockerは、Linuxのコンテナ技術を使ったもので、よく仮想マシンと比較されます。VirtualBoxなどの仮想マシンでは、ホストマシン上でハイパーバイザを利用しゲストOSを動かし、その上でミドルウェアなどを動かします。それに対し、コンテナはホストマシンのカーネルを利用し、プロセスやユーザなどを隔離することで、あたかも別のマシンが動いているかのように動かすことができます。そのため、軽量で高速に起動、停止などが可能です。

引用元:Docker入門(第一回)~Dockerとは何か、何が良いのか~

Dockerというコンテナ環境で開発を行うと、その環境をパッケージング化できて何かと便利ということみたいです。

3 Dockerのインストール

公式ドキュメントに沿って、ubuntu上で、Dockerのインストールをしていきます。

3.1 念のため古いバージョンのDockerをアンインストール

古いバージョンのDockerをインストールしている可能性が微粒子レベルで存在するので削除コマンドを実行します。やらなくても良いみたいです。

$ sudo apt-get remove docker docker-engine docker.io containerd runc

Package 'XXXX' is not installed, so not removedみたいなのが出てくればOKです。

3.2 パッケージインデックスを更新・aptがリポジトリを利用できるようパッケージをインストール

Dockerをインストールするために必要なパッケージをインストールします。主にaptがHTTPSに対応していないのを補う目的があるみたいです。

$ sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common

3.3 公式GPGキーを追加

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

何をしているのかよく分からないので、ちょっと詳しく見ます。

3.3.1 curlとは

3.2でcurlをインストールしているので、curlコマンドが使えるようになっています。curlコマンドは何かというと、

引数にURLを指定すると、そのURLのファイルをダウンロードします。デフォルトの出力先は「標準出力」なので、リダイレクトで保存するか、「-O」オプションまたは「-o」オプションを指定します。

引用元:【 curl 】コマンド――さまざまなプロトコルでファイルをダウンロード(転送)する

curlコマンドはダウンロードするコマンドです。(-fsSLはそのオプションです。今回は省略します。)

3.3.2 GPGとは

curlコマンドの引数のURLはDockerのGPGのURLになっています。curlコマンドはダウンロードするコマンドなので、DockerのGPGをダウンロードすることになります。GPGとはGnuPGの略で、これは何なのかというと、

公開鍵でファイルの署名を検証したり、公開鍵と秘密鍵のペアでメールの暗号化・復号化を行ったり署名を添付したりするツール。

引用元:GnuPG | IT用語辞典 | 大塚商会

つまり、認証に必要な鍵のことと思っておけばよさそうです。

3.3.3 apt-keyとは

DockerのGPGをapt-keyに渡しています。apt-keyとは何かというと、

「apt-key」は、「apt」が パッケージの認証に使用するキーの一覧を管理するコマンドです。Ubuntu公式以外からパッケージを取得するには、このコマンドで認証する鍵情報を取り込んでおく必要があります。

引用元:apt ・ apt-keyの使い方|npaka|note

つまり、DockerをインストールするためにはDockerのGPGをローカルのapp-keyに取り込んでおく必要がある、ということみたいです。

3.4 キーの確認

GPGキーが追加されていることを確認します。DockerのGPGキーのフィンガープリントは「9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88」なので、この下8桁で以下のように検索し、結果が表示されればOKです。

$ sudo apt-key fingerprint 0EBFCD88
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]

3.5 stableリポジトリを設定

$sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

【Ubuntu】PPAを追加・削除する方法について | Hbk project

この記事を見ると、何のための作業なのかわかりやすいと思います。aptをつかってインストールできるパッケージは、デフォルトでは/etc/apt/source.listにあるものだけです。つまり、Dockerをインストールするためには、PPA(Personal Package Archive)を追加する必要があるということですね。

3.6 インストールの実行

アプトのパッケージインデックスを更新し、インストールを実行します。

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

これでDockerのインストールが完了しました。

4 Dockerを使ってみる

ここからが本番です。公式ドキュメントに沿って実際にDockerを使ってみます。

4.1 オリエンテーション

まずはDockerが動くか確認します。

4.1.1 バージョンの確認

本当にDockerがインストールされているか確認します。

$ docker --version
Docker version 19.03.12, build 48a66213fe

されていました。

4.1.2 hello-worldイメージを実行

hello-worldイメージを取得します。

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
ca4f61b1923c: Pull complete
Digest: sha256:ca0eeb6fb05351dfc8759c20733c91def84cb8007aa89a5bf606bc8b315b9fc7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

何をしているのかは以下のサイトを参考にするとわかりやすいです。

Docker入門(第二回)~Dockerセットアップ、コンテナ起動~ | さくらのナレッジ

Docker Hubとよばれるコンテナ共有サービスにある、公式のイメージ「hello-world」を取得し、それをもとにコンテナを起動させた形になります。

参考:hello-worldイメージのページ

4.1.3 イメージがダウンロードされていることの確認

$ docker image ls

hello-worldのイメージがあるのが確認できると思います。

4.1.4 コンテナが起動していることの確認

docker runは元々イメージを取得するコマンドではなくイメージを元にコンテナを起動するコマンドですので、コンテナが起動しているはずです。

$ docker ps --all

CONTAINER ID     IMAGE           COMMAND      CREATED            STATUS
54f4984ed6a8     hello-world     "/hello"     20 seconds ago     Exited (0) 19 seconds ago

確かにコンテナが確認できました。

4.2 イメージのビルド&コンテナの実行

Dockerを動かすことができたので、次はイメージをビルド・実行していきます。

4.2.1 掲示板アプリのgit cloneを作成

テスト用の掲示板アプリのクローンを作成します。

$ git clone https://github.com/dockersamples/node-bulletin-board

4.2.2 イメージのビルド

イメージをビルドします。

$ cd node-bulletin-board/bulletin-board-app
$ docker build --tag bulletinboard:1.0 .

4.1.2にあるように、コンテナを起動させるにはイメージが必要です。4.1.2では公式のイメージを持ってきましたが、コンテナ環境は開発環境の数だけあるため、独自のイメージが必要となります(探せば誰かがDockerHubに公開しているものが使えるかもしれませんが)。ビルドとは既にあるイメージ(ベースイメージ)を元に、新しいイメージを作成することです。ビルドは、Dockerfileがおかれている場所で実行し、Dockerfileを元に実行されます。

Dockerfileを見てみましょう。

Dockerfile
FROM node:current-slim

WORKDIR /usr/src/app
COPY package.json .
RUN npm install

EXPOSE 8080
CMD [ "npm", "start" ]

COPY . .

1行目の「FROM node:current-slim」に注目してください。「node:current-slim」というベースイメージを元に、新しいイメージをビルドするという記述です。先ほど実行したコマンドの引数に当たる「bulletinboard:1.0 .」という名前のイメージが作成されました。実際にイメージが作成されているか確認してみます。

$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
bulletinboard       1.0                 789f62d53520        13 minutes ago      177MB
node                current-slim        3aaf4acbaad7        2 days ago          159MB
hello-world         latest              bf756fb1ae65        10 months ago       13.3kB

ベースイメージ、およびビルドされたイメージが確認できました。

4.2.3 コンテナを起動

作成したイメージを元にコンテナを起動します。

$ docker run --publish 8000:8080 --detach --name bb bulletinboard:1.0

ブラウザでlocalhost:8000にアクセスし、掲示板アプリが動作していることが確認できます。
これについて、細かく見ていきます。

4.2.3.1 --publish 8000:8080

8000がホスト側のポート番号、8080がコンテナ側のポート番号です。

4.2.3.2 --detach

コンテナをバックグラウンドで起動する際に使うオプションです。

4.2.3.3 --name bb bulletinboard:1.0

「bulletinboard:1.0」というイメージを元に「bb」という名前のコンテナを起動します。

4.2.4 コンテナを停止

コンテナを停止・削除します。

docker rm --force bb

これで無事、イメージのビルドとコンテナ化の理解ができました。

5 最後に

Dockerを利用したコンテナ環境の構築や配布のイメージがあらかたつかめたのでよかったです。

Twitterのフォローもお願いします!

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

Dockerの導入--その①--

背景

  • 会社でDocker環境で開発しているが、よくわからないので自分で環境を作ってみようと思ったため。

やること

  • githubでリポジトリの作成
  • 作成したリポジトリとローカル環境の同期
  • githubとdockerの同期

必要なもの

  • githubのアカウント
  • dockerhubのアカウント

1.githubでリポジトリの作成

  • githubの右上の「+」ボタンからリポジトリを作成。  これは普通に書いてある通りにすれば誰でもできる。

2.作成したリポジトリとローカル環境の同期

  • リポジトリ作成後に表示されるURLをコピー
  • ローカルで同期するディレクトリの作成
init
# ~/Documents配下にディレクトリを作成(作成場所、ディレクトリ名は任意)
mkdir ~/Documents/Sample
# 作成したディレクトリに移動して、クローンする
cd ~/Documents/Sample
git clone [URL]
# これにより ~/Documents/Sample 配下に作成したリポジトリ名でディレクトリが作成される

3.githubとdockerの同期
- まずはgithubとの連携

  • Dockerhubにログイン後、右上の指紋マーク見たいのをクリックし「Account Setting」を選択
  • その後、Linked Accountsを選択し、あとは流れに沿って連携

    • dockerhubでリポジトリの作成
  • メニューバーのRepositoriesを選択、その後CreateAccountを選択

  • NameとDescriptionを入力後下にあるgithubのマークをクリックするとどこのリポジトリと連携するか選べる

とりあえずこれで連携は完了。

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

【UnauthorizedOperation】EC2インスタンス作成時にエラーが起きたので備忘録

概要

DockerホストからEC2インスタンス上でコンテナ起動時にエラーがおきました。
AWSもDockerもDockerマシンも学習中を始めたばかりでエラーが起きたときに手探りで進めているという感覚ですが、解決できたので備忘録としてまとめさせていただきます。また、同じエラーに悩まれている方がいれば、その方の一助となれば幸いです。遠回りをしているかもしれませんが、そのときはご意見を頂きたく存じます。

仮説検証

まずこちらが今回のエラー文です。エラー文から考えられることを仮説検証してエラーを解決していきます。

ターミナル
% docker-machine create --driver amazonec2 --amazonec2-open-port 8000 --amazonec2-vpc-region ap-northeast-1 <EC2インスタンス名>
(EC2インスタンス名) Couldn't determine your account Default VPC ID : "UnauthorizedOperation: You are not authorized to perform this operation.\n\tstatus code: 403, request id: <~~request id~~>"
Error setting machine configuration from flags provided: amazonec2 driver requires either the --amazonec2-subnet-id or --amazonec2-vpc-id option or an AWS Account with a default vpc-id

1.デフォルトのVPCがない

VPCダッシュボードを確認したところ存在していたので、原因はこれではなかったみたいです。vpc-idを引数で直接指定しましたが、それでもEC2インスタンス作成することはできませんでした。

2.UnauthorizedOperation

この操作を操作する権限がないというエラー。

こういうときは極力一次情報を見て解決したほうが今後の応用も効くし間違いない情報なので確認していきました。

さっそく解決方法の手順を踏んで解決していこうかとおもっていたところ、出鼻をくじかれました。

ターミナル
% aws --version

awsのコマンドが使えない command not found:awsというエラー文。

ということでまずはamazon cliのインストールからしていきます。

3.エラーが変わらず出ていたので、権限がないというのはどういうことか現状把握

そもそもIAMユーザーの認証情報を使って、DockerホストからEC2インスタンスを作成しようとしています。そのため、認証情報の記述に問題があるのではないか?と考えました。

そこでまず、環境変数を疑いました。

以前にAWS IAMのアクセスキーを環境変数にいれていた。

今回別のIAMユーザーのアクセスキーを扱っています。ところが、前回作成したIAMユーザーのアクセスキーを環境変数に入れてPATHを通している状態でした。そのIAMには権限を与えていないのでUnauthorizedOperationと警告されているのかなと思いました。
そのため、前回のIAMユーザーのアクセスキー(環境変数)を一度削除しました。ディレクトリごとに、PATHを通す方法のほうが良いかと思いますが、今回は削除いたしました。

以下の記述で設定した環境変数を削除しました。※お使いのPCのバージョンにより設定方法が異なるかもしれません。

ターミナル
 vim ~/.zshrc

iでインサートモード(記述できる)に変える。変更を加えたらesc:wqEnterで完了。

これだとまだPATHが反映されていないので、下記を実行。

ターミナル
source ~/.zshrc

これでDockerホストからEC2インスタンスを作成できる!と思いきや、別のエラーが。

別のエラーが出ましたが、エラーが変わったのを見ると、やはり権限がないIAM(前回作成したIAM)からEC2インスタンスを作成しようとしていたみたいです。

別のエラーというのはファイルの記述が間違っているというエラーでした。( ターミナルのエラーをメモし忘れました。。)
そのため以下~/.aws.credentialsファイルの修正。

修正前
[default]
aws_access_key = <認証キー>
aws_secret_access_key = <認証キー>
修正後
[default]
aws_access_key_id = <認証キー>
aws_secret_access_key = <認証キー>

~/.aws.credentialsファイルを確認。
を作成したときに自動的にファイル内に記述された型をよく見てみると、aws_access_key_idが抜けておりました。
自動生成された型だったので、安心していましたがそんなことはないみたいです。

コード修正後再度、EC2インスタンスの作成を実行。

DockerホストからのEC2インスタンスの作成を成功しました!!

結論

今回はエラーの原因が一つではなかったので、仮説を立て最善なものを選び検証していくしかないのかなと思いました。エラーが起きたときは自分の理解できていない部分が浮き彫りになっていくので、ものすごく勉強になります。今回で言えば、環境変数やAWS、Linuxについても理解が足りていないなと強く感じました。エラーが起きたらそれに関連することも調べなければ解決できないので、エラーが起きてもポジティブに対処していくことで今後に応用していきます。

まとめ

  • エラーが起きた時原因が一つとは限らない。
  • 仮説を立て検証し最善なものを1つ1つエラーを解決していく。
  • 自動生成されたものでも疑う目をもつ(特に環境構築やセキュリティーに関わるところ)。

参考文献

この記事は以下の情報を参考にして執筆しました。

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

Docker+Laravel+Codeception

LaravelでCodeceptionを使用した時の記録

Codeceptionの準備

下のコマンドでインストール

composer require codeception/codeception --dev

下のコマンドでテストに必要なファイルを作成

composer exec codecept bootstrap

seleniumサーバー用意

Acceptionテストに使用するseleniumサーバーを用意する
docker-compose.ymlに下の4行を追加する
yml
selenium:
...
depends_on:
- nginx
links:
- nginx:localhost

サーバー起動

docker-compose up -d selenium

その他の準備

envファイルのコピー

cp .env .env.testing

/tests/functional.suite.yml
yml
actor: FunctionalTester
modules:
enabled:
- Laravel5:
environment_file: .env.testing
- \Helper\Functional

/tests/unit.suite.yml
yml
actor: UnitTester
modules:
enabled:
- Asserts
- Laravel5:
environment_file: .env.testing
- \Helper\Unit

/tests/acceptance.suite.yml
yml
actor: AcceptanceTester
modules:
enabled:
- WebDriver:
url: http://localhost/
browser: chrome
host: selenium
- \Helper\Acceptance

参考

https://codeception.com/for/laravel

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

Angularはじめました

DockerでAngularを試してみた時の記録
サーバー起動中に自動的にソースコード更新の検知とコンパイルを行わせるのに手間取った

環境

Docker for Windows
Angular CLI: 8.1.2
Node: 11.15.0

コンテナの作成と起動

Dockerfile
```text
FROM node:11.15.0-stretch

RUN npm install -g @angular/cli && ng config -g cli.packageManager yarn

WORKDIR /app

yml
version: '3'

services:
node:
build: .
ports:
- "4200:4200"
volumes:
- ".:/app"
tty: true

コンテナ起動

docker-compose up -d

コンテナのコンソールに入る
ユーザーはrootかnodeかお好みで

docker-compose exec --user node node bash
```

Angular

コンテナのappディレクトリにてプロジェクト作成
--styleはcss, scss, sassなどが選べる
--routingでルートモジュールを追加する

ng new my-project --style=scss --routing

サーバー起動
--host Dockerを使用しているので0.0.0.0
--poll Dockerを使用している場合はソースコードの更新を検知し、コンパイルする間隔を指定する必要がある

cd my-project
ng serve --host=0.0.0.0 --poll=2000

これでlocalhost:4200からAngularのアプリにアクセス出来るはず
さらにdocker-compose.ymlに下のコマンドを追加すればコンテナ立ち上げ時にサーバーも立ち上がる
```yml
version: '3'

services:
node:
build: .
ports:
- "4200:4200"
volumes:
- ".:/app"
tty: true
command: [sh, -c, cd my-project && ng serve --host=0.0.0.0 --poll=2000]
```

参考

https://qiita.com/k5n/items/1a4987a430cf32e3e57d
https://qiita.com/k5n/items/dbda26cf6b899a11329d
https://qiita.com/friedaji/items/c3aba48542872f029c21

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

Dockerのコンテナビルドでphp-radisのインストールに失敗する

Dockerでコンテナをビルドする中でphp-radisをインストールする際に下のエラーが出た
```
E: Failed to fetch http://ppa.launchpad.net/ondrej/php/ubuntu/pool/main/p/php-redis/php-redis_4.2.0-1+ubuntu16.04.1+deb.sury.org+1_amd64.deb 404 Not Found

E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

php-redisのバージョンが新しくなり古いファイルが見つからないようだ
Dockerfileでアップデートしたものをインストールする場合は同じRUNの中でアップデートインストールしないいけないらしい
http://docs.docker.jp/engine/articles/dockerfile_best-practice.html
なのでDockerfileの記述は下のように
```doc
Dockerfile
apt-get update && apt-get install -yqq php-redis

これでビルド出来るようになった

以上

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

laradock+VSCode+xdebugの設定でハマったところ

環境

laradock
Docker for Windows 2.0.0.3 (31259)
VSCode 1.33.1
xdebug 2.7.2
php 7.2

laradock側の設定

ワークスペースとPHPでxdebugをインストールするよう設定(.env)

...
WORKSPACE_INSTALL_XDEBUG=true
...
PHP_FPM_INSTALL_XDEBUG=true
...

2つのxdebug.iniを下のように修正
(/php-fmp/xdebug.ini)
(/workspace/xdebug.ini)
xdebug.remote_host windowsの場合はdockerhostで動いたがmacの場合はDockerのネットワーク構成が異なるので別の設定じゃいと動かないらしい
xdebug.remote_port 他のアプリで使用していないポートならデフォルトの9000でも何でも良い

xdebug.remote_host=dockerhost
xdebug.remote_connect_back=0
xdebug.remote_port=9002
...
xdebug.remote_autostart=1
xdebug.remote_enable=1
xdebug.cli_color=1

これでdocker-compose upすればlaradock側はok

VSCode側の設定

拡張機能のPHP Debugをインストール

Vscodeで開いているlaravelプロジェクトに下記のファイルを作成(/.vscode/launch.json)
portはxdebug.iniで指定した値
pathMappingsは {リモートのドキュメントルート} : {ホストのドキュメントルート}
json
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9002,
"stopOnEntry": true,
"pathMappings": {
"/var/www": "${workspaceRoot}"
}
}
]
}

Firewallの設定

VSCodeがDocker内のXdebugと通信出来るようにFirewallを設定する必要がある。
とりあえずVSCodeはプライベートネットワークでの通信出来るように設定した。
Dockerのworkspaceコンテナでxdebugを試みるが下のようなエラーが出て接続出来ない。
```
I: Connecting to configured address/port: dockerhost:9002.

    E: Time-out connecting to client. :-(
色々調べてみたらDockerが動いているネットワークが識別されていないネットワーク(パブリック)なためFirewallに通信を遮断されていた。
なのでVSCodeがパブリックネットワークでも通信出来るようにするか、識別されていないネットワークをプライベートとみなすかすることで接続出来るようになった。

# 参考
https://qiita.com/hiro-tarosuke/items/adcc382ca98dfb89401b
https://qiita.com/ditflame/items/bf4b5f412bf607c5c6d2#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%8C%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerfileの基礎

はじめに

本来的には公式ドキュメントを読むべきですが、いきなり読んでも難しいので、
この記事で大まかなイメージを掴めるようにしたいと思って書きました。

必要最低限の知識

  • Dockerfileとは、Dockerイメージの生成材料
    • docker build - < Dockerfileで生成する
  • 形式は命令 引数
  • 主な命令

    • FROM: ベースイメージの指定
      • イメージは層(レイヤ)としてのっかっていくので、ベースイメージの上にイメージをのせることができる
      • イメージとは、本質的にはRead Onlyな情報の集まり。情報とは例えば、ファイルの実体やファイルのメタデータ。
        • 複数のイメージが層状に合体している。ミルフィーユみたいな。
      • ちなみにコンテナとは、イメージの上にのっかる1つのレイヤ。このレイヤは特別で、書き込み可能。
    • RUN: コンテナ生成中(=コンテナレイヤーをのせる前)にコマンド(echoとかyumとか)を実行する。

      • ENTRYPOINTやCMDはコンテナ生成後(=コンテナレイヤーをのせた後)にコマンドを実行する。
      • CMDは1つのDockerfileに1つしか書けない。複数のコマンドを実行したい場合は、複数のコマンドを実行するシェルスクリプトを作り、それをCMDで実行する。
      • 実行ファイル 引数という組み合わせをENTRYPOINT CMDという感じで書く。
      ENTRYPOINT test.sh
      CMD args
      
      • CMDで指定した引数よりも、docker build時に指定するオプションの方が優先される。
        • つまりCMDの引数はデフォルト値ということ。
    • COPY: ローカルのファイルをイメージにコピーする。

      • リモートのファイルをコピーしたいときはADDを使う。

補足的な知識

  • docker buildのとき、内部的には、ビルドコンテキストというものを、dockerデーモンという存在に渡して、dockerデーモンがコンテナ生成を頑張っている。
    • dockerデーモンはdocker関連の諸々を頑張ってくれる存在。
    • ビルドコンテキストとは要するにdocker buildのときに取り扱うディレクトリ。docker buildのときにPATH形式やURL形式で指定できる。デフォルトはdocker buildを実行した場所?要確認
    • DockerfileはDockerfileという名前じゃなくても良い(buildのときにオプションでファイル名やパスを指定できる)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerコンテナ内のログを確認する方法

phpでエラーを出力する。

error_log()

ログを確認する。

Docker logs -f コンテナID

# -f(follow)で出力し続ける。

アクセスログのみ表示したい時

Docker logs コンテナID -f 2>/dev/null

# /dev/null で 表示を消去。 2 はエラー出力

エラーログのみ表示したい時

Docker logs コンテナID -f 1>/dev/null

# /dev/null で 表示を消去。 1 は標準出力

docker-composeで

docker-compose logs

#アクセスログとエラーログ を切り分けることができない。

※Dockerは仕組み上、標準出力とエラーログ でしか分けることしかできない。アプリケーションごとに(apache,phpなど)でログを分けることができない。

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