我想在我们的CI工具CircleCI中尝试让Rails和MSSQL交谈。我在Mac上工作,所以设置它是相当痛苦的。我使用Homebrew在本地安装了FreeTDS。然后我产生了一个MSSQL docker镜像,并在我的rails应用程序中设置我的配置指向它,一切正常。
CircleCI有点不同。
我做了以下事情。
在我的gemfile中添加:
# mssql database gems
gem 'tiny_tds'
gem 'activerecord-sqlserver-adapter'
修改了我们的database.yml文件:
default: &default
adapter: sqlserver
pool: 5
encoding: utf8
mode: dblib
development:
<<: *default
host: localhost
database: collections_development
username: sa
password: P@55w0rd
test:
<<: *default
host: localhost
database: collections_test
username: sa
password: P@55w0rd
我用:
构建了一个泊坞窗图像FROM circleci/ruby:2.4.1-node-browsers
RUN set -ex \
&& sudo apt-get install build-essential \
&& sudo apt-get install libc6-dev \
&& sudo wget -O freetds-1.00.54.tar.gz "ftp://ftp.freetds.org/pub/freetds/stable/freetds-1.00.54.tar.gz" \
&& sudo tar -xzvf freetds-1.00.54.tar.gz \
&& cd freetds-1.00.54 \
&& sudo ./configure \
&& sudo make \
&& sudo make install
此图片托管于docker hub here。
接下来我构建了CircleCI配置:
version: 2
jobs:
build:
working_directory: ~/collections-api
docker:
- image: legendaryrob/ruby:2.4.1-node-browser-freetds54-lib6c
environment:
RAILS_ENV: test
- image: microsoft/mssql-server-linux
environment:
ACCEPT_EULA: Y
SA_PASSWORD: P@55w0rd
environment:
RAILS_ENV: test
steps:
- checkout
- restore_cache:
name: Restore bundle cache
keys:
- collections-api-bundle-{{ checksum "Gemfile.lock" }}
- run:
name: Allow CI to read from pdg gemserver
command: bundle config https://gems.pdg.io/ $GEMS_USERNAME:$GEMS_PASSWORD
- run:
name: Bundle Install
command: bundle install --path vendor/bundle --jobs 4 --retry 3
- save_cache:
name: Store bundle cache
key: collections-api-bundle-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:1433 -timeout 1m
- run:
name: test tds connection
command: tsql -C
# Run setup
- run: ./spec/setup/circle_setup.sh
- run:
name: Create the database
command: bundle exec rake -v --trace db:create
- run:
name: Migrate the database
command: bundle exec rake -v --trace db:migrate
- run:
name: Check environment variables are present
command: bundle exec rake env_variables:check
- run:
name: Run tests
command: bundle exec rspec
我直接从Microsoft的docker hub帐户获取的MSSQL docker镜像 - &gt; https://hub.docker.com/r/microsoft/mssql-server-linux/
在这里你可以看到几件事。我设置了我用TDS安装的ruby盒子以及所需的所有依赖项。我确保我们使用的是我们在本地使用的相同版本的TDS,因为它在本地工作,我还尝试了一些其他版本,只是因为我正在处理一个flakey版本。
我还确保我们可以连接到MSSQL docker box并确保我们有正确的tds配置:
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:1433 -timeout 1m
- run:
name: test tds connection
command: tsql -C
这将产生以下结果:
#!/bin/bash -eo pipefail
dockerize -wait tcp://localhost:1433 -timeout 1m
enter code here
2017/09/01 09:25:40 Waiting for: tcp://localhost:1433
2017/09/01 09:25:40 Problem with dial: dial tcp 127.0.0.1:1433:
getsockopt: connection refused. Sleeping 1s
2017/09/01 09:25:41 Problem with dial: dial tcp 127.0.0.1:1433:
getsockopt: connection refused. Sleeping 1s
2017/09/01 09:25:42 Problem with dial: dial tcp 127.0.0.1:1433:
getsockopt: connection refused. Sleeping 1s
2017/09/01 09:25:48 Connected to tcp://localhost:1433
和
#!/bin/bash -eo pipefail
tsql -C
[TinyTds][v2.0.0][tsql]: /usr/local/bin/tsql
Compile-time settings (established with the "configure" script)
Version: freetds v1.00.54
freetds.conf directory: /usr/local/etc
MS db-lib source compatibility: no
Sybase binary compatibility: no
Thread safety: yes
iconv library: yes
TDS version: auto
iODBC: no
unixodbc: no
SSPI "trusted" logins: no
Kerberos: no
OpenSSL: yes
GnuTLS: no
MARS: no
然后我得到超时。这些超时是间歇性的,当我们尝试连接到localhost时会出现这些超时:1433
但主要是当我们进入佣金任务时。
下面是我得到的堆栈跟踪,我已经尝试了几个不同版本的MSSQL docker,但没有效果。如果有人试过这样做,请告诉我,我真的很感激这方面的一些帮助。
#!/bin/bash -eo pipefail
bundle exec rake -v --trace db:create
** Invoke db:create (first_time)
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:create
TinyTds::Error: Adaptive Server connection timed out: CREATE DATABASE [collections_test]
Couldn't create database for {"adapter"=>"sqlserver", "pool"=>5, "encoding"=>"utf8", "mode"=>"dblib", "host"=>"localhost", "database"=>"collections_test", "username"=>"sa", "password"=>"P@55w0rd"}
rake aborted!
ActiveRecord::StatementInvalid: TinyTds::Error: Adaptive Server connection timed out: CREATE DATABASE [collections_test]
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:274:in `do'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:274:in `raw_connection_do'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:215:in `block in do_execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:612:in `block (2 levels) in log'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:611:in `block in log'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.3/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:603:in `log'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:215:in `do_execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_tasks.rb:10:in `create_database'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/tasks/sqlserver_database_tasks.rb:22:in `create'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:117:in `create'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:137:in `block in create_current'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:304:in `block in each_current_configuration'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:303:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:303:in `each_current_configuration'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:136:in `create_current'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/railties/databases.rake:27:in `block (2 levels) in <top (required)>'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `block in execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:194:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:187:in `invoke_with_call_chain'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:180:in `invoke'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:152:in `invoke_task'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `block (2 levels) in top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `block in top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:117:in `run_with_threads'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:102:in `top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:80:in `block in run'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:178:in `standard_exception_handling'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:77:in `run'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/bin/rake:23:in `load'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/bin/rake:23:in `<top (required)>'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `load'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `kernel_load'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:27:in `run'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:362:in `exec'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:22:in `dispatch'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:13:in `start'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/exe/bundle:30:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/friendly_errors.rb:121:in `with_friendly_errors'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/exe/bundle:22:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
TinyTds::Error: Adaptive Server connection timed out
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:274:in `do'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:274:in `raw_connection_do'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:215:in `block in do_execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:612:in `block (2 levels) in log'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:611:in `block in log'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.3/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/abstract_adapter.rb:603:in `log'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_statements.rb:215:in `do_execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/connection_adapters/sqlserver/database_tasks.rb:10:in `create_database'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-sqlserver-adapter-5.1.1/lib/active_record/tasks/sqlserver_database_tasks.rb:22:in `create'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:117:in `create'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:137:in `block in create_current'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:304:in `block in each_current_configuration'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:303:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:303:in `each_current_configuration'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/tasks/database_tasks.rb:136:in `create_current'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.3/lib/active_record/railties/databases.rake:27:in `block (2 levels) in <top (required)>'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `block in execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:250:in `execute'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:194:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:187:in `invoke_with_call_chain'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task.rb:180:in `invoke'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:152:in `invoke_task'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `block (2 levels) in top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `each'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `block in top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:117:in `run_with_threads'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:102:in `top_level'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:80:in `block in run'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:178:in `standard_exception_handling'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/application.rb:77:in `run'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/bin/rake:23:in `load'
/home/circleci/collections-api/vendor/bundle/ruby/2.4.0/bin/rake:23:in `<top (required)>'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `load'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `kernel_load'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:27:in `run'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:362:in `exec'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:22:in `dispatch'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/cli.rb:13:in `start'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/exe/bundle:30:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/friendly_errors.rb:121:in `with_friendly_errors'
/usr/local/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/exe/bundle:22:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => db:create
Exited with code 1
注意:我们需要连接到MSSQL的原因是因为我们将在短时间内写入数据库,我们有另一个团队依赖于使用MSSQL的Access。我只是希望有一个人在那里与这个野兽战斗并赢得了胜利。
编辑:freetds.conf
# $Id: freetds.conf,v 1.12 2007-12-25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".
# Global settings are overridden by those in a database
# server specific section
[global]
# TDS protocol version
tds version = auto
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
; dump file = /tmp/freetds.log
; debug flags = 0xffff
# Command and connection timeouts
; timeout = 10
; connect timeout = 10
# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.
# Try setting 'text size' to a more reasonable limit
text size = 64512
# If you experience TLS handshake errors and are using openssl,
# try adjusting the cipher list (don't surround in double or single quotes)
# openssl ciphers = HIGH:!SSLv2:!aNULL:-DH
# A typical Sybase server
[egServer50]
host = symachine.domain.com
port = 5000
tds version = 5.0
# A typical Microsoft server
[egServer70]
host = ntmachine.domain.com
port = 1433
tds version = 7.0