Can Rails 2 different databases in the production environment? - ruby-on-rails

My goal is to have 2 databases and 2 deployments of rails on the same server. I want to have the regular production server using the production database. Then I want to be able to deploy to a different web address that will use a different database. My goal is to be able to push the backup first and make sure all the migrations etc. work in the full environment. I would then push it to the main server.
The issue I seem to run into is that the database.ml file only lists the 3 database types. The passenger environment will also assume that its running in production and would migrate the main MySQL database even if I deploy the code to a different directory. Whats the best way around this? Was wondering if it is simple or if it involves setting lots of variables in lots of places? Any suggestions would be great!

You can add other database types to database.yml as you see fit.
staging:
adapter: postgresql
host: mydb_host
database: mydb_staging
etc...
You can copy config/environments/production.rb to config/environments/staging.rb and leave it as is so the two environments are exactly the same, or tweak staging.rb as you see fit.
Now you have a staging environment! Use it where appropriate, e.g.:
rake RAILS_ENV=staging db:migrate
I am not a passenger expert, but know that my shop has both staging and production instances of apps running on the same server under passenger, so it can be done. Google can probably instruct you better on configuring that than I can.

Related

Ruby-on-rails development and production on same server

Is it possible (or normal) to have Ruby on Rails development and production on the same server? And is it OK to have sqlite for development and postgresql for production?
It is not normal, but it is possible - and occasionally needed - to debug problems that are only showing up in production. A couple of examples are assets (javascripts, images, etc) that are served up differently in development as opposed to production due to the asset pipeline. Another area is caching which tends to be different in production and is frequently disabled in development.
In ruby on rails there are usually (at least) three modes that the server can run in.
These are referred to as 'environments'.
development. This is your local machine and is what you normally use locally during development
tests. This is used when you run tests and test suites.
production. This is the mode used for actual production servers which are usually on a remote server.
Sometimes you do want/need to run a local development server in 'production mode' and in these cases you do this inline with
RAILS_ENV=production rails server
or
rails server -e production
or
rails server -e production -p 3001
# Specify the port (e.g. **-p 3001**) if you want to run on a different port (the default port is 3000),
# e.g. to run in development mode in one window and production mode in another.
When you run your local server in another mode, such as production, you'll need to be aware that this also affects your database connection. config/database.yml has your database connection and also uses the RAILS_ENV settings.
You may want/need to run your server in production mode - but use your local database. You can do this by temporarily using the actual setting from the development block in the production block of config/database.yml. Just be sure to save the original settings / restore afterwards (before you do your next push).
It's also totally ok and indeed common to have sqlite locally and mysql/postgres/oracle in production.
I wouldn't say it is "normal" or not to have both environments on a single server. A lot of small structures already do it, so to my mind it won't cause any problems.
Anyway, as long as both environments are clearly isolated (i.e. two separate folders at least, and two rvm gemsets or rbenv environments for the ruby and gem versions), it won't cause any problems. Just remember to launch both servers with different ports or sockets and you're done.
That is the way I've done for five projects and it ran without trouble.
You can run same app on same machine on different mode like production or development using different port
rails s # which will run on development mode like localhost:3000
rails s -e production 3002 # for production mode like localhost:3002
second answer regarding database.. Yes you can use different database in different mode like for development sqlite3 and for production postgress by modifying your database.yml file
development:
adapter: sqlite3
database: yourapp_development
username: root
password: root
host: localhost
production:
adapter: postgresql
host: localhost
username: postgres
password: password
pool: 5
timeout: 5000
database: yourapp_production
and in your gemfile
group :development do
gem "sqlite3"
end
group :production do
gem 'pg'
end
You generally run RoR in development mode on development machines - i.e., on your local system where application development takes place. The point is to run RoR in development-friendly manner - exposing error messages, avoiding the need to precompile assets, etc - it's slower but much easier to actively work with.
Having different database systems for development and production is possible, but inadvisable. Ideally the application development environment is closely matched with the production environment - allowing for your code to work in an identical, and predictable manner. SQLite3 can behave quite differently from PostgreSQL - the two have different feature-sets. There are a lot of things that PostgreSQL can do that SQLite can't (I'm not sure about the reverse). See http://edgeguides.rubyonrails.org/active_record_postgresql.html for PostgreSQL-specific features.

rails app running multiple times on production with different configurations

I want to run the same rails app several times with a few configuration differences on the same server. Each app must have its own:
database
ports
cookie_store key(not sure if needed)
secret_key_base
Let's say I want to run the same code multiple times to service different cities:
newyork.myapp.com and boston.myapp.com. I wonder what would be the best way to store and use the different configurations.
Use environments:
Add a file to config/environments, one for each site you want to host. Name it something along the lines of 'production_[city]', replacing [city] with the city name. Copy the production.rb file contents into each.
in config/database.yml find the 'production' block of yml and duplicate it once for each site you want to host. Rename the root node of each block to production_[city], matching the filenames above. For example:
production_ny:
adapter: mysql2
username: my_user
password: my_pa$$w0rd%&*#
database: production_ny
This takes care of the database settings per app.
Assuming Rails 4, your secret key base will be in config/secrets.yml under an environment node, as per config/database.yml so just add an entry per site:
production_ny:
secret_key_base: xxxxxxxx1111111122222223333333344444444...
All sites will need an end-point. Using a different domain for each would give you separate cookies and sessions for free. Or you could go the subdomain route:
http://guides.rubyonrails.org/configuring.html#deploy-to-a-subdirectory-relative-url-root
tldr:
In your config/environments/production_ny.rb:
config.relative_url_root = "/ny"
for example. Then set up your webserver to handle subdirectories. You may need to add a path to cookies in order to scope them to the virtual directory. Just use:
Rails.configuration.relative_url_root
Ports, again, will have to be set up at the webserver level. (Apache, nginx, etc.)
To see if it all works, try this in the command-line:
RAILS_ENV=production_ny bundle exec rails s
This should start a development style webserver for you to access, but use the production_ny environment.
You will need to create and set up your database as normal - create, migrate, seed.
The final step is setting the RAILS_ENV environment variable to production_[city] per app using your web server. The steps to do this will depend on your technology choice.

