プロビジョニングツールをChef-soloからItamaeに替えてみました

Chef から Itamae ?

EY-Officeではサーバーソフトの構築を行うプロビジョニングツールとして現在は Chef-solo を使っています。しかし Chef-solo は終了するらしいのですが、その移行先が良いように思えず悩みながら使い続けてきました。

そんなとき登場してきた Itamae はシンプルでとても魅力を感じました。詳しくは クックパッド開発者ブログのItamae記事 をご覧下さい。

今回時間があったので、EY-Officeの開発支援サーバー (Redmine, Git/Gnatara, CI ...)の全プロビジョニングをChefからItamaeに置き換えてみました。書き換えたレシピは約700行です、そこで感じた事を書きます。

Itamaeの良いところ、良くないところ

1. 情報が貧弱

まず良くない点ですが、Chefのドキュメント に比べると情報の量、質ともに低いです。どうしても思ったように動作しない場合は Itamae の実装を読むことが度々ありました。

公式なドキュメントは

今回、参考になった情報は

2. Chefとは動作モデルが違うぞ!

最初に戸惑ったのでは、Chefとの動作モデルの違いです。

Chef-solo の利用イメージは

  1. Chefを開発環境にインストール
  2. 利用開始時にChefのRubyインタプリターを含む実行環境をターゲットにインストール (knife solo prepare コマンド)
  3. レシピの作成・修正
  4. 実行 (knife solo cooke コマンド)
    1. レシピの文法チェック等
    2. レシピを含むcookbookをターゲットへ転送
    3. レシピをターゲットで実行
  5. 問題があれば 3.に戻る

ですが、Itamaeは

  1. Itamaeを開発環境にインストール
  2. レシピの作成・修正
  3. 実行 (itamaeコマンド)
    1. レシピに対応する操作をsshを使いターゲット上で実行
  4. 問題があれば 2.に戻る

ChefのレシピのRubyコードはターゲット上で実行されますが、Itamaeはレシピは開発環境で実行されます。 したがって、ターゲットの状況によって処理を変更する部分、たとえば not_ifonly_if にはRubyのコードは書けず、shellのコードを書く必要があります。

Chef

execute "apt-get-update" do
  command "apt-get update"
  only_if { File.mtime('/var/lib/apt/lists') < Time.now - 86400 }
end

Itamae

execute "apt-get-update" do
  command "apt-get update"
  only_if "exit $(( `stat -c %Y /var/lib/apt/lists` > (`date +%s` - 86400) ))"
end

実行時にターゲット上の情報を動的に取得できないので、今回はレシピ(コード)で自動的に取得するのをあきらめnode で指定するようにした部分もありました。

3. Chefに似ているけど・・・

Itamae のResource (DSL, 命令?)はChefと似た作りになっていて、そのまま動くものもありますが、少し違う部分もあります。また無いものもあります。

  • Chef の cooke_fileremote_file
  • Chef の remote_file に相当するものは無い?
  • ファイル等のモード指定に8進数が使えない
  • useraction: :modify が出来ない
  • cron Resource が無い
  • ・・・

4. defineを使おう

無いResourceを簡単に作れる Definitions があり、これを使って足りないResourceを補いました。

# URL指定でネット上のファイルをダウンロードするResource
define :external_file, url: nil, owner: nil, group: nil, mode: nil do
    p = params

    execute "download #{p[:name]} from #{p[:url]}" do
        cmd =  "curl -s -f -L -o #{p[:name]} #{p[:url]}"
        cmd += " && chown #{p[:owner]} #{p[:name]}"  if p[:owner]
        cmd += " && chgrp #{p[:group]} #{p[:name]}"  if p[:group]
        cmd += " && chmod #{p[:mode]} #{p[:name]}"   if p[:mode]

      command cmd
      not_if "test -e #{p[:name]}"
    end
end

