dock is an alternative way to use Docker (and very soon other container engines) without writing config files: cd into any directory, type
dock and you're inside new or existing container with the directory mounted into it by default.
This toolset isn't forcing anyone else on the team to use itself or even Docker.
It is written in Bash entirely and has minimum requirements. While currently intended for Desktop use by developers, the hope is to eventually allow it to be easily used as part of a deployment process and production environments.
If you prefer cinematic experience, click on one of the videos below. They are not narrated, and are perfectly watchable and self-explanatory.
With dock you can easily:
- Create a container and mount any directory into it - or multiple
directories - with just single command:
It rarely requires any additional arguments on a day-to-day usage (that's from 1,5 years of the experience of using it myself).
- Automatically connect to the container via ssh (or other means later). If you just created the container, it will also do this step automatically.
- Have beautifully set up environment with zsh shell and Vim waiting for you inside the default image based on Ubuntu 20.04. You can, of course, customize it and install any shell, text editor and other software. See the INSTALLATION section to download the image.
Create images with environments specifically designed for your projects, which is what
containers are for. At the same time may you forget about Dockerfiles - not needed anymore.
dock was created with
the idea that Dockerfiles shall not be used.
INCREMENTAL IMAGE UPDATES section in .documentation/IMAGES.txt explains the reasoning and expands on that topic.
Others wouldn't even need to know you're using this tool, let alone familiarize themselves with Docker or dock. It is designed to be "exceptionally optional" and "personally useful".
There are also a few more non-default images you might find useful in your daily sessions as a developer, such as the ones that provide VPN and TOR functionality.
Please also kindly read CONTRIBUTE, ABOUT, DONATE, and LICENCE pages for more information. I believe that this software may be useful to people who aren't software engineers, but who know their way around command line - a least a little bit and so it'd would be great if we could continue this work.
GOALS (or why?)
NO Dockerfiles or learning new DSL, or programming language, or some other convoluted configuration options. Or even NO understanding how Docker itself works. This tool is eventually intended to be used with different containerization tools.
ease of use of dock itself (less cli-options or configuration).
make code reasonably uncomplicated, while acknowledging the ambiguity - which is necessary to achieve GOAL (2) - managing it with as little complexity in code as possible.
Make it last. Even if not a single line of code is added after the official release, it will be useful for years to come. It's all POSIX-compliant and written in Bash, so not much can break. The only serious dependency is Docker, but even that one can be disregarded when GOAL 5 is achieved.
make this tool work with different container engines in such a way, that the cli stays the same for the end user. Support for engines likely to be added first: BSD jails & Podman.
Right now Docker-specific code is not very well isolated and rather scattered among various files, but there isn't too many calls to various docker commands, so, hopefully, it'll be easy to identify and separate them.
Tilix terminal (try, it's very cool). If you're using Tilix, containers will be properly highlighted when you connect to them. Other terminal have different escape codes for that and I haven't adjusted for them all just yet. See https://gnunn1.github.io/tilix-web/
if you don't have it, it's no problem, but nice icons inside the container PROMPT when you connect will be replaced with less nice icons, that's all. But remember, "font-awesome" needs to be installed on your host machine, not inside the container.
STEPS TO INSTALL
GET THE dock UTILITIES SET
Download the archive with the stable version of the dock utilities set, which includes all submodules, but no git-related files or other unnecessary artifacts:
curl https://dock.orion3.space/releases/dock_stable.tgz \ -o dock_stable.tgz && tar xvzf dock_stable.tgz && rm dock_stable.tgzOR
Clone the git repository, and place it anywhere on your file system, then initialize and update all git submodules in it:
git clone -b stable \ https://github.com/0rion3/dock.git && cd dock && \ git submodule init && git submodule update
RUN THE INSTALLER SCRIPT
Navigate to the directory with project's source code you've just obtained and run this command:
It'll ask you a few questions, but they're simple. You won't need to edit any configuration files manually. The script will download the default image for either directly from the official Docker Hub or website, but it also will offer you to use a magnet link first too  (you can, of course, say no).
Please consider downloading it via BitTorrent and seeding. You can then tell the script the downloaded image filename to use (it'll ask).
You may not be able to run this default image under MacOSX, although dock scripts themselves are fully compatible. The problem is that MacOSX is not running on an amd64 architecture, so the default image may not be able to boot. I don't use MacOSX, nor intend to, but I'd like this to work on any major OS. As far as I'm concerned, Docker has a tool called buildx to help convert images for various architectures. If you're on MacOSX and can help me do it, I'll happily publish the converted, dock-compatible base image of Ubuntu 20.04 that would run on MacOSX.
dockcommand from anywhere. Try it with the
dock -yflag (dry run), which will print all the variables and other debug information about creating or starting/connecting to a container with relation to your current directory
While everyone hates tar, because it's impossible to remember the correct cli-options to it (see XKCD) the download archive includes a utility called untar, which does the job for you. Ironically, it's trapped inside that very same archive it could've extracted.
But, on a more serious note, this tiny untar script is part of a set of libraries under ./vendor/bashjazz which I strongly recommend you explore. They are small to medium sized bash-scripts (some executable, some source-able, some both) helping you in everyday life (you can use zsh, or any other shell, of course - they just require bash installed).
dock [IMAGE_NAME] [CONTAINER_NAME]Here, with just one positional argument provided, dock will be doing some guessing:
dock [IMAGE_NAME] dock [CONTAINER_NAME]And, finally, without any positional arguments dock will be basing its guessing on default image you set in ~/.dockrc and your current directory:
dockBoth positional arguments are optional, however they're not exactly positional. If the second one isn't provided, dock tries its best to guess what's going on. The simplified version looks like this when only the first argument is supplied:
Assume $1 (first argument to dock) is the name of an existing CONTAINER. If it exists, launch it and connect via ssh.
If container cannot be found, assume it's an image name.
If NO image is found, use the default one defined in ~/.dockrc to create a new container.
Go trough the EXAMPLES section as it shows pretty much all possible ways in which dock can be in invoked to create or start a container.
For a detailed overview of the "guessing" process with all two, only one or none of the positional arguments provided in the DECISION TREE file it's actually quite intuitive in terms of usage and the elaborate explanation is intended for those who read and/or contribute code to this project.
Navigate to the target directory you want mounted inside your container - let us suppose it's called ~/dev/my/new/project - this is the directory that will be mounted as /home/docker/main inside the container by default. It's also the directory you'll automatically cd into when you connect to the container.
See your terminal displaying what it's about to do when calling
docker runand asking for the confirmation (y/n).
Type y and press ENTER, then see yourself connected to the newly created container via ssh (no additional configuration is necessary) as user docker.
EXPLORE INSIDE THE CONTAINER
Once you're connected you can:
pwdand you'll see you're inside /home/docker/main directory into which the current directory on your host machine is mounted in read+write mode.
If you have used the -H option when creating the container, ~/main will not be be created and nothing is mounted into it.
If you had used -u root option with dock when creating, starting or connecting to the container, you'll found yourself in the /root dir of the container. The root user doesn't have a ~/main directory - it's only the docker user's $HOME/main is where dock would mount current host directory.
exit- you guessed it, to exit the container.
If you're in the same directory, type
dock(WITHOUT arguments) to reconnect to the same running container or start and connect to the stopped one named project.new.my.
If you're in a different directory, type
dock project.new.myto connect.
container names DON'T HAVE to contain dots (.) - they only do because the names are auto-assigned from the target directory path upon creation of the container. But you could easily create a container with a simple name, mounting current directory inside of it:
dock dock/ubuntu20:stable newapp
You can then connect to it from anywhere by simply typing:
Current list of images can be be found here here.
You don't have to manually visit this link every time and download and import/load the images with Docker commands. Instead, dock already provides a simple way to do this. Try:
dock -c image list
It isn't optimal at all to pull images from Docker Hub, or download them. Instead, work is currently being done on an alternative way of achieving this: it will be possible to "patch" any Docker images with a series of Bash scripts applied consecutively, much like migrations to a database. This doesn't achieve 100% reproducible environment, but since we've already established Dock will be doing things slightly differently, just accept it.
What this does achieve is:
no issues with running docker images on various platforms. You'll be able to pull an image of, say, Ubuntu, that runs on your platform and just patch, such that it's dock-compatible, or, better, yet, has Python environment, or a Ruby environment etc.
Patches will be receiving updates, but it will be up to you whether to apply them.
Bash scripts cannot conceal anything. You can open it and read every command to be run inside your container.
This displays a list of stable images available for automatic download and approved by the dock maintainer(s). Each line represents a particular image with all its multiple aliases. The last alias on each line will be used to tag the image when it's downloaded:
dock -c image import nodejs hub
This command pulls a stable image from orion3 Docker Hub repo, then tags it as
dock/ubuntu20-nodejs16:stable, because at Docker Hub the image would normally
have a different name. At the time of writing the image on Docker Hub which
corresponds to nodejs alias is called
Instead of pulling it from Docker Hub, you ask for a magnet link and use a BitTorrent client to download the image:
dock -c image import nodejs magnet
In this case, when the download is completed and you have the .tgz archive of the image you can import it with this command:
dock -c image import dock_ubuntu20-nodejs16_300322_SQ.tgz file
That's assuming the file was downloaded into your $DOCK_PATH/tmp dir. If not, specify the full path:
dock -c image import ~/Downloads/dock_ubuntu20-nodejs16_300322_SQ.tgz file
WITH NO CONTAINERS THAT CAN BE MATCHED
docker ps -a | grep 'project1' cd ~/dev/pets/project1 dock
Example 2: one positional argument given, dock assumes it's an image name
docker ps -a | grep 'project1' cd ~/dev/pets/project1 dock dock/ruby3:stable
Example 3: both positional arguments are provided
docker ps -a | grep 'project1' cd ~/dev/pets/project1 dock dock/ruby3:stable project1
WITH EXISTING CONTAINERS, THAT MIGHT OR
MIGHT NOT MATCH
docker ps -a | grep 'project1' cd ~/dev/pets/project1 dock
Example 5: one positional argument given, dock assumes it's a container name
docker ps -a | grep 'project2' cd ~/dev/pets/project1 dock project2
Example 6: one positional argument given, dock assumes it's an image name
docker ps -a | grep 'project1' cd ~/dev/pets/project1 dock dock/python3.8:stable
Example 7: one positional argument given, dock assumes it's a container name
docker ps -a | grep 'project1' | grep ruby3 dock project1
Example 8: one positional argument given, no image or container found
docker ps -a | grep 'projectABC' | grep ruby4 dock projectABC dock ruby4
Example 9: both positional arguments are provided
docker ps -a | grep 'project1' | grep ruby3 dock dock/ruby3:stable project1
HOW THE MAGIC WORKS
What makes dock awesome is that you don't have to type container names or image names every time, if ever. The information to make the decision is supplied by other helper scripts and variables (you may have guessed that from the EXAMPLES section already). The implementation of this process - the decision making process - while slightly complex (because of positional parameters ambiguity) improves ease-of-use for the end user. As in any good program, there are some ugly parts hidden in corners, that, like corruption in general, help the wheels keep on rolling.
Presented here, is the simplified version of what dock does under the hood. If you'd like to get familiarized with the details - refer to the DECISION TREE page
POSSIBLE ACTIONS or OUTCOMES
There are only four outcomes of the decision making process made by the script and we'll just abbreviate them with simple words:
Connect via ssh to the picked container (or possible other ways later)
Start the picked container when it's stopped, then perform, then perform action CONNECT.
Create a new container based on an certain picked image name and assign it a name, then perform actions START and CONNECT.
Do not proceed and exit the program with code 1. This action will not invoke any other actions.
These are not function names, nor can you easily identify them in the code (yet - because, well, Bash!), but it's good to have some structure in mind when you think about the code.
As of right now, there is no option to instruct the dock script to
invoke the CREATE without invoking START. You can, however, choose not to
automatically connect to the started container if you provide the -S flag to
dock command. The -S flag means
"do not connect after start).
To summarize, these are the sets of actions that you may end up with depending on how and under which circumstances the dock script was invoked:
(CREATE, START, CONNECT) or (CREATE, START) or (START, CONNECT) or (CONNECT) or (ERROR)
And that's what the decision is all about: do we start a new container because we can't really find any matching existing container or did the user actually meant that they wanted to create a new one? As there's no database to keep track of that (I don't think there should be another layer of configuration/data for containers). Therefore, some amount of non-trivial code in Bash is necessary to implement the decision tree, which is presented below.
IMPLICIT CONTAINER NAMING
When dock creates a new container, this container's name often isn't
explicitly provided by the user typing the
command - it only happens in case (2.2) of the decision tree.
In all other cases current directory path is used to construct a name for
the new container.
Before container is created, you will be shown all the information related to it, including the image, container name, which directories are to be mounted inside the container etc. Yo will then be asked to confirm with (y/n). A new container is NEVER created unless you confirm by typing "y" end pressing Enter.
Whenever container name cannot be assumed from the cli-arguments provided by the user, the path is used and the following changes are applied:
$IGNORED_PREFIX_PATH is stripped from the current path if it's defined in
It's useful, because sometimes the path may be too long and you may not want your container name to be long (even though you can manually provide a name for it). Another reason is that if you keep all your work in ~/dev, there's no reason for all of your containers to have a ".dev" in their names. But you may think otherwise, so presume away and simply comment out the IGNORED_PREFIX_PATH line in
2.All slashes / are replaced with dots .
Then what's remained is reversed
INSIDE A CONTAINER
Please read IMAGES page to find out more about how dock-compatible images and containers work, what's required of them to remain compatible and many more.
One important piece of information that probably is too small and simple not to repeat here is the next section...
Since dock is all about avoiding Dockerfiles, it's hard to use the init.d or systemd to launch services. But there's another way to do it, which, if you think about it, can be standardized when dock adds support for other container engines.
Have your /etc/init.d/* script ready (it usually would be installed along with
the package) and simply add the
service start ... command to /root/dock_bin/startup_jobs
on the guest:
echo 'service nginx start' >> /root/dock_bin/startup_jobs
dock provides a number of options with regards to mounting/not-mounting directories, giving containers privileged access, and some other things:
ssh username to use when connecting to the container via ssh. Defaults to "docker", but sometimes might want "root". Although, in that case, it's easier to define an alias:
alias dock-r="dock -u root"
Mounts additional directories into the Docker container. Format is the same as in Docker - consult Docker manual
- -t [OPTIONS]Defines some ssh connection options. Currently there's just one, which is the theme for the terminal to be set.
ATTENTION: works ONLY in Tilix terminal for now, because that's what I use, and I have not tested it in other Terminals
- -pRun docker container with the --privileged flag. More info can be found here: https://www.redhat.com/sysadmin/privileged-flag-container-engines. It helps with setting up Wireguard in particular.
- -nCreate new container regardless of whether there's already a container with the provided name. This is only marginally useful.
- -MDO NOT mount whatever is specified in the $DEFAULT_MOUNT_OPTIONS. Current directory would still be mounted, so use -H to prevent mounting it.
- -HBy default, current directory from which the dock script is launched will be mounted to ~/main inside the container. This option prevents it, but keeps all the other default mount options.
- -SDon't automatically connect to the container via ssh after it's started. The DEFAULT IS TO CONNECT, so you'll immediately be inside the container in your terminal, unless this option is passed. This option is useful if you want to start your container, with, say, a database, but there isn't a point to connect to the container yourself, as you're not intending to do anything with it as a user.
- -dPrint debug information
- -yDry run: just show what would be the different variables involved in creating, starting and connecting to containers and the images that are either used to create containers or which existing containers are based off. At this point it will print the same info as when you use the "debug" flag -d, only without proceeding with the actions.
For your convenience, dock's installation script will ask you whether you want to add aliases for the most frequently used Docker commands. The aliases can be found in the ./local/docker_aliases.sh file and the installation script will add them (with your permission, of course) into your .bashrc or .zshrc or any shell rc file of your choice, if your shell supports the
The output is intentionally formatted to be concise and informative enough. Below is the list of aliases along with their short description.
dilists docker images
dclists docker containers, stopped or running
dock-rconnects you to the container as root - same as
dock -u root, and it accepts all the other cli-arguments that
dcs [CONTAINER_NAME]stops the container, but don't remove it. Marginally useful, for example when testing dock startup_jobs inside the container. (Interestingly enough, this is slower than stopping AND removing the container with
dcr- see below).
dcr [CONTAINER_NAME]shuts down and removes Docker container. Don't forget to commit changes to an image if you want to retain them.
dcom [CONTAINER NAME] [IMAGE_NAME]commits changes from container to image.
dri [FULL_IMAGE_NAME]removes docker image (CAREFUL!)
dc-sizelists Docker containers' size (will take time to calculate). Marginally useful when you feel you might have installed too much and container size needs to be checked.
These aliases will help you navigate things more easily, but dock itself DOES NOT rely on these aliases, so if they're not added, everything will still work.On this page
In depthOther pages
- GOALS (or why?)
- BASIC USAGE
- COMMON WORKFLOW
- MORE IMAGES
- HOW THE MAGIC WORKS
- IMPLICIT CONTAINER NAMING
- INSIDE A CONTAINER
- LAUNCHING SERVICES
- CLI OPTIONS
- USEFUL ALIASES
- -t [OPTIONS]