# blog-django-py **Repository Path**: podchaolucky66/blog-django-py ## Basic Information - **Project Name**: blog-django-py - **Description**: aaaaaaaaaaaaaaaaaaaa - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 3 - **Created**: 2022-09-07 - **Last Updated**: 2023-12-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README This repository contains a sample implementation of a blog application, designed to show off various features of OpenShift. The blog application is implemented using Python and Django. In the default deployment configuration, the blog application uses a SQLite database within the container. When using the SQLite database, it will be pre-populated each time the application starts with a set of blog posts. An initial account will also be created for logging into the application to add more posts. The user name for this account is ``developer`` and the password is ``developer``. Because the SQLite database is stored in the container, new posts and any uploaded images, will be lost when the container restarts. A PostgreSQL database can be attached to the application to add persistence for posts and demonstrate the use of a database. A separate persistent volume can also be attached to the blog application to provide persistent storage for uploaded images. In the case of PostgreSQL being used, a manual step is required to setup the database the first time. The appearance of the blog application can also be adjusted using a set of environment variables to make it easier to demonstrate blue/green or a/b deployments, split traffic etc. # Deploying from an image An image is automatically built from this repository when code changes are made using the Docker Hub automated build mechanism. To deploy the sample application from the command line, you can run: ``` oc new-app openshiftkatacoda/blog-django-py --name blog-from-image oc expose svc/blog-from-image ``` # Building from source code A source build and deployment can be run direct from this repository. To build and deploy the sample application from the command line, you can run: ``` oc new-app python:latest~https://github.com/openshift-katacoda/blog-django-py --name blog-from-source-py oc expose svc/blog-from-source-py ``` Note that you need to provide the S2I builder name of ``python:latest`` if you are not explicitly telling ``oc new-app`` that the source build strategy should be used. This is because the repository also contains a ``Dockerfile`` and automatic detection performed by ``oc new-app`` would give precedence to the docker build strategy. To build and deploy the sample application from the command line, but at least have automatic source language detection occur, you can run: ``` oc new-app --strategy=source https://github.com/openshift-katacoda/blog-django-py --name blog-from-source-auto oc expose svc/blog-from-source-auto ``` # Building from Dockerfile A docker build and deployment can be run direct from this repository. To build and deploy the sample application from the command line, you can run: ``` oc new-app https://github.com/openshift-katacoda/blog-django-py --name blog-from-docker oc expose svc/blog-from-docker ``` This relies on ``oc new-app`` doing auto detection and finding that a ``Dockerfile`` exists. If want to be specific, you can use the ``--strategy=docker`` option to be sure. # Adding a PostgreSQL database A PostgreSQL database can be used to add persistence for blog posts. To deploy a PostgreSQL database from the command line, you can run: ``` oc new-app postgresql-persistent --name blog-database --param DATABASE_SERVICE_NAME=blog-database --param POSTGRESQL_USER=sampledb --param POSTGRESQL_PASSWORD=sampledb --param POSTGRESQL_DATABASE=sampledb ``` To re-configure the blog application to use the database, you need to set the ``DATABASE_URL`` environment variable for the blog application. ``` oc set env dc/blog-from-source-py DATABASE_URL=postgresql://sampledb:sampledb@blog-database:5432/sampledb ``` As a separate service is used for the database, it is necessary to manually setup the database the first time. This requires logging into the pod and running a ``setup`` script. To run the ``setup`` script from the command line, you can run: ``` POD=`oc get pods --selector app=blog-from-source-py -o name` oc rsh $POD scripts/setup ``` The ``setup`` script will initialize the database tables and then prompt you for details of an initial account to setup. ``` $ oc rsh $POD scripts/setup -----> Running Django database table migrations. Operations to perform: Apply all migrations: admin, auth, blog, contenttypes, sessions Running migrations: No migrations to apply. Your models have changes that are not yet reflected in a migration, and so won't be applied. Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them. -----> Running Django super user creation Username: developer Email address: mail@example.com Password: Password (again): Superuser created successfully. -----> Pre-loading Django database with blog posts. Installed 2 object(s) from 1 fixture(s) ``` You can login to the blog application by clicking on the person icon top right of the blog application web page. Then click the plus icon top right to add a new post. The blog posts title and text content should now survive a restart of the container. Any uploaded image will still be lost at this point on a restart. # Adding a persistent volume A persistent volume can be used to add persistence for uploaded images. Before a persistent volume is added, it is necessary to change the deployment strategy for the blog application to ``Recreate`` instead of ``Rolling``. If this is not done and an ``RWO`` type persistent volume is used, then deployments may fail due to the volume only being able to be mounted to a single cluster node at a time. To change the deployment strategy from the command line, you can run: ``` oc patch dc/blog-from-source-py -p '{"spec":{"strategy":{"type":"Recreate"}}}' ``` When mounting the persistent volume for storing images it should be mounted in the blog application at ``/opt/app-root/src/media``. To add the persistent volume from the command line, you can run ``` oc set volume dc/blog-from-source-py --add --name=blog-images -t pvc --claim-size=1G -m /opt/app-root/src/media ``` When images are attached to a post, they do not appear on the top level page containing all posts, you need to drill down into the post to see it. Once you add a persistent volume, if it is of type ``RWO`` and you are not on a single node cluster, you should also not demonstrate scaling up the number of replicas as the volume will not be able to be mounted on multiple nodes at the same time. # Customising appearance To make it easy to demonstrate green/blue or a/b deployments, it is possible to modify the appearance of the blog application by setting environment variables. These are: * ``BLOG_SITE_NAME`` - Sets the title for pages. * ``BLOG_BANNER_COLOR`` - Sets the color of the page banner. To set environment variables from the command line, you can run: ``` oc set env dc/blog-from-source-py BLOG_BANNER_COLOR=blue ``` Under the title on each page, the host name for the pod handling the request is also shown if disabling sticky sessions on routing, or using curl to show how requests or different users are automatically load balanced across instances when scaled up. # Demonstrating Config Maps In addition to being able to perform customisations using environment variables, use of a config map is also supported. The config map should be defined as a JSON data file. For example, save this as ``blog.json``. ``` { "BLOG_SITE_NAME": "OpenShift Blog", "BLOG_BANNER_COLOR": "black" } ``` The config map can be created using the command: ``` oc create configmap blog-settings --from-file=blog.json ``` and then mounted into the container using: ``` oc set volume dc/blog --add --name settings --mount-path /opt/app-root/src/settings --configmap-name blog-settings -t configmap ``` Even if a config map is used, environment variables, if defined for the same settings, will take precedence.