# crontab 設定用 Resource
define :cron_for, crontab: nil do
  user = params[:name]
  crontab = params[:crontab]
  crontab_path = "/tmp/crontab.#{rand(10000)}"

  file crontab_path do
    content crontab
    not_if "crontab -u #{user} -l"
  end

  execute "crontab -u #{user}" do
    command "crontab -u #{user} #{crontab_path} && rm #{crontab_path}"
    only_if "test -e #{crontab_path}"
  end
end

利用レシピ

ruby_package = "ruby-2.2.2"
external_file "/usr/local/src/#{ruby_package}.tar.bz2" do
  url "http://cache.ruby-lang.org/pub/ruby/2.2/#{ruby_package}.tar.bz2"
end

cron_for "root"  do
  crontab <<-EOH
#
PATH=/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
30 5 * * * /usr/local/bin/backup.sh >> /var/tmp/bakup.log  2>&1
  EOH
end

Chef の cron Resource は crontab形式を知らなくてもDSLで設定出来るようになっていましたが、define であまり高度な機能を作る事は考えない方が良いと思いました。やってみると直ぐに限界が見えます。

どうしても高度な Resourceが必要な場合は Quirra: itamae resourceの書き方 を参考に Resource を作った方が良いと思います。

5. シンプルで早い

動作モデルの違いやResourceの充実度の違いはありますが、Itamaeはレシピが実行されるまでの時間が早くとても快適です!

Chef-soloを利用していて、複雑化するChefの推奨移行環境に疑問を持つ方は、ぜひ一度 Itamaeを試してみると良いと思います。

今回作ったレシピ

今回作ったレシピの一部です(ubuntu 14.04用です)

execute "apt-get-update" do
  command "apt-get update"
  only_if "exit $(( `stat -c %Y /var/lib/apt/lists` > (`date +%s` - 86400) ))"
end


execute "ensure ja_JP.UTF-8" do
  command "locale-gen ja_JP.UTF-8"
  not_if "grep -c 'ja_JP.UTF-8' /var/lib/locales/supported.d/local"
end

execute "ensure JST" do
  command <<-EOH
echo "Asia/Tokyo" | sudo tee /etc/timezone
sudo dpkg-reconfigure --frontend noninteractive tzdata
  EOH
  not_if "date | grep -c 'JST'"
end

# shell を zsh に変更 (ユーザーは node[:user]で指定)
file "/etc/passwd" do
  action :edit
  block do |content|
    content.gsub!("/home/#{node[:user]}:/bin/bash", "/home/#{node[:user]}:/bin/zsh")
  end
end

postgreSQLをインストールし DBのencoding, localeを変更する

%w{postgresql-9.3 libpq-dev postgresql-client-9.3 postgresql-contrib-9.3}.each do |pkg|
  package pkg do
    action :install
  end
end

service "postgresql" do
  action [:start, :enable]
end

link "/usr/local/bin/psql" do
  to "/usr/local/pgsql/bin/psql"
end

execute "initdb" do
  user "postgres"
  cwd "/var/lib/postgresql/9.3/"
  command <<-EOH
rm -rf main
/usr/lib/postgresql/9.3/bin/initdb -D main --encoding=UTF-8 --locale=ja_JP.UTF-8
rm main/pg_hba.conf main/pg_ident.conf main/postgresql.conf
ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem main/server.crt
ln -s /etc/ssl/private/ssl-cert-snakeoil.key main/server.key
EOH
  action :nothing
end

execute "re-initdb with ja_JP.UTF-8" do
  command "echo re-initdb"
  notifies :stop, 'service[postgresql]', :immediately
  notifies :run, 'execute[initdb]', :immediately
  notifies :start, 'service[postgresql]', :immediately
  not_if "/usr/lib/postgresql/9.3/bin/psql -U postgres -c \"select * from pg_database where datname ='template0'\" " +
    "| grep -c 'ja_JP.UTF-8'"
end

注) specinfra 2.41.1 で Ubuntu14.04でPostgreSQL起動中判定の問題が対処されたので暫定パッチは不要になりました :-)

GitLabを使ったプライベートGitリポジトリーの管理を止め改造版 Ginatra にしました。

プライベートGitリポジトリーの管理

私の会社 EY-Ofiice零細企業なので プライベートGitリポジトリーGitHub等の有料サービスではなく、さくらクラウド上のサーバーで GitLab を動かしてきました。 しかし、

  • 通常の開発は一人でしか行わないのでpull request等の機能はいらない
  • GitLabは処理が重くサーバーのメモリーを増やさないと遅すぎる
  • 複数人で開発するような仕事ではお客様側でGitHub等を用意してくれる
  • 教育でGitLabを使う事があるが、その時だけGitLab用サーバーを用意すれば良い気がする

ということで、あまりメリットを感じていませんでした。

Gitを使い始めた頃は GitWeb でリポジトリーや履歴が表示と。自作した新規リポジトリー作成CGIで運用していました。

Ginatra

Git用のWebツール を見ていたらSinatraベースの Ginatra ( GitHub ) を知り、インストールしてみました。

Ginatraは Gitリポジトリーのファイル(コード)や履歴の表示ツールです。Sinatraベースなので動作も軽いし、メンテも楽で、今風の画面デザインも気に入りました。

Ginatraの改造

ただし、不満もあり Fork し機能を追加。変更しました。

1. リポジトリーの階層化

Ginatraは複数のGitリポジトリーディレクトリーをサポートしていますが、フラットに管理しています。EY-Officeでは docs(ドキュメント), edu(教育用), products(製品)・・・などのディレクトリーの下にGitリポジトリーを置いています。GitLabには Groupという機能がありこれを使っていました。

やはり、グループが無いと不便なので Repo クラスに group属性を追加し group:nameレポジトリーの識別子として使うように改造しました。 また、一覧表示は Bootstrap の Collapse(Accordion) を使い表示するようにしました。

f:id:yuum3:20150811153016p:plain

2. 新規リポジトリーの作成

Web上かから新規にGitリポジトリーが作成作成出来るようにしました。Ginatraで使っているRugged (libgit2のRubyインターフェース)に git init のAPIがあったので簡単にできました。

f:id:yuum3:20150811153029p:plain

3. その他

などです。まだ RSpec を修正していません ^^;

RedmineのコンテンツをMarkdownに変換しました

Textile vs Markdown

軽量マークアップ言語にはたくさんの種類があります。私も教育で使うテキストの作成やRedmineWikiでは長年 Textile を使って来ました。 しかし、最近はGithubの標準のマークアップ言語がMarkdownだったり、Atom(エディター)をはじめたくさんのMarkdownをサポートするツールが現れ、私も MacDownというツールが気に入り開発ドキュメント等のMarkdown化がどんんどん進んでいます。このブログもはてな記法ではなくMarkdownを使っています。

TextileとMarkdownを比べると 標準のMarkdown は記述能力が低くテキストを作るには能力不足ですが、 GitHubの拡張php Markdown Extra などの拡張機能を使えば、ほぼ同等です。

Redmine

Redmineマークアップ言語のデフォルトはTextileですが、Version 2.5からMarkdownをサポートするようになりました。ただし、Redmineサーバー全体の設定なので新規にRedmineを始める人以外には使いにくいものでした。 redmine_persist_wfmtのようなプラグインを使えばコンテンツ(Wiki, Ticket...)単位でTextitle/Markdownが選択できるのでこれを使えば良いかもしれません。

しかし、私はRedmineWikiを教育でよく使っています。お客様毎に教育で使うコード、ヒント、参考情報・・・などをWikiを使い提供しています。しかも以前に作ったWikiを元に作成する事が多いので、そのTextileとMarkdwonが混在するのは望ましくありません。

そこで、Textileコンテンツを全てMarkdownに変換してしま事にしました。

Textile to Markdown

