Study & Practice

北海道札幌市のプログラマによる技術とか雑記のブログ

AWS EC2にLarabel + MySQL + Apache + Vue.jsの環境を一歩ずつ作ってみる

EC2でWebアプリの公開するための土台作りとして環境構築を行っていく
codeDeployでの自動化とかも調べてみたけどとりあえず一番シンプルな方法か始めることにしました

以下、EC2インスタンス内での操作

すべて下記のAmazon Linux上で実施する

$ cat /etc/system-release
Amazon Linux AMI release 2018.03

まずはApacheのインストールと起動

sudo yum install -y httpd24
sudo service httpd start

Apache自動起動設定も行っていく

sudo chkconfig httpd on

ここで一旦Apacheが動いているか動作確認

http://EC2インスタンスIPアドレス/ にアクセスして以下が表示されたらOK

Amazon Linux Test Page
Amazon Linux Test Page

次はドキュメントルートにファイルを配置して正常に表示されるかの確認

ドキュメントルートのデフォルトディレクトリに移動

cd /var/www/html/

index.htmlを以下の内容で作成

<p>Hello, World!!</p>

再度 http://EC2インスタンスIPアドレス/ にアクセスしてHello,World!!が表示されたらOK

次はPHPのインストールを行っていく

sudo yum install -y php72

下記の内容でindex.phpをindex.htmlと同じディレクトリに配置

<?php
phpinfo();

このままだと優先順位がindex.html > index.phpなのでindex.htmlが表示されてしまうので
Apacheの設定を変えていく

まずはバックアップを取る

sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak

次にvimhttpd.confを開いて

sudo vim /etc/httpd/conf/httpd.conf

DirecotryIndexをindex.htmlから

<IfModule dir_module>
    DirectoryIndex index.html
</IfModule>

index.phpに変更

<IfModule dir_module>
    DirectoryIndex index.html
</IfModule>

httpd.confはApacheの起動時にしか読み込まれないのでApacheを再起動

sudo service httpd restart

http://EC2インスタンスIPアドレス/ にアクセスして以下が表示されたらOK

result phpinfo();
phpinfo

次はMySQLのインストールと起動

sudo yum install mysql57-server -y
sudo service mysqld start

MySQLに入って

mysql

MySQLのユーザー作成と権限追加

create user ユーザー名 identified by 'パスワード';
grant all privileges on *.* to 'ユーザー名'@'%';

データベースとテーブルの作成
テーブルはテスト用のユーザーテーブルとする

create database データベース名;
create table test_user (id int auto_increment, name varchar(20));

あとで使うためにレコードを追加しておく

insert into test_user (name) values ('任意のユーザー名');
insert into test_user (name) values ('任意のユーザー名');
insert into test_user (name) values ('任意のユーザー名');

mysqlから出る

exit


PHPからMySQLを使うのに必要なものをインストール

sudo yum install php72-pdo php72-mysqlnd php72-mbstring -y

上記のインストールを有効にするためにApacheを再起動

sudo service httpd restart

以下の内容でindex.phpを更新

<?php

$dsn = 'mysql:host=localhost;dbname=データベース名;charset=utf8';
$user_name = ユーザーネーム;
$password = パスワード;

try {
        $pdo = new PDO($dsn, $user_name, $password);
        echo 'Success';
} catch (Exception $e) {
        echo 'Error.';
        exit($e->getMessage());
}

SUCCESSと表示されればOK

次は実際にDBから値を取得する

index.phpを以下に更新

<?php

$dsn = 'mysql:host=localhost;dbname=backlog_app;charset=utf8';
$user_name = ユーザー名;
$password = パスワード;

try {
        $pdo = new PDO($dsn, $user_name, $password);
	$test_users = $pdo->query("select * from test_user");
	foreach($test_users as $user) {
		echo "$user[name]<br>";
	}
} catch (Exception $e) {
        echo 'Error.';
        exit($e->getMessage());
}

