フリーランスエンジニア4年目の2017年振り返り
遅ればせながらフリーランスエンジニアとして4年目の2017年の振り返りです。
個人開発
個人開発で多産多死を行っている状態でした。利益を出したいためにアフィリエイトを中心に置いたサービスの開発を行っていたのですが、SEOやアフィリエイト周りのことに注力する時間が多くなり開発へのモチベーションが下がってしまう難しい状況でした。一方で、アフィリエイターの方々は職人的な気質の人が多く文化としても近いため、姿勢や取り組み方など勉強になりました。どこに軸を置くにせよ、2017年は結果を残せなかったことが大きな反省点でした。年末にpeingを開発したせせりさんの存在を知り、そのスタンスが個人開発者として目標とする姿に近かったため、2018年に何かしら活かしたいと思いました。
情報収集
2017年はヨーロッパを一周しました。アジアは日本も含めてビルがひしめき合い中心地は「都市」というイメージですが、ヨーロッパはロンドン以外ほとんどそういった印象を持ちませんでした。街中はゆったりしたスケール感覚で、都心エリアでも建物は低層が中心でした。ヨーロッパの人がアジアに対してサイバーパンク的なイメージを持つ理由も何となく分かりました。しかし、UberEats的な配達員の人を街中で見かける回数はヨーロッパのほうが多く、伝統的な街の雰囲気の中で先端サービスのチャレンジが受け入れられているような印象でした。ベルリンのsoundcloud社など有名サービスのオフィスも(外側から)見てまわりました。
業務委託
長くお付き合いをさせていただいた企業様との契約が終わり、新しい企業様との契約を結びました。今回はリモートワークの割合を増やしました。朝の満員電車から解放され、通勤時間も節約できるため、個人的にはリモートワークのほうが合っています。実際にやってみた感想としては、リモートワークは個人の努力だけでなくリモートワークを受け入れる会社側の土壌も必要だと思いました。今回お世話になっている企業様ではリモートワークを推奨していて、特に開発チームのトップの方が率先して文化や仕組みをつくっているため、リモートで非常に働きやすい環境が用意されていました。リモートで働く側としては、この文化を壊さないため・発展させるために、リモートで働く上での信頼関係をつくることを意識的に取り組みました(レスの速度を上げる・開発の過程を残すなど)。このあたりは勉強中のため2018年の課題の1つです。
仕事場
北向きの部屋で作業していると煮詰まった時に滅入ってしまうため、南向きの物件に移りました。古いですが、とていもいい物件で気に入っています。ただ古い物件なりの課題(寒い・コンセントの数少ない等)があるので徐々に解決できればと。
2018年に向けて
新しいことへのチャレンジや新しい分野の勉強をはじめたい一方で、現在仕事で使っているRuby/RoRの基礎をしっかり固めたい気持ちもあります。今年は6:4ぐらいの割合で基礎固めを多めにしたいなと思っています。この記事を書いている時点で年が明けて1ヶ月経ちそうですが、現在は「プロを目指す人のためのRuby入門」をすすめています。読み終えたらRailsチュートリアルにうつる予定です。
プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plusシリーズ)
- 作者: 伊藤淳一
- 出版社/メーカー: 技術評論社
- 発売日: 2017/11/25
- メディア: 大型本
- この商品を含むブログを見る
Rails+Capistrano環境でデプロイ
Rails+Capistranoでデプロイした時のメモ
Gitで管理
Capistrano
GitHub - capistrano/capistrano: Remote multi-server automation tool
動作確認用に最小限の設定です。設定等はお好みで適宜変更してください。(記事に関係ない部分は一部省略している箇所もあります)
- Gemfile
group :development do gem 'capistrano', '~> 3.10' gem 'capistrano-rails' gem 'capistrano-rbenv' gem 'capistrano-bundler' gem 'capistrano3-unicorn' end
$ bundle install $ bundle exec cap install mkdir -p config/deploy create config/deploy.rb create config/deploy/staging.rb create config/deploy/production.rb mkdir -p lib/capistrano/tasks create Capfile Capified
- config/deploy/production.rb
set :branch, 'master' server '192.0.2.0', user: 'username', roles: %w{web app db} role :app, %w{username@192.0.2.0} role :web, %w{username@192.0.2.0} role :db, %w{username@192.0.2.0} # ポートフォワーディングを利用する場合 set :ssh_options, { keys: %w(~/.ssh/id_rsa), forward_agent: true, auth_methods: %w(publickey) }
- Capfile
require 'capistrano/setup' require 'capistrano/deploy' require 'capistrano/rails' require 'capistrano/rails/assets' require 'capistrano/rails/migrations' require 'capistrano/rbenv' require 'capistrano/bundler' require 'capistrano3/unicorn' require 'capistrano/sitemap_generator' require 'whenever/capistrano' require "capistrano/scm/git" install_plugin Capistrano::SCM::Git Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
- config/deploy.rb
# config valid only for current version of Capistrano lock "3.8.0" set :application, "my_app_name" set :repo_url, "git@example.com:me/my_repo.git" set :deploy_to, "/var/www/nginx/example.com" set :pty, true set :linked_files, "config/database.yml", "config/secrets.yml" set :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system" # rbenv set :rbenv_type, :user set :rbenv_ruby, '2.5.0' set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec" set :rbenv_map_bins, %w{rake gem bundle ruby rails} set :rbenv_roles, :all # unicorn set :unicorn_pid, "#{shared_path}/tmp/pids/unicorn.pid" set :unicorn_config_path, "config/unicorn.rb" # whenever set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:stage)}" } before 'deploy:publishing', 'db:seed_fu' after 'deploy:publishing', 'deploy:restart' namespace :deploy do task :restart do invoke 'unicorn:restart' end end after 'deploy:restart', 'deploy:sitemap:create'
- unicorn.rb
app_path = "/var/www/nginx/example.com" working_directory "#{app_path}/current" pid "#{app_path}/shared/tmp/pids/unicorn.pid" listen "#{app_path}/shared/tmp/sockets/unicorn.sock" stderr_path "#{app_path}/shared/log/unicorn.stderr.log" stdout_path "#{app_path}/shared/log/unicorn.stdout.log" worker_processes 3 timeout 15 preload_app true before_exec do |server| Dotenv.overload ENV['BUNDLE_GEMFILE'] = "#{app_path}/current/Gemfile" end before_fork do |server, worker| if defined?(ActiveRecord::Base) ActiveRecord::Base.connection.disconnect! end old_pid = "#{server.config[:pid]}.oldbin" if File.exists?(old_pid) && server.pid != old_pid begin Process.kill("QUIT", File.read(old_pid).to_i) rescue Errno::ENOENT, Errno::ESRCH end end end after_fork do |server, worker| if defined?(ActiveRecord::Base) ActiveRecord::Base.establish_connection end end
動作確認
$ bundle exec cap production deploy:check
参考リンク
DeviseとOmniAuthで複数のSNSを利用して認証する
DeviseとOmniAuthで複数のSNSを利用して認証する機能を開発した時のメモ。
全体の流れ
参考リンク
- OmniAuth with multiple models
- [Devise How-To] OmniAuth認証を複数のモデルで共用する方法(翻訳)
ポイント
- Userモデルから:omniauthable引数を削除する(ここに気づかずにはまった)
Controller周り
参考リンク
Model周り
omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'] end
get '/auth/:action/callback', controller: 'authentications', constraints: { action: /twitter/ }
app/controllers/authentications_controller.rb
class AuthenticationsController < ApplicationController auth = request.env['omniauth.auth'] end
https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview#facebook-example https://github.com/omniauth/omniauth/wiki/Managing-Multiple-Providers
$ rails g model Authentications user:references provider uid access_token access_secret
class CreateAuthentications < ActiveRecord::Migration[5.0] def change create_table :authentications do |t| t.references :user, foreign_key: true, null: false t.string :provider, null: false t.string :uid, null: false t.string :access_token t.string :access_secret t.timestamps end add_index :authentications, [:provider, :uid], unique: true end end
authentication.rb
class Authentication < ApplicationRecord belongs_to :user validates :user_id, presence: true validates :provider, presence: true validates :uid, presence: true, uniqueness: { scope: :provider } end
https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview#facebook-example
参考
https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview https://github.com/plataformatec/devise/wiki/OmniAuth-with-multiple-models https://techracho.bpsinc.jp/hachi8833/2017_05_18/40208 https://github.com/omniauth/omniauth/wiki/Managing-Multiple-Providers https://qiita.com/awakia/items/03dd68dea5f15dc46c15 http://sinsoku.hatenablog.com/entry/2016/01/03/090000 https://qiita.com/kami_zh/items/94aec2d94a2b4e9a1d0b
node.jsをインストール
node.jsをインストールした時のメモ
$ brew install nodebrew $ nodebrew -v $ nodebrew ls-remote $ mkdir -p ~/.nodebrew/src $ nodebrew install-binary v8.9.3 $ nodebrew ls $ nodebrew use v8.9.3 $ nodebrew ls v8.9.3 current: v8.9.3 $ node -v -bash: node: command not found
~/.bash_profile
export PATH=$HOME/.nodebrew/current/bin:$PATH
$ source ~/.bash_profile $ node -v v8.9.3 $ npm -v 5.5.1
参考
BL902HWの子機にWLI-UTX-AG300/Cを設定
- 親機:BL902HW
- 子機:WLI-UTX-AG300/C
BUFFALO 11n/a/g/b 300Mbps 簡単無線LAN子機 WLI-UTX-AG300/C
- 出版社/メーカー: バッファロー
- 発売日: 2012/08/01
- メディア: Personal Computers
- 購入: 1人 クリック: 3回
- この商品を含むブログ (4件) を見る
加えてMacbookAirでWLI-UTX-AG300/Cの設定を行うためLANアダプタを購入。
BUFFALO 10/100M USB2.0用 LANアダプタ 【Nintendo Switch, Wii,Wii U,MacBookAir動作確認済】 LUA3-U2-ATX
- 出版社/メーカー: バッファロー
- 発売日: 2009/08/01
- メディア: Personal Computers
- 購入: 58人 クリック: 288回
- この商品を含むブログ (28件) を見る
Androidローカライズの参考リンク
Androidでローカライズする方法の参考リンク。
Android StudioのTranslations Editorを使うと便利そうなので試してみる。