This is part two of a three-part series. In this post, we’ll cover live synchronization. Part one covered manually copying files into and out of a container. Finally, in part three, we’ll cover copying files into a new persistent volume.
Part Two: Synchronizing Files with a Container
In addition to being able to manually upload or download files when you want, the
oc rsync command can also be set up to perform live synchronization of files between your local computer and the container.
That is, the file system of your local computer will be monitored for any changes made to files. When there is a change to a file, the changed file will be automatically copied to the container.
This same process can also be run in the opposite direction if required, with changes made in the container being automatically copied back to your local computer.
An example of where it could be useful to have changes automatically copied from your local computer into the container is during application development.
For scripted programming languages such as PHP, Python, or Ruby, where no separate compilation phase is required (provided that the web server can be manually restarted without causing the container to exit), or if the web server always reloads code files which have been modified, you can perform live code development with your application running inside of OpenShift.
If you’ve completed [part one](https://blog.openshift.com/transferring-files-in-and-out-of-containers-in-openshift-part-1-manually-copying-files/ of this blog post series, you’ve already deployed a web application from a Git repository. Now, to demonstrate the ability that we’re referring to above, you should clone this Git repository for the app that you've already deployed:
git clone https://github.com/openshift-katacoda/blog-django-py
This will create a subdirectory
blog-django-py that contains the source code for the application:
Cloning into 'blog-django-py'...
remote: Counting objects: 125, done.
remote: Total 125 (delta 0), reused 0 (delta 0), pack-reused 125
Receiving objects: 100% (125/125), 22.59 KiB | 0 bytes/s, done.
Resolving deltas: 100% (45/45), done.
Inside your terminal, navigate to the directory that you created when cloning the Git repo. This is where you’ll be working for a while.
If you haven’t already done so, get the name of the pod, as was done in the previous part of this series:
oc get pods --selector app=blog
This should give a result that is similar to this:
NAME READY STATUS RESTARTS AGE
blog-1-t7932 1/1 Running 0 1m
Getting the name of the pod enables you to use it as an argument for interacting with it, so replace this pod name with your actual pod name in the subsequent commands.
Now, open a new terminal window, and from the source directory for the application, run the following command to have
oc rsync perform live synchronization of the code, copying any changes from the
blog-django-py directory to the container.
oc rsync . blog-1-t7932:/opt/app-root/src --no-perms --watch
When initially running this
oc rsync command, you'll see it copy files so that the local and remote directory are synchronized. Any changes made to the local files will now be automatically copied to the remote directory.
Before we make a change, bring up the web application we've deployed in a separate browser window. You can find the URL for this by going to the web console, and finding the route link that was created in the Overview.
The color of the title banner for the website should be red.
Let's change the banner color by running this command:
echo "BLOG_BANNER_COLOR = 'blue'" >> ./blog/context_processors.py
Wait to see that the changed file is uploaded, and then refresh the page for the website.
Unfortunately, you'll see that the title banner is still red. This is because, for Python, any code changes are cached by the running process, and it's necessary to restart the web server application processes to see a change.
For this deployment, the WSGI server
mod_wsgi-express is being used. To trigger a restart of the web server application process, run:
oc rsh blog-1-t7932 kill -HUP 1
This command will have the effect of sending a HUP (hang up) signal to process ID 1 running within the container, which is the instance of
mod_wsgi-express that's running. This will trigger the required restart and reloading of the application, but without the web server actually exiting.
Refresh the page for the website once more, and the title banner should now be blue.
Note that the name of the pod as displayed in the title banner is unchanged, indicating that the pod was not restarted, and only the web server application processes were restarted.
Manually forcing a restart of the web server application processes will get the job done, but a better way is if the web server can automatically detect code changes and trigger a restart.
In the case of
mod_wsgi-express and how this web application has been configured, this can be enabled by setting an environment variable for the deployment. To set this, run:
oc set env dc/blog MOD_WSGI_RELOAD_ON_CHANGES=1
This command will update the deployment configuration, shut down the existing pod, and replace it with a new instance of our application with the environment variable now being passed through to the application.
Monitor the re-deployment of the application by running:
oc rollout status dc/blog
Use ctrl+C to interrupt the existing
rsync command so that it can be restarted.
oc get pods --selector app=blog to get the name of the new pod.
NAME READY STATUS RESTARTS AGE
blog-2-10rsz 1/1 Running 0 1m
oc rsync command again for the new pod:
oc rsync . blog-2-10rsz:/opt/app-root/src --no-perms --watch
Refresh the page for the website again, and the title banner should still be blue, but you'll notice that the pod name has changed.
Modify the code file once more, setting the color to green this time.
echo "BLOG_BANNER_COLOR = 'green'" >> ./blog/context_processors.py
Refresh the website again, multiple times if needed, until the title banner is green. The change may not be immediate, as the file synchronization, detection of the code changes, and automatic restart of the web server application process may take a few moments.
Although one can synchronize files from the local computer into a container in this way, whether you can use it as a mechanism for enabling live coding will depend on the programming language and web application stack being used. This was possible for Python when using
mod_wsgi-express, but may not be possible with other WSGI servers for Python, or other programming languages.
Note that, even for the case of Python, this can only be used when modifying code files. If you need to install additional Python packages, you'll need to re-build the application from the original source code. This is because changes to packages are required (which for Python, is given in the
requirements.txt file), and the installation of that package isn't going to be triggered when using this mechanism.
In this post, you've learned about
oc commands that you can use to set up live synchronization so that changes are automatically copied from a local machine into a running container.
You can find a summary of the key command covered below. To see more information on each
oc command, run it with the
oc rsync ./local/dir <pod-name>:/remote/dir --no-perms --watch: Copy the directory to the remote directory in the pod, and then keep the remote directory synchronized with the local directory, with any changed files automatically being copied to the pod. The
--no-permsoption ensures that no attempt is made to transfer permissions, which can fail if remote directories are not owned by the user that the container runs as. The
--watchoption is what enables the synchronization mechanism.
Would You Like to Learn More?
This post is based on one of OpenShift’s interactive learning scenarios. To try it and our other tutorials without needing to install OpenShift, visit https://learn.openshift.com
Do you have an OpenShift Online account? There's no reason to wait. Get your applications running in minutes with no installation needed. Sign up for the free trial of OpenShift Online.
What other topics would you like to see in the future on this blog? We're happy to make tutorials about anything that helps you with your OpenShift experience. Comment and let us know!