http://EC2インスタンスIPアドレス/ にアクセスして先程DBに登録して任意のユーザー名
が表示されればOK

これでMySQLのセットアップは終了

これからLaravelのセットアップを行う

まずはLaravelのパッケージマネージャーであるcomposerをインストールする

ホームに戻って

cd /home/ec2-user

公式の手順https://getcomposer.org/download/にしたがって行う

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'e0012edf3e80b6978849f5eff0d4b4e4c79ff1609dd1e613307e16318854d24ae64f26d17af3ef0bf7cfb710ca74755a') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

その後ファイル名の変更とデフォルトでPATHの通ったディレクトリに移動する

mv composer.phar /usr/local/bin/composer

以下のコマンドで

composer -V

以下が表示されたらOK(2020/3/10時点でのバージョン)

Composer version 1.9.3 2020-02-04 12:58:49


Composerがinstallできたら/var/www/html配下でLaravleプロジェクトの作成

composer create-project --prefer-dist laravel/laravel .

その後以下のコマンドで依存ライブラリのインストールとアップデート

composer install
composer update


そして/etc/httpd/conf/httpd.confのドキュメントルートを
/var/www/html/から/var/www/html/publicに修正

DocumentRoot "/var/www/html/public"

これでhttp://EC2インスタンスIPアドレス/にアクセスしたらLaravelのテストーページが表示されるはず

Laravel Test Page
Laravel Test Page

これで最低限のLaravelの環境構築が完了

次はVue.jsのセットアップ
Lravelは公式でVue.jsをサポートしているので非常に簡単

laravel/uiパッケージをインストールして
Vue.js用にファイルを生成

composer require laravel/ui
php artisan ui vue

そしてnode.js

レポジトリの取得してインストールして最新に更新

curl -sL https://rpm.nodesource.com/setup_13.x | sudo bash -
sudo yum install -y nodejs
sudo npm update -g npm

そして/var/www/html配下で

npm install && npm run dev

して依存パッケージをインストール、ビルドする

するとresources/js/components配下にExampleComponent.vueが生成させているのでこれを利用する

/var/www/html/resources/views配下にexample.blade.phpというファイル名で
以下のファイルを作る

<div id="app">
        <example-component></example-component>
</div>
<script src="{{asset('js/app.js')}}"></script>

/var/www/laravel/routes配下のweb.php

Route::get('/', function () {
    return view('welcome');
});

部分を

Route::get('/', function () {
    return view('example');
});

に変更する

これでhttp://EC2インスタンスIPアドレス/にアクセスすると

example.blade.php
example.blade.php

こう表示されるはず

最後にLaravelでMySQLの設定をして簡単なリスト表示をする

まずはAPIの呼べているかの確認

routes/web.phpを以下に変更してテスト用のAPI作成

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('sample');
});

Route::get('/test', function() {
    return 'This is test.';
});

次にExampleComponent.vueを以下に変更

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Example Component</div>

                    <div>{{ testData }}</div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                testData: '',
            }
        },
        mounted() {
            this.updateTableData()
        },
        methods: {
            updateTableData() {
                axios
                    .get('/test')
                    .then(response => this.testData = response.data)
            },
        }
    }
</script>

これで準備完了

http://EC2インスタンスIPアドレス/にアクセスする

f:id:carametal:20200317210013p:plain
Index Page

これが表示されるはず

次はweb.phpを以下に変更する

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('sample');
});

Route::get('/test', 'TestController@index');

そして/var/www/html/app/Http/Controllers配下にTestController.phpを以下の内容で作成

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Test;

class TestController extends Controller
{
    public function index()
    {
        return 'This is TestController.';
    }
}

http://EC2インスタンスIPアドレス/にアクセスすると以下が表示される

f:id:carametal:20200317210013p:plain
Index Page TestController

次は/var/www/html/.env以下の部分を

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=

以下に変更(各項目はMySQLに設定済みの項目)

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=データベース名
DB_USERNAME=ユーザー名
DB_PASSWORD=パスワード

そしてTestController.phpを以下に変更

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;

class TestController extends Controller
{
    public function index()
    {
        $testUsers = DB::select('select * from test_user;');
        return $testUsers;
    }
}

ExampleComponent.vueを以下に変更

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Example Component</div>

                    <div v-for='user in testUsers'
                        :key='user.id'
                    >
                        {{ user.id }}: {{ user.name}}
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                testUsers: '',
            }
        },
        mounted() {
            this.updateTableData()
        },
        methods: {
            updateTableData() {
                axios
                    .get('/test')
                    .then(response => this.testUsers = response.data)
            },
        }
    }
</script>

http://EC2インスタンスIPアドレス/にアクセスすると

f:id:carametal:20200317212202p:plain
Index Page TestUsers

このような表示になるはず

これで環境構築終了

まとめ

これでタイトルの「AWS EC2にLarabel + MySQL + Apache + Vue.jsの環境を一歩ずつ作ってみる」を終えることができた

今回実際に環境を作ってみたけどまだまだ知識が足りていないと改めて実感した。
以前大ハマリしたおかげかVue.jsの導入はスムーズだったがLaravelとApacheは今回の記事に載せてないエラーに
たくさん遭遇した。そのたびにエラーメッセージを検索をかけては解決策を調べて世界のどこかにいる人たちに力を借りて
解決した。

まだまだエントリの書き方もまとまってないしブログを書く習慣もないけど一つずつエントリを増やしてこのブログと一緒に成長していけたらいいなと思う。

Dockerを使ってPHP7+Apache+MySQLの開発環境を作る

今回は前回に引き続き実技試験の予習として開発環境を作っていく

前回はPHP7+Apacheまで作ったのでMySQLを含めた環境を作っていく
carametal.hatenablog.com

こちらの記事を参考にさせていただきました。

qiita.com

こちらの記事ではMySQLクライアントにphpMyAdminを使っていますが
ひとまず環境構築のみの目的なのでphpMyAdminは扱いません。

前回の記事ではDockerfileを用いていましたが今回はdocker-composeで環境を作っていきます。

手始めにdocker-compose.ymlを作成

version: '3'

services:
  php:
    image: php:7.2-apache
    volumes:
      - ./html:/var/www/html
    ports:
      - 8000:80
    container_name: php7.2-trial2
  mysql:
    image: mysql:5.7
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=test
      - MYSQL_USER=test
      - MYSQL_PASSWORD=test
    container_name: mysql5.7-trial2
    

ほとんど参考にさせていただいた記事からの流用ですが

phpのimageは前回記事同様にphp:7.2-apacheを使用
volumes項目でカレントディレクトリにあるhtmlディレクトリを
コンテナ内の/var/www/htmlにマウント
公開ポートは8000番、ポートフォワーディング先は80番に指定
ビルド後のコンテナ名にphp7.2-trial2を指定

mysqlのimageにはmysql5.7を使用
volumes項目で./mysqlを/var/lib/mysqlにマウント(ここはよくわかっていないけどディレクトリがなくてもdocker-compose up したときに自動的に作られるみたい※要調査)
environment項目では環境変数を設定し
コンテナ名にmysql5.7-trial2を指定

docker-compose.ymlはこれで完了

htmlディレクトリにはindex.phpを配置する

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>php7.2-apache</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<?php
    echo 'Hello world.';
?>
</body>
</html>mysql5.7-trial2

index.phpは一旦echoでHello world.するようにする(あとでDBのデータを取得するように変更します)

最後にphp.ini
phpの設定ファイルなわけですが今回はお試し環境構築なのでこちらから拝借させていただきました
qiita.com

以上で必要なファイルはそろいました

docker-compose up -d 

でコンテナの作成&実行する

docker container ps

を実行してphp7.2-trial2とmysql5.7-trial2の2つのコンテナが起動していれば成功

http://localhost:8000/にアクセスしてHello worldと表示されるはず

次はMySQLにアクセスしてDBから取得したtextを表示してみる

まずはmysql5.7-trial2コンテナに入って

docker exec -it mysql5.7-trial2 bash

MySQLにログイン

mysql -uroot -proot
  • uはログインユーザの指定
  • pはパスワードの指定

この2つはdocker-composeで指定したものを使用する

mysqlにログインできたら

show databases;

とするとMYSQL_DATABASEにtestと設定しているので一覧にtestというDBがあるはず

use test;
show tables;

当然まだtableはまだないはずなのでEmpty set (~~~ sec)と表示されるはず

tableを作ってテストデータを作る

create table test (id int not null auto_increment, text char(30), primary key (id));
insert into test (text) values ('first test.');
insert into test (text) values ('second test.');
insert into test (text) values ('second test.');
select * from test;

+----+--------------+
| id | text         |
+----+--------------+
|  1 | first test.  |
|  2 | second test. |
|  3 | third test.  |
+----+--------------+

これが出たら準備は完了

index.phpを修正する

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>php7.2-apache</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<?php
try {
    $dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root');
    foreach($dbh->query('select * from test') as $row) {
        echo $row['text'] . '<br>';
    }
    $dbh = null;
} catch (PDOException $e) {
    echo $e;
    die();
}
$dbh = null;
?>
</body>
</html>

これでtestデータベースのtestテーブルのデータが表示される

と思ったが

Fatal error: Uncaught PDOException: could not find driver in /var/www/html/index.php:11

というエラーが

どうやらPDO(PHP Data Object)にMySQL用のドライバーがないというエラーの模様

今回の対応として公式のphp:7.2-apacheではなくドライバー入りのimageを作って
そっちを使うようにする

まず、以下のようなDockerfileを作る

FROM php:7.2-apache
RUN docker-php-ext-install pdo_mysql

そしてこれをbuildする

docker image build -t php7.2-apache-trial2 .
||>

このとき、php.iniやhtmlディレクトリのあるディレクトリでビルドすると下記のようなエラーが出ることがあるので注意

>||
error checking context: 'no permission to read from '/home/carametal/dev/docker/soltwarks/trial2/mysql/ca-key.pem''.

これはカレントディレクトリ配下をDockerfile内の命令からアクセス可能な範囲として指定されるため発生するらしい(以下の記事参照)
developer-collaboration.com

imageのビルドができたらdocker-compose.ymlを修正

version: '3'

services:
  php:
    image: php7.2-apache-trial2
    volumes:
      - ./html:/var/www/html
    ports:
      - 8000:80
    container_name: php7.2-trial2

  mysql:
    image: mysql:5.7
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=test
      - MYSQL_USER=test
      - MYSQL_PASSWORD=test
    container_name: mysql5.7-trial2

phpの指定imageをphp:7.2-apacheから今回新しくbuildしたphp7.2-apache-trial2に変更するだけ

さぁこれでDBから取得したデータが表示されるはず

PDOException: could not find driver in /var/www/html/index.php:12 Stack trace: #0 /var/www/html/index.php(12): PDO->__construct('mysql:host=mysq...', 'root', 'root') #1 {main}

と思いきやこのようなエラーメッセージが出てきてしまった

これは正直めちゃくちゃハマったんだけどこちらの記事のおかげで助かりました
qiita.com
内部的にどんな処理になってるのかわからないんだけど
PDOのコンストラクタに渡すhostはlocalhostではだめで

<?php
// NG
$dbh = new PDO('mysql:host=localhost;dbname=test', 'root', 'root');
//OK
$dbh = new PDO('mysql:host=mysql5.7-trial2;dbname=test', 'root', 'root');

docker-compose.ymlのcontainer_nameで指定しているコンテナ名にしなければならないらしい
ローカルにそのままMySQLサーバーを立てるんだったらlocalhostでいいんだろうけど
Dockerを使っている場合はコンテナ名を指定しなきゃいけない

ということでhttp://localhost:8000/にアクセスしたら

first test.
second test.
third test.

と表示されます

なんとかphp7+Apache+MySQL開発環境をDockerで作る目標を達成しました。

Dockerもいいけど明日からは実技試験に向けてPHPのコードを書いていきたい

面接とSPI試験の対策もしておかなきゃなぁ

Dockerでapacheサーバーを立ててphpでHello worldするまで

Django+PostgreSQLの環境を作る予定だったけど先日、3年くらい前から憧れていた札幌の企業に
エントリーしたらPHPでの実技試験があるとのことだったので、予習をすることに

今回はその第一弾としてphpの開発環境(DBなし)までやっていこうと思う。

まずはindex.phpの用意
ファイルはカレントディレクトリに作る

<?php
<!-- index.php -->
<?php
echo 'Hello world!!';

Hello Worldするだけなのでとても簡単

次はDockerfileの作成

作らなくてもできるけどindex.phpを毎度コピーするのは面倒なので作る
なんとDockerには最初からphpapacheがセットになった公式イメージがあるので
今回も目的はとても簡単に達成できる
hub.docker.com

# Dockerfile
FROM php:7.2-apache
LABEL maintainer="carametal"
COPY ./ /var/www/html/

今回はmaintainerを設定してみた
maintainerはだれが管理しているimageなのかを示すラベルで
個人開発だし世の中に出すわけじゃないけどお試し

COPY命令でカレントディレクトリをコンテナの/var/www/htmlにコピーすることで
カレントディレクトリのindex.phpとDockerfileが/var/www/html配下にコピーされる

apacheは「IPアドレス/」へのアクセスに対して/var/www/html/index.phpをデフォルトで実行するので
これでOK

あとはビルドして実行する

docker build -t php7.2-apache .
docker container run --rm -d -p 8000:80 --name php-test php7.2-apache

これでhttp://localhost:8000/にアクセスするとHello world!!と表示される

次回はMySQLを入れて簡単なDBアクセスを実行するところまでやっ見る予定

Dockerを使ってcentosコンテナ内にnginxサーバーをたてる

前回はdockerでnginx環境を立てたので今回は一歩進めてcentosコンテナ内にnginxを立ててみようと思う

前回の記事はこちら
carametal.hatenablog.com

そして今回はこちらの記事を参考にさせていただきました
qiita.com

前回はdockerでnginxコンテナを実行するだけで良かったけど今回は
centosコンテナの中にnginxサーバーをたてるのでコンテナを実行するだけでは実現できない

centosコンテナを実行してコンテナ内に入ってコマンドを叩くだけでも良いが
Dockerを使うのであれば簡単に環境を作り直せるようにDockerfileを使っていく

結論から言うと

カレントディレクトリに以下のようなDockerfileを作り

FROM centos:8
RUN /bin/sh -c 'yum install -y nginx'
CMD ["nginx", "-g", "daemon off;"]

以下のコマンドを流すだけでcentosコンテナ内にnginxサーバーをたてることができて
http://localhost:9000/ にアクセスするとnginxのテストページが表示されるようになる

docker build -t centos-nginx .
docker container run -d --rm -p 9000:80 --name test-centos-nginx centos-nginx

せっかくなので掘り下げてみる

まずはDockerfileについて

FROM centos:8

ではFROM命令を使って使用するイメージを指定する
FROM命令はDockerfile内で一番最初に書く必要がある(コメントを除く)
今回はcentosコンテナを利用するためcentosを指定し、現在の最新版であるcentos8を使用するため
オプションでタグを指定してcentos:8とした

RUN /bin/sh -c 'yum install -y nginx'