"Convert Textile to Markdown" で検索すると Pandoc というドキュメント変換ツールが良く出来てきます。このツールは色々なドキュメント形式を相互変換できる素晴らしいツールですが、やはり完璧ではありませんでした。 Markdown→TextileではGitHub拡張をサポートしていますが、Textile→MarkdownではテーブルをGitHub拡張に変換してくれたりしません・・・

そこで、自作を検討しました。MarkdownとTexitleは似ています、正規表現を使えばほとんど変換できます。

def textile_to_markdown(textile)
  d = []
  pre = false
  table_header = false
  text_line = false

  textile.each_line do |s|
     s.chomp!

    if pre
      if s =~ /<\/pre>/
        d << "~~~"
        pre = false
      else
        d << s
      end
      next
    end

    s.gsub!(/(^|\s)\*([^\s\*].*?)\*(\s|$)/, " **\\2** ")
    s.gsub!(/(^|\s)@([^\s].*?)@(\s|$)/, " `\\2` ")
    s.gsub!(/(^|\s)-([^\s].*?)-(\s|$)/, " ~~\\2~~ ")
    s.gsub!(/"(.*?)":(.*?)\.html/, " [\\1](\\2.html) ")

    d << ""  if text_line
    text_line = false

    case s
    when /^<pre>/
      d << "~~~"
      pre = true
    when /^\*\*\* (.*)$/
      d << "      * " + $1
    when /^\*\* (.*)$/
      d << "   * " + $1
    when /^\* (.*)$/
      d << "* " + $1
    when /^\#\#\# (.*)$/
      d << "      1. " + $1
    when /^\#\# (.*)$/
      d << "   1. " + $1
    when /^\# (.*)$/
      d << "1. " + $1
    when /^h(\d)\. (.*)$/
      d << "#" * $1.to_i + " " + $2
    when /^!(.*?)!/
      d << "![](#{$1})"
    when /^\|_\./
      d << s.gsub("|_.", "| ")
      table_header = true
    when /^\|/
      d << s.gsub(/\=\..+?\|/, ":---:|").gsub(/\s+.+?\s+\|/, "---|") if table_header
      table_header = false
      d << s.gsub("|=.", "| ")
    when /^\s*$/
      d << s
    else
      d << s
      text_line = true
    end
  end

  d.join("\n") + "\n"
end

このコードは全てのTextileフォーマットをサポートしているわけではありませんが、私が使ってる機能はほぼ網羅しています。 変換されたMarkdownはGitHub拡張やphp Markdown Extraの機能を使っています。

さてRedmineでは色々なところにTextileが書けますが、今回は Wiki, Ticket, Ticketの履歴のコンテンツに対応しました。必要があれば追加して下さい。

def update_content(model, attrbute)
  total = model.count
  step = total / 10
  puts "  #{model}.#{attrbute} : #{total}"
  model.all.each_with_index do |rec, ix|
    n = ix + 1
    puts sprintf("%8d", n)   if n % step == 0
    rec[attrbute] = textile_to_markdown(rec[attrbute])  if rec[attrbute]
    rec.save!
  end
end

update_content(WikiContent, :text)
update_content(Issue, :description)
update_content(Journal, :notes)

コードは Gistにも置きました。

このコードを以下のように runnder で実行するとTextileがMarkdownに変換されます。

$  rails runner -e production tools/textile2md.rb  

注意: このプログラムは全てのTextile形式を変換できるものではありません、またバグ等で正しく変換できない場合もありますので、変換前に必ずRDBのバックアップを取って下さい。

iOS 開発者のためのバックエンド入門 (2)

iOS開発者の勉強会 yidev 第20回勉強会iOS 開発者のためのバックエンド入門 (2) という発表をしました。 iOSだけでなく、Androidの開発者の方にも参考になる話だと思います。

今回の内容は、Ruby on Railsを使い簡単なバックエンドをその場で作ってみるという実演付きの話をしました

Ruby, Ruby on Railsに付いて

Ruby on Rails を使い簡単なバックエンドを作る

  • クライアントになるiOS アプリの紹介 ーー Swiftで作りました
  • Ruby on RailsのScaffoldでバックエンドを作る実演

f:id:yuum3:20150712112536p:plain

バックエンドをHerokuにデプロイ

  • 出来たバックエンドを代表的なPaaS (Platform as a Service) である、Heroku にデプロイする
    • ライブラリー構成を少し変え、Herokuにgit pushするだけでデプロイが完了
    • Herokuへのデプロイ手順はHerokuのページにもありますが、RailsGirlのHeroku の Rails アプリをアップページ が判りやすいです

コード、資料

使ったコードは GitHub におきました

iOS 開発者のためのバックエンド入門 (1)

iOS開発者の勉強会 yidev 第18回勉強会iOS 開発者のためのバックエンド入門 (1) という発表をしました。 iOSだけでなく、Androidの開発者の方にも参考になる話だと思います。

今回の発表で伝えたかった事は

バックエンドを作るにはいろいろな選択肢がある

  • Parse.comに代表される BaaS (Backend as a Service)を使うとプログラミングやサーバーの構築なしにバックエンドが持てます。ただしBaaS側が提供している機能(データ共有、プッシュ通知...)出来ることには限界があります。
  • BaaSの中には StrongLoopのように、プログラミング出来る自由度の高いものもあります。
  • たいていのBaaSは、お試し的な利用は無料ですが負荷が高くなると課金されます。ビジネスの場合にはコスト的にも独自のバックエンドを作るという選択もあります。
  • 独自のバックエンドを作る場合には、プログラミング言語フレームワーク... とたくさんの選択肢があります。これはどの用途でもベストという解答はないので、目的に応じて選んで下さい。

独自のバックエンドを作る場合、最初はPaaSがお勧め

インフラは知識だけでなく、安定したインフラを運用して行くには経験も必要になります。

しかし、Heroku に代表される PaaS (Platform as a Service) を使うとインフラの知識(エンジニア) 無しに始められのでお勧めです。

APIフレームワークGrapeをRuby on Railsの中で動かすと遅いぞ

ある仕事でスマフォ用のAPIサーバーを作る事になり、REST-like APIが簡単に作れるフレームワーク grape を調査してみました。grapeの良さは、DSLで簡単にAPIサーバーが書ける点とRackで動く軽いフレームワークなのでRuby on Railsに比べ高いパフォーマンスが期待できる点です。

システム構成

Grapeは Mounting に書かれているようにいくつかの構成で動かせます

今回のシステムでは管理者用のWebアプリは Ruby on Railsで作るので、モデルを共有できるRuby on Railsに組み込み使うのが魅力的です。

評価用コードを作ってみた

準備

  • まずはRailsのプロジェクトを作り、scaffoldでいつものアプリを作成
$ rails new api_test
$ cd apt_test
$ rails g scaffold todo due:date task:string
  • テストデータ作成 db/seed.rb も作成
Todo.delete_all
100.times { |i| Todo.create!(due: Time.now + i.day, task: sprintf("task%02d", i)) }
  • 性能比較のために app/views/todos/index.json.jbuilder を変更
json.array!(@todos) do |todo|
  json.extract! todo, :id, :due, :task, :created_at, :updated_at
end

Grape

grape ページの情報を基に API を作成

  • Gemfile
source 'https://rubygems.org'
  ....
gem 'grape'
  • API のコード
class SimpleApi < Grape::API
  version 'v1'
  format :json

  resource :todos do
    desc "Return all todos."
    get  do
      Todo.all
    end
  end
end
  • config/routes.rb に APIをマウント
Rails.application.routes.draw do
  resources :todos
  mount SimpleApi => '/api'
end
  • config/application.rb にAPIのコードを読み込むように設定
module ApiTest
  class Application < Rails::Application
    ....
    config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
    config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
  end
end

