I recently tried to setup GIT continuous deployment for a Java WebApp (https://azure.microsoft.com/en-us/documentation/articles/web-sites-publish-source-control/).
I've uploaded my war archive into a separate branch on my GIT repository (see https://gist.github.com/koraktor/85964), setup the fetch keys and run it.
As you may see here - https://azure.microsoft.com/en-us/documentation/articles/web-sites-java-add-app/ all Java WebApps have a 'webapps' folder beneath 'wwwroot' folder.
Git continous deployment will copy all files under 'wwwroot' folder, hence, Java WebApps cannot be continuously deployed. The files need to be copied under 'webapps' folder.
Is there anything that I'm missing here? Or actually is not possible to continuously deploy a Java WebApp using Git?
Found a relatively simple solution - http://blogs.msdn.com/b/azureossds/archive/2015/12/11/use-custom-context-for-azure-tomcat-application.aspx
Deploy a custom Tomcat (don't forget the web.config) (see https://azure.microsoft.com/en-us/documentation/articles/web-sites-java-custom-upload/).
Modify your server.xml to point to wwwroot directory.
Modify any JAVA_OPTS if you want (OPTIONAL) (e.g In this web.config, you can specify your own JVM memory settings:
<environmentVariable name="JAVA_OPTS" value="-Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8 -Xms512m -Xmx8192m -XX:MaxPermSize=256m" />
There is a small problem with this approach, when you want to create a deployment slot (see https://azure.microsoft.com/en-us/documentation/articles/web-sites-staged-publishing/) . That deployment slot is a brand new WebApp that only clones the settings not the files in the main WebApp (not the custom Tomcat that you just deployed). Hence, you will have to copy it over (which is a little bit error-prone).
Usually deployment slots, should be as similar to production slots as possible.
Related
I am working on a Java project and have a problem with Wildfly 10's deployment. I don't find the solution in its documentation and would appreciate some help.
When I deploy a .WAR, Wildfly creates a temporary folder to store the exploded files:
./standalone/tmp/vfs/temp/tempb75b67d7adb84a3d/web.war-47f6d3d54946006d/
and as soon as I stop Wildfly with /etc/init.d/wildfly stop, all these temporary files are instantly deleted from the disk.
Problem:
The WAR contains default .properties files which have to be modified/configured by the administrator. Since the files are deleted with every deployment, this is not currently possible.
Questions:
Is there a way to have Wildfly deploys the .WAR to a permanent folder (similar to Apache Tomcat) ?
Is it a good J2E practice to do so considering the client wants to deploy this .WAR to a Debian Cloud infrastructure, but also occasionally to Windows Server?
What alternatives should we consider to store the .properties values?
WildFly does support unzipped (exploded) deployments. Have a look at $JBOSS_HOME/standalone/deployments/README.txt for details. Basically, you can just unzip your WAR to a subdirectory and add a marker file to have it deployed.
However, any configuration information that depends on the given host environment should not be placed in the WAR. A WAR is a compile-time artifact which should be regarded as immutable at run-time. (The fact that some web containers unzip the WAR and expose its internals is an implementation detail you should never rely on.)
Instead, you can define configuration data via system properties, environment variables, JNDI entries, whatever.
A very simple approach I often use with WildFly is the -P option:
cd $JBOSS_HOME/bin
./standalone.sh -P myconfig.properties
where myconfig.properties is a simple Java properties file. WildFly reads this file very early in its start-up phase and sets all properties as system properties.
Being system properties, these configuration items will be visible to all deployments, which shouldn't be a problem as long as you control what gets deployed to your server. To avoid conflicts between properties for different deployments, you can use deployment specific prefixes for your property keys, e.g.
app1.jdbc.url = jdbc:postgresql://localhost/app1
app2.jdbc.url = jdbc:postgresql://localhost/app2
Currently, when you deploy a Java WebApp using the default Tomcat, the default Tomcat will listen for WAR archives on D:\home\site\wwwroot\webapps (See https://azure.microsoft.com/en-us/documentation/articles/web-sites-java-add-app/).
The problem is that if you plan to use continuous deployment through GIT, the new fetched archives will be copied under wwwroot folder, not under wwwroot/webapps, so the default Tomcat can listen on them.
Is there any way in which I can tell the default Tomcat to listen for War archives on a specific folder (e.g wwwroot instead) ?
Are there settings that I can play with?
Having a custom Tomcat (second solution of
http://blogs.msdn.com/b/azureossds/archive/2015/12/11/use-custom-context-for-azure-tomcat-application.aspx) is not the most optimal solution, since we will have to copy the Tomcat to all deployment slots that we configure (that's error prone). Deployment slots should be as similar as possible.
At the same time, some of the settings from ApplicationSettings won't be applied anymore, since they apply only on the default Tomcat.
There is my answer for the other thread that the needs was similar with yours. I think it can help you, please refer to the thread Azure Tomcat Eclipse Deployment.
Based on my understanding, you want to deploy the war file into Azure WebApps thru Azure Git continuous deployment. So you can follow the steps modified from the answered thread above, see below.
Open the git bash cmd and make a new directory webapps for war files.
Copy or export the war file into the directory webapps.
git init
git add webapps
git commit -m "Something Commit"
git remote add <app-name> <git-clone-url>
git push <app-name> master
Note: For the variables <app-name> and <git-clone-url>, you can find them on Azure new portal.
Now, you can browse https://<app-name>.azurewebsites.net/<war-file-name> to see it after tomcat unzip the war file to the same name folder automatically.
For continous deployment, you just need to repeat the step 2, 4 and 6.
Any concern, please feel free to let me know.
I created a normal Dynamic Web Project in Eclipse. I added a folder to the project, which shows up after refreshing the project. The folder is containing an XML-file with configurations for the applications.
When I deploy the application on the tomcat in eclipse, the relative pathes do not match anymore. I need to copy the folder in the catalina home directory and then it works.
Question
How can I add the folder to my project, that when I start tomcat (V7) in eclipse the folder is deployed as well and the relative pathes work too?
When the development comes to an end, I will export a WAR-File and deploy it on my server. It would be great, if then the configurations will be included as well.
If you have any questions or you need some further information, do not hesitate to ask nor to comment!
In the project's properties I have found where I can add the folder when I export the WAR-file. But it doesn't deploy in eclipse's tomcat yet. This part is still remaining.
I copied the configs-folder into the WebContent-folder and accorded the paths.
Now i have two configurations, one for my local execution and one for the execution on Tomcat after the deployment.
Important Advise
I needed to accord the filepaths starting from CATALINA's home directory.
Does anybody know a gradle 'hot deployment' plugin (or middleware as shell script) which is coping files from source folder directly into project folder at tomcat's webapps directory (not embedded server like gretty or gradle tomcat plugin; version7, environment independent)?
At the end I want to realize a smart dev workflow to (re-, un-) deploy a java web application during code crafting. I'm searching for something like grunt watch tasks.
Scenario: Java web application with self contained, executable jar file at WEB-INF/lib folder.
register watcher tasks on top on gradle task
java source is changed
tomcat stopped
remove jar file at WEB-INF/lib folder
deploy jar file
copy jar into WEB-INF/lib folder
(delete all log files)
start tomcat
Restart tomcat is not needed if static sources are changed (e.g. JSP, JS, ect.).
Solution
I thought about our working practices at the office. My colleagues and I, we program on Windows machines and we use a key map configuration in IDEA to start and stop our local installed Tomcat.
The easiest way for me is to define a user related CATALINA_HOME system environment variable which references the path to Tomcat server.
CATALINA_HOME = C:\Program Files\apache-tomcat-7.0.56
I define a deploy task which copy compiled war file into webapps folder ((re)start Tomcat manually via IEDA).
task deploy(type: Copy) {
def WEBAPPS_HOME = System.getenv()['CATALINA_HOME'] + '/webapps'
from 'build/libs/app.war' into WEBAPPS_HOME
dependsOn war
}
Nobody need to change Tomcat path inside build.gradle file or there is no additional user.config file which is ignored by git.
But I don't like manual Tomcat handling and it is unusual to work with environment variables on Mac's.
So, I decide to search an embedded Tomcat server as Gradle cargo plugin for local development. It is recommanded from Benjamin Muschko (Gradleware Engineer) at How to use local tomcat?... and he describe the differences between Cargo or Tomcat plugin....
Setup of this plugin is quite easy. I don't need to explain.
Nobody need to install there own Tomcat and everybody work with same version server.
For our nigthly build I use the power of Gradle wrapper as Jenkins task configuration.
I execute a wintods batch command.
cd "%WORKSPACE%\app"
gradlew.bat clean build
I use Jenkins to manage deployments for our applications.
There are a number of plugins which help with such tasks along with having the ability to write your own scripts.
Jenkins is highly configurable so you are able to adapt it to your own needs.
Jenkins URL
While development I need to frequently update my web app source code & deploy the updated war to a remote Tomcat server. Uploading a big war(25MB) takes too long(around 30 min) on my connection which is very unproductive. Is there any way I could reduce the war size ? There are a lot of external dependencies in my project. Could I deploy just the changes(may be dependencies remain intact) ?
It depends how much control you have over the upload process. If you have remote access to the filesystem, the following should work:
Upload the WAR
Let Tomcat expand it
Stop Tomcat
Delete the WAR
Start Tomcat
Tomcat should run your app from the expanded directory
Upload changed files only and replace the old ones in the expanded directory
For static files, no further action is necessary
If up update classes or JARs, you'll need to restart Tomcat
What you are asking (Could I deploy just the changes?) cannot be done. There are other things you can do though to reduce the file size of your war file:
You can place libraries in tomcat's common directory (tomcat-dir/common/lib) and remove them from your dependencies in your war file (Does Tomcat load the same library file into memory twice if they are in two web apps?).
Place static file on a cdn or another web application on your tomcat (that would require code modification though)
You can use git hooks (http://www.git-scm.com/book/en/v2/Customizing-Git-Git-Hooks). Altough, this requires a git repository on your webserver. Deployments may triggered by push events.
Actually, if exploded war deployment is an option for you then you could use kwatee. It's a free and unrestricted tool (I'm the author) with a simple web interface (or CLI automation) that can do incremental exploded war updates and many other things.