Django Pipeline, Heroku, and SASS

Django Pipeline, Heroku, and SASS

OK, here's how I got this working using Compass to compile my SASS files.

  • Use multiple Heroku buildpacks - Heroku Buildpack Multi
  • Put the following in your .buildpacks file

    https://github.com/heroku/heroku-buildpack-ruby.git
    https://github.com/heroku/heroku-buildpack-nodejs
    https://github.com/heroku/heroku-buildpack-python.git
  • Create a Gemfile with compass and any other requirements you have. Here's mine:

    source 'https://rubygems.org'

    ruby '1.9.3'

    gem 'bootstrap-sass'
    gem 'compass'
  • Create a config.rb file. Here's mine. As you can see it, requires the bootstrap-sass that I included in my Gemfile:

    # Require any additional compass plugins here.
    require 'bootstrap-sass'

    # Set this to the root of your project when deployed:
    http_path = "/"
    css_dir = "app_folder/static/css"
    sass_dir = "app_folder/static/sass"
    images_dir = "app_folder/static/images"

    output_style = :compact

    more details on config.rb can be found here

  • Install node packages (django-pipeline wants yuglify). You'll need a package.json file:

    {
    "dependencies": {
    "yuglify": "0.1.4"
    },
    "engines": {
    "node": "0.10.x",
    "npm": "1.3.x"
    },
    "repository": {
    "type": "git",
    "url": "your repo url"
    }
    }
  • almost ready...
  • when Heroku runs the ruby buildpack, it will look for a rake task called assets:precompile. So now you'll need to add a Rakefile with the following:

    namespace 'assets' do
    desc 'Updates the stylesheets generated by Sass/Compass'
    task :precompile do
    print %x(compass compile --time)
    end
    end

    this will put compile your stylesheets. You need to make sure you set the output (back in config.rb) to the place that django-pipeline is looking for CSS files (shown in the original question).

  • You should get rid of this part in the original question as django-pipeline isn't compiling your SASS for you:

    PIPELINE_COMPILERS = (
    'pipeline.compilers.sass.SASSCompiler',
    )
  • That should be it! Deploys should just work now, and it didn't really add a significant amount of time to my deploy process.

All in all, it amounts to a lot of setup, but for me it was well worth it as I no longer have to commit compiled files into the repository, which was causing a lot of merge conflicts when working with branches and pull requests.

I would like to figure out how to do this using only two buildpacks (obviously only one would be ideal but I don't know if it's possible). The problem is trying to find binary paths so that pipeline can do it's thing when it doesn't find the defaults. I'm not sure if the reason I can't do this is because of how Heroku is installing things, or because there is a bug in django-pipeline, but right now this is good enough for me.

If you try this and it doesn't work for you, let me know, if I missed something I'm happy to make updates.

Compile SASS/SCSS files on Heroku in Django app

It seems that heroku skipps the compiling scss files part, and pass directly to collecting statics so:

1st step was to disable collecting static files:

heroku config:set DISABLE_COLLECTSTATIC=1

2nd step is to run a post-compile process:

heroku run python manage.py compressscss

and then

heroku run python manage.py collectstatic --noinput 

This can be run automatically by overriding the post-compile of python build pack shown here in this post Link to a how to create postcompile file

Where you create a file in bin/post_compile in the root of the app with:

#!/usr/bin/env bash

cd "$1" || exit 1
python manage.py compilescss --traceback
python manage.py collectstatic --noinput --traceback

And push to Heroku to apply changes.

Static files not working with Django, Heroku, and Django Sass Processor

I haven't used this exact set of tools before, but I think you'll have better luck if you approach things this way:

  1. Make sure your application is configured to run two buildpacks. heroku/nodejs should run first and heroku/python should run second.

    Since you're manually running yarn now I suspect that this is already done. yarn isn't included in the Python buildpack.

  2. Add a heroku-postbuild script to your package.json that runs yarn build. This should cause your React code to get built during deployment after your Node.js dependencies have been installed.

  3. Re-enable Heroku's automatic collectstatic by running heroku config:unset DISABLE_COLLECTSTATIC. I don't think you actually need to ignore the .scss files.

You might also want to take a look at django-heroku, a Django library from Heroku that helps set up deployment on their platform. It's officially recommended and may well help resolve your HTTP 404 issues.

How to use SASS in Django?

I would suggest to use django-webpack-loader & configure webpack.
This might help https://github.com/khadegd/django-webpack-starter.

Notice: I'm the owner of django-webpack-loader

Django with django pipeline / Amazon s3 / Cloudfront : versioning assets

Thanks to cyberdelia I managed to make it works.

First, the "CachedFilesStorage" only put hashname in the filenames if your DEBUG settings is turned off (= False).
It runs well on my production server.

From here, the "collectstatic" command is uploading the right files on S3 (with hash in the name).
I met a second problem: the URL cached is pointing to the S3 Bucket but not the Cloudfront defined in the "STATIC_URL" setting.
I think it's related to django-storages / boto used by my custom storage which works with S3 and not Cloudfront:

class S3PipelineStorage(PipelineMixin, CachedFilesMixin, StaticStorage):
pass

(Static storage is a S3BotoStorage subclass with location sets to "static").

Now, I have to find a way to make it works properly with Cloudfront and not S3.

Thanks for your help!

EDIT:

I figured out to make it works via this post: Django-compressor: how to write to S3, read from CloudFront?

While you define the "custom domain" key, it will use the Cloudfront domain instead of the Amazon S3.

I forgot to mention that I had to put the AWS_QUERYSTRING_AUTH to False to make it works.



Related Topics



Leave a reply



Submit