All Projects → ansible → django-gulp-nginx

ansible / django-gulp-nginx

Licence: other
Django + PostgreSQL + Nginx with Gulp-built static assets framework, managed with Ansible Container

Programming Languages

javascript
184084 projects - #8 most used programming language
python
139335 projects - #7 most used programming language
CSS
56736 projects
shell
77523 projects
HTML
75241 projects
Makefile
30231 projects

Build Status

django-gulp-nginx

A framework for building containerized django applications. Utilizes Ansible Container to manage each phase of the application lifecycle, and enables you to begin developing immediately with containers.

Includes django, gulp, nginx, and postgresql services, pre-configured to work together, and ready for development. You can easily adjust the settings of each, as well as drop in new services directly from Ansible Galaxy. The following topics will help you get started:

Requirements

Before starting, you'll need to have the following:

Getting Started

To start creating your Django application, create a new directory, and initialize it with a copy of this project:

# Create a new directory for your project
$ mkdir demo

# Set the working directory
$ cd demo 

# Initialize the project
$ ansible-container init ansible.django-gulp-nginx

Next, build a local copy of the project's images. From the new project directory, start the build process by running the following:

# Create the container images
$ ansible-container build

The build process will take a few minutes to complete. It will take longer the first time you run it, because it needs to pull the base image, and build the Conductor image.

After the Conductor build completes, each service in the container.yml file will be built. Services are built by executing one or more Ansible roles, and as the build process progresses, task names will scroll across your session window as each role executes.

Once completed, you'll have a local copy of the built images that can be used to run the application. When you're ready to start the application, run the following:

# Start the containers
$ ansible-container run

Requests are proxied through the gulp service. Before you can view the sample web page, the gulp web server needs to be started. This may take a couple moments, as the process first install node modules and bower components prior to starting the service. You can watch the logs by running the following:

# Watch the logs for gulp service
$ docker logs -f demo_gulp_1

The following message in the logs indicates the service is running:

[17:05:29] Starting 'js'...
[BS] Access URLs:
 -----------------------------------
       Local: http://localhost:8080
    External: http://172.21.0.4:8080
 -----------------------------------
          UI: http://localhost:3001
 UI External: http://172.21.0.4:3001
 -----------------------------------
[BS] Serving files from: dist
[17:05:30] Finished 'lib' after 601 ms
[17:05:30] Finished 'html' after 574 ms
[17:05:30] Finished 'sass' after 644 ms
[17:05:30] Finished 'templates' after 685 ms
[17:05:30] Finished 'js' after 631 ms

To view the sample app, open a browser and go to http://localhost:8080, where you'll see a simple "Hello World!" message.

Developing

When you start the containers with ansible-container run, they start in development mode, which means that the dev_overrides section of each service definition in container.yml takes precedence, causing the gulp, django and postgresql services to start, and the nginx service to stop.

The frontend code can be found in the src directory, and the backend django code is found in the project directory. You can begin making changes right away, and as you do, you'll see the results reflected in your browser almost immediately.

Here's a brief overview of each of the running services:

gulp

While developing, the gulp service will actively watch for changes to files in the src directory tree, where custom frontend components (i.e. html, javascript, css, etc.) live. As new files are created, or existing files modified, the gulp service will compile the updates, place results in the dist directory, and using browsersync, refresh your browser.

In addition to compiling the frontend components, the gulp service will proxy requests beginning with /static or /admin to the django service. The proxy settings are configurable in gulpfile.js, so as you add additional routes to the django service, you can expand the number of paths forwarded by the gulp service.

NOTE

As you add new routes to the backend, be sure to update the nginx service definition by modifying container.yml, and adjusting the parameters passed to the ansible.nginx-container role. Specifically, you'll need to update the PROXY_LOCATION value.

django

The django service provides the backend of the application. During development the runserver process executes, and accepts requests from the gulp service. The source code to the Django app lives in the project directory tree. To add additional Python and Django modules, add the module names and versions to requirements.txt, and run the ansible-container build command to install and incorporate them into the django image.

When the django container starts, it waits for the PostgreSQL database to be ready, and then it performs migrations, all before starting the server process. Use make django_manage makemigrations and make django_manage migrate to create and run migrations during development.

postgresql

The postgresql service provides the django service with access to a database, and by default stores the database on the postgres-data volume. Modify container.ym to set the database name, and credentials.

Adding Services

You can add preconfigured services to the application by installing Container Enabled roles directly from the Galaxy web site. Look for roles on the site by going to the Browse Roles page, setting the filter to Role Type, and choosing Containr Enabled.

