I several of my projects I am using docker and docker-compose.
It's great, but now many command I am using are very long, like
docker run --rm -it -v $(pwd):/app -u $(id -u):$(id -g) php:7.1 php vendor/bin/phpunit
I would like to use just something like
docker phpunit
providing details in docker-compose or some other configuration file.
Is there a way to define aliases of these commands on a per project basis?
I don't want to use global aliases since such commands can vary for every project.
You could simply add a bash script docker.sh to each one of your projects:
#!/usr/bin/env bash
docker run --rm -it -v $(pwd):/app -u $(id -u):$(id -g) php:7.1 php vendor/bin/phpunit
and run it with ./docker.sh. This is a easy way to customize it considering each particularity and have the command under your version control.
Related
To start a docker container with the current user I can call docker run with the --user parameter like
docker run --user $(id -u):$(id -g) myimage
However that leaves the user inside the container without a name which inhibits the execution of some programs. For example it is not possible to mount a directory via fuse as a user without a name.
So what is the preferred approach to specify the UID and the username for a docker run command?
The only workaround I have found so far is to bind-mount /etc/password into the container:
docker run -v /etc/passwd:/etc/passwd:ro --user $(id -u):$(id -g) myimage
but that looks rather ugly to me. Isn't there a better way to do this?
I have working docker image that i can run locally by command
docker run --rm -u $(id -u) -v${PWD}:${PWD} -w${PWD} protocbuilder:1.0 [other unimportant args]
And everything works fine. I want use makefile to automate things using that container, so i created make command:
test:
docker run --rm -u $(id -u) -v${PWD}:${PWD} -w${PWD} protocbuilder:1.0 [other unimportant args]
But when I call make test I'm getting following output:
docker run --rm -u -v/Users/mikolaj/GolandProjects/project:/Users/mikolaj/GolandProjects/project -w/Users/mikolaj/GolandProjects/project protocbuilder:1.0 [other unimportant args]
docker: Error response from daemon: unable to find user -v/Users/mikolaj/GolandProjects/project: no matching entries in passwd file.
make: *** [test] Error 125
I'm not very into makefile things, so I don't understand why makefile fails with that when in standard call of docker run in console everything works fine. It seems that there is a problem with mapping user into container using -u, -v and -w arguments. Should I do some additional steps in makefile to make this work correctly? Or maybe I need to change something in docker run command inside makefile?
Thanks in advance
$(...) is (GNU) make function syntax. If you need to include a literal $ in a shell command for something like command substitution, you need to escape it by doubling the $
test:
docker run --rm -u $$(id -u) ...
# ^^
You could also use the backtick syntax to avoid this escaping issue
test:
docker run --rm -u `id -u` ...
Similarly ${PWD} gets expanded by make before the command gets run in the shell, but this probably isn't a significant difference.
Running a docker image with a command line such as:
> docker run -it -v $OutsideDir:$InsideDir -u $(id -u):$(id -g) c0ffeebaba bash
I am able to work on my data as the current user on the host from inside the docker container. However, asking inside the container 'whoami' gives the response that the UID is unknown.
So the shell is executed on a user without a home-directory. How
can I get some initialization being done for that user? Is there a way to map the user id and group id of an external user to a specific user name from inside? Can this be done dynamically, so that it would work for any user, specified through the '--user' flag as shown above?
My first approach would have been to use 'CMD' in the Dockerfile such as
CMD ["source", "/home/the_user/.bashrc" ]
But, that does not work.
A relatively simple solution would be to wrap the docker run in a script, mapping in the /etc/passwd and /etc/group files from the host onto the container, as well as the user's home directory, so something like:
#!/bin/bash -p
# command starts with mapping passwd and group files
cmd=(docker run -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro)
# add home directory:
myhome=$(getent passwd $(id -nu) | awk -F: '{print $6}')
cmd+=(-v $myhome:$myhome)
# add userid and groupid mappings:
cmd+=(-u $(id -u):$(id -g))
# then pass through any other arguments:
cmd+=("$#")
"${cmd[#]}"
This can be run as:
./runit.sh -it --rm alpine id
or, for a shell (alpine doesn't have bash by default):
./runit.sh -it --rm centos bash --login
You can throw in a -w $HOME to get it to start in the user's home directory, etc.
I'm on Docker 17.06.0-ce and I'm attempting to mount a CIFS share in a container and only having some luck. If I use --privileged, it works, but that's not desirable for me. I've tried using --cap-add as well as suggested in this answer (even trying with --cap-add ALL with no success.
The same mount command works fine on the host system as well.
Here's a simple docker file I've tried playing with
FROM alpine:latest
RUN apk add --no-cache cifs-utils
Run with many different permutations, all with the same result below:
Works:
docker run --rm -it --privileged cifs-test /bin/sh
Doesn't Work:
docker run --rm -it --cap-add SYS_ADMIN --cap-add DAC_READ_SEARCH cifs-test /bin/sh
Doesn't Work:
docker run --rm -it --cap-add SYS_ADMIN --cap-add DAC_READ_SEARCH --cap-add NET_ADMIN cifs-test /bin/sh
Doesn't Work:
docker run --rm -it --cap-add ALL cifs-test /bin/sh
And the command:
mkdir /test && mount.cifs //myserver/testpath /test -o user=auser,password=somepass,domain=mydomain
And the result from each run command above except the first:
mount error(13): Permission denied
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
Has something changed in Docker that requires --privileged all the time for these types of mounts now? Or is there something else I'm missing?
I started using docker-volume-netshare so far with good success. There are some minor problems, like volumes created with docker volume create not being persistent, but nevertheless it looks like this volume driver is quite usable. One advantage is that special caps/privileged mode are not necessary. Here are some hints on how to use it.
Install (Ubuntu/Debian)
$ curl -L -o /tmp/docker-volume-netshare_0.34_amd64.deb https://github.com/ContainX/docker-volume-netshare/releases/download/v0.34/docker-volume-netshare_0.34_amd64.deb
$ sudo dpkg -i /tmp/docker-volume-netshare_0.34_amd64.deb
$ rm /tmp/docker-volume-netshare_0.34_amd64.deb
Configure
$ sudo vi /etc/default/docker-volume-netshare
enter as single setting
DKV_NETSHARE_OPTS="cifs --netrc=/root/"
then
$ sudo vi /root/.netrc
enter the following settings per host:
machine <host>
username <user>
password <password>
domain <domain>
Note that <host> must be a host name or an IP address followed by a colon (e.g. 10.20.30.4:)
Enable the volume driver as a systemd service
Note: if your OS does not support systemd, another method to install it as a service is necessary.
$ sudo systemctl enable docker-volume-netshare
Use a volume in docker run and docker service create
$ sudo docker run -it --rm --mount type=volume,volume-driver=cifs,source=<myvol>,destination=<absolute-path-in-container>,volume-opt=share=<ip>:/<share> ubuntu:zesty bash
$ sudo docker service create --name <name> --mount type=volume,volume-driver=cifs,source=<myvol>,destination=<absolute-path-in-container>,volume-opt=share=<host>/<share> <image>
Obviously it is not necessary to use the identical volume in multiple containers, because the volumes only map to a cifs share which in turn is shared among containers mounting it. As mentioned above, don't use docker volume create with this volume driver, as volumes are lost as soon as docker-volume-netshare is stopped and/or restarted (and hence on reboot).
Get help
$ docker-volume-netshare --help
$ docker-volume-netshare cifs --help
Logs
Hint: for debugging use DKV_NETSHARE_OPTS="cifs --netrc=/root/ --verbose" in /etc/default/docker-volume-netshare or stop the service and start docker-volume-netshare cifs --netrc=/root/ --verbose in a shell)
$ dmesg | tail
$ tail -50 /var/log/docker-volume-netshare.log
Resources
github
project
I'm new to docker. When I run a docker images like ubuntu image by using the command,
sudo docker run -i -t ubuntu:14.04
By default, it is entering into the container as root like this.
I searched regarding this, but I couldn't get any of how to start a docker image as a non root user as I'm completely a starter for this topic.
It would be great if someone explains with an example of how to run a docker image as a non root user.
the docker run command has the -u parameter to allow you to specify a different user. In your case, and assuming you have a user named foo in your docker image, you could run:
sudo docker run -i -t -u foo ubuntu:14.04 /bin/bash
NOTE: The -u parameter is the equivalent of the USER instruction for Dockerfile.
This is admittedly hacky, but good for those quick little containers you start just to test something quickly:
#!/bin/bash
set -eu
NAME=$1
IMG=$2
#UID=$(id -u)
USER=$(id -un)
GID=$(id -g)
GROUP=$(id -gn)
docker run -d -v /tmp:/tmp -v "/home/$USER:/home/$USER" -h "$NAME" --name "$NAME" "$IMG" /bin/bash
docker exec "$NAME" /bin/bash -c "groupadd -g $GID $GROUP && useradd -M -s /bin/bash -g $GID -u $UID $USER"
Full version of the script I use here:
https://github.com/ericcurtin/staging/blob/master/d-run
udocker is a basic variant of docker which runs in user space:
udocker is a basic user tool to execute simple docker containers in user space without requiring root privileges. Enables download and execution of docker containers by non-privileged users in Linux systems where docker is not available. It can be used to pull and execute docker containers in Linux batch systems and interactive clusters that are managed by other entities such as grid infrastructures or externally managed batch or interactive systems.
It is not advisable to allow running docker without sudo as Docker has no auditing or logging built in, while sudo does.
If you want to give docker access to non-root users Red Hat recommends setting up sudo.
Add an entry like the following to /etc/sudoers.
dwalsh ALL=(ALL) NOPASSWD: /usr/bin/docker
Now, set up an alias in ~/.bashrc for running the docker command:
alias docker="sudo /usr/bin/docker"
Now when the user executes the docker command as non-root it will be allowed and get proper logging.
docker run -ti --privileged -v /:/host fedora chroot /host
Look at the journal or /var/log/messages.
journalctl -b | grep docker.*privileged
Aug 04 09:02:56 dhcp-10-19-62-196.boston.devel.redhat.com sudo[23422]: dwalsh : TTY=pts/3 ; PWD=/home/dwalsh/docker/src/github.com/docker/docker ; USER=root ; COMMAND=/usr/bin/docker run -ti --privileged -v /:/host fedora chroot /host