Move File From Docker to Host

How can I accomplish this? I wrote a python script that fires when my front gate opens. The script will send a notification to a Google Hangout Chat webhook. I have the ability in that webhook to send in a URL of an image that will then be presented in the message. I’m using the uvc cameras and figured out that I can call the IP of a camera on my network with /snap.jpg and it will get the still image from the camera. I want to attach this image to the message, but I am restricted to only attaching public images. I figured I’d get the image, save it with a UUID name, and place it on my host system, which also runs a webserver.

But I can’t figure out how I’m supposed to get a file from the docker image to the host. I found this post:

The last note:

EDIT: You have to renew this procedure everytime you update HA, since a new docker container is created for the new version HA.

makes it pretty unattractive though. Any good ideas?

It’s docker. Bind mount a directory on the host.

Where do I set those preferences? I figured I could do something like this, but when I boot up my pi, docker starts with the docker.service, but I don’t see where it’s getting the runtime parameters from (things like how does /config resolve to something on my host). Thanks!

Are you running HassOS? Hassio on Linux? Straight ha docker?

Hassio on Linux

On the host the file path for your config is /usr/share/hassio/homeassistant

Save your images in a directory in your config directory. It’s already on the host then.

Otherwise you’ll need to modify the scripts that your systemd service starts with another bind mount.

1 Like

Well, that would be easy, but my webserver doesn’t look at that path. I want to save them on my host to something like /var/www/images/. I guess I could make another path in my config directory and setup apache to read that directory, but I much prefer to keep anything that’s going to be exposed to the outside on my webserver to a set root.

I see people post comments on here about “when execute docker run, add these parameters, etc etc.” Hassio is my first docker experience, so I’m a little unsure how I would change something like this. Thanks!

You don’t really use docker run commands when you’re running hassio. The supervisor service handles all of that along with the systemd services.

Why not symlink a directory in /var/www/ to a directory in the configuration

I’ll try a symlink. I had in my head that those didn’t work with docker, but that may have been specific to the ssl cert files I was dealing with at the time.

??

I wasn’t suggesting you symlink that way. Files stored in config directory and symlinked to your Apache server

The answer is here https://docs.docker.com/engine/reference/commandline/cp/

Is your python script working under Hassio/HA or is it a direct linux python script?
If it is a hassio python script; then you have 2 options:

  1. Bind mount a folder to hassio docker container; either with the method i used in your 1st message, or deal with docker run commands.
  2. Find a way to send your camera snapshot to /usr/share/hassio/homeassistant/www folder. It could be either push or pull style. Whenever door entity is triggered, pull the image from camera directly or push the snapshot from camera or linux host to that folder with a python script, REST or whatever method you choose. This requires more work btw.

symlinks generally doesn’t work under docker container.

And let me clarify this again.

I was suggesting to create a symlink from the web server to the hassio config directory, where the file actually lives in the config directory and the web server uses the symlink to the files.

Thanks for the feedback from all!

@nickrout - docker cp is good to know and I wasn’t aware of that command, but in this instance I want to trigger something from the container. So I wouldn’t be able to execute a docker command within the container.

@febalci - When you say “deal with using docker run commands” - would that mean I wouldn’t be using hassio and I’d deploy the home assistant container myself?
My python script is working under hassio. I’m executing it from an automation by doing: service: shell_command.notify. My shell_command in the configuration is this:

notify: python3 /config/scripts/hangout_home_assistant_bot.py --msg "{{ message }}" --token "{{ token }}" --space "{{ space }}"

@flamingm0e - I’ve set up what you suggested (adding a folder in my /config path and mapping that on my webserver. This isn’t ideal in my mind, but it’s likely the best approach. I thought of building a webservice to call from the container to move the image, but that would have some lag I assume. The time from gate opening to text should be short, and I was worried this would slow it down. The symlink very well may have worked, but I figured if the file is actually living in the /config directory, I wanted to be able to define certain access rules within apache.

In case anyone comes across this out of curiosity, here is my python script (with some redaction). It’s not finished yet because I basically took over the script to test sending images and removed the ability to send a text, so I need to add that back. But it works to send an image, which was my goal in this post:

from httplib2 import Http
from json import dumps
import argparse
import urllib.request
import uuid 

parser = argparse.ArgumentParser(description='This scrtipt is used tp push messages to a Hangouts Chat room.  It is used by Home Assistant to send notifications.')
parser.add_argument("--msg", default="default message content", help="This is used to send the message text.  It's ignored when using as an image.")
parser.add_argument("--space", default="<redacted>", help="This is part of the bot URL that specifies which group to use.")
parser.add_argument("--token", default="<redacted>", help="This is part of the bot URL to provide some type of auth.")
args = parser.parse_args()

def main():
    file_name = str(uuid.uuid4()) + '.jpeg'
    img_url = 'https://<external webserver FQDN>/ha_www_images/' + file_name
    print(file_name)
    urllib.request.urlretrieve("http://<internal camera IP>/snap.jpeg", "/config/ha_www_images/" + file_name)

    url = 'https://chat.googleapis.com/v1/spaces/' + args.space + '/messages?key=<redacted>&token=' + args.token
    bot_message = {
        'cards' : [
        	{'sections':[
        		{'widgets':[
              {'image':
              	{'imageUrl': img_url
              	,'onClick':
                  {'openLink':
                    {'url': img_url
                    }
                  }
              	}
              }
            ]}
          ]}
        ]}
    message_headers = { 'Content-Type': 'application/json; charset=UTF-8'}
    http_obj = Http()

    response = http_obj.request(
        uri=url,
        method='POST',
        headers=message_headers,
        body=dumps(bot_message),
    )

    print(response)

if __name__ == '__main__':
    main()

Why not use the hangouts integration?

At some point Google will retire Hangouts - they’ve delayed this a number of times, so who knows when. This uses Hangouts Chat. The GSuite variant, which will not be retired.

Thanks, I wasn’t aware of the difference.