使用Docker创建开发环境
首先
在Docker上建立开发环境有很多信息可供参考,但有些信息已经过时或配置不同,因此我们进行了一些尝试和错误,暂时总结如下。顺便提一句,目前我们并没有在生产环境中使用Docker,只是为了方便地搭建开发环境而使用它。
目前正在开发中的服务由以下组件构成:
– Ruby on Rails 4
– MySQL
– memcached
– redis
– nginx
Docker引入前后的变化
我们公司为每个员工的个人电脑配置了开发环境。
我通常在设置环境时安装了一些依赖模块,例如mysqld、memcached和ImageMagick,但是构建过程需要花费很长时间,而且版本可能会有所不同,导致我经常要花费整整一天的时间来完成。
通过使用Docker搭建开发环境,即使电脑是全新的状态,只需30分钟即可完成设置并开始开发。
虽然我们刚刚开始实施,但我最近真切地感受到了一个效果:实习生一加入,他们立即投入开发并保持初期的动力,这对我们来说非常重要。
做过的事情 de
1. 引入必要的工具组
因为发布了包含了VirtualBox等所有内容的Docker Toolbox,所以只要用这个就可以了。
使用brew cask的人可以通过以下命令安装dockertoolbox:
$ brew cask install dockertoolbox
2. 建立基础形象
需要一个能够运行Ruby(rails)的镜像。虽然官方提供了预装Ruby的镜像文件,但是为了创建一个与Amazon Linux相等的环境,我决定自己基于CentOS创建镜像。除了Ruby之外,还使用yum添加了ImageMagick等当前服务所需的软件。
顺便提一句,最开始我想从Amazon Linux的AMI创建和使用Docker镜像,但是由于yum只能在AWS环境中访问的初级问题而被卡住了,所以放弃了。
因此,关于图像的创建,首先要准备Dockerfile。
FROM centos:centos6
RUN yum -y update
RUN yum -y install gcc git rsync tar openssl openssl-devel readline-devel zlib-devel libffi-devel gdbm-devel tk tk-devel tcl tcl-devel patch gcc-c++ which sqlite-devel wget openssh-server file
RUN yum -y install http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
RUN yum -y install mysql mysql-devel ImageMagick
# rbenvのインストール
RUN git clone https://github.com/sstephenson/rbenv.git /root/.rbenv
RUN git clone https://github.com/sstephenson/ruby-build.git /root/.rbenv/plugins/ruby-build
RUN ./root/.rbenv/plugins/ruby-build/install.sh
ENV PATH /root/.rbenv/shims:/root/.rbenv/bin:$PATH
RUN echo 'export PATH=/root/.rbenv/shims:/root/.rbenv/bin:$PATH' >> /root/.bashrc
RUN echo 'eval "$(rbenv init -)"' >> /root/.bashrc
# rubyのインストール
ENV CONFIGURE_OPTS --disable-install-doc
RUN rbenv install 2.2.2
RUN rbenv global 2.2.2
RUN rbenv rehash
RUN rbenv exec gem install bundler
ENV APP_HOME /app
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
ADD Gemfile* $APP_HOME/
RUN bundle install
我最後執行了bundle install,但在每個人的環境中執行docker-compose build時,我認為最好將其安裝在能夠永久保存gem的區域。然而,由於某些情況,我無法成功地將其放置在適當的位置。因此,由於Docker的特性,每次更新Gemfile都需要執行docker-compose build。然而,由於每次都從頭開始安裝各個gem太耗時間且令人煩躁,所以我選擇在某一時間點上保留了已安裝好gem的狀態,以便在短時間內完成Build。
一旦准备好上述文件后,可以进行docker构建。(在此之前需要执行docker-machine create 命令。)
docker-machine create --virtualbox-disk-size 3000 -d virtualbox dev
eval "$(docker-machine env dev)"
docker build -t my-dockerhub-repository/centos6-ruby2.2.3 .
此外,我已将生成的映像上传至Docker Hub,以便每个个人的PC都能使用它。由于无需使用私有存储库,因此可以在免费计划中完成(可能是这样)。
将”my-dockerhub-repository/centos6-ruby2.2.3″推送到Docker Hub的命令。
3. 准备设置文件
首先,我會將設定檔案完整地放在下方。解說會稍後提供。以下是該設定檔案放置在Rails的根目錄下。
#由於為了保密某些資訊,我已修改了一些內容,因此可能因輸入錯誤等原因而無法正常運作。
FROM my-dockerhub-repository/centos6-ruby2.2.3
ENV APP_HOME /app
WORKDIR $APP_HOME
ADD Gemfile* $APP_HOME/
RUN bundle install
ADD . $APP_HOME
EXPOSE 3000
CMD ["bundle", "exec", "rails", "s"]
mysql:
image: mysql:5.6.23
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- '3306:3306'
volumes:
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
volumes_from:
- datastore
redis:
image: redis:2.8.19
ports:
- '6379:6379'
volumes_from:
- datastore
memcached:
image: memcached:1.4.24
ports:
- '11211:11211'
volumes_from:
- datastore
datastore:
build: docker/datastore
web:
build: .
ports:
- '3000:3000'
environment:
RAILS_ENV: development
MYSQL_ROOT_PASSWORD: 'password'
DATABASE_HOST: mysql
REDIS_HOST: redis
MEMCACHED_HOST: memcached
dns:
- 8.8.8.8
volumes:
- .:/app
volumes_from:
- datastore
links:
- mysql
- redis
- memcached
FROM busybox:latest
VOLUME /var/lib/mysql
VOLUME /data
CMD /bin/sh
简单解释
可以在 docker-compose.yml 文件中轻松定义 memcached、mysql、redis 等依赖关系。
由于需要设置MySQL为utf8mb4,因此我定义了使用本地的my.cnf配置文件。
为了持久化数据库信息,我们使用busybox保存 /data 和 /var/lib/mysql。我们准备了 docker/datastore/Dockerfile,并在 docker-compose.yml 中将其定义为 datastore。
主要的 Dockerfile 看起来非常简单,只是复制了 Gemfile 并运行了 bundle install。当运行时,会执行 rails s 并且将 3000 端口映射到容器的端口(不确定这个表达是否正确)。
修改Rails侧的database.yml等配置文件。
尽管可以使用Docker构建开发环境,但过去一直在本地构建环境的人可能仍希望继续这样开发。此外,为了确保在引入Docker后,如果出现问题可以回退到以前的开发方式,我们还确保可以在没有Docker的情况下无问题地进行开发。
如果环境变量已定义,将使用该环境变量;否则将查看 localhost 的设置。
development:
<<: *default
database: db
encoding: utf8mb4
charset: utf8mb4
collation: utf8mb4_general_ci
host: <%= ENV["DATABASE_HOST"] || "localhost" %>
port: 3306
password: password
请确认在docker-compose.yml中定义了名为 DATABASE_HOST 的环境变量。
同样地,请设置memcached和redis的主机信息。
4. 在每台個人電腦進行設置。
我的Mac初装状态下,只安装了git、dockertoolbox和文本编辑器,就能开始开发了。
安装
$ docker-machine create --driver virtualbox dev
$ eval "$(docker-machine env dev)"
$ docker-compose build
迁移
$ docker-compose run web bundle exec rake db:create db:migrate db:seed RAILS_ENV=development
$ docker-compose run web bundle exec rake db:create db:migrate RAILS_ENV=test
**立ち上げ**
$ docker-compose up
默认的URL访问地址为:http://192.168.99.100:3000
进行测试
$ docker-compose run web bundle exec rake spec
请注意:当你更新了Gemfile时。
$ docker-compose build
不要忘记去做。
常见问题解答
建立完成并重新启动后,应该执行哪个命令?
请执行下面的3个指令。
$ docker-machine start
$ eval "$(docker-machine env dev)"
$ docker-compose up
我想要用”Pry”。
docker-compose run --service-ports app
启动时可以做到。
但是,采用这种启动方式时,有时在结束时进程无法正确终止,导致下次启动时端口被占用,有时会变得很麻烦。
有点不知为何,docker-compose up不能再启动了。
有时会发生一些原因不明的事情,虽然不经常发生。
$ docker-compose stop
$ docker-compose kill
试试看周围的地方。如果不行的话
$ docker-machine restart
$ eval "$(docker-machine env dev)"
或什么。 (huò
如果那样还不行的话
$ docker-machine rm dev
从一开始就进行设置。
MySQL等无法启动
在本地检查是否正在运行 mysqld 和 memcache。由于端口冲突,如果有重叠,无法启动。
供应商/捆绑包共享的问题
由於無法成功設置 .dockerignore,所以問題尚未解決。在本地使用指定路徑的形式(例如:bundle install –path vendor/bundle)進行 bundle install,會導致在 Docker 環境中也使用了該 .bundle/config 文件,進而導致 Rails 無法正常啟動。刪除 .bundle/config 後問題得以解決。
最后
在Docker上直接使用SSH登录并在那里直接编辑文件的方式也是不错的,我也考虑过这种方式,但经过多次尝试,我最终选择了这种形式。还有其他选择,比如尝试使用docker-osx-dev,但要找到最合适的方案确实有些困难。
因为我刚开始运营,所以可能会出现问题。
如果有任何问题,请留下评论,谢谢。