How to get files .gitignore'd on heroku?

We have inherited a Rails project hosted on Heroku. The problem is that I don't understand how to get a copy of the database.yml or other various config files that have been ignored in the .gitignore file.
Sure I can look through the history but it seems like a hip shot when comparing it to what should be on the production server. Right now we are having to make changes to the staging environment which makes things a bit arduous and less efficient than having a local dev environment so we can really get under the hood. Obviously, having an exact copy of the config is a good place to start.
With other hosts it's easy to get access to all the files on the server using good ol' ftp.
This might be more easily addressed with some sort of git procedure that I am less familiar with.
Heroku stores config variables to the ENV environment
heroku config will display these list of variables
heroku config:get DATABASE_URL --app YOUR_APP
Will return the database url that Heroku as assigned to your app, using this string one can deduce the parameters necessary to connect to your heroku applications database, it follows this format
username:password#database_ip:port/database_name
This should provide you with all the values you'll need for the heroku side database.yml, its a file that is created for you each time you deploy and there is nothing it that can't be gotten from the above URL.
gitignoring the database.yml file is good practice
It's not something you can do - entries added to .gitignore means they've been excluded from source control. They've never made it into Git.
As for database.yml you can just create the file in app\config\database.yml with local settings, it should look something like;
development:
adapter: postgresql
host: 127.0.0.1
username: somelocaluser
database: somelocaldb
It's safe to say though, that if the file is not in Git then it's not on Heroku since that's the only way you can get files to Heroku. Any config is likely to be in environment variables - heroku config will show you that.

Partitioning Heroku Production Database -- Possible?

I'm considering paying the $50/ mo for a production database so I can use PostGIS with my rails 4 app. My issue is that I would like to continue developing with a 'staging' environment, but can't yet justify paying for two production databases. Staging is obviously just a clone of production, so just pointing both apps to the same DB url (post) would likely cause some major headaches.
Is there any way to partition the database, or another strategy you'd recommend?
Initial answer from heroku support is no, but I'm hoping there's a scrappy workaround.
Thanks!
First off, I would highly suggest just paying the extra $50/mo. For that, you get all kinds of cool stuff like forking and pipelines, as well as the fact that this is kind of hacky. I honestly don't know if this might end up wiping your production data when you clear the staging database. Please make backups before trying this.
I'll view this answer as an answer to a technical challenge rather than a business decision. Without further ado,
Setting up multiple environments on the same database with Heroku Postgres schemas
First, I deleted the existing dev database and added a production database to my production app.
heroku addons:add heroku-postgresql:crane
> Adding heroku-postgresql:crane on test-shared-app... done, v# ($50/mo)
> Attached as HEROKU_POSTGRESQL_RED_URL
This attached a database under the RED color, so replace HEROKU_POSTGRESQL_RED_URL with the appropriate color for your app.
This attaches a database to the production app, but we need to connect to the same app for staging. First, create the staging schema
heroku run "bundle exec rails runner 'ActiveRecord::Base.connection.execute(%q{CREATE SCHEMA staging})'"
Next, create the staging app. See Managing Multiple Environments for an App for more information.
heroku create --remote staging test-shared-app-staging
heroku config:set RACK_ENV=staging RAILS_ENV=staging --remote staging
Then, copy the environment data from your existing app. Add ?schema_search_path=staging to the end of the URL.
heroku config --remote heroku --shell
# make note of your database URLs
heroku config:set --remote staging \
DATABASE_URL=postgres://...?schema_search_path=staging \
HEROKU_POSTGRESQL_RED_URL=postgres://...?schema_search_path=staging
And push to staging
git push staging master
Now, run migrations on staging
heroku run --remote staging bundle exec rake db:migrate
And try it out.
My "app" is running at http://test-shared-app.herokuapp.com/posts and http://test-shared-app-staging.herokuapp.com/posts. You can see the source at https://github.com/benmanns/heroku-shared-app.
If I were you, I would use production DB until the right moment (start making money or getting more users, etc). I would replicate all the tables in production DB and give the new tables new names by prepending something like "stag_{original_table_name}. So, you would have two different sets of the same tables. In your models, make them use the new table on staging environment:
class Foo < ActiveRecord::Base
self.table_name = "staging_#{self.class.name}" if Rails.env.staging?
I am pretty cheap... and this may be an ugly solution in the eyes of the true Rails masters.
Heroku Schemas is another approach to this; it's a Heroku plugin that basically lets you run a single command to apply Benjamin Manns's solution of multiple schemas.

Some troubles with deploy rails application

I created rails application, it works great in development environment, but now I want to deploy it. I have a vps with passenger and nginx, I deployed rails application with static pages, but now application needs database.
Which best way to clone structure from development base and then deploy it?
Please give any guides to deploy application?
I use (ubuntu 10.04_64, rails 3.0.6)
It sounds like you want a copy of your development database (structure and data).
If you are using a sqlite3 database in development (which you probably are), then on the server (after you've deployed) make a copy of it and name it production.sqlite3
cp development.sqlite3 production.sqlite3
This will copy the structure and data of your development database. If its a static site however, you could do this on the development machine before you deploy.
Let me know if you need instructions to do this for mysql (or any other database) and I will edit this answer.
rake db:migrate RAILS_ENV=production
or I misunderstood the question?

Resources