ではRUN命令を使ってnginxをcentos内にインストールしている
RUN命令はシェル形式とexec形式と呼ばれる2つの形式があり今回使用しているのはシェル形式と呼ばれている方
/bin/sh/ -c」の部分でシェルスクリプトを実行する用のインタプリタを指定
あとに続く「yum install -y nginx」でnginxのインストールを実行している
yumはRed Had系のLinuxディストリビュージョンで使用されるパッケージ管理コマンドのひとつ
Ubuntuでいうとapt-getに当たるもの、-yオプションはインストール時の質問(yes/no)をすべれyesにしてくれる便利なオプション

RUN命令をシェル形式で実行する場合、インタプリタの指定は「/bin/sh -c」がデフォルトで設定されているため

RUN yum install -y nginx

のように省略できる。

ちなみにexec形式で今回のRUN命令を書くと以下のようになる

RUN ["/bin/sh", "-c", "yum install -y nginx"]

最後の

CMD ["nginx", "-g", "daemon off;"]

ではCMD命令を使ってnginxサーバーを起動している
RUN命令はシャル形式exec形式のどちらでも良いようだがCMD命令はexec形式が推奨されているので
exec形式を使用している
docs.docker.jp

パラメータで渡している「-g」はグローバル設定ディレクトリというものを指定するためのオプションで
daemon off;」はその引数になり、nginxがデーモンになるべきか(バックグラウンドで動くべきか)どうかを
指定している今回は「off」にしているのでnginxはフォアグラウンドで動く

なぜこんなものを指定しているのかというと
nginxを動かすだけなら「nginx」コマンドで事足りるのだが
Dockerコンテナ内で動かす際はフォアグラウンドで動かしていないと
コンテナ自体が即座に終了してしまうらしい
以下の記事が参考になりました

qiita.com

実際にDockerfileを

FROM centos:8
RUN yum install -y nginx
CMD ["nginx"]

として

docker build -t centos-nginx-damon-on .
docker container run -d --rm -p 9000:80 --name test-centos-nginx centos-nginx

のようにコマンドを流してみたところ
正常にコンテナが生成されるものの

docker container ps

で実行中のコンテナを確認してもtest-centos-nginxは一覧になく
コンテナが終了してしまったいることが確認できた

ひとまず目的である「centosコンテナ内にnginxサーバーをたてる」が達成できたので
今日はこんなところで終了

この調子でDjango+PostgreSQL環境を作っていきたい

nginxのDockerコンテナを立てるまで

docker container run -d -p 8000:80 --name test_nginx nginx:latest

これだけだった。

  • d - バックグラウンド実行
    • name - コンテナの名前指定
  • p ポート指定 8000は外部からのアクセス時のポート番号、80はポートフォワーディング設定
  • pオプションだけあんまりよくわかってなかったのでちょっと調べてみた

qiita.com

この記事によると8000番(Dockerコンテナ)へのリクエストをコンテナ内部の80番(nginx)に転送する感じかな?

ためしに

docker container run -d -p 9000:81 --name test_nginx2 nginx:latest

してみたけどnginxの初期表示のページが出てこなかった。
nginxのポートはデフォルトが80番みたいなので上記の解説であってるはず

タイトルは達成したけどさすがに短すぎるので停止と再起動を試す

docker container stop test_nginx

このコマンドでコンテナが停止する

docker container start test_nginx

これで起動

一回docker runすると

docker container start -p 9000:80 test_nginx

みたいにあとからオプションを変更することができないので開発中なんかは

docker container run -d --rm -p 8000:80 --name test_nginx nginx:latest

のように--rmオプションをつけて
コンテナを停止するごとに自動的に削除されるようにするのが一般的らしい

ちなみに今回は全部「docker container run」みたいにcontainerをつけたけど
「container」は省略できるから

docker run -d --rm -p 8000:80 --name test_nginx nginx:latest

とかでも同じことができる

目標も達成したし今日はここまで

Django でpython3 mange.py startapp ~~~ がエラーになった

前から予定していた掲示板アプリを実際に作り始めたところすぐに詰まったので特にハマったわけでもないけど記録

 django-admin startproject boardproject

からの

python3 manage.py startapp board

