Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Working with Docker containers with the dexec bash script (atomicobject.com)
106 points by ingve on June 27, 2023 | hide | past | favorite | 31 comments


    #!/bin/bash

    # Grab the container name and use fzf to let us pick it
    result=$(docker container ls --format "{{.Names}}" | fzf)

    # No command - try bash
    if [ $# -eq 0 ]
      then
        echo "docker exec -it $result /bin/bash"
        docker exec -it "$result" /bin/bash
    fi

    # Command was given so use that 
    if [ $# -eq 1 ]
      then
        echo "docker exec -it $result $1"
        docker exec -it "$result" "$1"
    fi
Requires fzf but other wise `ec, select container, it'll try bash or whatever shell/command you supplied.


Always use [[ and ]] where possible in conditions. You could also use set -x and avoid the echo


[[ and ]] are not portable. [ and ] are portable and specified in POSIX.

Like if you always use [[ and ]] you are going to be surprised when the default shell used for running unattended scripts in Debian, Ubuntu refuses to run your script.

  dash: 1: [[: not found
I know your parent commenter mentioned "#!/bin/bash" so your point is still valid. But I recommend that always use "#!/bin/sh" and always use [ and ] so that the scripts are portable.

I say this as a former package maintainer who has spent a great deal of time converting Bash scripts to POSIX sh scripts just so that I can package them as .deb.


IMHO this is also a good remark in context of those container images that most of all have /bin/sh. Technically not all, but many distro based containers.

so if someone plans to extend the script so that it injects it iself into the container or what not.


I'll take the bash dependency. The features are well worth it.


simpler: just this, after the result=..

docker exec -it "$result" "${1:-/bin/bash}"


Can you explain this last part?

This is why I usually stop myself from trying anything very complex with shell scripts: unlike scripting languages, half the power of shell is hiding inside little piles of punctuation marks that I don’t think I can even Google!


Use the argument ($1) if supplied otherwise default to /bin/bash.

It's why I avoid using stuff like that because I won't remember how it works in 6mths.


I think something that would make me consider using this, is auto-completion support. I've added it to a lot of my own commands and it is awesome. I think compared to this tool, raw docker commands using tab completion would still be faster for me.


Whenever you use docker it seems you'll want to write custom wrappers for it.

In particular what I've found useful:

  - automatically create a user with the same uid as yourself and run the command as that user. Pretty much required whenever you mount some directories for writing.
  - automatically login and pull if necessary




lazydocker is one of those fantastic utilities that I use daily


I usually end up with project specific "run" scripts which are just shell scripts so I can do things like `./run shell` to drop into the shell of a container, or `./run rails db:migrate` to run a command in a container.

Here's a few project specific examples. They all have similar run scripts:

    - https://github.com/nickjj/docker-flask-example
    - https://github.com/nickjj/docker-rails-example
    - https://github.com/nickjj/docker-django-example
    - https://github.com/nickjj/docker-node-example
    - https://github.com/nickjj/docker-phoenix-example


In don't see it, it helps you with the easy part that is the same across projects, but you still need to know the project specifics to use it.

I use "just" these days, per project, autocompletion with explanation what each command does.


just?


docker exec -it <tab tab> sh


Indeed, wrapping basic docker commands in a script feels like wrapping git commands in a script. You’re probably better off learning the commands for this ubiquitous tool.


Or learn the commands and then wrap them, best of both worlds, developer affordance is a useful characteristic as long as it doesn't reduce understanding.


In addition to OP, I use the following aliases:

    alias dps='docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"'
    alias dcup='docker compose up -d'
    alias dcupf='docker compose up -d && docker compose --follow logs'
    alias dcdown='docker compose down'
    alias docker-compose='docker compose'


I use this one all the time to list the containers I currently have running:

    docker_names() { docker ps | awk '{print $NF}'; }


DDEV has a similar feature called container commands which is very useful

[1] https://ddev.readthedocs.io/en/stable/users/extend/custom-co...

[2] https://ddev.com


Am I missing anything here? This is just a shell wrapper for running a couple of basic docker commands in sequence. It's not even zsh, so you can have some semi-decent argument parsing with zparseopts.

For similar docker automation I just use a Makefile with pattern rule (e.g. `docker-sh-%`). This is much more flexible than shell scripts because recipes can be easily remixed to provide higher-level functionality.


This is just a shell wrapper, yes. Like you, these shell wrappers don't appeal to me either. Like you, I just use a Makefile too. But HN is a large place with all kinds of people with their own preferences. It looks like simple shell wrappers do appeal to a large number of them. Not complaining about it. Just observing.


To save new people the trouble- this script just wraps this

  docker exec -it <container> <command>


That looks like using docker-compose ? My problem now that we switched to docker swarm is that docker compose commands are not available anymore. Need to use « docker service » or docker on the hosts and again deal with the complexity of some commands.


I saw your comment and am wondering what in particular you are struggling with.

I recently fixed one of my biggest pet peeves with docker swarm - the inability to directly exec into a service without first SSHing to the host the task is running on.

https://github.com/neuroforgede/docker-swarm-proxy

Maybe your issue is in this ballpark? Happy to exchange notes on this. If you are looking for a community of Swarm users, check out https://devops.fan (that's a discord hosted by Bret Fisher)


As a Docker novice this is fantastic. Every time I need to execute commands inside of a container I end of on Google.


When I'm learning a new toolset I have a habit of writing a cheat-sheet. The frequent command incantations, where params go, common "gotcha"/footgun.


I do this in all projects I work on too, there is always lots of arbitrary knowledge in long running projects.

I formalized it into a .notes folder inside every project and I have a command with useful note related tasks, that works out of the present directory .notes folder.

I have the same for project tasks, so common bash tasks go into a script inside .tasks and I have a command runner that works similar to npm run.


Curios, i don't know what is so complex with `docker exec -it CONTAINER_NAME COMMAND`

Sure, they better made -it the default, so we don't have to write it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: