- 投稿日:2019-03-24T22:19:44+09:00
Apache + Flask 環境の Dcokerfile を作成する
この文章の前提
- Apache、Flask、Dockerが何かということの説明は割愛する
- Dockerはホストマシンにインストール済みのものとして記載する
目的
Apache+Flask環境を他のマシンでも再現できるようにする
用語
- mod_wsgi
Apacheでpythonプログラムを動かすためのモジュール環境
対象 バージョン OS macOS Mojave (10.14.3) Docker 18.09.0 資材
起動方法
- ビルド
$ docker-compose build
- 起動
$ docker-compose up -d
- 確認
$ curl http://localhost:8080/ Hello, Flask!構成 - コンテナ構築関連(ホスト側)
. ├── Dockerfile ├── README.md ├── docker-compose.yml └── src ├── adapter.wsgi ├── flask.conf └── run.py構成 - アプリケーション関連(コンテナ側)
- mod_wsgiの設定ファイル
/ └── etc/ └── httpd/ └── conf.d/ └── flask.conf★
- アプリケーションディレクトリ
/ └── var/ └── www/ └── projects/ └── test/ ├── adapter.wsgi★ └── application/ └── run.py★構築概要(Dockerfile概要)
imageのダウンロード
CentOS7をダウンロード変数の設定
アプリケーションディレクトリ等の名前を設定必要なパッケージのインストール
- 依存ライブラリ等
- Apache関連
- python3関連(リポジトリ登録の上、yumでインストール)
- pythonモジュール
- mod_wsgi(上記python3を起動するためyumではなくpipでインストール)
- Flask
資材の配備
[構成 - アプリケーション関連(コンテナ側) ] 通りにディレクトリを作成、資材をコピーサービスの起動
httpdサービスの自動起動をON
起動時のコマンドを設定Listen Portを設定
コンテナ内のListen Portを設定参考URL
PythonのFlaskを初めて触ってから30分で本番環境にデプロイ+ HTTPS通信まで完成
CentOS7にPython3をインストール
- 投稿日:2019-03-24T21:59:20+09:00
ローカルからDocker内のlint-stagedを呼び出す
huskyとlint-stagedを使って、コミット時に自動でlintを走らせるのは一般的だと思う。
しかしDockerの
nodeコンテナで開発しているプロジェクトを、ローカルのWindowsなどからGitでコミットすると、lint-stagedのバイナリが実行できない。これはバイナリがwindowsで使われることを想定していない、つまりlinux向けにコンパイルされたものだからである。こういった場合は、以下のように
docker-compose runでコンテナ越しにlint-stagedを呼び出すと良い。package.json"husky": { "hooks": { "pre-commit": "docker-compose run --rm node yarn exec lint-staged" } }, "lint-staged": { "*.{js,vue}": [ "eslint --fix", "git add" ] },alpineイメージを使用する場合だと、gitがインストールされていないため、Dockerfileを以下のように書く。
FROM node:11.12-alpine RUN apk add --no-cache gitついでに
docker-compose.ymlも載せておく。docker-compose.ymlversion: '3' services: node: build: context: ./docker/node
- 投稿日:2019-03-24T21:28:20+09:00
【Microsoft Flow】Arukas アプリ作成時にハマったこと( API 認証編)
はじめに
さくらインターネットの Docker ホスティングサービスである Arukas でアプリを作成しているときにハマったのでメモ。
顛末
Microsoft Flow から Arukas アプリの制御を行いたい。
Arukas にはユーザーが利用できる API が用意されており、以下の公式ドキュメントに
API によるアプリの作成、設定変更、起動、停止などの方法がまとまっている。https://arukas.io/en/documents-en/arukas-api-reference-en/
これをフローの HTTP アクションで叩くだけで良いと思ったが、ハマったのが API 利用時の認証方法についてである。
ドキュメントの Authentication の章を見ると、
The API keys consist of API token and secret token. You can generate them in Arukas user control panel.
To follow along with this document smoothly, it would be nice to create including a ~/.netrc line of code below.
machine app.arukas.io login #{ARUKAS_JSON_API_TOKEN} password #{ARUKAS_JSON_API_SECRET}とだけあり、コントロールパネルで取得できる API key を netrc ファイルに設定せよとのこと。
しかし、今回使いたい Microsoft Flow では netrc ファイルによる認証は利用できない。そこで Arukas のサポートに問い合わせてみると以下のような回答があった。
--user オプションを指定して、リクエスト可能です。
curl -H "Content-Type: application/json" --user #{ARUKAS_JSON_API_TOKEN}:#{ARUKAS_JSON_API_SECRET}@app.arukas.io/api/apps/${APP_ID}また以下のような書き方でもリクエスト可能となります。
curl -X GET https://#{ARUKAS_JSON_API_TOKEN}:#{ARUKAS_JSON_API_SECRET}@app.arukas.io/api/apps/${APP_ID}つまりは基本認証でも API の認証が可能とのこと。
幸い、Microsoft Flow の HTTP アクションでは基本認証が利用できるので、以下のように API Key を設定したら、認証も通り Arukas API を利用してアプリを制御できた。(画像はアプリを起動する場合)
おわりに
「API key で netrc ファイルによる認証が利用可能」という情報から、「つまり同じ API key をそのまま指定した基本認証も利用可能なのでは?」へ、自分の中ですぐに結びつかなかったは残念でした。
- 投稿日:2019-03-24T21:28:20+09:00
【Microsoft Flow】Arukas アプリ作成時にハマったこと(API 認証編)
はじめに
さくらインターネットの Docker ホスティングサービスである Arukas でアプリを作成しているときにハマったのでメモ。
顛末
Microsoft Flow から Arukas アプリの制御を行いたい。
Arukas にはユーザーが利用できる API が用意されており、以下の公式ドキュメントに
API によるアプリの作成、設定変更、起動、停止などの方法がまとまっている。https://arukas.io/en/documents-en/arukas-api-reference-en/
これをフローの HTTP アクションで叩くだけで良いと思ったが、ハマったのが API 利用時の認証方法についてである。
ドキュメントの Authentication の章を見ると、
The API keys consist of API token and secret token. You can generate them in Arukas user control panel.
To follow along with this document smoothly, it would be nice to create including a ~/.netrc line of code below.
machine app.arukas.io login #{ARUKAS_JSON_API_TOKEN} password #{ARUKAS_JSON_API_SECRET}とだけあり、コントロールパネルで取得できる API key を netrc ファイルに設定せよとのこと。
しかし、今回使いたい Microsoft Flow では netrc ファイルによる認証は利用できない。そこで Arukas のサポートに問い合わせてみると以下のような回答があった。
--user オプションを指定して、リクエスト可能です。
curl -H "Content-Type: application/json" --user #{ARUKAS_JSON_API_TOKEN}:#{ARUKAS_JSON_API_SECRET}@app.arukas.io/api/apps/${APP_ID}また以下のような書き方でもリクエスト可能となります。
curl -X GET https://#{ARUKAS_JSON_API_TOKEN}:#{ARUKAS_JSON_API_SECRET}@app.arukas.io/api/apps/${APP_ID}つまりは基本認証でも API の認証が可能とのこと。
幸い、Microsoft Flow の HTTP アクションでは基本認証が利用できるので、以下のように API Key を設定したら、認証も通り Arukas API を利用してアプリを制御できた。(画像はアプリを起動する場合)
おわりに
「API key で netrc ファイルによる認証が利用可能」という情報から、「つまり同じ API key をそのまま指定した基本認証も利用可能なのでは?」へ、自分の中ですぐに結びつかなかったは残念でした。
- 投稿日:2019-03-24T17:41:42+09:00
Docker Image を runして、 bundle exec rails new する
自分用の備忘録です。
まず、ビルド
docker build . -t <IMAGE_NAME>Rails new
docker run --rm -v $PWD:$PWD -w $PWD <IMAGE_NAME> bundle exec rails new . --database=mysql --skip-test
docker runのオプションは下に説明参考にした記事
Dockerコンテナからホスト側カレントディレクトリにアクセス
--rmオプションでDockerコンテナのプロセス(コマンド)が終了した時点でコンテナを破棄します。コマンド終了後にDockerコンテナ上のファイルを色々とアクセスしたい場合は外しても構いません。--userオプションでホスト側のUIDを指定します。指定しない場合、生成したファイル等の所有者がroot:rootとなるためホスト側のユーザが編集したり削除したりできません。-v $PWD:$PWDオプションで、ホス ト側カレントディレクトリとコンテナ側カレントディレクトリのボリューム内容を一致させます。-w $PWDオプションで、ホスト側カレントディレクトリとコンテナ側カレントディレクトリのディレクトリパスを一致させます。-v $PWD:$PWDオプションと組み合わせて使います。
- 投稿日:2019-03-24T16:24:09+09:00
DockerfileのRUNとCMD、docker-compose.yaml内のマウントタイミング
- 投稿日:2019-03-24T13:28:49+09:00
Testcontainers で Spring Boot + MyBatis のテスト実行中だけ MySQL のコンテナを起動
はじめに
Testcontainers を使用すると、JUnit のテスト中だけ MySQL のコンテナを起動することができます。
SimpleMySQLTest.java というサンプルコードを見ると結構簡単に使えそうですが、Spring Boot + MyBatis で試してみたら結構苦労したので、どうすれば動くかまとめておきます。
まずは普通に Spring Boot + MyBatis を動かす
Testcontainers でテストを試す前に、動くコードを書いておきます。
MyBatis のコードを作成
UserRepositoryImpl.java、UserMapper.java、UserMapper.xml の 3 ファイルを作成します。
UserRepositoryImpl.javapackage springdockerexample.infrastructure.user; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import springdockerexample.domain.user.Name; import springdockerexample.domain.user.User; import springdockerexample.domain.user.UserRepository; import springdockerexample.domain.user.Users; import java.util.List; @Repository public class UserRepositoryImpl implements UserRepository { @Autowired private UserMapper mapper; @Override public Users findAll() { List<User> users = mapper.selectAll(); return new Users(users); } }UserMapper.javapackage springdockerexample.infrastructure.user; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import springdockerexample.domain.user.Name; import springdockerexample.domain.user.User; import java.util.List; @Mapper public interface UserMapper { List<User> selectAll(); }UserMapper.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="springdockerexample.infrastructure.user.UserMapper"> <resultMap id="user" type="springdockerexample.domain.user.User"> <result property="name.value" column="name"/> <result property="age.value" column="age"/> </resultMap> <select id="selectAll" resultMap="user"> SELECT name, age FROM users </select> </mapper>プロパティファイルを用意
DB の接続情報を application.yaml に書きます。
application.yamlspring: datasource: url: jdbc:mysql://localhost/mydb username: user password: password driverClassName: com.mysql.cj.jdbc.Driverテストデータを用意
開発・テスト用のデータをファイルに用意します。
src/test/resources/docker-entrypoint-initdb.d/init.sqlUSE `mydb`; CREATE TABLE `users` ( `name` VARCHAR(255) NOT NULL, `age` int NOT NULL ); INSERT INTO `users` (`name`, `age`) VALUES ('Alice', 20), ('Bob', 30);ローカルでコンテナを起動
Spring Boot + MyBatis の動作確認のため、Docker Compose で MySQL を起動します。
このとき、先ほど用意した SQL ファイルを docker-entrypoint-initdb.d にマウントすることで、データが自動的に挿入されます。
docker-compose.yamlversion: '3' services: my-db: image: mysql:5.7.25 ports: - 3306:3306 volumes: - ./src/test/resources/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: mydb MYSQL_USER: user MYSQL_PASSWORD: password動作確認
spring-dev-tools を入れておけば、
./mvnw spring-boot:runで起動します。$ ./mvnw spring-boot:run $ curl localhost:8080/users {"users":[{"name":"Alice","age":20},{"name":"Bob","age":30}]}無事動作しています。
※ RestController なども書いていますが、記事への掲載は省略しました。
このように、Docker Compose で起動したコンテナでテストすることも可能ですが、それではテストケースごとにコンテナを起動し直したりすることはできません。
JUnit のテストの中で自由自在にコンテナを起動するため、Testcontainers を使います。
Testcontainers で JUnit 実行中だけコンテナを起動
テスト用の MySQL 起動 + 接続情報設定
「testcontainersで使い捨てのデータベースコンテナを用意してSpring Bootアプリケーションのテストをおこなう」を参考に、テスト用の MySQL コンテナの起動と Context への接続情報設定のため、以下のファイルを作成します。
MySQLContainerContextInitializer.javapackage springdockerexample.testhelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.testcontainers.containers.BindMode; import org.testcontainers.containers.MySQLContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; public class MySQLContainerContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { private static final String MYSQL_IMAGE = "mysql:5.7.25"; private static final String DATABASE_NAME = "mydb"; private static final String USERNAME = "user"; private static final String PASSWORD = "password"; private static final int PORT = 3306; private static final String INIT_SQL = "docker-entrypoint-initdb.d/init.sql"; private static final String INIT_SQL_IN_CONTAINER = "/docker-entrypoint-initdb.d/init.sql"; private static final Logger LOGGER = LoggerFactory.getLogger(MySQLContainerContextInitializer.class); private static final MySQLContainer MYSQL = (MySQLContainer) new MySQLContainer(MYSQL_IMAGE) .withDatabaseName(DATABASE_NAME) .withUsername(USERNAME) .withPassword(PASSWORD) .withExposedPorts(PORT) .withLogConsumer(new Slf4jLogConsumer(LOGGER)) .withClasspathResourceMapping(INIT_SQL, INIT_SQL_IN_CONTAINER, BindMode.READ_ONLY); static { MYSQL.start(); } @Override public void initialize(ConfigurableApplicationContext context) { String mysqlJdbcUrl = MYSQL.getJdbcUrl(); TestPropertyValues.of("spring.datasource.url=" + mysqlJdbcUrl) .applyTo(context.getEnvironment()); } }この内容を順に説明していきます。
MySQL のコンテナの設定
private static final MySQLContainer MYSQL = (MySQLContainer) new MySQLContainer(MYSQL_IMAGE) .withDatabaseName(DATABASE_NAME) .withUsername(USERNAME) .withPassword(PASSWORD) .withExposedPorts(PORT) .withLogConsumer(new Slf4jLogConsumer(LOGGER)) .withClasspathResourceMapping(INIT_SQL, INIT_SQL_IN_CONTAINER, BindMode.READ_ONLY);ここでは、先ほど docker-compose.yaml で書いていた内容とほとんど同じ設定を Java で記述しています。
new MySQLContainer(MYSQL_IMAGE) でイメージ名を指定し、データベース名やユーザ名、パスワードといった設定もここで行なっています。
また、withClasspathResourceMapping で DB の初期化用の SQL をマウントしています。
同様にして、 MySQL の設定ファイルもマウントできるようです。MySQL のコンテナ起動
static { MYSQL.start(); }MySQL のコンテナを起動しています。
MySQL.start() は後述する initialize 内の MySQL.getJdbUrl() より先に実行される必要があります。この例ではサボっていますが、終了時に MySQL.stop() を呼び出したほうがお行儀がいいと思われます。
接続情報の設定
Testcontainers で起動した MySQL に接続するためのポートは動的に割り当てられるため、それを踏まえて動的に接続情報を設定する必要があります。
MySQLContainerContextInitializer というクラスを作成したのは、Spring Bootの設定を動的に変更するためです。
具体的な設定方法は以下の通りです。
@Override public void initialize(ConfigurableApplicationContext context) { String mysqlJdbcUrl = MYSQL.getJdbcUrl(); TestPropertyValues.of("spring.datasource.url=" + mysqlJdbcUrl) .applyTo(context.getEnvironment()); }ちなみに、MySQL への接続情報を MySQLContainer インスタンスから取得する必要があることは、SimpleMySQLTest.java の以下の部分からも分かります。
SimpleMySQLTest.java@NonNull protected ResultSet performQuery(MySQLContainer containerRule, String sql) throws SQLException { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setDriverClassName(containerRule.getDriverClassName()); hikariConfig.setJdbcUrl(containerRule.getJdbcUrl()); hikariConfig.setUsername(containerRule.getUsername()); hikariConfig.setPassword(containerRule.getPassword()); HikariDataSource ds = new HikariDataSource(hikariConfig); Statement statement = ds.getConnection().createStatement(); statement.execute(sql); ResultSet resultSet = statement.getResultSet(); resultSet.next(); return resultSet; }テストの記述
Spirng Boot のテストを通常通り記載します。
UserRepositoryImplTest.javapackage springdockerexample.infrastructure.user; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import springdockerexample.domain.user.UserRepository; import springdockerexample.domain.user.Users; import springdockerexample.testhelper.MySQLContainerContextInitializer; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; @RunWith(SpringRunner.class) @SpringBootTest @ContextConfiguration(initializers = { MySQLContainerContextInitializer.class }) public class UserRepositoryImplTest { @Autowired UserRepository userRepository; @Test public void test() { Users users = userRepository.findAll(); assertThat(users.count(), is(2)); } }ポイントは、
@ContextConfiguration(initializers = { MySQLContainerContextInitializer.class })で先ほど作成したクラスを指定し、MySQL の起動と接続情報の設定を行なっているところです。あとは普通の JUnit のテストを記述すれば、問題なく DB にアクセスできます。
まとめ
まとめると全然難しくないのですが、実際には結構苦労しました。
セットアップし終えてしまえば便利に使えるかもしれません。Testcontainers は DB 以外にも任意のコンテナに対応しているので、自由自在な自動テストが可能になります。
なお、この記事の内容の最終的なファイル構成はおおよそ以下のようになっています。
$ tree . ├── pom.xml ├── ... └── src ├── main │ ├── java │ │ └── springdockerexample │ │ ├── SpringDockerExampleApplication.java │ │ ├── ... │ │ └── infrastructure │ │ └── user │ │ ├── UserMapper.java │ │ └── UserRepositoryImpl.java │ └── resources │ ├── application.yaml │ └── springdockerexample │ └── infrastructure │ └── user │ └── UserMapper.xml └── test ├── java │ └── springdockerexample │ ├── SpringDockerExampleApplicationTests.java │ ├── infrastructure │ │ └── user │ │ └── UserRepositoryImplTest.java │ └── testhelper │ └── MySQLContainerContextInitializer.java └── resources └── docker-entrypoint-initdb.d └── init.sqlソースコードは こちら です。
- 投稿日:2019-03-24T11:16:36+09:00
【Docker】Arukas アプリ作成時にハマったこと(EXPOSE 宣言は必須編)
はじめに
さくらインターネットの Docker ホスティングサービスである Arukas でアプリを作成しているときにハマったのでメモ。
顛末
まず、Arukas で アプリ(= Docker コンテナ)を起動するためには、Docker Hub に登録されているイメージを利用する必要があります。
今回使おうとしたのは Ubuntu18.04 の公式イメージ。
Arukas のアプリ追加コンソールを開いて、イメージとして Docker Hub で公式提供されている
ubuntu:18.04を指定してアプリ作成。
アプリのステータスが「アプリはデプロイ中です」となったまましばらく待つ1と...「アプリの起動に失敗しました」となり起動できない。
イメージ名を
_/ubuntu:18.04と指定して再試行したが同様に起動に失敗する。調べてみると Arukas のFAQに以下のような記載があった。
https://support.arukas.io/hc/ja/articles/210357188
対象ポートはDockerfile内においてEXPOSE宣言で開放されておりますでしょうか。 EXPOSEで開放されているポートが入力されていない場合、サーバとして起動しないことがございます。
とのこと。
これ、特にポート開放を必要とするサービスは入れない場合に、適当なポートをEXPOSE宣言しておくだけでいいのか?例えば SSH デーモンを動かさずとも取り敢えずEXPOSE 22を設定しておくだけで正常起動の要件は満たされるのか?検証してみる。
以下のような、素の Ubuntu にポート22を開放するだけの Dockerfile を用意。FROM ubuntu:18.04 EXPOSE 22 CMD echo 'Hello docker world!'上記 Dockerfile からイメージをビルドして、自身の管理する Docker Hub に登録。(実際の試行ではxxxxxxを実在の Docker Hub アカウント名としています)
docker build . -t xxxxxx/ubuntu:18.04 docker push xxxxxx/ubuntu:18.04Arukas のアプリ作成画面に戻り、先程登録したイメージ
xxxxxx/ubuntu:18.04を指定し、アプリを作成し、起動。(この時、Arukas 側のポート設定は不要です。)
結論
Arukas のアプリで利用するイメージは何らかの一つ以上のポートが
EXPOSE宣言されている必要がある。
しかし、コンテナ内でそのポートを利用するサービスを動かしたり、 Arukas 側のポート設定で同じ番号のポートを開放する必要はない。おまけ
因みに、SSH デーモンがちゃんと設定されたイメージを使用し、以下のように Arukas 側でもポート22を設定してあげれば、
作成後のアプリのポート22に対して動的なハイポート(
~arukascloud.io:31XXXの31XXX部分)が自動的にマッピングされるので、例えば以下のようなマッピングが行われた場合はssh root@seaof-163-43-82-XXX.jp-tokyo-02.arukascloud.io -p 31XXXとすればアプリに SSH 接続できます。(アプリを再起動するたびに URI やハイポートの値は動的に変わるので注意。)
https://support.arukas.io/hc/ja/articles/210357188 によると、アプリケーションの設定内容に誤りがある場合は起動試行中のアプリケーションは15分以内に強制停止されるとのこと。 ↩
- 投稿日:2019-03-24T11:16:36+09:00
【Docker】Arukas アプリ作成時にハマったこと( EXPOSE 宣言は必須編)
はじめに
さくらインターネットの Docker ホスティングサービスである Arukas でアプリを作成しているときにハマったのでメモ。
顛末
まず、Arukas で アプリ(= Docker コンテナ)を起動するためには、Docker Hub に登録されているイメージを利用する必要があります。
今回使おうとしたのは Ubuntu18.04 の公式イメージ。
Arukas のアプリ追加コンソールを開いて、イメージとして Docker Hub で公式提供されている
ubuntu:18.04を指定してアプリ作成。
アプリのステータスが「アプリはデプロイ中です」となったまましばらく待つ1と...「アプリの起動に失敗しました」となり起動できない。
イメージ名を
_/ubuntu:18.04と指定して再試行したが同様に起動に失敗する。調べてみると Arukas のFAQに以下のような記載があった。
https://support.arukas.io/hc/ja/articles/210357188
対象ポートはDockerfile内においてEXPOSE宣言で開放されておりますでしょうか。 EXPOSEで開放されているポートが入力されていない場合、サーバとして起動しないことがございます。
とのこと。
これ、特にポート開放を必要とするサービスは入れない場合に、適当なポートをEXPOSE宣言しておくだけでいいのか?例えば SSH デーモンを動かさずとも取り敢えずEXPOSE 22を設定しておくだけで正常起動の要件は満たされるのか?検証してみる。
以下のような、素の Ubuntu にポート22を開放するだけの Dockerfile を用意。FROM ubuntu:18.04 EXPOSE 22 CMD echo 'Hello docker world!'上記 Dockerfile からイメージをビルドして、自身の管理する Docker Hub に登録。(実際の試行ではxxxxxxを実在の Docker Hub アカウント名としています)
docker build . -t xxxxxx/ubuntu:18.04 docker push xxxxxx/ubuntu:18.04Arukas のアプリ作成画面に戻り、先程登録したイメージ
xxxxxx/ubuntu:18.04を指定し、アプリを作成し、起動。(この時、Arukas 側のポート設定は不要です。)
結論
Arukas のアプリで利用するイメージは何らかの一つ以上のポートが
EXPOSE宣言されている必要がある。
しかし、コンテナ内でそのポートを利用するサービスを動かしたり、 Arukas 側のポート設定で同じ番号のポートを開放する必要はない。おまけ
因みに、SSH デーモンがちゃんと設定されたイメージを使用し、以下のように Arukas 側でもポート22を設定してあげれば、
作成後のアプリのポート22に対して動的なハイポート(
~arukascloud.io:31XXXの31XXX部分)が自動的にマッピングされるので、例えば以下のようなマッピングが行われた場合はssh root@seaof-163-43-82-XXX.jp-tokyo-02.arukascloud.io -p 31XXXとすればアプリに SSH 接続できます。(アプリを再起動するたびに URI やハイポートの値は動的に変わるので注意。)
https://support.arukas.io/hc/ja/articles/210357188 によると、アプリケーションの設定内容に誤りがある場合は起動試行中のアプリケーションは15分以内に強制停止されるとのこと。 ↩
- 投稿日:2019-03-24T02:58:17+09:00
laradock で『laradock_mysql_1 docker-entrypoint.sh mysqld Exit 2』となる問題を解決
環境
OS:macOS Mojave 10.14.3
Docker:18.09.2
docker-compose:1.23.2
docker-machine:0.16.1
php:7.1.23
Laravel Framework:5.8.7
mysql:Ver 14.14 Distrib 5.7.25, for Linux (x86_64) using EditLine wrapper事象
laradockで構築したmysqlを起動すると
$ docker-compose up -d php-fpm nginx mysql Recreating laradock_mysql_1 ... done Starting laradock_docker-in-docker_1 ... done Starting laradock_workspace_1 ... done Starting laradock_php-fpm_1 ... done Starting laradock_nginx_1 ... done $ docker-compose ps Name Command State Ports ----------------------------------------------------------------------------------------------------------------- laradock_docker-in-docker_1 dockerd-entrypoint.sh Up 2375/tcp laradock_mysql_1 docker-entrypoint.sh mysqld Exit 2 laradock_nginx_1 /bin/bash /opt/startup.sh Up 0.0.0.0:443->443/tcp, 0.0.0.0:8080->80/tcp laradock_php-fpm_1 docker-php-entrypoint php-fpm Up 9000/tcp laradock_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcpとなり起動にコケてしまう事象が発生しました。
解決方法
一旦dockerを止めます。
docker-compose stop以下のファイルを変更します。
.env### MYSQL ################################################# MYSQL_VERSION=latest #latestのまま - MYSQL_DATABASE=default + MYSQL_DATABASE=laradock - MYSQL_USER=root + MYSQL_USER=laradock - MYSQL_PASSWORD=root + MYSQL_PASSWORD=secret MYSQL_PORT=3306 MYSQL_ROOT_PASSWORD=root MYSQL_ENTRYPOINT_INITDB=./mysql/docker-entrypoint-initdb.dさらに、以下のディレクトリ配下のファイルをすべて削除します。
/Users/{USER NAME}/.laradock/data/mysql/終わり
以上、対応後にdockerを起動すると
$ docker-compose up -d php-fpm nginx mysql Starting laradock_docker-in-docker_1 ... done Recreating laradock_mysql_1 ... done Starting laradock_workspace_1 ... done Starting laradock_php-fpm_1 ... done Starting laradock_nginx_1 ... done $ docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------------------------------------- laradock_docker-in-docker_1 dockerd-entrypoint.sh Up 2375/tcp laradock_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp laradock_nginx_1 /bin/bash /opt/startup.sh Up 0.0.0.0:443->443/tcp, 0.0.0.0:8080->80/tcp laradock_php-fpm_1 docker-php-entrypoint php-fpm Up 9000/tcp laradock_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcpmysqlのプロセスが確認できれば完了です。お疲れ様でした^^
- 投稿日:2019-03-24T00:53:18+09:00
docker-compose build でE: Failed to fetch http://... Writing more data than expected (1123368 > 1086978)が発生する時の対応方法
環境
OS:macOS Mojave 10.14.3
Docker:18.09.2, build 6247962
docker-compose:1.23.2, build 1110ad01
docker-machine:0.16.1, build cce350d7
php:7.1.23事象
dockerを以下のコマンドでビルドをすると
docker-compose build --no-cache workspace . . 省略 . + groupadd -g 1000 laradock + useradd -u 1000 -g laradock -m laradock -G docker_env + usermod -p * laradock -s /bin/bash + apt-get install -yqq apt-utils php7.1-zip nasm E: Failed to fetch http://220.152.42.162:80/data/06abb81878b24fba/archive.ubuntu.com/ubuntu/pool/universe/n/nasm/nasm_2.11.08-1ubuntu0.1_amd64.deb Writing more data than expected (1088616 > 1086978)となりビルドがエラーで落ちるといった事象が発生しました。
対象となる方は少ないかと思いますが、もし同じ事象でお困りの方がいましたら、一旦私が行った処置をシェアしたいと思います。
お役に立てれは幸いです。解決ではないが一旦これでエラー回避
以下のファイルの対象の部分をコメントアウトするだけです。
laradock/workspace/Dockerfile# always run apt update when start and after add new source list, then clean up at end. RUN set -xe; \ apt-get update -yqq && \ pecl channel-update pecl.php.net && \ groupadd -g ${PGID} laradock && \ useradd -u ${PUID} -g laradock -m laradock -G docker_env && \ usermod -p "*" laradock -s /bin/bash && \ apt-get install -yqq \ apt-utils && \ # #-------------------------------------------------------------------------- # Mandatory Software's Installation #-------------------------------------------------------------------------- # # Mandatory Software's such as ("php-cli", "git", "vim", ....) are # installed on the base image 'laradock/workspace' image. If you want # to add more Software's or remove existing one, you need to edit the # base image (https://github.com/Laradock/workspace). # # next lines are here becase there is no auto build on dockerhub see https://github.com/laradock/laradock/pull/1903#issuecomment-463142846 - libzip-dev zip unzip \ + # libzip-dev zip unzip \ コメントアウトした # Install the zip extension - php${LARADOCK_PHP_VERSION}-zip \ + # php${LARADOCK_PHP_VERSION}-zip \ コメントアウトした # nasm - nasm && \ + # nasm && \ コメントアウトした php -m | grep -q 'zip'結論
時間がなくなぜエラーが発生しているのかまだわかっていません。
私が必要とする環境では、必要のないモジュールでエラーが発生していたので一旦コメントアウトで対応しました。もし解決方法をご存知の方がいらしたら是非教えていただけると嬉しいです。
- 投稿日:2019-03-24T00:21:07+09:00
Docker コマンドで Volume の設定をしようとしたら invalid volume specification エラーに遭遇した
一応解決できたので備忘録として残しておく。
前提
- ホストOS: Windows10
- WSL: Ubuntu16.04
- Docker: 18.09.3
- WSL上のシンボリックリンク:
workspace -> /mnt/c/Users/<user_name>/workspace<user_name>のところは適宜置き換えてくださいエラーについて
srcディレクトリが存在するディレクトリで下記コマンドを実行したところ、「無効なボリューム指定してるよ」と、エラーが出た。
コマンド
docker run -v "$(pwd)"/src:/src <container>※ コンテナの
WORKDIRはsrcに設定してあるエラー内容
docker: Error response from daemon: invalid volume specification: '/home/<user_name>/workspace/hoge/src:/src'. See 'docker run --help'.対応
ローカルのパス指定方法(
"$(pwd)"/src)を変更してみる検証①
/home/<user_name>/workspace/hoge/srcに変更してみる結果
同様のエラーが出て検証失敗
まあ当然でしょう。検証②
/mnt/c/Users/<user_name>/workspace/hoge/srcに変更してみる結果
docker: Error response from daemon: invalid volume specification: '/mnt/c/Users/<user_name>/workspace/hoge/src:/src'. See 'docker run --help'.いけると思ったが、失敗。。
検証③
C:\\Users\\<user_name>\\workspace\\hoge\\srcに変更してみる結果
いけたー!
結論
WSL から見たファイルパスを指定をしても、Docker Daemon からしたら分からない!ってことっぽい。
WSL 便利だけど、変なところで詰まるのでやっぱりMacの方が絶対ラク。。
- 投稿日:2019-03-24T00:07:01+09:00
docker-composeでレプリケーション練習(写経)
docker-composeでMaster/Slave構成のMySQLを手に入れる の写経
- 永続化のところはmasterもtmpfsへ
MYSQL_ALLOW_EMPTY_PASSWORD(実験用には)便利すぎる- 固定IPを振らないとreplユーザーのネットワークアクセス制限ができない
- レプリケーションをrootからreplユーザーで行うよう変更
準備
$ ls docker-compose.yml master.cnf slave.cnf start-slave.shdocker-compose.ymlversion: '3' services: mysql: image: mysql:5.7 ports: - "3306:3306" tmpfs: /var/lib/mysql volumes: - ./master.cnf:/etc/mysql/conf.d/my.cnf networks: db_net: ipv4_address: 192.168.192.2 environment: MYSQL_ALLOW_EMPTY_PASSWORD: 1 TZ: "Asia/Tokyo" mysql-slave: image: mysql:5.7 ports: - '13306:3306' depends_on: - mysql tmpfs: /var/lib/mysql volumes: - ./slave.cnf:/etc/mysql/conf.d/my.cnf - ./start-slave.sh:/docker-entrypoint-initdb.d/start-slave.sh networks: db_net: ipv4_address: 192.168.192.3 environment: MYSQL_ALLOW_EMPTY_PASSWORD: 1 TZ: "Asia/Tokyo" networks: db_net: driver: bridge ipam: config: - subnet: 192.168.192.0/24$ cat master.cnf slave.cnf [mysqld] character-set-server=utf8 collation-server=utf8_general_ci log-bin=mysql-bin expire_logs_days=5 server-id=1 [mysqld] character-set-server=utf8 collation-server=utf8_general_ci log-bin=mysql-bin expire_logs_days=5 server-id=2 read_only=1cat start-slave.sh #!/bin/sh # depends_onの設定しておけば気にならないけど念の為masterの起動を待つ while ! mysqladmin ping -h mysql --silent; do sleep 1 done mysql -u root -h mysql -e "CREATE USER 'repl'@'192.168.192.3' IDENTIFIED BY 'slavepass';" mysql -u root -h mysql -e "GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.192.3';" # masterをロックする mysql -u root -h mysql -e "RESET MASTER;" mysql -u root -h mysql -e "FLUSH TABLES WITH READ LOCK;" # masterのDB情報をDumpする # ここでは --all-databases にしてるけど用途に応じて必要なDBだけにしていいと思う mysqldump -uroot -h mysql --all-databases --master-data --single-transaction --flush-logs --events > /tmp/master_dump.sql # 特定のDBだけにする場合はこんな感じ(my.cnfのreplica-do-dbも忘れずに設定すること) # mysqldump -uroot -h mysql データベース名 --master-data --single-transaction --flush-logs --events > /tmp/master_dump.sql # dumpしたmasterのDBをslaveにimportする mysql -u root -e "STOP SLAVE;"; mysql -u root < /tmp/master_dump.sql # masterに繋いで bin-logのファイル名とポジションを取得する log_file=`mysql -u root -h mysql -e "SHOW MASTER STATUS\G" | grep File: | awk '{print $2}'` pos=`mysql -u root -h mysql -e "SHOW MASTER STATUS\G" | grep Position: | awk '{print $2}'` # slaveの開始 mysql -u root -e "RESET SLAVE"; #mysql -u root -e "CHANGE MASTER TO MASTER_HOST='mysql', MASTER_USER='root', MASTER_PASSWORD='', MASTER_LOG_FILE='${log_file}', MASTER_LOG_POS=${pos};" mysql -u root -e "CHANGE MASTER TO MASTER_HOST='mysql', MASTER_USER='repl', MASTER_PASSWORD='slavepass', MASTER_LOG_FILE='${log_file}', MASTER_LOG_POS=${pos};" mysql -u root -e "start slave" # masterをunlockする mysql -u root -h mysql -e "UNLOCK TABLES;"実食
$ docker-compose up -d $ docker-compose exec mysql-slave bash // slaveにログイン # mysql -u root -e "SHOW SLAVE STATUS\G" // レプリケーションできていること確認 # exit $ docker-compose exec mysql bash // masterにログイン # mysql -u root mysql> CREATE DATABASE users; // usersデータベースを作成 mysql> quit # exit $ docker-compose exec mysql-slave bash // 再びslaveにログイン # mysql -u root -e "show databases" +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | users | // 追加されたものが同期されている +--------------------+参考
mysql - Docker Hub
MySQL GTID レプリケーション素振り - ngyukiの日記
docker-composeでMaster/Slave構成のMySQLを手に入れる - Qiita
docker-composeで起動したコンテナにbashで入ったりコマンドを渡す - Qiita
MySQLチートシート - Qiita
MySQL コマンドチートシート 初心者向け - Qiita
PostgreSQLとMySQLの基本的なコマンドを比較 - Qiita
docker-composeでお手軽mysqlのmaster-slave構成 - ウェブエンジニア珍道中
日々の覚書: MySQL 8.0.3とそれ以降では expire_logs_days は非推奨なパラメーターになりました
MySQLでバイナリログを定期的に削除するmy.cnfの設定(expire_logs_days) - ドラあり!*ドラゴンに挑むアリの物語 ** Python使いの日々