で以下のエラー

Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "/home/carametal/.local/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/home/carametal/.local/lib/python3.6/site-packages/django/core/management/__init__.py", line 357, in execute
django.setup()
File "/home/carametal/.local/lib/python3.6/site-packages/django/__init__.py", line 24, in setup
apps.populate(settings.INSTALLED_APPS)
File "/home/carametal/.local/lib/python3.6/site-packages/django/apps/registry.py", line 91, in populate
app_config = AppConfig.create(entry)
File "/home/carametal/.local/lib/python3.6/site-packages/django/apps/config.py", line 90, in create
module = import_module(entry)
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'board

どうやら python3 manage.py startapp board する前にINSTALLED_APPSに 'board'を追加してしまったこと原因らしい。

内部的にどんな処理か見てないけどsettings.INSTALLED_APPS内にすでに新規に作ろうとしているアプリ名があると
同じエラーが出るみたい。

INSTALLED_APPSに追加するのはstartapp後、簡単なことなのでしっかり覚えていきたい。

 

「小さなチーム、大きな仕事」を読んでみた

前回に引き続き組織論系の本を読んだので感想を書いていく。

今回は2冊目「小さなチーム、大きな仕事」について

 

小さなチーム、大きな仕事〔完全版〕: 37シグナルズ成功の法則

小さなチーム、大きな仕事〔完全版〕: 37シグナルズ成功の法則

  • 作者: ジェイソン・フリード,デイヴィッド・ハイネマイヤー・ハンソン,黒沢 健二,松永 肇一,美谷 広海,祐佳 ヤング
  • 出版社/メーカー: 早川書房
  • 発売日: 2012/01/11
  • メディア: 単行本
  • 購入: 21人 クリック: 325回
  • この商品を含むブログ (39件) を見る
 

全体的な感想

もっとチームを運用する上での知識やTIPSが載っている本かと思ったけどそうではなくて、心構えや意識的な内容が多かった。初めて見るような内容はほとんどなかったが、バイブル的にたびたび読み返してみると目の前の問題を解決する糸口をつかめるかもしれない。そんな印象を受けた。前回読んだ「エンジニアリング組織論への招待」とは違った理解できないよな内容はまったくなく、スラスラと読むことができた。しかし、難しくなくシンプルだからこそ強力な効果が得られるんじゃないだろうか。これは依然読んだ「SIMPLE RULES」で書かれていた基本的で簡潔な美しいルールの先にこそ素晴らしい成果が待っている。という考えに通づるものがある気がする。

 

SIMPLE RULES 「仕事が速い人」はここまでシンプルに考える (単行本)

SIMPLE RULES 「仕事が速い人」はここまでシンプルに考える (単行本)

 

 「小さなチーム、大きな仕事」は厳格なルールに関する本ではないけど、自分、もしくはチームの判断基準、行動指針として徹底していくべき本だと思った。

印象的だった内容 

顧客を(あなたよりも)成長させよう

 心惹かれた内容はいくつもあったが特別刺さってきたのがこれ。

僕は現在、SESによる客先常駐で仕事をしていてあまりチームとして知見が溜まってどんどん成長する組織の中にいるわけではない。なので常駐先によってはコードは汚いしパフォーマンスもよくない、技術的に成長しようという意思が感じられないようなメンバーも少なくない。そんな状況からもっと技術的に優れたプロジェクトへ移りたい、自社開発の企業へ移ってその中で成長したいと感じることが多かった。今でも自社開発をしたいという思いは変わらないが、チームへの不満をもったままにするよりもそのチームを成長に導くという考えをするべきだった。

たしかに今後のことを考えると自社開発、特に自社製品を持つ企業で経験を積みたいがそれはあくまで今後の方針で会って今すぐにできることではない。結局、今できることをするしかない。そう考えたときに今できるベストのことは客先のチームを成長させることしかないと思う。じゃあチームにどう影響を与えられるかと考えたときに、チームメンバーと比較して僕が優れているのはきれいなコードを書くことや、若い世代の考えを伝えることという結論に至った。きっとチームを成長に導くことができれば、自分にとっても大きな成長、大きな経験になるのだと思う。