これで http://localhost:3000/api/v1/todos をアクセスするとtodosテーブルの全内容がJSONで取得できます

性能が気になる

Ruby on Railsのコードも http://localhost:3000/todos.jsonJSONを返せるます。grapeがどれくらい性能が良いのかを比較してみました。

比較する環境は実際の環境に近くなるように

  • RAILS_ENV は production
  • サーバーは unicorn、worker_processes は 4
  • アプリは EC2 t2.micro で実行
  • ただし、RDBはsqlite3のまま、Nginx等のフロントエンドは無し

ab -c 8 -n 1000 URL で性能を計測

Framework Requests per second
Grape within Rails 33.66
Ruby on Rails 34.49

Grape の性能は Ruby on Rails と同じくらい!? もちろん、テストデータ、abのパラメータにより多少状況は変わりますが・・・

ActiveRecord without Railsを試した

Rackの上で直接動くシンプルな grape の性能がこんなに低いのは納得出来なかったので、ActiveRecord without Rails で試してみました

  • Rackの上で動かす grape.ru を作成
require 'grape'
require 'active_record'
require 'sqlite3'
require_relative 'app/api/simple_api'
require_relative 'app/models/todo'

use ActiveRecord::ConnectionAdapters::ConnectionManagement
ActiveRecord::Base.configurations = YAML.load_file('config/database.yml')
ActiveRecord::Base.establish_connection(:production)

run SimpleApi

この grape.ru を指定し unicorn 起動

Framework Requests per second
Grape 56.65

Ruby on Rails に比べ 1.6倍の性能が出ました!

結論

テスト中のサーバーのメモリー使用量も調べてみました。実メモリ使用量(RES)は Ruby on Railsに比べると半分以下です。

Framework Requests per second VIRT(memory) RES(memory)
Grape within Rails 33.66 345308 91828
Ruby on Rails 34.49 345308 91828
Grape 56.65 253472 38852

結論としては、grape を使って API サーバーを作るなら Rackベースで起動し、 Ruby on Railsとは別に動かした方が良い。

ただし、開発時は Ruby on Railsの中で動かした方が開発しやすいかも知れませんね。

開けましておめでとうございます。本年もEY-Officeをよろしくお願いいたします。

2015年、開けましておめでとうございます。

本年も吉田裕美ならびに、EY-Officeをよろしくお願いいたします。お正月休みに考えた事を少し書いてみました。

f:id:yuum3:20150105103907j:plain

すし処佐治のおせち料理

EY-Officeの歴史を振り返った

2000年に長年勤めたCADのベンチャー企業から独立し EY-Office という会社を作り1人で仕事を始めました。開発や教育の仕事自体は私一人で行っていますが、お金の面を中心に大塚絵理さんに助けてもらっている2人の会社です。

もう独立してから、15年に成ろうとしています。そこで簡便的に5年に区切りまとめてみます。

2000〜2004年

独立し開発を始めたとはいえ、実はお仕事の殆どは一つの会社から受託していました。以前行っていたCADの開発とはまったく違うWeb系の仕事で色々な事を学ばせて頂きました。そして、その会社の売り上げの中心になるサービースのWeb Application Framework を作りました。CADの会社でもCADのベースになる図形データを扱う基本部分を作ってきた経験が生かせ、その会社の社長の経験や発想を混ぜたユニークなフレームワークが出来たと思っています。

また、Perl言語を使って開発していたので Perlのコミュニティーである Shibuya.pm に参加し、色々な方と知り合えたり、他の技術系のコミュニティー(例えば Seasarプロジェクト) などにも参加するようになっていきました。

2005〜2010年

一つの会社から受託していると その会社の経営状況に依存します、またコミニュティーなどを通じて得た新しい技術を試すことも出来なくなります。

そして一つの会社の仕事を行っていると、サラリーマンとそれほど変わらない立場、メンタルになってしまします。そこで、コミニュティーなどを通じて知り合った方などに紹介して頂いた新しい会社とのお付き合いが始まりました。