For example, if you want to install a Redis service, you can install the j00bar.redis-container role by running the following:

# Set the working directory to your project root
$ cd demo

# Install the role
$ ansible-container install j00bar.redis-container

After the install completes, the new service will be included in container.yml. You'll then need to run the build process to update the project's images:

# Rebuild the project images
$ ansible-container build 

After the build process completes, restart the application by running the following:

# Run the application 
$ ansible-container restart

Testing

After you've made changes to the app, and you're ready to test, you'll first run ansible-container build to create a new set of images containing the latest code. During the build process, the project directory, which contains your custom Django files, will be copied into the django image at /django, and your frontend assets, contained in src, will be compiled and copied to the dist directory, and then copied into the nginx image at /static.

Once the new images are built, run the following to test the images:

# Restart the application in production mode for testing
$ ansible-container stop
$ ansible-container run --production

The above starts the containers in production mode, ignoring the dev_overrides section of each service definition in container.yml`, and executing the containers as if they were deployed to production. This time the django, nginx, and postgresql containers starts, and the gulp container stops. Just as before, access the application at http://localhost:8080.

django

In production this service will run the gunicorn process to accept requests from the nginx service. Just as before, when the service starts it will wait for the PostgreSQL database to become available, and then perform migrations, before starting the server process.

nginx

This service will respond to requests for frontend assets, and proxy requests to django service endpoints. Before running ansible-container build, if you added new routes to your django application, be sure to update the nginx configuration by modifying container.yml, and adjusting the PROXY_LOCATION parameter passed to the ansible.nginx-container role. This will impact the nginx.conf file that gets added to the image.

postgresql

Just as before, the postgresql sevice provides the django service with access to a database, and by default stores the database on the postgres-data volume.

NOTE

If you start the image build process by running make build, the postgres-data volume will be deleted, and the application will start with an empty database.

Deploying

Ansible Container can deploy to Kubernetes and OpenShift. For the purposes of demonstrating the deployment workflow, we'll use OpenShift. If you want to carry out the actual steps, you'll need access to an OpenShift instance. The Install and Configure Openshift guide at our doc site provides a how-to that will help you create a containerized instance.

Log into the cluster using your developer account:

# Log into the local cluster
$ oc login -u developer

Create a demo project:

# Create a new project
$ oc new-project demo

The project name is defined in container.yml. Within the settings section, you will find a k8s_namespace section that sets the name. The project name is arbitrary. However, before running the deploy command, the project must already exist, and the user you're logged in as, must have access to it.

Next, use the deploy command to push the project images to the local registry, and create the deployment playbook. For demonstration purposes, we're referencing the local_openshift registry defined in container.yml. Depending on how you created the local OpenShift cluster, you may need to adjust the registry attributes.

One of the registry attributes is namespace. For OpenShift and K8s, the registry namespace should match the name value set in k8s_namespace within the settings section. In the case of OpenShift, the name in k8s_namespace will be the project name, and for K8s, it's the Namespace.

Once you're ready to push the images, run the following from the root of the demo project directory:

# Push the built images and generate the deployment playbook
$ ansible-container --engine openshift deploy --push-to local_openshift --username developer --password $(oc whoami -t)

The above will authenticate to the registry using the developer username, and a token generated by the oc whoami -t command. This presumes that your cluster has a developer account, and that you previously authenticated to the cluster with this account.

After pushing the images, a playbook is generated and written to the ansible-deployment directory. The name of the playbook will match the project name, and have a .yml extension. In this case, the name of the playbook will be demo.yml.

You will also find a roles directory containing the ansible.kubernetes-modules role. The deployment playbook relies on this role for access to the Ansible Kubernetes modules.

To deploy the application, execute the playbook, making sure to include the appropriate tag. Possible tags include: start, stop, restart, and destroy. To start the application, run the following:

# Run the deployment playbook
$ ansible-playbook ./ansible-deployment/demo.yml --tags start

Once the playbook completes, log into the OpenShift console to check the status of the deployment. From the Applications menu, choose Routes, and find the URL that points to the nginx service. Using this URL, you can access the appication running on the cluster.

Contributing

If you work with this project and find issues, please submit an issue.

Pull requests are welcome. If you want to help add features and maintain the project, please feel free to jump in, and we'll review your request quickly, and help you get it merged.

Dependencies

This project depends on the following Galaxy roles:

License

Apache v2

Authors

View AUTHORS for a list contributors. Thanks everyone!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].