a method to deploy app to heroku using docker

def deploy_docker(self, dockerfile_path, virtualbox_name='default'):

        ''' a method to deploy app to heroku using docker '''

        title = '%s.deploy_docker' % self.__class__.__name__

    # validate inputs
        input_fields = {
            'dockerfile_path': dockerfile_path,
            'virtualbox_name': virtualbox_name
        }
        for key, value in input_fields.items():
            object_title = '%s(%s=%s)' % (title, key, str(value))
            self.fields.validate(value, '.%s' % key, object_title)
    
    # check app subdomain
        if not self.subdomain:
            raise Exception('You must access a subdomain before you can deploy to heroku. Try: %s.access()' % self.__class__.__name__)
            
    # import dependencies
        from os import path

    # validate docker client
        from labpack.platforms.docker import dockerClient
        dockerClient(virtualbox_name, self.verbose)

    # validate dockerfile
        if not path.exists(dockerfile_path):
            raise Exception('%s is not a valid path on local host.' % dockerfile_path)
        dockerfile_root, dockerfile_node = path.split(dockerfile_path)
        if dockerfile_node != 'Dockerfile':
            raise Exception('heroku requires a file called Dockerfile to deploy using Docker.')

    # validate container plugin
        from os import devnull
        from subprocess import check_output
        self.printer('Checking heroku plugin requirements ... ', flush=True)
        sys_command = 'heroku plugins --core'
        heroku_plugins = check_output(sys_command, shell=True, stderr=open(devnull, 'wb')).decode('utf-8')
        if heroku_plugins.find('heroku-container-registry') == -1 and heroku_plugins.find('container-registry') == -1:
            sys_command = 'heroku plugins'
            heroku_plugins = check_output(sys_command, shell=True, stderr=open(devnull, 'wb')).decode('utf-8')
            if heroku_plugins.find('heroku-container-registry') == -1 and heroku_plugins.find('container-registry') == -1:
                self.printer('ERROR')
                raise Exception(
                    'heroku container registry required. Upgrade heroku-cli.')
        self.printer('done.')

    # verify container login
        self.printer('Checking heroku container login ... ', flush=True)
        sys_command = 'heroku container:login'
        self._handle_command(sys_command)
        self.printer('done.')
    
    # Old Login Process (pre 2018.02.03)
        # import pexpect
        # try:
        #     child = pexpect.spawn('heroku container:login', timeout=5)
        #     child.expect('Email:\s?')
        #     child.sendline(self.email)
        #     i = child.expect([pexpect.EOF, pexpect.TIMEOUT])
        #     if i == 0:
        #         child.terminate()
        #     elif i == 1:
        #         child.terminate()
        #         raise Exception('Some unknown issue prevents Heroku from accepting credentials.\nTry first: heroku login')
        # except Exception as err:
        #     self._check_connectivity(err)
        # self.printer('done.')
        
    # verbosity
        self.printer('Building docker image ...')
    
    # build docker image
        sys_command = 'cd %s; heroku container:push web --app %s' % (dockerfile_root, self.subdomain)
        self._handle_command(sys_command, print_pipe=True)
        sys_command = 'cd %s; heroku container:release web --app %s' % (dockerfile_root, self.subdomain)
        self._handle_command(sys_command, print_pipe=True)
        self.printer('Deployment complete.')

        return True