この時期にEY-Officeにとって大きな事がおきました。一つは、開発でお付き合いのあった会社から「教育」を行ってくれないかという依頼があり、コミニュティーの学んだスタイルを元におそるおそる教育を行ってみました。 長年開発しかしてこなかったので、講師としての能力の低さを痛感しながらも教えるのは面白いなと感じました。

さらに、空前のRuby on Railsブームが起こり、キャッチアップするために Rails勉強会@東京 に参加するようになりました、超出来るプログラマー達が集まる勉強会はとても刺激的でした。そして何回か参加する頃から初心者向けのセッションを行うようになっていきました。これが現在の EY-OfficeのRuby on Rails教育へと繋がって行きました。

2010〜2014年

Ruby on Rails教育 はEY-Officeという会社としての初めてのビジネスだったのかも知れません。しかし営業力もなく、Ruby on Railsブームも開発者だけでの盛り上がりで教育ビジネスでだけで食べて行くことはできず、受託開発も行いながらたまに教育を行うというスタイルが続きました。ただし、2012年頃から経営層にもRuby on Railsが届いたようで、大企業からも教育の注文が来るようになってきました。

しかし教育の仕事を絶えず取るのは難しいです、しばらく仕事絶えてしまう事もありました、そんなあるとき iPhoneMacも持っているのだからiPhone開発でもやってみるか! という感じで勉強でアプリを作ったり、受託でアプリを作ったりしました。 iPhoneの開発情報は当初NDAで保護されていた事もあり開発コミニュティー等が少なかったのですが、ある時期から勉強会が始まり参加するようになりました。 自分が勉強して来た事は教育コンテンツとして教えられると判っていたので、iPhone開発の教育も始めました。ある時期はかなり需要がありましたが、現在はあまり需要がないようです。

仕事が絶えてしまった時にコミニュティーで知り合った方から仕事を頂いたり、たくさんの方のおかげで何とかやっている状況でした。

さて今年はどうしようか

昨年は、このブログ、会社のホームページ 開発の仕事を募集したのですが、ほぼありませんでした。教育の仕事はある程度あるのですが、夏は暇で(Docker, Node.js,Swift,Go..など)たくさんのお勉強をする時間に恵まれてしまいました ^^;

昨年末に、以前お世話になった方から小規模の開発の仕事を頂きました。その方と話をしていた時に、受託はどうしてもお客様に依存してしまうので、やはり自社で何かビジネスをしないとダメなのではと言われました。

また最近はベンチャーがたくさん立ち上がって来ていますが、最初から開発者を抱えて自分たちのビジネスを育てています。以前に比べると技術者の流動化は高まっていて、魅力的なビジネス・経営者であれば優秀なエンジニアをリクルートしやすくなり、フリーの技術者に頼る必要性が下がってきたのかも知れません。 開発会社としてのEY-Officeや開発者としての吉田裕美というのは知名度が低すぎマーケットに届いていないと思います。

そこで、今年はどうするかですが、

  • 教育ビジネスも力を入れて行っていきます。
  • 受託の開発案件も引き続き探します、よろしくお願いいたします。
  • 今のところ、自社サービスやアプリの目処はないですが、今年はあいている時間で思いついた、小さなアプリやサービスをリリースしていきたいと思います。少しずつアイデアを貯めています・・・・
  • 頂いた仕事は、開発も教育も自分の力を出し切りがんばって行きます。

さらに個人的には

  • 英語力の無さを痛感しています。挨拶程度の会話は出来ますが、現在は issueを書いたり質問をしたり出来る能力が不足しています。中学校2年くらいですでに英語を捨てていたの単語力や基本的な文法力がありません。先ずはこの辺をクリア出来るようにしたと思います。
  • 歳をとり体力が落ちています、近くの公園でのジョギングを毎週おこなうように心がけます、昨年も時々行っていたのですが、ついつい行かない時期がありました。

結論

お仕事募集中です !