Resin Cloud Deployment Reference
From Resin 3.0
(→Deploying to a local server) |
(→Cluster deployment NOT IMPLEMENTED UNTIL Resin 4.0.25 (coming soon)) |
||
(29 intermediate revisions by one user not shown) | |||
Line 1: | Line 1: | ||
− | |||
# Deploying to a local server | # Deploying to a local server | ||
+ | ## Deploying to a staging server (locally) | ||
+ | ## Deploying to a preview staging server (locally) | ||
# Deploying to a remote server | # Deploying to a remote server | ||
+ | ## Setting up a user and password | ||
+ | ## Deploying to a remote server | ||
# Setting up a cloud topology | # Setting up a cloud topology | ||
## Deploying to the Triad | ## Deploying to the Triad | ||
Line 44: | Line 47: | ||
== Deploying to a local server == | == Deploying to a local server == | ||
+ | |||
+ | Deploy commands available | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl help deploy | ||
+ | |||
+ | |||
+ | Output: | ||
+ | usage: bin/resin.sh [-conf <file>] [-server <id>] deploy -user <user> \ | ||
+ | -password <password> [options] <war-file> | ||
+ | |||
+ | description: | ||
+ | deploys application specified in a <war-file> to resin server | ||
+ | |||
+ | options: | ||
+ | -conf <file> : resin configuration file | ||
+ | -server <id> : id of a server | ||
+ | -address <address> : ip or host name of the server | ||
+ | -port <port> : server http port | ||
+ | -user <user> : user name used for authentication to the server | ||
+ | -password <password> : password used for authentication to the server | ||
+ | -host <host> : virtual host to make application available on | ||
+ | -name <name> : name of the context to deploy to, defaults to war-file name | ||
+ | -stage <stage> : stage to deploy application to, defaults to production | ||
+ | -version <version> : version of application formatted as <major.minor.micro.qualifier> | ||
+ | -m <message> : commit message | ||
+ | </pre> | ||
+ | </code> | ||
Turning on versioning: | Turning on versioning: | ||
Line 77: | Line 109: | ||
Output: | Output: | ||
− | Deployed production/webapp/default/blog from ./target/blog-0.1.0.war to hmux://127.0.0.1:6800 | + | Deployed production/webapp/default/blog from \ |
+ | ./target/blog-0.1.0.war to hmux://127.0.0.1:6800 | ||
</pre> | </pre> | ||
</code> | </code> | ||
Line 114: | Line 147: | ||
</pre> | </pre> | ||
</code> | </code> | ||
+ | |||
+ | Now deploy it with versioning: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy ./target/blog-0.1.0.BUILD-SNAPSHOT.war -name blog -version 0.1.0 | ||
+ | |||
+ | Output: | ||
+ | Deployed production/webapp/default/blog-0.1.0 from \ | ||
+ | ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800 | ||
+ | |||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | Blog application is under the version 0.1.0 | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-list | ||
+ | |||
+ | Output: | ||
+ | production/webapp/default/blog-0.1.0 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | * TODO explain production/webapp/default/blog-0.1.0 | ||
+ | * TODO add a table | ||
+ | * TODO explain how to start up a server with different staging servers | ||
+ | |||
+ | === Deploying to a staging server === | ||
+ | |||
+ | Deploy to staging server. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy ./target/blog-0.1.0.BUILD-SNAPSHOT.war -name blogz -version 0.1.0 -stage staging | ||
+ | |||
+ | Output | ||
+ | Deployed staging/webapp/default/blogz-0.1.0 from \ | ||
+ | ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | The staging name is logical. You can call it anything. The app will not be served unless | ||
+ | the server is started with this staging name. | ||
+ | |||
+ | Showing items deployed to staging server. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-list | ||
+ | production/webapp/default/blog-0.1.0 | ||
+ | staging/webapp/default/blogz-0.1.0 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | The /blog works but /blogz does not work because server is by default setup as production server. | ||
+ | |||
+ | /blog works because server is setup for production | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ wget localhost:8080/blog | ||
+ | ... | ||
+ | HTTP request sent, awaiting response... 200 OK | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | /blogz does not work because server is not setup for production | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ wget localhost:8080/blogz | ||
+ | ... | ||
+ | HTTP request sent, awaiting response... 404 Not Found | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | To run the server as a staging server do the following: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl stop | ||
+ | |||
+ | Output: | ||
+ | Resin/4.0.24 stopped -server 'app-0' for watchdog at 127.0.0.1:6600 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl help start | ||
+ | |||
+ | Output: | ||
+ | usage: bin/resin.sh [-options] start | ||
+ | |||
+ | where options include: | ||
+ | -conf <file> : select a configuration file | ||
+ | -data-directory <dir> : select a resin-data directory | ||
+ | -join-cluster <cluster> : join a cluster as a dynamic server | ||
+ | -log-directory <dir> : select a logging directory | ||
+ | -resin-home <dir> : select a resin home directory | ||
+ | -root-directory <dir> : select a root directory | ||
+ | -server <id> : select a <server> to run | ||
+ | -watchdog-port <port> : override the watchdog-port | ||
+ | -verbose : print verbose starting information | ||
+ | -preview : run as a preview server | ||
+ | -debug-port <port> : configure a debug port | ||
+ | -jmx-port <port> : configure an unauthenticated jmx port | ||
+ | -stage <staging-name> : The stage the server is serving (default production) | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ sudo resinctl start -stage staging | ||
+ | |||
+ | Output: | ||
+ | Resin/4.0.24 launching watchdog at 127.0.0.1:6600 | ||
+ | Resin/4.0.24 started -server 'app-0' for watchdog at 127.0.0.1:6600 | ||
+ | |||
+ | |||
+ | $ wget localhost:8080/blogz | ||
+ | ... | ||
+ | ... | ||
+ | HTTP request sent, awaiting response... 200 OK | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | === Deploying to a preview staging server === | ||
+ | |||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | |||
+ | $ resinctl deploy ./target/blog-0.1.0.BUILD-SNAPSHOT.war -name blogp -version 0.1.0 -stage preview | ||
+ | |||
+ | Output | ||
+ | Deployed preview/webapp/default/blogp-0.1.0 from \ | ||
+ | ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800 | ||
+ | |||
+ | $ resinctl deploy-list | ||
+ | |||
+ | Output | ||
+ | preview/webapp/default/blogp-0.1.0 | ||
+ | production/webapp/default/blog-0.1.0 | ||
+ | ... | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Restart the server in preview stage, since preview staging is a common thing, you can just use the -preview command. | ||
+ | |||
+ | |||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl stop | ||
+ | |||
+ | Output: | ||
+ | Resin/4.0.24 stopped -server 'app-0' for watchdog at 127.0.0.1:6600 | ||
+ | |||
+ | $ sudo resinctl start -preview | ||
+ | |||
+ | Output: | ||
+ | Resin/4.0.24 launching watchdog at 127.0.0.1:6600 | ||
+ | Resin/4.0.24 started -server 'app-0' for watchdog at 127.0.0.1:6600 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Now the preview blog site is available. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ wget localhost:8080/blogp | ||
+ | ... | ||
+ | HTTP request sent, awaiting response... 200 OK | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | == Deploying to a Remote Server == | ||
+ | |||
+ | Setup the remote box (Install Resin) | ||
+ | |||
+ | You need to create a user name and password. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | REMOTE SERVER $ resinctl generate-password -user rick -password dogbones | ||
+ | |||
+ | Output: | ||
+ | admin_user : rick | ||
+ | admin_password : {SSHA}JmojvNUU4OpTOw0/SESRsnpEHejxkhZZ | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Modify resin.properties | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | |||
+ | REMOTE SERVER$ cat /etc/resin/resin.properties | ||
+ | |||
+ | Output: | ||
+ | admin_user : rick | ||
+ | admin_password : {SSHA}JmojvNUU4OpTOw0/SESRsnpEHejxkhZZ | ||
+ | admin_remote_enable : true | ||
+ | ... | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | Now from the local server deploy your app as follows: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | LOCAL SERVER $ resinctl deploy target/blog-0.1.0.BUILD-SNAPSHOT.war -name blogdb \ | ||
+ | -address 192.168.248.168 -port 8080 -user rick -password dogbones | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | You can verify that the deploy worked as follows: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-list -address 192.168.248.168 -port 8080 -user rick -password dogbones | ||
+ | |||
+ | Output: | ||
+ | production/webapp/default/blog | ||
+ | ... | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | == Working with deploy-copy to release, and rollback == | ||
+ | |||
+ | |||
+ | Deploy version to archive. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy ./target/blog-0.1.0.BUILD-SNAPSHOT.war -name blog -stage archive -version 0.1.0 | ||
+ | |||
+ | Output: | ||
+ | Deployed archive/webapp/default/blog-0.1.0 from \ | ||
+ | ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | List versions deployed. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-list | ||
+ | |||
+ | Output: | ||
+ | archive/webapp/default/blog-0.1.0 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Copy deployment to production | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-copy -source blog -source-stage archive \ | ||
+ | -source-version 0.1.0 -target blog | ||
+ | |||
+ | Output: | ||
+ | copied archive/webapp/default/blog-0.1.0 to production/webapp/default/blog | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-list | ||
+ | |||
+ | Output: | ||
+ | archive/webapp/default/blog-0.1.0 | ||
+ | production/webapp/default/blog | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | When you deploy this way you must start the app as follows: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-start blog | ||
+ | |||
+ | Output: | ||
+ | 'production/webapp/default/blog' is started | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | Then you would deploy copy a different version to rollback or promote a different version to prod. | ||
+ | |||
+ | In review of the above, we have decided to make the process a bit easier. | ||
+ | |||
+ | The following section has not yet been implemented, but is slated for 4.0.25. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | == Proposed but not Implemented 4.0.25 Deploy and Rollback== | ||
+ | |||
+ | |||
+ | ''The following section has not yet been implemented, but is slated for 4.0.25.'' | ||
+ | |||
+ | |||
+ | Deploy version to archive. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy ./target/blog-0.1.0.BUILD-SNAPSHOT.war -name blog -version 0.1.0 | ||
+ | |||
+ | Output: | ||
+ | Deployed archive/webapp/default/blog-0.1.0 from \ | ||
+ | ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800 | ||
+ | into production \ | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | List versions deployed with all option. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-list -all | ||
+ | |||
+ | Output: | ||
+ | Tag Ver. DD-MM-YYYY-HH:MM:SS | ||
+ | archive/webapp/default/blog-0.1.0 0.1.0 05-12-2011-13:00:00 | ||
+ | production/webapp/default/blog 0.1.0 05-12-2011-13:00:00 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | Later you decide to update to a new version likely after weeks or months of hard development. | ||
+ | The line marked with production/webapp/default/blog is the /blog that is deployed in the running server. | ||
+ | |||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy ./target/blog-0.2.0.BUILD-SNAPSHOT.war -name blog -version 0.2.0 | ||
+ | |||
+ | Output: | ||
+ | Deployed archive/webapp/default/blog-0.2.0 from \ | ||
+ | ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800 | ||
+ | deployed into production. | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | At this point the following will be deployed: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-list -all | ||
+ | |||
+ | Output: | ||
+ | Tag Ver. DD-MM-YYYY-HH:MM:SS | ||
+ | archive/webapp/default/blog-0.1.0 0.1.0 05-12-2011-13:00:00 | ||
+ | archive/webapp/default/blog-0.2.0 0.2.0 05-01-2012-11:00:00 | ||
+ | production/webapp/default/blog 0.2.0 05-01-2012-11:00:00 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Even after rigorous load testing and QA testing, a critical bug was found in 0.2.0 blog and now you need to quickly rollback to a previous version. | ||
+ | |||
+ | |||
+ | To rollback to a previous version use the '''deploy-rollback''' as follows: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-rollback blog -version 0.1.0 | ||
+ | |||
+ | Output: | ||
+ | Deployed archive/webapp/default/blog-0.1.0 to hmux://127.0.0.1:6800 \ | ||
+ | into production | ||
+ | |||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Alternatively you can use deploy-promote to accomplish the same thing. | ||
+ | |||
+ | To rollback to a previous version use the '''deploy-promote''' as follows: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-promote blog -stage archive -version 0.1.0 | ||
+ | |||
+ | Output: | ||
+ | Deployed archive/webapp/default/blog-0.1.0 to hmux://127.0.0.1:6800 \ | ||
+ | into production | ||
+ | |||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | We specify the stage as archive (-stage archive) because deploy-promote defaults to working with the preview stage (more on this in the next section). | ||
+ | |||
+ | Now after the rollback the deployed servers should look like this. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-list -all | ||
+ | |||
+ | Output: | ||
+ | Tag Ver. DD-MM-YYYY-HH:MM:SS | ||
+ | archive/webapp/default/blog-0.1.0 0.1.0 05-12-2011-13:00:00 | ||
+ | archive/webapp/default/blog-0.2.0 0.2.0 05-01-2012-11:00:00 | ||
+ | production/webapp/default/blog 0.1.0 05-12-2011-13:00:00 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Notice that 0.1.0 is now in production and 0.2.0 is not. | ||
+ | |||
+ | ==Promoting an app from preview mode to production== | ||
+ | |||
+ | Options | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl deploy-promote blog | ||
+ | |||
+ | Output: | ||
+ | Deployed preview/webapp/default/blog to hmux://127.0.0.1:6800 \ | ||
+ | into production | ||
+ | |||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | Promotes blog that is currently in preview stage into production. | ||
+ | |||
+ | == Cluster deployment NOT IMPLEMENTED UNTIL Resin 4.0.25 (coming soon) == | ||
+ | |||
+ | This section is slated for Resin 4.0.25 but not released yet and may change. | ||
+ | |||
+ | Resin 4.0.25 adds the following config command line options to support remote configuration and cloud configuration of Resin servers. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | resinctl | grep config | ||
+ | config-deploy - deploys configuration directory | ||
+ | config-copy - copies configuration | ||
+ | config-list - lists all deployed configurations | ||
+ | config-ls - list contents of config dir as a tree (ex. ./lib) | ||
+ | config-cat - list contents of config file (must be text) | ||
+ | config-undeploy - undeploys a config | ||
+ | config-rollback - rollback to a different config | ||
+ | config-promote - promotes a staged config to production | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ===Background on need=== | ||
+ | At times you need to include things like jar files that are available to more than one application. | ||
+ | Resin allows you to deploy these to remote servers (which can be 1 to hundreds of servers) with one simple command. | ||
+ | |||
+ | Let's say your /blog application that relies on MySQL. | ||
+ | |||
+ | |||
+ | By default resin uses the /etc/resin/resin.properties file. You could add these properties to /etc/resin/resin.properties. | ||
+ | |||
+ | '''/etc/resin/resin.properties on resin server''' | ||
+ | <code> | ||
+ | <pre> | ||
+ | |||
+ | blogdb.url : blogdb.cvolnlau763z.us-east-1.rds.amazonaws.com | ||
+ | blogdb.user : bloguser | ||
+ | blogdb.password : roofoo | ||
+ | |||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | These properties will vary for dev, production, qa, etc. And once they are set, they will not change often. | ||
+ | |||
+ | You could test locally by copying this file (blog-database.xml) to /etc/resin/resin.d/. | ||
+ | |||
+ | |||
+ | '''/etc/resin/resin.d/database.xml''' blog-database.properties under /etc/resin/resin.d. | ||
+ | <code> | ||
+ | <pre> | ||
+ | <resin xmlns="http://caucho.com/ns/resin" | ||
+ | xmlns:resin="urn:java:com.caucho.resin"> | ||
+ | |||
+ | <database jndi-name="jdbc/blogdb"> | ||
+ | <driver type="com.mysql.jdbc.Driver"> | ||
+ | <url>jdbc:mysql://${blogdb.url}:3306/blogdb</url> | ||
+ | <user>${blogdb.user}</user> | ||
+ | <password>${blogdb.password}</password> | ||
+ | </driver> | ||
+ | </database> | ||
+ | </resin> | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | The problem now is that you don't have a mysql.jar file and you will get a class not found exception when the apps starts up. | ||
+ | |||
+ | |||
+ | |||
+ | If you are using maven locally you can copy mysql from the maven local repo as follows: | ||
+ | |||
+ | Find and copy the mysql jar file from the maven local repo to Resin as follows: | ||
+ | |||
+ | Find it: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ find ~/.m2/repository/ -name "*mysql*.jar" | ||
+ | /home/rick/.m2/repository/mysql/mysql-connector-java/5.1.18/mysql-connector-java-5.1.18.jar | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Now deploy it | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ sudo cp ~/.m2/repository/mysql/mysql-connector-java/5.1.18/mysql-connector-java-5.1.18.jar \ | ||
+ | /usr/local/share/resin/lib/ | ||
+ | |||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | Or you can use yum to get the mysql driver as follows: | ||
+ | |||
+ | Next install the mysql driver. | ||
+ | $ sudo yum install mysql-connector-java | ||
+ | $ sudo cp /usr/share/java/mysql-connector-java.jar /usr/local/share/resin/lib/ | ||
+ | |||
+ | |||
+ | The problem with this approach is that things work for you locally for /blog application if it relies on mysql being managed under jndi:jdbc/blogdb, but all of your remote deployments will fail unless you manually add the mysql jar to each server, manually add the blog-database.xml file to each server, and manually update each resin.properties file. | ||
+ | |||
+ | === Remote config deployment === | ||
+ | Resin 4.0.25 allows you to deploy configuration files not just applications. This allows you to change what jar files get loaded into the Resin classpath, config files and properties. If you are doing deployment to 1 remote server or to a triad for cloud deployment with 100's of servers, deploying mysql to them can be as easy as what we are going to describe. | ||
+ | |||
+ | Ok assuming you have developed and tested the /blog app locally and now you want to push a blog to a remote server or set of servers, you can do the following: | ||
+ | |||
+ | |||
+ | # Create a directory blog-database | ||
+ | # Create a directory called blog-database/lib | ||
+ | # Copy blog-database.xml into blog-database directory | ||
+ | # Copy mysql.jar into blog-database/lib | ||
+ | # Create a file called blog-database/resin.properties | ||
+ | # Use resinctl config-deploy to deploy the configuration | ||
+ | |||
+ | |||
+ | First create the dirs and copy the jar. | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ mkdir blog-database | ||
+ | $ mkdir blog-database/lib | ||
+ | $ cp /etc/resin/resin.d/blog-database.xml blog-database/ | ||
+ | $ cp /usr/local/share/resin/lib/mysql-connector*.jar blog-database/lib/ | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | Instead of modifying every servers /etc/resin/resin.properties, you can add a resin.properties to blog-database dir that gets deployed with the config bundle as follows: | ||
+ | |||
+ | '''./blog-database/resin.properties''' | ||
+ | <code> | ||
+ | <pre> | ||
+ | blogdb.url : blogdb.cvolnlau763z.us-east-1.rds.amazonaws.com | ||
+ | blogdb.user : bloguser | ||
+ | blogdb.password : roofoo | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | It might make sense to deploy the database properties in a separate config deployment, but for simplicity we bundle together in one. | ||
+ | |||
+ | '''NOTE: This works for dir/lib . We should allow dir/webapp-jars and it should work the same. | ||
+ | The jars get loaded per webapp for dir/webapp-jars. END NOTE''' | ||
+ | |||
+ | Next deploy to the remote server as follows: | ||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl config-deploy blog-database -version=0.1.0 -address=199.99.99.01 -port=8080 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | To see what is deployed you can do the following: | ||
+ | |||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl config-list -all -address=199.99.99.01 -port=8080 | ||
+ | |||
+ | Output: | ||
+ | archive/config/default/blog-database-0.1.0 0.1.0 05-12-2011-13:00:00 | ||
+ | production/config/default/blog-database 0.1.0 05-12-2011-13:00:00 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | |||
+ | Or to see everything in the deployment use config-ls | ||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl config-ls blog-database -version=0.1.0 -address=199.99.99.01 -port=8080 | ||
+ | |||
+ | Output: | ||
+ | blog-database.xml | ||
+ | resin.properties | ||
+ | lib/ | ||
+ | mysql-connector-java-5.1.18.jar | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | |||
+ | If you wanted to see exactly what was in blog-database/blog-database.xml you could do the following: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl config-cat blog-database -file=./blog-database.xml -version=0.1.0 -address=199.99.99.01 -port=8080 | ||
+ | |||
+ | Output: | ||
+ | <resin xmlns="http://caucho.com/ns/resin" | ||
+ | xmlns:resin="urn:java:com.caucho.resin"> | ||
+ | |||
+ | <database jndi-name="jdbc/blogdb"> | ||
+ | <driver type="com.mysql.jdbc.Driver"> | ||
+ | <url>jdbc:mysql://${blogdb.url}:3306/blogdb</url> | ||
+ | <user>${blogdb.user}</user> | ||
+ | <password>${blogdb.password}</password> | ||
+ | </driver> | ||
+ | </database> | ||
+ | </resin> | ||
+ | |||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | The following commands work like deploy-undeploy, deploy-rollback and deploy-promote, but for configuration. | ||
+ | |||
+ | # config-undeploy - undeploys a config | ||
+ | # config-rollback - rollback to a different config | ||
+ | # config-promote - promotes a staged config to production | ||
+ | |||
+ | |||
+ | === Using config-deploy for a local server === | ||
+ | Note you also do these same steps for a local development server instead of copying jar files and config files as follows: | ||
+ | |||
+ | Next deploy to the remote server as follows: | ||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl config-deploy blog-database -version=0.1.0 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | (Just leave off the address and port.) | ||
+ | |||
+ | To see what is deployed you can do the following: | ||
+ | |||
+ | <code> | ||
+ | <pre> | ||
+ | $ resinctl config-list -all | ||
+ | |||
+ | Output: | ||
+ | archive/config/default/blog-database-0.1.0 0.1.0 05-12-2011-13:00:00 | ||
+ | production/config/default/blog-database 0.1.0 05-12-2011-13:00:00 | ||
+ | </pre> | ||
+ | </code> | ||
+ | |||
+ | Just leave off address and port to see what is configured locally. | ||
+ | |||
+ | The advantage of using confg-deploy locally is that your dev system is more like your integration, qa and production system. | ||
+ | It is like having a local cloud. |
Latest revision as of 01:19, 7 December 2011
- Deploying to a local server
- Deploying to a staging server (locally)
- Deploying to a preview staging server (locally)
- Deploying to a remote server
- Setting up a user and password
- Deploying to a remote server
- Setting up a cloud topology
- Deploying to the Triad
- license-add enabling Resin features
- Deploy to a staging server
- Setting up load balancer to not to deploy to staging server
- Common tasks
- Deploying a new application deploy
- Listing current versions of deployed application
- Undeploying a new application
- Using deploy-copy to promote a release to production
- Using deploy-copy to rollback a release that was deployed to production
- Installing mysql driver for a web application using config-deploy
- Showing what is in remote config with config-list-ls and config-list-cat
- web-app-deploy settings
$ resinctl | grep deploy deploy - deploys an application deploy-copy - copies an application deploy-list - lists all deployed applications deploy-restart - restarts an application deploy-start - starts an application deploy-stop - stops an application undeploy - undeploys an application config-deploy - deploys configuration directory config-undeploy - undeploys a config $ resinctl | grep config config-deploy - deploys configuration directory config-copy - copies configuration config-list - lists all deployed configurations config-list-ls - list contents of config dir (ex. ./lib) config-list-cat - list contents of config file config-undeploy - undeploys a config
Contents |
Deploying to a local server
Deploy commands available
$ resinctl help deploy Output: usage: bin/resin.sh [-conf <file>] [-server <id>] deploy -user <user> \ -password <password> [options] <war-file> description: deploys application specified in a <war-file> to resin server options: -conf <file> : resin configuration file -server <id> : id of a server -address <address> : ip or host name of the server -port <port> : server http port -user <user> : user name used for authentication to the server -password <password> : password used for authentication to the server -host <host> : virtual host to make application available on -name <name> : name of the context to deploy to, defaults to war-file name -stage <stage> : stage to deploy application to, defaults to production -version <version> : version of application formatted as <major.minor.micro.qualifier> -m <message> : commit message
Turning on versioning:
$ cat /etc/resin/resin.properties | grep deploy Output: deploy_versioning : true
$ sudo grep "web-app-deploy" -A 1 /etc/resin/resin.xml Output: <web-app-deploy path="webapps" versioning="${deploy_versioning}" expand-preserve-fileset="WEB-INF/work/**"/>
"if true, use the web-app's numeric suffix as a version"
Run deploy command passing location of war file.
$ resinctl deploy ./target/blog-0.1.0.war -name blog Output: Deployed production/webapp/default/blog from \ ./target/blog-0.1.0.war to hmux://127.0.0.1:6800
To see the deployed you can use resinctl deploy-list
$ resinctl deploy-list Output: production/webapp/default/blog
- TODO explain production/webapp/default/blog
- TODO add a table
- TODO explain how to start up a server with different staging servers
Now undeploy it:
$ resinctl undeploy blog Output: Undeployed blog from hmux://127.0.0.1:6800
At this point there should be nothing
$ resinctl deploy-list
Now deploy it with versioning:
$ resinctl deploy ./target/blog-0.1.0.BUILD-SNAPSHOT.war -name blog -version 0.1.0 Output: Deployed production/webapp/default/blog-0.1.0 from \ ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800
Blog application is under the version 0.1.0
$ resinctl deploy-list Output: production/webapp/default/blog-0.1.0
- TODO explain production/webapp/default/blog-0.1.0
- TODO add a table
- TODO explain how to start up a server with different staging servers
Deploying to a staging server
Deploy to staging server.
$ resinctl deploy ./target/blog-0.1.0.BUILD-SNAPSHOT.war -name blogz -version 0.1.0 -stage staging Output Deployed staging/webapp/default/blogz-0.1.0 from \ ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800
The staging name is logical. You can call it anything. The app will not be served unless the server is started with this staging name.
Showing items deployed to staging server.
$ resinctl deploy-list production/webapp/default/blog-0.1.0 staging/webapp/default/blogz-0.1.0
The /blog works but /blogz does not work because server is by default setup as production server.
/blog works because server is setup for production
$ wget localhost:8080/blog ... HTTP request sent, awaiting response... 200 OK
/blogz does not work because server is not setup for production
$ wget localhost:8080/blogz ... HTTP request sent, awaiting response... 404 Not Found
To run the server as a staging server do the following:
$ resinctl stop Output: Resin/4.0.24 stopped -server 'app-0' for watchdog at 127.0.0.1:6600
$ resinctl help start Output: usage: bin/resin.sh [-options] start where options include: -conf <file> : select a configuration file -data-directory <dir> : select a resin-data directory -join-cluster <cluster> : join a cluster as a dynamic server -log-directory <dir> : select a logging directory -resin-home <dir> : select a resin home directory -root-directory <dir> : select a root directory -server <id> : select a <server> to run -watchdog-port <port> : override the watchdog-port -verbose : print verbose starting information -preview : run as a preview server -debug-port <port> : configure a debug port -jmx-port <port> : configure an unauthenticated jmx port -stage <staging-name> : The stage the server is serving (default production)
$ sudo resinctl start -stage staging Output: Resin/4.0.24 launching watchdog at 127.0.0.1:6600 Resin/4.0.24 started -server 'app-0' for watchdog at 127.0.0.1:6600 $ wget localhost:8080/blogz ... ... HTTP request sent, awaiting response... 200 OK
Deploying to a preview staging server
$ resinctl deploy ./target/blog-0.1.0.BUILD-SNAPSHOT.war -name blogp -version 0.1.0 -stage preview Output Deployed preview/webapp/default/blogp-0.1.0 from \ ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800 $ resinctl deploy-list Output preview/webapp/default/blogp-0.1.0 production/webapp/default/blog-0.1.0 ...
Restart the server in preview stage, since preview staging is a common thing, you can just use the -preview command.
$ resinctl stop Output: Resin/4.0.24 stopped -server 'app-0' for watchdog at 127.0.0.1:6600 $ sudo resinctl start -preview Output: Resin/4.0.24 launching watchdog at 127.0.0.1:6600 Resin/4.0.24 started -server 'app-0' for watchdog at 127.0.0.1:6600
Now the preview blog site is available.
$ wget localhost:8080/blogp ... HTTP request sent, awaiting response... 200 OK
Deploying to a Remote Server
Setup the remote box (Install Resin)
You need to create a user name and password.
REMOTE SERVER $ resinctl generate-password -user rick -password dogbones Output: admin_user : rick admin_password : {SSHA}JmojvNUU4OpTOw0/SESRsnpEHejxkhZZ
Modify resin.properties
REMOTE SERVER$ cat /etc/resin/resin.properties Output: admin_user : rick admin_password : {SSHA}JmojvNUU4OpTOw0/SESRsnpEHejxkhZZ admin_remote_enable : true ...
Now from the local server deploy your app as follows:
LOCAL SERVER $ resinctl deploy target/blog-0.1.0.BUILD-SNAPSHOT.war -name blogdb \ -address 192.168.248.168 -port 8080 -user rick -password dogbones
You can verify that the deploy worked as follows:
$ resinctl deploy-list -address 192.168.248.168 -port 8080 -user rick -password dogbones Output: production/webapp/default/blog ...
Working with deploy-copy to release, and rollback
Deploy version to archive.
$ resinctl deploy ./target/blog-0.1.0.BUILD-SNAPSHOT.war -name blog -stage archive -version 0.1.0 Output: Deployed archive/webapp/default/blog-0.1.0 from \ ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800
List versions deployed.
$ resinctl deploy-list Output: archive/webapp/default/blog-0.1.0
Copy deployment to production
$ resinctl deploy-copy -source blog -source-stage archive \ -source-version 0.1.0 -target blog Output: copied archive/webapp/default/blog-0.1.0 to production/webapp/default/blog
$ resinctl deploy-list Output: archive/webapp/default/blog-0.1.0 production/webapp/default/blog
When you deploy this way you must start the app as follows:
$ resinctl deploy-start blog Output: 'production/webapp/default/blog' is started
Then you would deploy copy a different version to rollback or promote a different version to prod.
In review of the above, we have decided to make the process a bit easier.
The following section has not yet been implemented, but is slated for 4.0.25.
Proposed but not Implemented 4.0.25 Deploy and Rollback
The following section has not yet been implemented, but is slated for 4.0.25.
Deploy version to archive.
$ resinctl deploy ./target/blog-0.1.0.BUILD-SNAPSHOT.war -name blog -version 0.1.0 Output: Deployed archive/webapp/default/blog-0.1.0 from \ ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800 into production \
List versions deployed with all option.
$ resinctl deploy-list -all Output: Tag Ver. DD-MM-YYYY-HH:MM:SS archive/webapp/default/blog-0.1.0 0.1.0 05-12-2011-13:00:00 production/webapp/default/blog 0.1.0 05-12-2011-13:00:00
Later you decide to update to a new version likely after weeks or months of hard development. The line marked with production/webapp/default/blog is the /blog that is deployed in the running server.
$ resinctl deploy ./target/blog-0.2.0.BUILD-SNAPSHOT.war -name blog -version 0.2.0 Output: Deployed archive/webapp/default/blog-0.2.0 from \ ./target/blog-0.1.0.BUILD-SNAPSHOT.war to hmux://127.0.0.1:6800 deployed into production.
At this point the following will be deployed:
$ resinctl deploy-list -all Output: Tag Ver. DD-MM-YYYY-HH:MM:SS archive/webapp/default/blog-0.1.0 0.1.0 05-12-2011-13:00:00 archive/webapp/default/blog-0.2.0 0.2.0 05-01-2012-11:00:00 production/webapp/default/blog 0.2.0 05-01-2012-11:00:00
Even after rigorous load testing and QA testing, a critical bug was found in 0.2.0 blog and now you need to quickly rollback to a previous version.
To rollback to a previous version use the deploy-rollback as follows:
$ resinctl deploy-rollback blog -version 0.1.0 Output: Deployed archive/webapp/default/blog-0.1.0 to hmux://127.0.0.1:6800 \ into production
Alternatively you can use deploy-promote to accomplish the same thing.
To rollback to a previous version use the deploy-promote as follows:
$ resinctl deploy-promote blog -stage archive -version 0.1.0 Output: Deployed archive/webapp/default/blog-0.1.0 to hmux://127.0.0.1:6800 \ into production
We specify the stage as archive (-stage archive) because deploy-promote defaults to working with the preview stage (more on this in the next section).
Now after the rollback the deployed servers should look like this.
$ resinctl deploy-list -all Output: Tag Ver. DD-MM-YYYY-HH:MM:SS archive/webapp/default/blog-0.1.0 0.1.0 05-12-2011-13:00:00 archive/webapp/default/blog-0.2.0 0.2.0 05-01-2012-11:00:00 production/webapp/default/blog 0.1.0 05-12-2011-13:00:00
Notice that 0.1.0 is now in production and 0.2.0 is not.
Promoting an app from preview mode to production
Options
$ resinctl deploy-promote blog Output: Deployed preview/webapp/default/blog to hmux://127.0.0.1:6800 \ into production
Promotes blog that is currently in preview stage into production.
Cluster deployment NOT IMPLEMENTED UNTIL Resin 4.0.25 (coming soon)
This section is slated for Resin 4.0.25 but not released yet and may change.
Resin 4.0.25 adds the following config command line options to support remote configuration and cloud configuration of Resin servers.
resinctl | grep config config-deploy - deploys configuration directory config-copy - copies configuration config-list - lists all deployed configurations config-ls - list contents of config dir as a tree (ex. ./lib) config-cat - list contents of config file (must be text) config-undeploy - undeploys a config config-rollback - rollback to a different config config-promote - promotes a staged config to production
Background on need
At times you need to include things like jar files that are available to more than one application. Resin allows you to deploy these to remote servers (which can be 1 to hundreds of servers) with one simple command.
Let's say your /blog application that relies on MySQL.
By default resin uses the /etc/resin/resin.properties file. You could add these properties to /etc/resin/resin.properties.
/etc/resin/resin.properties on resin server
blogdb.url : blogdb.cvolnlau763z.us-east-1.rds.amazonaws.com blogdb.user : bloguser blogdb.password : roofoo
These properties will vary for dev, production, qa, etc. And once they are set, they will not change often.
You could test locally by copying this file (blog-database.xml) to /etc/resin/resin.d/.
/etc/resin/resin.d/database.xml blog-database.properties under /etc/resin/resin.d.
<resin xmlns="http://caucho.com/ns/resin" xmlns:resin="urn:java:com.caucho.resin"> <database jndi-name="jdbc/blogdb"> <driver type="com.mysql.jdbc.Driver"> <url>jdbc:mysql://${blogdb.url}:3306/blogdb</url> <user>${blogdb.user}</user> <password>${blogdb.password}</password> </driver> </database> </resin>
The problem now is that you don't have a mysql.jar file and you will get a class not found exception when the apps starts up.
If you are using maven locally you can copy mysql from the maven local repo as follows:
Find and copy the mysql jar file from the maven local repo to Resin as follows:
Find it:
$ find ~/.m2/repository/ -name "*mysql*.jar" /home/rick/.m2/repository/mysql/mysql-connector-java/5.1.18/mysql-connector-java-5.1.18.jar
Now deploy it
$ sudo cp ~/.m2/repository/mysql/mysql-connector-java/5.1.18/mysql-connector-java-5.1.18.jar \ /usr/local/share/resin/lib/
Or you can use yum to get the mysql driver as follows:
Next install the mysql driver.
$ sudo yum install mysql-connector-java $ sudo cp /usr/share/java/mysql-connector-java.jar /usr/local/share/resin/lib/
The problem with this approach is that things work for you locally for /blog application if it relies on mysql being managed under jndi:jdbc/blogdb, but all of your remote deployments will fail unless you manually add the mysql jar to each server, manually add the blog-database.xml file to each server, and manually update each resin.properties file.
Remote config deployment
Resin 4.0.25 allows you to deploy configuration files not just applications. This allows you to change what jar files get loaded into the Resin classpath, config files and properties. If you are doing deployment to 1 remote server or to a triad for cloud deployment with 100's of servers, deploying mysql to them can be as easy as what we are going to describe.
Ok assuming you have developed and tested the /blog app locally and now you want to push a blog to a remote server or set of servers, you can do the following:
- Create a directory blog-database
- Create a directory called blog-database/lib
- Copy blog-database.xml into blog-database directory
- Copy mysql.jar into blog-database/lib
- Create a file called blog-database/resin.properties
- Use resinctl config-deploy to deploy the configuration
First create the dirs and copy the jar.
$ mkdir blog-database $ mkdir blog-database/lib $ cp /etc/resin/resin.d/blog-database.xml blog-database/ $ cp /usr/local/share/resin/lib/mysql-connector*.jar blog-database/lib/
Instead of modifying every servers /etc/resin/resin.properties, you can add a resin.properties to blog-database dir that gets deployed with the config bundle as follows:
./blog-database/resin.properties
blogdb.url : blogdb.cvolnlau763z.us-east-1.rds.amazonaws.com blogdb.user : bloguser blogdb.password : roofoo
It might make sense to deploy the database properties in a separate config deployment, but for simplicity we bundle together in one.
NOTE: This works for dir/lib . We should allow dir/webapp-jars and it should work the same. The jars get loaded per webapp for dir/webapp-jars. END NOTE
Next deploy to the remote server as follows:
$ resinctl config-deploy blog-database -version=0.1.0 -address=199.99.99.01 -port=8080
To see what is deployed you can do the following:
$ resinctl config-list -all -address=199.99.99.01 -port=8080 Output: archive/config/default/blog-database-0.1.0 0.1.0 05-12-2011-13:00:00 production/config/default/blog-database 0.1.0 05-12-2011-13:00:00
Or to see everything in the deployment use config-ls
$ resinctl config-ls blog-database -version=0.1.0 -address=199.99.99.01 -port=8080 Output: blog-database.xml resin.properties lib/ mysql-connector-java-5.1.18.jar
If you wanted to see exactly what was in blog-database/blog-database.xml you could do the following:
$ resinctl config-cat blog-database -file=./blog-database.xml -version=0.1.0 -address=199.99.99.01 -port=8080 Output: <resin xmlns="http://caucho.com/ns/resin" xmlns:resin="urn:java:com.caucho.resin"> <database jndi-name="jdbc/blogdb"> <driver type="com.mysql.jdbc.Driver"> <url>jdbc:mysql://${blogdb.url}:3306/blogdb</url> <user>${blogdb.user}</user> <password>${blogdb.password}</password> </driver> </database> </resin>
The following commands work like deploy-undeploy, deploy-rollback and deploy-promote, but for configuration.
- config-undeploy - undeploys a config
- config-rollback - rollback to a different config
- config-promote - promotes a staged config to production
Using config-deploy for a local server
Note you also do these same steps for a local development server instead of copying jar files and config files as follows:
Next deploy to the remote server as follows:
$ resinctl config-deploy blog-database -version=0.1.0
(Just leave off the address and port.)
To see what is deployed you can do the following:
$ resinctl config-list -all Output: archive/config/default/blog-database-0.1.0 0.1.0 05-12-2011-13:00:00 production/config/default/blog-database 0.1.0 05-12-2011-13:00:00
Just leave off address and port to see what is configured locally.
The advantage of using confg-deploy locally is that your dev system is more like your integration, qa and production system. It is like having a local cloud.