無名であることを受け入れる

 今まさに僕がそうなのだが、無名であることは多大なメリットがあると教えてくれた章。有名になる、つまり規模が大きくなり人気がでてくるとリスクが小さい行動をとらざる負えなくなり、保守的にならざる負えない。無名であるというのは成功者であるというプライドを失うこともない。そんなときにこそ他人にあれこれ指摘されずに失敗を繰り返して成長をすることができる。次々と新しい挑戦を繰り返すことこを今すべきこと。自分のことを考えるとやはり失敗したときのリスクが怖くて挑戦ができなくなってしまうが、無名で何も持たない今だからこそ挑戦のリスクは少ない。どんどん挑戦して失敗を重ねていこうと思う。本書では失敗から学ぶことは過大評価されすぎている。という章もあるが、失敗ばかりで成功しない状況と、成功の中に失敗があるのではまるで状況が違う。成功することも大事だが、成功しかないという状況は新たな挑戦ができていないということでもある。無名の今だからこそリスクを負った挑戦ができる。心にとめて日々挑戦していきたい。

まずは作り始めよう

 この章に書かれていることはアイディアなんて持っていても意味がない。なんでもいいから作り始めろということ。僕は将来、自社開発を行う企業で自社製品開発をしたいと思っている。自社製品開発で活躍するには技術力だけでなく、製品を成長させるための知見やアイディアが必要になる。その経験を積むためにまず技術力を身に着けて自社製品を持つ企業に転職する必要があると思っていた、実はそうではない。まず、自分で何かを作ることが何よりも大事で、自分で作ったことがあるという経験が自社製品開発のための大きな経験になるし、技術力の成長にもつながる。そしていざ自分で何かを作るとなったときに、何を作ればよいのかと思ってしまうこともある。この章に例として書かれている通り、一番大事なのは始めることでまずはなんでもいいから作る。作りながらより良い作るべきモノや、作り方を学んでいけばいい。僕自身技術を身に着けようと技術書を読んだり、チュートリアルをやってみたり、Qiitaや技術ブログのTIPSを漁ったりを繰り返してきたが、今やるべきことはオリジナルの製品を作り出すことで、作りながら成長していくこと。なのでこのブログが書き終わったらさっそくブログアプリでも作ろうと思う。前にUdemyで作った掲示板アプリにリプライ機能を追加してみるのもいいかもしれない。

まとめ

 振り返ってみると印象に残ったことは「まずやれ」ばかりで、いかに自分が行動不足か思い知らされる。正直、読む前に期待していた内容とは全然違ったが成果を出すための内容が詰まっていて本当に読んでよかった。今はチームをまとめる立場ではないので僕個人が成長していくためという視点で読んでしまったが、もっとチームの中心を担うようになったときにはまた違った見方ができると思う。前回読んだ「エンジニアリング組織論への招待」も含めて、チーム・組織運用で悩んでいるリーダーやマネージャー、経営者は読んでおいて損はないと思う。また僕のようにいまいちなチームに物申したい。いつかチームをまとめる側になったときのために組織論を学んでおきたいという人には心からおすすめできる書籍でした。

 

小さなチーム、大きな仕事〔完全版〕: 37シグナルズ成功の法則

小さなチーム、大きな仕事〔完全版〕: 37シグナルズ成功の法則

  • 作者: ジェイソン・フリード,デイヴィッド・ハイネマイヤー・ハンソン,黒沢 健二,松永 肇一,美谷 広海,祐佳 ヤング
  • 出版社/メーカー: 早川書房
  • 発売日: 2012/01/11
  • メディア: 単行本
  • 購入: 21人 クリック: 325回
  • この商品を含むブログ (39件) を見る
 

 

 

エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング

エンジニアリング組織論への招待 ~不確実性に向き合う思考と組織のリファクタリング