Docker: Difference between revisions
(→Usage) |
|||
Line 1: | Line 1: | ||
Official web page http://docker.io | Official web page http://docker.io. | ||
Docker is both a client and a server: the server is a daemon that runs on Linux. The normal approach was that you used docker on the same server the daemon was running on - however it was possible to connect the docker client to a remote docker daemon. | |||
= Installation = | = Installation = | ||
== Ubuntu == | == Which OS to install? == | ||
https://docs.docker.com/installation/ | * [https://containerjournal.com/2017/03/07/os-best-docker-heres-decide/ Which OS Is Best for Docker? Here’s How to Decide] | ||
* [https://blog.codeship.com/container-os-comparison/ Container OS Comparison] | |||
** CoreOS. See [http://www.makeuseof.com/tag/best-linux-server-operating-systems/ 12 Best Linux Server Operating Systems and Who Should Use Them] | |||
** [http://rancher.com/rancher-os/ RancherOS] | |||
** Snappy Ubuntu Core | |||
** RedHat Project Atomic | |||
** Mesosphere DCOS | |||
** [https://vmware.github.io/photon/ VMware Photon]. [https://www.linux.com/learn/intro-to-linux/2017/11/photon-could-be-your-new-favorite-container-os Photon Could Be Your New Favorite Container OS] | |||
== Containers vs virtual machines == | |||
* Differences: https://youtu.be/BFKNwr_wllc | |||
* Work together: https://youtu.be/BFKNwr_wllc | |||
=== KubeVirt === | |||
* [https://kubevirt.io/ KubeVirt] brings VMs into containerized workflows by converting the VMs into containers, where they run with the benefits of containerized applications. [https://opensource.com/article/20/12/containers-101 6 container concepts you need to understand] | |||
== OS containers vs application containers == | |||
* https://blog.risingstack.com/operating-system-containers-vs-application-containers/ | |||
* [https://thecustomizewindows.com/2017/07/openvz-versus-docker-linux-system-container-platforms/ OpenVZ Versus Docker And More On Linux System Container Platforms] | |||
* [http://www.liventerprise.com/compare/Docker_vs_OpenVZ/ Docker vs OpenVZ] | |||
Differences: | |||
* OS containers: LXC, [https://openvz.org/Main_Page OpenVZ], Linux VServer, BSD Jails and Solaris zones. The container acts as VPS. | |||
* App containers: Docker, Rocket. The container acts as an application. | |||
== Current release version == | |||
* https://docs.docker.com/release-notes/docker-ce/ (stable release) | |||
* https://github.com/docker/docker-ce/releases (stable & pre-release, could be newer than the above release-notes) | |||
== Ubuntu x86 and Mint == | |||
<ul> | |||
<li>https://docs.docker.com/install/linux/docker-ce/ubuntu/ | |||
{{Pre}} | |||
# Uninstall old versions | |||
$ sudo apt-get remove docker docker-engine docker.io | |||
# Install using the repository | |||
$ sudo apt-get update | |||
$ sudo apt-get install \ | |||
ca-certificates \ | |||
curl \ | |||
gnupg \ | |||
lsb-release | |||
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg | |||
$ echo \ | |||
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ | |||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null | |||
$ sudo apt-get update | |||
$ sudo apt-get install docker-ce docker-ce-cli containerd.io | |||
# Verify | |||
$ sudo docker run hello-world | |||
</pre> | |||
Install docker-compose https://docs.docker.com/compose/install/ | |||
<pre> | |||
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose | |||
$ sudo chmod +x /usr/local/bin/docker-compose | |||
$ docker-compose --version | |||
</pre> | |||
</li> | |||
<li>[https://www.howtoforge.com/tutorial/how-to-install-kubernetes-on-ubuntu/ How to Install and Configure Kubernetes and Docker on Ubuntu 18.04 LTS] </li> | |||
<li>[https://forums.linuxmint.com/viewtopic.php?t=414617 How install docker in Mint?] | |||
</ul> | |||
=== One-line script === | |||
https://github.com/docker/docker-install, https://docs.docker.com/engine/install/ubuntu/, https://twitter.com/portainerio/status/1650171336864550912 | |||
Note that 1) the one-liner is a huge security issue. 2) but how will you add the current user to docker group and then logout and log back in. 3) Linux Mint does not work. | |||
<syntaxhighlight lang='sh'> | |||
$ curl -fsSL https://get.docker.com | bash | |||
... | |||
Client: Docker Engine - Community | |||
Version: 24.0.7 | |||
API version: 1.43 | |||
Go version: go1.20.10 | |||
Git commit: afdd53b | |||
Built: Thu Oct 26 09:08:17 2023 | |||
OS/Arch: linux/amd64 | |||
Context: default | |||
Server: Docker Engine - Community | |||
Engine: | |||
Version: 24.0.7 | |||
API version: 1.43 (minimum version 1.12) | |||
Go version: go1.20.10 | |||
Git commit: 311b9ff | |||
Built: Thu Oct 26 09:08:17 2023 | |||
OS/Arch: linux/amd64 | |||
Experimental: false | |||
containerd: | |||
Version: 1.6.26 | |||
GitCommit: 3dd1e886e55dd695541fdcd67420c2888645a495 | |||
runc: | |||
Version: 1.1.10 | |||
GitCommit: v1.1.10-0-g18a0cb0 | |||
docker-init: | |||
Version: 0.19.0 | |||
GitCommit: de40ad0 | |||
--------------- | |||
To run Docker as a non-privileged user, consider setting up the | |||
Docker daemon in rootless mode for your user: | |||
dockerd-rootless-setuptool.sh install | |||
Visit https://docs.docker.com/go/rootless/ to learn about rootless mode. | |||
To run the Docker daemon as a fully privileged service, but granting non-root | |||
users access, refer to https://docs.docker.com/go/daemon-access/ | |||
WARNING: Access to the remote API on a privileged Docker daemon is equivalent | |||
to root access on the host. Refer to the 'Docker daemon attack surface' | |||
documentation for details: https://docs.docker.com/go/attack-surface/ | |||
-------------- | |||
$ # sudo groupadd docker | |||
$ sudo usermod -aG docker $USER; newgrp docker | |||
$ docker run hello-world | |||
</syntaxhighlight> | |||
The '''newgrp docker''' command in Linux is used to switch the current user’s group ID during a login session. Specifically, it changes the user’s '''primary group''' to the docker group without logging out and back in. This is particularly useful when you need to gain the permissions associated with the docker group to run Docker commands. | |||
<pre> | |||
$ id -gn | |||
docker | |||
</pre> | |||
=== Docker Desktop === | |||
* https://docs.docker.com/desktop/linux/install/ | |||
* [https://www.docker.com/blog/the-magic-of-docker-desktop-is-now-available-on-linux/ The Magic of Docker Desktop is Now Available on Linux] | |||
* [https://ostechnix.com/docker-desktop-for-linux/ A Beginners Manual To Docker Desktop For Linux] | |||
== Without sudo, Post-installation == | |||
* https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/ | |||
* [https://www.howtoforge.com/tutorial/docker-installation-and-usage-on-ubuntu-16.04/ Ubuntu 16.04] | |||
To use docker without ''sudo'', follow the instruction on [https://docs.docker.com/engine/installation/linux/linux-postinstall/#manage-docker-as-a-non-root-user the official guide]. | |||
<pre> | |||
# Add the docker group if it doesn't already exist. | |||
# sudo groupadd docker | |||
# Add your user to the docker group. | |||
sudo usermod -aG docker $USER | |||
# Log out and log in | |||
</pre> | |||
After running this command, you need to log out and log back in for the changes to take effect. This is because group membership is determined at login time. When you log in, the system reads the group membership information and assigns the appropriate permissions to your user account. | |||
== Upgrade Docker Desktop == | |||
It seems it does not affect running containers (e.g. RStudio on Mac). | |||
== Is it fine to upgrade Docker-ce while a container is running? == | |||
[https://www.reddit.com/r/docker/comments/q21spb/comment/hfi97s4/ Doesn't matter. Your system will stop the container if you update docker.] | |||
== Is there a way to hibernate a docker container == | |||
* https://stackoverflow.com/a/45170070 | |||
* Reference for [https://docs.docker.com/engine/reference/commandline/checkpoint/ docker checkpoint] (This command is experimental) | |||
== Live restore == | |||
* [https://stackoverflow.com/a/45352682 Can I save my running containers when upgrading from `docker` to `docker-ce`?] | |||
* [https://www.sobyte.net/post/2022-05/docker-live-restore/ Docker's Live Restore feature] Docker provides a feature that keeps containers running when Daemon is unavailable, thus reducing container downtime when Daemon is upgraded or has problems. That feature is called '''Live Restore'''. | |||
== Rate limits for GitHub Apps == | |||
[https://docs.github.com/en/developers/apps/rate-limits-for-github-apps Rate limits for GitHub Apps] | |||
When I tried several times of ''docker build'', I finally got a message | |||
{{Pre}} | |||
Downloading GitHub repo XXX/XXXXX@HEAD | |||
Error: Failed to install 'unknown package' from GitHub: | |||
HTTP error 403. | |||
API rate limit exceeded for XXX.XX.XXX.X. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.) | |||
Rate limit remaining: 0/60 | |||
Rate limit reset at: 2021-04-12 20:32:28 UTC | |||
To increase your GitHub API rate limit | |||
- Use `usethis::browse_github_pat()` to create a Personal Access Token. | |||
- Use `usethis::edit_r_environ()` and add the token as `GITHUB_PAT`. | |||
Execution halted | |||
</pre> | |||
== CentOS == | |||
<ul> | |||
<li>https://docs.docker.com/engine/installation/linux/docker-ce/centos/. Note that Centos 9 Stream is required. I have tried to follow [https://linux.how2shout.com/how-to-install-docker-ce-on-oracle-linux-8-7/ this] to install on Oracle 7/8 and it does not work now. A possible workaround is either [https://docs.docker.com/engine/install/centos/ download RPM packages manually] ([https://download.docker.com/linux/centos/7/x86_64/stable/Packages/ CentOS 7], [https://download.docker.com/linux/centos/8/x86_64/stable/Packages/ CentOS 8]) or [https://docs.docker.com/engine/install/binaries/ Install Docker Engine from binaries]. | |||
{{Pre}} | |||
sudo yum install -y yum-utils | |||
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo | |||
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin | |||
sudo systemctl start docker | |||
sudo systemctl enable docker.service | |||
sudo systemctl enable containerd.service | |||
sudo docker run hello-world | |||
sudo usermod -aG docker $USER | |||
newgrp docker | |||
</pre> | |||
<li>[https://stackoverflow.com/questions/36545206/how-to-install-specific-version-of-docker-on-centos How to install specific version of Docker on Centos?] | |||
<pre> | |||
sudo yum list docker-ce.x86_64 --showduplicates | sort -r | |||
</pre> | |||
</ul> | |||
== Boot2Docker == | |||
For Windows and OS operation systems, we have to use Boot2Docker. Boot2Docker is a local virtual machine with its own network interface and IP address. To find the Boot2Docker IP address you can check the value of the DOCKER_HOST environment variable. You're be prompted to set this variable when you start or install Boot2Docker the first time. You can find the IP address by running ''boot2docker ip'' command. | |||
Note that since Windows and OS X don't share a file system as Linux, the command 'docker run' with '-v' flag to mount a local directory into a Docker container will not work with Boot2Docker release prior to 1.3. The support for volumes is now available for OS X but is not yet present for Windows with the release of Boot2Docker 1.3. | |||
== Windows == | == Windows == | ||
* [https://docs.docker.com/installation/windows/#windows Windows]. It will install Boot2Docker management tool with | Note many of the information here have not been updated. | ||
* If the installer detects a version of VirtualBox installed, the VirtualBox checkbox will not be checked by default (Windows OS). The VirtualBox cannot be used anymore after updating my VB from 4.3.18 to 4.3.20. | |||
Docker can be run on Windows 10 Pro as a native application; see | |||
* https://docs.docker.com/engine/installation/windows/. | |||
* [https://tutorials.ubuntu.com/tutorial/tutorial-windows-ubuntu-hyperv-containers#0 Run Linux containers on Windows] & [https://linux.cn/article-8873-1.html?utm_source=rss&utm_medium=rss Chinese translation] | |||
The information below is based on running Docker on Windows 7.1 and 8. Your processor needs to support hardware virtualization. | |||
* [https://github.com/boot2docker/windows-installer Windows Installer] includes msys-git, Virtualbox, Boot2Docker-cli management tool and Boot2Docker ISO. | |||
* [https://docs.docker.com/installation/windows/#windows Installation instruction for Windows] OS. It will install Boot2Docker management tool with the boot2docker iso (based on [http://tinycorelinux.net/ Tiny Core Linux]), Virtualbox and MYSYS-git UNIX tools. | |||
* Docker needs Admin right to be installed. However, Virtualbox can be installed by user's account. | |||
* If the installer detects a version of VirtualBox installed, the VirtualBox checkbox will not be checked by default (Windows OS). The VirtualBox cannot be used anymore after updating my VB from 4.3.18 to 4.3.20. The error may be related to Windows update according to Virtualbox forum. | |||
<pre> | <pre> | ||
Error in supR3HardenedWinReSpawn | Error in supR3HardenedWinReSpawn | ||
</pre> | </pre> | ||
The error | * Note that <span style="color: red">boot2docker cannot be installed/run inside a Windows guest machine</span>. See [https://github.com/boot2docker/windows-installer/issues/14 this post] and my Virtualbox wiki [[Virtualbox#Install_on_a_Windows_machine|here]]. If we try to launch boot2docker-vm from Virtualbox, we will see a message "This kernel requires an x86-64 CPU, but only detected an i686 CPU." | ||
* After I switch back to an old version of virtualbox, every thing works again. I can even install Docker successfully. | |||
** Boot2Docker Start icon cannot be run directly because Notepad++ will automatically open it. A possible solution is to go to control panel and change default program for .sh file from Notepad++ to C:\Program Files (x86)\Git\bin\bash.exe. | |||
** The above step does not work well since a terminal appears and disappears quickly. | |||
** A working approach is to open Git Bash from Start menu. And run /c/Program Files/Boot2DockerforWindows/start.sh (or ''boot2docker start'' or ''boot2docer init'') | |||
** A new VM called 'boot2docker-vm' will be created (we can open VirtualBox Manager to check). But I got an error <span style="color: red">error in run: Failed to start machine "boot2docker-vm" (run again with -v for details)</span>. The VM has an error on Network>Adapter2>VirtualBox Host-Only Ethernet Adapter #2. So I open the setting of <boot2docker-vm>, go to Network > Adapter 2 and change the dropdown list of Name from ''VirtualBox Host-Only Ethernet Adapter #2'' to ''VirtualBox Host-Only Ethernet Adapter''. | |||
** Now it works either I directly click boot2docker-vm VM from VB Manager or use the command start.sh from Git Bash. | |||
[[File:Boot2docker-vm.png|200px]] | |||
<pre> | |||
$ # boot2docker is in the PATH variable, so there is not need to cd to the folder. | |||
$ boot2docker start | |||
initializing... | |||
Virtual machine boot2docker-vm already exists | |||
starting... | |||
Waiting for VM and Docker daemon to start... | |||
........o | |||
Started. | |||
Writing c:\Users\brb\.boot2docker\certs\boot2docker-vm\ca.pem | |||
Writing c:\Users\brb\.boot2docker\certs\boot2docker-vm\cert.pem | |||
Writing c:\Users\brb\.boot2docker\certs\boot2docker-vm\key.pem | |||
Docker client does not run on Windows for now. Please use | |||
"c:\Program files\Boot2Docker for Windows\boot2docker.exe" ssh | |||
to SSH into the VM instead. | |||
192.168.56.101 | |||
connecting... | |||
## . | |||
## ## ## == | |||
## ## ## ## === | |||
/""""""""""""""""\___/ === | |||
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~ | |||
\______ o __/ | |||
\ \ __/ | |||
\____\______/ | |||
_ _ ____ _ _ | |||
| |__ ___ ___ | |_|___ \ __| | ___ ___| | _____ _ __ | |||
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__| | |||
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__| < __/ | | |||
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_| | |||
Boot2Docker version 1.4.1, build master : 86f7ec8 - Tue Dec 16 23:11:29 UTC 2014 | |||
Docker version 1.4.1, build 5bc2ff8 | |||
docker@boot2docker:~$ docker | |||
Usage: docker [OPTIONS] COMMAND [arg...] | |||
A self-sufficient runtime for linux containers. | |||
The | Options: | ||
--api-enable-cors=false Enable CORS headers in the remote | |||
API | |||
-b, --bridge="" Attach containers to a pre-existi | |||
ng network bridge | |||
... | |||
Run 'docker COMMAND --help' for more information on a command. | |||
docker@boot2docker:~$ docker run hello-world | |||
Unable to find image 'hello-world:latest' locally | |||
hello-world:latest: The image you are pulling has been verified | |||
511136ea3c5a: Pull complete | |||
31cbccb51277: Pull complete | |||
e45a5af57b00: Pull complete | |||
Status: Downloaded newer image for hello-world:latest | |||
Hello from Docker. | |||
This message shows that your installation appears to be working correctly. | |||
To generate this message, Docker took the following steps: | |||
1. The Docker client contacted the Docker daemon. | |||
2. The Docker daemon pulled the "hello-world" image from the Docker Hub. | |||
(Assuming it was not already locally available.) | |||
3. The Docker daemon created a new container from that image which runs the | |||
executable that produces the output you are currently reading. | |||
4. The Docker daemon streamed that output to the Docker client, which sent it | |||
to your terminal. | |||
To try something more ambitious, you can run an Ubuntu container with: | |||
$ docker run -it ubuntu bash | |||
For more examples and ideas, visit: | |||
http://docs.docker.com/userguide/ | |||
docker@boot2docker:~$ ls | |||
boot2docker, please format-me | |||
docker@boot2docker:~$ pwd | |||
/home/docker | |||
docker@boot2docker:~$ ls / | |||
bin/ dev/ home/ lib/ mnt/ proc/ run/ sys/ usr/ | |||
c/ etc/ init linuxrc opt/ root/ sbin/ tmp var/ | |||
docker@boot2docker:~$ docker run hello-world | |||
Hello from Docker. | |||
This message shows that your installation appears to be working correctly. | |||
To generate this message, Docker took the following steps: | |||
1. The Docker client contacted the Docker daemon. | |||
2. The Docker daemon pulled the "hello-world" image from the Docker Hub. | |||
(Assuming it was not already locally available.) | |||
3. The Docker daemon created a new container from that image which runs the | |||
executable that produces the output you are currently reading. | |||
4. The Docker daemon streamed that output to the Docker client, which sent it | |||
to your terminal. | |||
To try something more ambitious, you can run an Ubuntu container with: | |||
$ docker run -it ubuntu bash | |||
For more examples and ideas, visit: | |||
http://docs.docker.com/userguide/ | |||
docker@boot2docker:~$ | |||
docker@boot2docker:~$ | |||
docker@boot2docker:~$ | |||
docker@boot2docker:~$ docker run -it ubuntu bash | |||
Unable to find image 'ubuntu:latest' locally | |||
ubuntu:latest: The image you are pulling has been verified | |||
53f858aaaf03: Pull complete | |||
837339b91538: Pull complete | |||
615c102e2290: Pull complete | |||
b39b81afc8ca: Pull complete | |||
511136ea3c5a: Already exists | |||
Status: Downloaded newer image for ubuntu:latest | |||
root@ea7e3289a01a:/# pwd | |||
/ | |||
root@ea7e3289a01a:/# df -h | |||
Filesystem Size Used Avail Use% Mounted on | |||
rootfs 19G 269M 17G 2% / | |||
none 19G 269M 17G 2% / | |||
tmpfs 1005M 0 1005M 0% /dev | |||
shm 64M 0 64M 0% /dev/shm | |||
/dev/sda1 19G 269M 17G 2% /etc/hosts | |||
tmpfs 1005M 0 1005M 0% /proc/kcore | |||
root@ea7e3289a01a:/# ls | |||
bin dev home lib64 mnt proc run srv tmp var | |||
boot etc lib media opt root sbin sys usr | |||
root@ea7e3289a01a:/# exit | |||
exit | |||
docker@boot2docker:~$ pwd | |||
/home/docker | |||
docker@boot2docker:~$ ls | |||
boot2docker, please format-me | |||
docker@boot2docker:~$ exit | |||
[Press any key to exit] | |||
brb@NCI-01825357 /c/Program files/Boot2Docker for Windows | |||
$ boot2docker down | |||
brb@NCI-01825357 /c/Program files/Boot2Docker for Windows | |||
$ | |||
$ boot2docker --help | |||
Usage: c:\Program files\Boot2Docker for Windows\boot2docker.exe [<options>] <command> [<args>] | |||
Boot2Docker management utility. | |||
Commands: | |||
init Create a new Boot2Docker VM. | |||
up|start|boot Start VM from any states. | |||
ssh [ssh-command] Login to VM via SSH. | |||
save|suspend Suspend VM and save state to disk. | |||
down|stop|halt Gracefully shutdown the VM. | |||
restart Gracefully reboot the VM. | |||
poweroff Forcefully power off the VM (may corrupt disk image). | |||
reset Forcefully power cycle the VM (may corrupt disk image). | |||
delete|destroy Delete Boot2Docker VM and its disk image. | |||
config|cfg Show selected profile file settings. | |||
info Display detailed information of VM. | |||
ip Display the IP address of the VM's Host-only network. | |||
shellinit Display the shell commands to set up the Docker client. | |||
status Display current state of VM. | |||
download Download Boot2Docker ISO image. | |||
upgrade Upgrade the Boot2Docker ISO image (restart if running). | |||
version Display version information. | |||
Options: | |||
--basevmdk="": Path to VMDK to use as base for persistent partition | |||
--clobber=false: overwrite Docker client binary on boot2docker upgrade | |||
--dhcp=true: enable VirtualBox host-only network DHCP. | |||
--dhcpip=192.168.59.99: VirtualBox host-only network DHCP server address. | |||
.... | |||
-v, --verbose=false: display verbose command invocations. | |||
--vm="boot2docker-vm": virtual machine name. | |||
--waittime=300: Time in milliseconds to wait between port knocking retries during 'start' | |||
error in run: config error: pflag: help requested | |||
brb@NCI-01825357 /c/Program files/Boot2Docker for Windows | |||
</pre> | |||
The big picture | |||
<pre> | |||
start.sh docker run -it ubuntu bash | |||
Git Bash Git Bash ----------> boot2docker-vm -------------> ubuntu | |||
docker@boot2docker: | |||
<------- <---------- <------------- | |||
boot2docker down exit exit | |||
(shutdown boot2docker) (boot2docker-vm is still on) | |||
| | |||
| | |||
| boot2docker up (start boot2docker) | |||
| | |||
| boot2docker ssh (log into docker acct) | |||
| | |||
v | |||
boot2docker-vm | |||
docker@boot2docker | |||
</pre> | |||
=== Increase boot2docker vmdk space === | |||
https://docs.docker.com/articles/b2d_volume_resize/ | |||
=== Install utilities in Boot2docker VM === | |||
http://blog.tutum.co/2014/11/05/how-to-use-docker-on-windows/ | |||
For example, to install cifs-utils, | |||
<pre> | |||
wget http://distro.ibiblio.org/tinycorelinux/5.x/x86/tcz/cifs-utils.tcz | |||
tce-load -i cifs-utils.tcz | |||
</pre> | |||
=== WSL2 === | |||
* [https://poweruser.blog/docker-on-windows-10-without-hyper-v-a529897ed1cc Docker on Windows without Hyper-V] | |||
* [https://docs.microsoft.com/en-us/windows/wsl/install-manual Manual installation steps for older versions of WSL]. I got this page when I installed Docker Desktop v4.9.0 (2022/6/14) on Windows 10. | |||
== Mac == | |||
<ul> | |||
<li>https://docs.docker.com/desktop/mac/ | |||
<li>Alternatives to Docker Desktop for Mac? Rancher is recommended. 2022-06-08 | |||
<li>Vagrant method. If you have Mac, you don't have to use boot2docker (iso & its management tool). You can use other Linux which comes with docker pre-installed. See [https://serversforhackers.com/getting-started-with-docker/ this post]. | |||
<li>To avoid the message ''Error: `brew cask` is no longer a `brew` command. Use `brew <command> --cask` instead'', use | |||
<pre> | |||
brew install --cask docker | |||
</pre> | |||
</ul> | |||
== Raspberry Pi == | |||
* [https://docs.balena.io/reference/hardware/devices/ Resin.io] (now called [https://www.balena.io/ balenaCloud]). They are supporting Docker on very low performance devices like Raspberry Pi 1 Zero or Beaglebone Black (512MB RAM, 1GHz ARM® Cortex-A8). | |||
* Another option is to use QEMU which allows Docker to create a container based on ARM. [https://ricardodeazambuja.com/rpi/2020/12/29/rpi2docker/ Creating a docker container from a Raspberry Pi Zero image... and the other way around] | |||
* [https://phoenixnap.com/kb/docker-on-raspberry-pi Docker on Raspberry Pi - Installation/uninstall Guide] | |||
* [https://raspberrytips.com/docker-on-raspberry-pi/ Getting Started With Docker On Raspberry Pi (Full Guide)] | |||
== ARM architeture from hub.docker.com == | |||
* [https://www.docker.com/blog/getting-started-with-docker-for-arm-on-linux/ Getting started with Docker for Arm on Linux] | |||
* Raspberry Pi | |||
** [https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi/ Docker Swarm on Raspberry Pi] | |||
** [https://linuxhint.com/install_docker_on_raspbian_os/ How to Install Docker on Raspbian OS] by Shahriar Shovon. | |||
** [https://blog.hypriot.com/getting-started-with-docker-on-your-arm-device/ Getting started with Docker on your Raspberry Pi] | |||
::<syntaxhighlight lang='bash'> | |||
curl -sSL https://get.docker.com | sh | |||
</syntaxhighlight> | |||
* UDOO Quad running Armbian 20.04 | |||
** The instruction on official Docker website does not work | |||
** The curl command method above does not work | |||
** '''sudo apt-get install -y docker.io''' works (''docker -v'' shows it is 19.03.8). After that, run '''sudo usermod -aG docker $USER''' and log out/in. | |||
* See Odroid magazine 2015 January and 2015 February. Note that the current versions of Docker and Docker Hub are not aware of the architecture for which the image has been built. All standard images are intended for the x86 architecture, and the autobuild feature offered by the Docker registry is only available for x86. | |||
* [https://blog.hypriot.com/post/nvidia-jetson-nano-intro/ NVIDIA Jetson Nano Developer Kit - Introduction], [http://collabnix.com/running-redis-inside-docker-container-on-jetson-nano/ Redis running inside Docker container on NVIDIA Jetson Nano] | |||
:<syntaxhighlight lang='bash'> | |||
sudo apt install curl | |||
curl -sSL https://get.docker.com/ | sh | |||
</syntaxhighlight> | |||
* [https://matchboxdorry.gitbooks.io/matchboxblog/content/blogs/build_and_run_arm_images.html How to Build and Run ARM Docker Images on x86 Hosts] | |||
=== docker-compose === | |||
<ul> | |||
<li>https://docs.docker.com/compose/install/. The binary version is only available for x86. So for raspi, see the Alternative Install Options where it suggests to use [https://docs.python-guide.org/dev/virtualenvs/ virtualenv]. See also [[Python#virtualenv|Python → virtualenv]].</li> | |||
<li>[https://withblue.ink/2020/06/24/docker-and-docker-compose-on-raspberry-pi-os.html Docker and Docker Compose on Raspberry Pi OS] | |||
<pre> | |||
sudo apt update | |||
sudo apt install -y python3-pip libffi-dev | |||
# Install Docker Compose from pip (using Python3) | |||
# This might take a while | |||
sudo pip3 install docker-compose | |||
</pre> | |||
</li> | |||
</ul> | |||
=== Some examples* === | |||
Not I use the arm64 image on my Pi3b+. | |||
[https://fleet.linuxserver.io/ Images] from https://www.linuxserver.io/. Some indices include number of pulls and stars. | |||
[https://en.wikipedia.org/wiki/List_of_tz_database_time_zones List of tz database time zones] | |||
'''[https://documentation.portainer.io/v2.0/deploy/linux/ Portainer]'''. The port number is 9000. Note '''the stack will be deployed using the equivalent of docker-compose. Only Compose file format version 2 is supported at the moment.''' | |||
'''[https://hub.docker.com/r/trnape/rpi-samba Samba]'''. Tested on iOS, Ubuntu & Windows 10. | |||
<pre> | |||
mkdir -p /mnt/usb/share/{data,backups} | |||
mkdir /mnt/usb/share/data/{alice,bob,documents} | |||
touch /mnt/usb/share/backups/backupsfile | |||
touch /mnt/usb/share/data/bob/bobfile | |||
touch /mnt/usb/share/data/documents/documentfile | |||
docker run -d -p 445:445 \ | |||
-v /mnt/usb/share/data:/share/data \ | |||
-v /mnt/usb/share/backups:/share/backups \ | |||
--name rpi-samba trnape/rpi-samba \ | |||
-u "alice:abc123" \ | |||
-u "bob:secret" \ | |||
-u "guest:guest" \ | |||
-s "Backup directory:/share/backups:rw:alice,bob" \ | |||
-s "Bob (private):/share/data/bob:rw:bob" \ | |||
-s "Documents (readonly):/share/data/documents:ro:guest,alice,bob" | |||
</pre> | |||
On '''Windows''', 1) right click on 'This PC' and choose 'Add a network location'. 2) type \\192.168.1.249\ and the dropdown list will populate all available folders. 3) choose the one (e.g. Bob) and then enter the credential. Done. On '''Ubuntu''', just type smb://192.168.1.249/. It will then populate the available folders. | |||
'''[https://www.digitalocean.com/community/tutorials/how-to-run-nginx-in-a-docker-container-on-ubuntu-14-04 Nginx]''' | |||
<pre> | |||
mkdir -p /mnt/usb/docker-nginx/html | |||
echo "hello world" >> /mnt/usb/docker-nginx/html/index.html | |||
nano /mnt/usb/docker-nginx/html/sharefile | |||
docker run --name rpi-nginx -p 8086:80 \ | |||
--restart always \ | |||
-v /mnt/usb/docker-nginx/html:/usr/share/nginx/html \ | |||
-d nginx:stable-alpine | |||
# Or a stack file | |||
version: '2' | |||
services: | |||
nginx: | |||
container_name: rpi-nginx | |||
ports: | |||
- '8086:80' | |||
restart: always | |||
volumes: | |||
- '/mnt/usb/docker-nginx/html:/usr/share/nginx/html' | |||
image: nginx:stable-alpine | |||
</pre> | |||
Note consider to use a samba share folder (see above) as a nginx document root. | |||
<pre> | |||
cp /mnt/usb/docker-nginx/html/* /mnt/usb/share/data/bob/ | |||
rm -rf /mnt/usb/docker-nginx/html | |||
ln -s /mnt/usb/share/data/bob/ /mnt/usb/docker-nginx/html | |||
</pre> | |||
'''[https://github.com/michaelmiklis/docker-rpi-monitor Rpi-monitor]'''. I need to change '''/dev/vcsm''' to '''/dev/vcsm-cma'''. But the temperature part is not working. I am using 64-bit Raspberry Pi OS and it does not show attached USB disks. The port number is 8888. | |||
'''[https://registry.hub.docker.com/r/linuxserver/code-server/ code-server]''' | |||
<pre> | |||
--- | |||
version: "2.1" | |||
services: | |||
code-server: | |||
image: ghcr.io/linuxserver/code-server | |||
container_name: code-server | |||
environment: | |||
- PUID=1000 | |||
- PGID=1000 | |||
- TZ=America/New_York | |||
- PASSWORD=password #optional | |||
- SUDO_PASSWORD=password #optional | |||
volumes: | |||
- /mnt/usb/code-server:/config | |||
ports: | |||
- 8443:8443 | |||
restart: unless-stopped | |||
</pre> | |||
'''[https://docs.linuxserver.io/images/docker-mstream mstream]''' Music streaming. Works great. | |||
'''[https://registry.hub.docker.com/r/emby/embyserver/#installation emby]''' does not work on arm64. It works on x86 though. Even I copy a mp4 file to movies directory the movie does not show up:( | |||
<pre> | |||
version: '2.1' | |||
services: | |||
embyserver: | |||
container_name: emby | |||
network_mode: bridge | |||
restart: always | |||
environment: | |||
- VERSION=latest | |||
- UID=1000 | |||
- GID=1000 | |||
- TZ=America/Denver | |||
volumes: | |||
- /media/crucial/emby/config:/config | |||
- /media/crucial/emby/tv:/mnt/tv | |||
- /media/crucial/emby/movies:/mnt/movies | |||
ports: | |||
- 8096:8096 | |||
image: 'emby/embyserver:latest' | |||
</pre> | |||
'''[https://github.com/linuxserver/docker-jellyfin jellyfin]''' Jellyfin is descended from Emby's 3.5.2 release and ported to the .NET Core framework to enable full cross-platform support. [https://youtu.be/c28kUNKJcqQ How to Install Jellyfin on Docker with Portainer] | |||
'''[https://github.com/greensheep/plex-server-docker-rpi plex]''' We can access the plex server via http://IP:32400/web. Note that in the first server setup, we need to add '''Library'''' by choosing the new library name (eg Other Videos) shown on plex & the data source (eg /data) so our own media can be found. After we added new media files we can rescan by clicking the vertical 3 dots icon and selecting scan library files. Pi3b+ is still a little weak since I can see all threads are busy when I played a mp4 file. | |||
{{Pre}} | |||
mkdir -p /mnt/usb/plex/{config,data} | |||
cp FILENAme.mp4 /mnt/usb/plex/data | |||
docker run \ | |||
-d \ | |||
--name plex \ | |||
--net host \ | |||
-p 32400:32400 \ | |||
--restart always \ | |||
--volume /mnt/usb/plex/config:/config \ | |||
--volume /mnt/usb/plex/data:/data \ | |||
greensheep/plex-server-docker-rpi:latest | |||
WARNING: The requested image's platform (linux/arm) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested | |||
</pre> | |||
'''[https://youtu.be/7EoEll0lVXc Nextcloud]'''. | |||
<pre> | |||
sudo mkdir -p /srv/dev-disk-by-label-Files/Databases/NextCloud | |||
sudo mkdir -p /srv/dev-disk-by-label-Files/Config/Nextcloud | |||
</pre> | |||
After that, copy and paste the [https://gist.github.com/dnburgess/fdcaf27280e031fe88dd2fb9728649f6 stack] into portainer. Wait for a few minutes on RPi3. The port number is 8080. Now we can create the admin username/password such as nextcloud/nextcloud. Click the little triangle next to "Storage and Database". Change to MySQL. In the next part we enter nextcloud/nextcloud/nextcloud/db (note the "db" replaces localhost b/c we use "db" as the service name). Again, wait for a few minutes. | |||
'''[https://youtu.be/I3fOq6zx1Zk?t=305 Heimdall]''' (Dashboard for web apps). I keep the PUID (1000) and PGID (1000). The instruction says it is from the '''admin''' user account but I don't find ''admin'' account? Change the volume to /srv/dev-disk-by-label-Files/Config/Heimdall (use '''sudo mkdir''' to create the directory on terminal). Change the port to 83 & remove port 443. Define the endpoint from Portainer -> Endpoints -> local -> Public IP as ''raspberrypi.local'' (depending on your hostname). We need to wait a little bit. Now go to the container and find heimdall and click the port in order to open the website correctly (instead 0.0.0.0). I can add apps like nextcloud, portainer, pi-hole, other servers, etc. The '''Application Type''' entry has a good list of popular apps and it will pre-populate the button icon and the background color for our app. | |||
'''[https://hub.docker.com/r/linuxserver/taisun taisun]''' The default port is 3000 | |||
'''[https://yacht.sh/Installation/yacht/ yacht]'''. The default login is '''[email protected]''' and '''pass'''. The name shown on portainer is '''pedantic_hermann''' | |||
{{Pre}} | |||
docker volume create yacht | |||
docker run -d -p 8001:8000 -v /var/run/docker.sock:/var/run/docker.sock -v yacht:/config selfhostedpro/yacht | |||
</pre> | |||
'''[https://youtu.be/Nf7m3h11y-s CloudFlare DDNS]''' - Update CloudFlare with Your Dynamic IP Address | |||
'''[https://youtu.be/nQMYfpCY310 WatchTower]''' | |||
'''[https://youtu.be/ji0kgXhXR6g bitwardenrs]'''. Use the terminal to create a volume first. The port number is 8100. This is straightforward. | |||
'''[https://youtu.be/-NyzdAYMarw Duplicati]''' for backup. | |||
'''[https://fleet.linuxserver.io/image?name=linuxserver/photoshow photoshow]'''. It works. It has a slideshow button. PhotoShow only displays videos in WebM. | |||
'''R'''. [https://hub.docker.com/_/r-base r-base] provide arm64 image but not not 32-bit arm architecture. | |||
<pre> | |||
# 64-bit OS | |||
docker pull r-base | |||
docker run -it --rm r-base # enter R directly | |||
</pre> | |||
'''rocker/rstudio''' DOES NOT work on arm64 even I can pull. ''WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested'' | |||
I build a 32-bit armv7 image for r-base v4.0.2. This image works on either 32-bit or 64-bit arm OS (tested on 32-/64-bit Raspberry Pi and other 32-bit SBC devices). | |||
<pre> | |||
docker pull arraytools/r402armv7 | |||
docker run -it --rm arraytools/r402armv7 R | |||
docker pull r-base | |||
# Using default tag: latest | |||
# latest: Pulling from library/r-base | |||
# no matching manifest for linux/arm/v7 in the manifest list entries | |||
</pre> | |||
== How and Why to Use A Remote Docker Host == | |||
* [https://www.cloudsavvyit.com/11185/how-and-why-to-use-a-remote-docker-host/ How and Why to Use A Remote Docker Host] | |||
* [https://www.cloudsavvyit.com/12514/how-docker-contexts-let-you-work-with-multiple-hosts/ How Docker Contexts Let You Work with Multiple Hosts] | |||
== Backup == | |||
* [https://docs.docker.com/storage/volumes/#backup-restore-or-migrate-data-volumes Backup, restore, or migrate data volumes] | |||
* [https://stackoverflow.com/a/28145912 Backup a running Docker container?] | |||
* [https://www.maketecheasier.com/copy-move-docker-container-to-another-host/ How to Copy/Move a Docker Container to Another Host] | |||
* [https://www.reddit.com/r/docker/comments/vi0o4k/comment/idbndut/?utm_source=share&utm_medium=web2x&context=3 Is backing up `/var/lib/docker/volumes` a good way to back up your Docker containers? If not, what is?] | |||
= Usage = | = Usage = | ||
== Basics | == Basics, docs, cheatsheet, introduction == | ||
https://docs.docker.com/articles/basics/ | * https://docs.docker.com/articles/basics/ | ||
* [https://www.fosstechnix.com/docker-command-cheat-sheet/ 81 Docker Command Cheat Sheet with Description] | |||
* https://coderwall.com/p/2es5jw/docker-cheat-sheet-with-examples | |||
* https://github.com/wsargent/docker-cheat-sheet | |||
* [https://www.howtoforge.com/tutorial/how-to-use-docker-introduction/ How to use Docker in a practical way] | |||
* https://hackernoon.com/introduction-to-docker-a7d9e1f6c0b3#.tezit0hkq | |||
* [http://www.cnblogs.com/wanliwang01/p/docker01.html Docker快速入门] | |||
* [http://blog.myplanet.com/docker-the-fun-and-easy-way Docker: The Fun and Easy Way] | |||
* [https://www.r-bloggers.com/2023/06/a-gentle-introduction-to-docker/ A Gentle Introduction to Docker]. docker build & renv. | |||
Note that we need '''sudo''' is needed unless it is on a Mac OS. | Note that we need '''sudo''' is needed unless it is on a Mac OS. | ||
If docker cannot find an image, it will try to pull it from its repository. | |||
<pre> | |||
$ sudo docker run -it ubuntu /bin/bash | |||
Unable to find image 'ubuntu' locally | |||
Pulling repository ubuntu | |||
04c5d3b7b065: Download complete | |||
511136ea3c5a: Download complete | |||
c7b7c6419568: Download complete | |||
70c8faa62a44: Download complete | |||
d735006ad9c1: Download complete | |||
root@ec83b3ac878d:/# | |||
</pre> | |||
{| class="wikitable" | |||
! purpose | |||
! command | |||
|- | |||
| run a container | |||
| docker container run -d -p 80:80 httpd | |||
|- | |||
| list running cotainer | |||
| docker container ls | |||
|- | |||
| view logs of Docker container | |||
| docker container logs cranky_cori | |||
|- | |||
| identify Docker container process? | |||
| docker container top cranky_cori | |||
|- | |||
| stop Docker container? | |||
| docker container stop cranky_cori | |||
|- | |||
| list stopped or not running Docker containers | |||
| docker container ls -a | |||
|- | |||
| start Docker container | |||
| docker container start c46f2e9e4690 | |||
|- | |||
| remove Docker container | |||
| docker container rm cranky_cori | |||
|- | |||
| list Docker images | |||
| docker images | |||
|- | |||
| remove Docker image | |||
| docker rmi iman/touch | |||
|} | |||
=== Restart docker daemon === | |||
When I try the Chap5 > Continuous integration (Jenkins) of the Docker Book, I found I cannot stop/kill the container. See others' report [https://github.com/docker/docker/issues/1906 here]. The solution is to restart the docker daemon. | |||
<pre> | |||
sudo service docker start | |||
</pre> | |||
After that, I can stop and rm the container. | |||
<pre> | |||
sudo docker stop jenkins | |||
sudo docker rm jenkins | |||
sudo docker ps -a | |||
</pre> | |||
=== images vs containers === | |||
<pre> | |||
$ sudo docker images | |||
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE | |||
iman latest 6e0f5644b2fd About a minute ago 460.4 MB | |||
iman/touch latest 77b9ac5951c2 4 minutes ago 460.4 MB | |||
<none> <none> aaa75e64ddf0 5 weeks ago 188.3 MB | |||
ouruser/sinatra v2 ea8c9f407a8d 5 weeks ago 447 MB | |||
ubuntu 14.04 ed5a78b7b42b 5 weeks ago 188.3 MB | |||
ubuntu latest ed5a78b7b42b 5 weeks ago 188.3 MB | |||
eddelbuettel/docker-ubuntu-r add-r-devel-san 3c19d078c5d9 3 months ago 460.4 MB | |||
hello-world latest ef872312fe1b 4 months ago 910 B | |||
training/sinatra latest f0f4ab557f95 8 months ago 447 MB | |||
$ sudo docker ps -a | |||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES | |||
8fbdbcdb5126 iman/touch:latest "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago thirsty_engelbart | |||
dc9e82f2c00a eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 9 minutes ago Exited (0) 3 minutes ago kickass_bardeen | |||
532a90f36aa8 eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 18 hours ago Exited (0) 18 hours ago happy_lalande | |||
7634024ee0bf eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 18 hours ago Exited (0) 18 hours ago insane_mclean | |||
14034a9720cb eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 18 hours ago Exited (0) 18 hours ago naughty_lumiere | |||
ca90954628db eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 19 hours ago Exited (130) 18 hours ago sick_hawking | |||
8bbdcb7c339f eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 19 hours ago Exited (0) 19 hours ago modest_davinci | |||
e8e24f80f0dd aaa75e64ddf0 "/bin/sh -c 'apt-get 5 weeks ago Exited (100) 5 weeks ago berserk_hodgkin | |||
d41959e0eb55 aaa75e64ddf0 "/bin/sh -c 'apt-get 5 weeks ago Exited (100) 5 weeks ago jovial_curie | |||
b408c0e2805b aaa75e64ddf0 "/bin/sh -c 'apt-get 5 weeks ago Exited (100) 5 weeks ago lonely_tesla | |||
72a551e4b492 ouruser/sinatra:v2 "/bin/bash" 5 weeks ago Exited (0) 5 weeks ago jolly_meitner | |||
75fd6cc4658b training/sinatra:latest "/bin/bash" 5 weeks ago Exited (0) 5 weeks ago evil_yalow | |||
cc8886f5a02e training/sinatra:latest "/bin/bash" 5 weeks ago Exited (130) 5 weeks ago elegant_curie | |||
0585e4f5fecd eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 5 weeks ago Exited (0) 5 weeks ago elated_euclid | |||
brb@brbweb4:~/Downloads$ | |||
</pre> | |||
When we want to delete a container, we use the container's '''CONTAINER ID''' or '''NAME''' (last column output from docker ps -a). But when we want to delete an image, we use the image's '''REPOSITORY''' or '''IMAGE ID''' (2nd column output from docker images) | |||
<pre> | |||
$ sudo docker rm thirsty_engelbart # iman/touch | |||
$ sudo docker rm dc9e82f2c00a # eddelbuettel/docker-ubuntu-r:add-r-devel-san | |||
$ sudo docker ps -a # check to see the container is gone now | |||
$ sudo docker rmi 6e0f5644b2fd | |||
$ sudo docker rmi iman/touch | |||
$ sudo docker images # check to see the images are gone now | |||
</pre> | |||
=== Command line interface, CLI === | |||
https://docs.docker.com/engine/reference/commandline/cli/ Docker command line | |||
<pre> | |||
$ docker | |||
Usage: docker COMMAND | |||
A self-sufficient runtime for containers | |||
Options: | |||
--config string Location of client config files (default "/home/brb/.docker") | |||
-D, --debug Enable debug mode | |||
-H, --host list Daemon socket(s) to connect to | |||
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") | |||
--tls Use TLS; implied by --tlsverify | |||
--tlscacert string Trust certs signed only by this CA (default "/home/brb/.docker/ca.pem") | |||
--tlscert string Path to TLS certificate file (default "/home/brb/.docker/cert.pem") | |||
--tlskey string Path to TLS key file (default "/home/brb/.docker/key.pem") | |||
--tlsverify Use TLS and verify the remote | |||
-v, --version Print version information and quit | |||
Management Commands: | |||
config Manage Docker configs | |||
container Manage containers | |||
image Manage images | |||
network Manage networks | |||
node Manage Swarm nodes | |||
plugin Manage plugins | |||
secret Manage Docker secrets | |||
service Manage services | |||
swarm Manage Swarm | |||
system Manage Docker | |||
trust Manage trust on Docker images | |||
volume Manage volumes | |||
Commands: | |||
attach Attach local standard input, output, and error streams to a running container | |||
build Build an image from a Dockerfile | |||
commit Create a new image from a container's changes | |||
cp Copy files/folders between a container and the local filesystem | |||
create Create a new container | |||
diff Inspect changes to files or directories on a container's filesystem | |||
events Get real time events from the server | |||
exec Run a command in a running container | |||
export Export a container's filesystem as a tar archive | |||
history Show the history of an image | |||
images List images | |||
import Import the contents from a tarball to create a filesystem image | |||
info Display system-wide information | |||
inspect Return low-level information on Docker objects | |||
kill Kill one or more running containers | |||
load Load an image from a tar archive or STDIN | |||
login Log in to a Docker registry | |||
logout Log out from a Docker registry | |||
logs Fetch the logs of a container | |||
pause Pause all processes within one or more containers | |||
port List port mappings or a specific mapping for the container | |||
ps List containers | |||
pull Pull an image or a repository from a registry | |||
push Push an image or a repository to a registry | |||
rename Rename a container | |||
restart Restart one or more containers | |||
rm Remove one or more containers | |||
rmi Remove one or more images | |||
run Run a command in a new container | |||
save Save one or more images to a tar archive (streamed to STDOUT by default) | |||
search Search the Docker Hub for images | |||
start Start one or more stopped containers | |||
stats Display a live stream of container(s) resource usage statistics | |||
stop Stop one or more running containers | |||
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE | |||
top Display the running processes of a container | |||
unpause Unpause all processes within one or more containers | |||
update Update configuration of one or more containers | |||
version Show the Docker version information | |||
wait Block until one or more containers stop, then print their exit codes | |||
Run 'docker COMMAND --help' for more information on a command. | |||
</pre> | |||
=== Version, system information === | |||
Docker version | |||
<syntaxhighlight lang='bash'> | |||
$ docker version | |||
Client: | |||
Version: 18.06.1-ce | |||
API version: 1.38 | |||
Go version: go1.10.3 | |||
Git commit: e68fc7a | |||
Built: Tue Aug 21 17:24:51 2018 | |||
OS/Arch: linux/amd64 | |||
Experimental: false | |||
Server: | |||
Engine: | |||
Version: 18.06.1-ce | |||
API version: 1.38 (minimum version 1.12) | |||
Go version: go1.10.3 | |||
Git commit: e68fc7a | |||
Built: Tue Aug 21 17:23:15 2018 | |||
OS/Arch: linux/amd64 | |||
Experimental: false | |||
</syntaxhighlight> | |||
System information. | |||
* what mode the Docker engine is operating in (swarm mode or not) | |||
* what storage drive is used for the union filesystem | |||
* what version of the Linux kernel we have on our host | |||
* et al | |||
<syntaxhighlight lang='bash'> | |||
$ docker system info | |||
Containers: 2 | |||
Running: 0 | |||
Paused: 0 | |||
Stopped: 2 | |||
Images: 10 | |||
Server Version: 18.06.1-ce | |||
Storage Driver: overlay2 | |||
Backing Filesystem: extfs | |||
Supports d_type: true | |||
Native Overlay Diff: true | |||
Logging Driver: json-file | |||
Cgroup Driver: cgroupfs | |||
Plugins: | |||
Volume: local | |||
Network: bridge host macvlan null overlay | |||
Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog | |||
Swarm: inactive | |||
Runtimes: runc | |||
Default Runtime: runc | |||
Init Binary: docker-init | |||
containerd version: 468a545b9edcd5932818eb9de8e72413e616e86e | |||
runc version: 69663f0bd4b60df09991c08812a60108003fa340 | |||
init version: fec3683 | |||
Security Options: | |||
apparmor | |||
seccomp | |||
Profile: default | |||
Kernel Version: 4.15.0-33-generic | |||
Operating System: Ubuntu 18.04.1 LTS | |||
OSType: linux | |||
Architecture: x86_64 | |||
CPUs: 4 | |||
Total Memory: 7.674GiB | |||
Name: t420s | |||
ID: VLWB:6BN3:U7KB:L4T4:GQIB:54F3:YZKJ:PAIR:HEUM:UQIC:XLZU:3IFJ | |||
Docker Root Dir: /var/lib/docker | |||
Debug Mode (client): false | |||
Debug Mode (server): false | |||
Registry: https://index.docker.io/v1/ | |||
Labels: | |||
Experimental: false | |||
Insecure Registries: | |||
127.0.0.0/8 | |||
Live Restore Enabled: false | |||
WARNING: No swap limit support | |||
</syntaxhighlight> | |||
=== List resource consumption === | |||
<syntaxhighlight lang='bash'> | |||
$ docker system df | |||
TYPE TOTAL ACTIVE SIZE RECLAIMABLE | |||
Images 10 2 2.58GB 1.519GB (58%) | |||
Containers 2 0 304B 304B (100%) | |||
Local Volumes 2 0 314.7MB 314.7MB (100%) | |||
Build Cache 0 0 0B 0B | |||
$ docker system df -v # more detailed information | |||
# We can use the information to clean up our system | |||
</syntaxhighlight> | |||
== [https://www.youtube.com/watch?v=umJYDAYxZys A brief intro to docker virtualization] == | == [https://www.youtube.com/watch?v=umJYDAYxZys A brief intro to docker virtualization] == | ||
Line 54: | Line 1,018: | ||
docker rm c85850ed0e13 # delete the container | docker rm c85850ed0e13 # delete the container | ||
</pre> | </pre> | ||
== Web Application/ | Note: Following the [http://askubuntu.com/questions/505506/docker-how-to-get-bash-ssh-inside-runned-container-run-d discussion], using '''attach''' can only launch one instance of shell. If we use '''exec''', we can launch multiple instances. | ||
https://docs.docker.com/ | <pre> | ||
sudo docker exec -i -t c85850ed0e13 bash #by ID | |||
or | |||
$ sudo docker exec -i -t loving_heisenberg bash #by Name | |||
</pre> | |||
== Rootless mode == | |||
<ul> | |||
<li>[https://docs.docker.com/engine/security/rootless/ Run the Docker daemon as a non-root user (Rootless mode)] | |||
* The data dir is set to '''~/.local/share/docker''' by default. The data dir should not be on NFS. | |||
<li>Setup on Ubuntu 22.04 | |||
<syntaxhighlight lang='sh'> | |||
curl -fsSL https://get.docker.com | bash | |||
sudo apt install -y uidmap | |||
dockerd-rootless-setuptool.sh install | |||
nano ~/.bashrc | |||
source ~/.bashrc | |||
systemctl --user start docker | |||
systemctl --user enable docker | |||
sudo loginctl enable-linger $(whoami) | |||
docker run hello-world | |||
docker run --rm -ti r-base:4.4.1 | |||
</syntaxhighlight> | |||
<li>Unfortunately, Rocker/rstudio does not work. I am not able to log in using username/password. It keeps saying incorrect username/password. | |||
<li>'''Limitations''': | |||
* Performance Overhead | |||
** OverlayFS Limitations: Rootless Docker uses fuse-overlayfs instead of OverlayFS by default, which can be slower. | |||
** Resource Limits: The performance might be slightly lower compared to running Docker with root privileges due to additional user namespace operations. | |||
* Network Restrictions | |||
** Network Drivers: Only the bridge and host network drivers are supported. macvlan and overlay network drivers are not supported. | |||
** Port Binding: Binding to ports below 1024 is not allowed. Only non-privileged ports (1024 and above) can be used. | |||
* File System | |||
** Volume Permissions: Issues with file permissions can arise when mounting volumes from the host, as the files created by rootless Docker processes will be owned by the user running Docker, not root. | |||
** NFS and Other Filesystems: Certain filesystems like NFS might have compatibility issues with rootless Docker due to permission and ownership constraints. | |||
* Compatibility | |||
** Certain Features: Some Docker features might not be fully supported or behave differently. For example, checkpoint/restore and cgroup v1 are not supported. | |||
** Security Features: Some security features like AppArmor, SELinux, and seccomp might have limited functionality or require additional configuration. | |||
* Configuration Complexity | |||
* Troubleshooting | |||
<li>[https://serverfault.com/a/1128797 What's the difference between rootless Docker, running a container as a non-root user, and Podman?] | |||
<li>[https://itnext.io/docker-running-in-rootless-mode-bdbcfc728b3a Docker Running In Rootless Mode] | |||
<li>[https://mohitgoyal.co/2021/04/14/going-rootless-with-docker-and-containers/ Going rootless with Docker and Containers] | |||
<li>[https://www.liquidweb.com/kb/how-to-docker-rootless-containers/ How to Run Rootless Docker Containers] | |||
</ul> | |||
== docker pull == | |||
https://docs.docker.com/engine/reference/commandline/pull/ | |||
<syntaxhighlight lang='bash'> | |||
$ docker pull ubuntu:zesty | |||
$ docker run -ti --rm ubuntu:zesty /bin/bash | |||
# lsb_release -a | |||
bash: lsb_release: command not found | |||
# cat /etc/*release | |||
DISTRIB_ID=Ubuntu | |||
DISTRIB_RELEASE=17.04 | |||
DISTRIB_CODENAME=zesty | |||
DISTRIB_DESCRIPTION="Ubuntu 17.04" | |||
NAME="Ubuntu" | |||
VERSION="17.04 (Zesty Zapus)" | |||
ID=ubuntu | |||
ID_LIKE=debian | |||
PRETTY_NAME="Ubuntu 17.04" | |||
VERSION_ID="17.04" | |||
HOME_URL="https://www.ubuntu.com/" | |||
SUPPORT_URL="https://help.ubuntu.com/" | |||
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" | |||
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | |||
VERSION_CODENAME=zesty | |||
UBUNTU_CODENAME=zesty | |||
</syntaxhighlight> | |||
=== Update/upgrade images === | |||
* I have an image called 'rocker/tidyverse:latest' that was pulled sometime ago. I ran ''docker pull rocker/tidyverse:latest' again. It will pull the latest image. The old image was not deleted and it has a new tag '''<none>'''. | |||
* [https://success.docker.com/article/how-to-remove-a-signed-image-with-a-none-tag How to remove a signed image with a <none> tag] | |||
* Same thing happened today. I run ''docker pull r-base'' to upgrade my r-base from v3.6.3 to v4.0.0. After the upgrade, the old image has a tag '''<none>'''. I can use '''docker rmi''' command to remove the <none> image. | |||
* [https://bytefreaks.net/applications/docker/how-to-update-all-pulled-docker-images-that-are-tagged-as-latest How to update all pulled Docker images that are tagged as latest] | |||
* [https://vsupalov.com/docker-latest-tag/ What's Wrong With The Docker :latest Tag?] '''Do not run any container with the latest tag.''' | |||
* [https://www.reddit.com/r/docker/comments/vjx9ct/how_to_upgrade_container_properly/ How to upgrade container properly?] "docker-compose pull" to update all your service and "docker-compose up -d" to start them all. docker swarm is even better because you can achieve zero downtme rolling upgrades. | |||
* The following two are equivalent | |||
:<syntaxhighlight lang='bash'> | |||
docker compose pull && docker compose up -d | |||
docker compose up --pull always -d | |||
</syntaxhighlight> | |||
=== <none>:<none> images === | |||
* [http://www.projectatomic.io/blog/2015/07/what-are-docker-none-none-images/ What are Docker <none>:<none> images? ] | |||
* [https://docs.docker.com/engine/reference/commandline/images/#filtering docker images] | |||
== Exit/detach from a container without stopping it == | |||
<syntaxhighlight lang='bash'> | |||
$ docker container run -it ubuntu:latest /bin/bash | |||
# Ctrl+p, Ctrl+q to exit the container without terminating it | |||
$ docker ps -a # showing the container 70c5aceb5512 is running in the background | |||
# You can reattach your terminal to it with the "docker container exec" command | |||
$ docker container exec -it 70c5aceb5512 bash | |||
</syntaxhighlight> | |||
== How to start a stopped Docker container with a different command == | |||
[https://stackoverflow.com/a/39329138 How to start a stopped Docker container with a different command?] | |||
== Clean shutdown DOCKER containers before reboot == | |||
* [https://forum.openmediavault.org/index.php?thread/22012-clean-shutdown-docker-containers-before-reboot-or-shutdown-omv/ Clean shutdown DOCKER containers before reboot or shutdown OMV] '''systemctl stop docker''' | |||
* [https://linuxhandbook.com/docker-stop-container/ How to Stop Docker Containers] '''docker ps -q | xargs docker stop''' | |||
== Dockerizing Applications/Detached mode == | |||
<pre> | |||
$ sudo docker run -d --name insane_babbage ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done" | |||
$ sudo docker ps -l | |||
$ sudo docker logs insane_babbage | |||
$ sudo docker stop insane_babbage | |||
$ sudo docker ps | |||
</pre> | |||
The -d flag tells Docker to run the container and put it in the background, to daemonize it. | |||
According to https://docs.docker.com/engine/reference/run/#detached-vs-foreground, | |||
'''containers started in detached mode exit when the root process used to run the container exits, unless you also specify the --rm option. If you use -d with --rm, the container is removed when it is stopped, exits or when the daemon exits, whichever happens first.''' | |||
=== Automatically restart after reboot === | |||
https://stackoverflow.com/questions/18786054/how-to-auto-restart-a-docker-container-after-a-reboot-in-coreos | |||
Add a '''--restart=always''' parameter. It will always restart a stopped container unless it has been explicitly stopped, such as via a "docker container stop" command. See the following | |||
* https://docs.docker.com/engine/reference/commandline/run/#restart-policies-restart | |||
* https://docs.docker.com/engine/admin/start-containers-automatically/#restart-policy-details | |||
<syntaxhighlight lang='bash'> | |||
$ docker run -d --restart always myCustomeDocker | |||
$ docker container run --name neverdie -it --restart always ubuntu /bin/bash | |||
# exit | |||
$ docker ps -a # the container is still ther | |||
$ docker stop neverdie | |||
$ docker ps -a | |||
</syntaxhighlight> | |||
== Working with Containers == | |||
<pre> | |||
$ sudo docker run -i -t ubuntu /bin/bash | |||
$ sudo docker version | |||
$ sudo docker | |||
$ sudo docker attach --help | |||
</pre> | |||
=== Environment variables === | |||
* [https://www.baeldung.com/ops/docker-container-environment-variables Passing Environment Variables to Docker Containers] | |||
* [https://docs.docker.com/compose/environment-variables/ Environment variables in Compose] | |||
* An example: [https://github.com/tcardonne/docker-github-runner Docker github runner] | |||
=== Docker container ID === | |||
* The full container ID is a hexadecimal string of 64 characters. | |||
* The minimum number of characters required for a Docker ID is 4. | |||
* We can use a shorter ID in docker command if that ID uniquely determined the container. For example, '''docker exec -it 9608 bash''' or even '''docker exec -it 9 bash''' works. | |||
=== Alpine image === | |||
* [https://www.makeuseof.com/alpine-linux-explained/ Alpine Linux: A Breath of Fresh Mountain Air for Linux Experts] | |||
* [https://docs.docker.com/samples/library/alpine/ A minimal Docker image based on Alpine Linux with a complete package index and only 5 MB in size!] | |||
* [http://containertutorials.com/alpine/get_started.html Container Tutorials > Getting Started with Alpine] | |||
* [https://nickjanetakis.com/blog/the-3-biggest-wins-when-using-alpine-as-a-base-docker-image The 3 Biggest Wins When Using Alpine as a Base Docker Image] | |||
* [https://www.cyberciti.biz/faq/10-alpine-linux-apk-command-examples/ 10 Alpine Linux apk Command Examples] | |||
: <syntaxhighlight lang='bash'> | |||
apk add htop | |||
</syntaxhighlight> | |||
=== Running a Web Application === | |||
<pre> | |||
$ sudo docker run -d -P training/webapp python app.py | |||
</pre> | |||
Alpine linux is 6MB. It is a good OS to run a web application. See the demo [https://youtu.be/BFKNwr_wllc here]. | |||
=== Viewing our Web Application Container === | |||
<pre> | |||
$ sudo docker ps -l | |||
$ sudo docker run -d -p 5000:5000 training/webapp python app.py | |||
</pre> | |||
=== Check container status (docker status) - CPU, Memory usage === | |||
<ul> | |||
<li>[https://www.cloudytuts.com/tutorials/docker/how-to-check-memory-and-cpu-utilization-of-docker-container/ How to Check Memory and CPU Utilization of Docker Container], [https://www.howtoforge.com/how-to-check-docker-container-ram-and-cpu-usage/ How to Check Docker Container RAM and CPU Usage] | |||
<pre> | |||
docker stats # ctrl + c to quit | |||
docker stats CONTAINER # multiple 'ctrl + c' to quit | |||
docker stats --no-stream | |||
docker stats --no-stream CONTAINER | |||
</pre> | |||
<li>[https://github.com/ColinFay/dockerstats docker stats] | |||
</ul> | |||
=== Container networking=== | |||
<ul> | |||
<li>https://docs.docker.com/network/ | |||
<li>[https://docs.docker.com/network/network-tutorial-standalone/#use-user-defined-bridge-networks Use user-defined bridge networks] | |||
<syntaxhighlight lang='bash'> | |||
$ docker network create MyNewNetworkName | |||
$ docker network ls | |||
NETWORK ID NAME DRIVER SCOPE | |||
abae0010bf2c MyNewNetworkName bridge local | |||
bf4e73473028 bridge bridge local | |||
7dac0804bc33 host host local | |||
dbe7f0daef6d none null local | |||
$ docker network remove MyNewNetworkName | |||
# OR docker network rm MyNewNetworkName | |||
</syntaxhighlight> | |||
<li>https://youtu.be/Ox5mZBwc92E | |||
<li>Use '''dig''' to find out the IP and run DNS query. [https://jvns.ca/blog/2021/01/04/docker-compose-is-nice/ Docker Compose: a nice way to set up a dev environment] | |||
<li>[https://dev.to/leandronsp/mastering-the-docker-networking-2h57 Mastering the Docker networking] | |||
</ul> | |||
=== [https://docs.docker.com/network/host/ Host network] === | |||
* If you use the '''host''' network driver for a container, that container’s network stack is not isolated from the Docker host. For instance, if you run a container which binds to port 80 and you use host networking, the container’s application will be available on port 80 on the host’s IP address. | |||
* One good example is if I want to use tailscale network from my host in Uptime Kuma container. See [https://wiki.taichimd.us/view/Docker_Applications#Uptime_Kuma HERE]. | |||
* Considerations. While host networking can be powerful, it's important to consider: | |||
** Security implications: Host networking reduces network isolation, potentially increasing security risks. | |||
** Port conflicts: Services using host networking may conflict with other applications running on the host machine. | |||
** Platform limitations: Host network mode only works on Linux hosts, not on Docker Desktop for Mac or Windows. | |||
=== ping, ifconfig and ip commands not found in Ubuntu container === | |||
<syntaxhighlight lang='bash'> | |||
apt update | |||
apt install iputils-ping # ping | |||
apt install net-tools # ifconfig | |||
apt install iproute2 # ip | |||
</syntaxhighlight> | |||
=== Network Port Shortcut === | |||
<pre> | |||
$ sudo docker port nostalgic_morse 5000 | |||
</pre> | |||
=== Access Ports on the Host from a Docker Container === | |||
[https://www.cloudsavvyit.com/6940/how-to-access-ports-on-the-host-from-a-docker-container/ How to Access Ports on the Host from a Docker Container] | |||
=== Multiple NICs === | |||
[https://www.reddit.com/r/docker/comments/vi2alw/containers_in_docker_to_use_public_ip_addresses/ containers in docker to use public ip addresses directly] | |||
=== Viewing the Web Application's Logs === | |||
<ul> | |||
<li>[https://linuxiac.com/dozzle-real-time-docker-logs-viewer/ Installing Dozzle: A Superb Real-Time Docker’s Logs Viewer], [https://github.com/amir20/dozzle Dozzle] docker image. | |||
<li>Command line | |||
<pre> | |||
$ sudo docker logs -f nostalgic_morse | |||
</pre> | |||
</ul> | |||
=== Clear Logs of Running Docker Containers === | |||
* [https://www.howtogeek.com/devops/how-to-clear-logs-of-running-docker-containers/ How to Clear Logs of Running Docker Containers] | |||
* [https://linuxiac.com/reducing-docker-logs-file-size/ Reducing Docker Logs Size: A Practical Guide to Log Management] | |||
=== Looking at our Web Application Container's processes === | |||
<pre> | |||
$ sudo docker top nostalgic_morse | |||
</pre> | |||
=== Inspecting our Web Application Container === | |||
<syntaxhighlight lang='bash'> | |||
$ sudo docker inspect nostalgic_morse | |||
</syntaxhighlight> | |||
=== Obtain the container's IP address, log into a running server === | |||
PS. '''Portainer''' web interface can show the IP addresses. | |||
<syntaxhighlight lang='bash'> | |||
$ docker inspect <container id> | grep "IPAddress" | |||
</syntaxhighlight> | |||
We don't need the IP address if we just want to log into a running server, | |||
<syntaxhighlight lang='bash'> | |||
$ docker exec -it <contianer id> bash | |||
</syntaxhighlight> | |||
=== How to Secure Docker’s TCP Socket === | |||
[https://www.cloudsavvyit.com/15079/how-to-secure-dockers-tcp-socket-with-tls/ How to Secure Docker’s TCP Socket with TLS] | |||
=== docker attach === | |||
Suppose I run ''docker run -it --user rstudio bioconductor/bioconductor_docker:devel R'' and I use ''q()'' to quit the container. The container is still there. To re-enter the R in the container, I use | |||
<pre> | |||
docker start XXXXXXXX # restart it in the background | |||
docker attach XXXXXXXX # reattach the terminal to a running container | |||
</pre> | |||
If we want the latest created container, then we use | |||
<pre> | |||
docker start `docker ps -q -l` && docker attach `docker ps -q -l` | |||
</pre> | |||
=== docker exec: SSH into a running container === | |||
Run a command in a running container | |||
<ul> | |||
<li>[https://docs.docker.com/engine/reference/commandline/exec/ Usage]: <syntaxhighlight lang='bash'> | |||
docker exec [OPTIONS] CONTAINER COMMAND [ARG...] | |||
</syntaxhighlight> | |||
<li>Examples: <syntaxhighlight lang='bash'> | |||
$ docker exec -d ubuntu_bash touch /tmp/execWorks # do st in the background | |||
$ docker exec -it ubuntu_bash bash | |||
$ docker exec -it -e VAR=1 ubuntu_bash bash # set an environment variable | |||
$ docker exec -it ubuntu_bash pwd | |||
$ docker exec -it -w /root ubuntu_bash pwd # change the working directory | |||
</syntaxhighlight> | |||
<li>[https://www.cloudsavvyit.com/14541/how-to-run-a-command-on-a-running-docker-container/ How to Run a Command on a Running Docker Container] | |||
<li>[https://thenewstack.io/how-to-use-the-docker-exec-command/ How to Use the Docker exec Command]. nginx container is used as an example. | |||
<pre> | |||
docker run --name docker-nginx -p 8080:80 -d nginx | |||
# method 1. Access the Running Container’s Shell | |||
docker exec -it ID /bin/bash | |||
apt-get update | |||
apt-get upgrade -y | |||
exit | |||
# method 2. Run a Command from Outside the Container | |||
docker exec ID apt-get update && apt-get upgrade | |||
docker exec ID cat /usr/share/nginx/html/index.html | |||
docker cp index.html ID:/usr/share/nginx/html/ | |||
docker exec ID cat /usr/share/nginx/html/index.html | |||
</pre> | |||
</ul> | |||
=== docker cp === | |||
* https://docs.docker.com/engine/reference/commandline/cp/ | |||
* https://linuxhandbook.com/docker-cp-example/ | |||
Copy files/folders between a container and the local filesystem. | |||
=== Restart an exited Container === | |||
* https://docs.docker.com/engine/reference/commandline/start/ | |||
* https://www.linuxnix.com/docker-start-exited-container/ | |||
<pre> | |||
$ docker start nostalgic_morse | |||
OR | |||
$ docker restart nostalgic_morse | |||
</pre> | |||
For an interactive container, use '''docker start -ai CONTAINER''' which is equal to run "docker start CONTAINER" and "docker attach CONTAINER". | |||
=== Rename a container === | |||
[https://docs.docker.com/engine/reference/commandline/container_rename/ docker container rename] | |||
<pre> | |||
docker container rename CONTAINER NEW_NAME | |||
</pre> | |||
=== Inspect container images and their metadata === | |||
* [https://www.cloudsavvyit.com/14663/how-to-inspect-a-docker-images-content-without-starting-a-container/ How to Inspect a Docker Image’s Content Without Starting a Container] | |||
* [https://microbadger.com/images/rocker/r-base MicroBadger] | |||
=== Know the container size === | |||
<syntaxhighlight lang='bash'> | |||
docker ps -s | |||
</syntaxhighlight> | |||
[https://github.com/docker/docker.github.io/issues/1520#issuecomment-305179362 Meaning of two sizes] | |||
* The "size" information shows the amount of data (on disk) that is used for the writable layer of each container | |||
* The "virtual size" is the amount of disk-space used for the read-only image data used by the container. | |||
=== Removing our Web Application Container === | |||
<syntaxhighlight lang='bash'> | |||
$ sudo docker stop nostalgic_morse | |||
$ sudo docker rm nostalgic_morse | |||
</syntaxhighlight> | |||
Note: Always remember that deleting a container is final! | |||
=== Dockerize an SSH service === | |||
https://docs.docker.com/engine/examples/running_ssh_service/#environment-variables | |||
=== Remove old docker containers === | |||
[http://stackoverflow.com/questions/17236796/how-to-remove-old-docker-io-containers This post] on stackoverflow.com. | |||
<pre> | |||
$ sudo docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs --no-run-if-empty sudo docker rm | |||
</pre> | |||
Similarly to remove all exited containers | |||
<pre> | |||
$ sudo docker ps -a | grep Exit | awk '{print $1}' | xargs sudo docker rm | |||
</pre> | |||
To kill/stop (not delete) all running containers | |||
<pre> | |||
$ sudo docker kill $(sudo docker ps -q) | |||
</pre> | |||
'''To delete all stopped containers''' | |||
<pre> | |||
$ sudo docker rm $(sudo docker ps -a -q) | |||
OR | |||
$ sudo docker rm `sudo docker ps -a -q` | |||
</pre> | |||
It is also helpful to create bash aliases for these commands by editing ~/.bash_aliases file. | |||
=== docker create vs docker run === | |||
https://stackoverflow.com/questions/37744961/docker-run-vs-create | |||
'''docker create''' is similar to '''docker run -d''' except the container is never started. | |||
=== Retrieve docker run command === | |||
https://stackoverflow.com/a/32774347. See the github page of [https://github.com/lavie/runlike runlike]. So it is better to put the docker run in a stack. Then for example the Portainer has an Editor tab to show the [https://docs.docker.com/compose/compose-file/ compose file]. | |||
<pre> | |||
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ | |||
assaflavie/runlike -p CONTAINER_NAME | |||
</pre> | |||
The '''-p''' option splits the output into pretty lines. | |||
=== docker run -it and -d together === | |||
* [https://stackoverflow.com/a/41918607 Practically, what is the difference between docker run -dit(-itd) vs docker run -d?] | |||
* [https://github.com/docker/docker.github.io/issues/10632 "docker run -dit" vs "docker run -d" #10632] | |||
=== How to Modify the Configuration of Running Docker Containers === | |||
[https://www.cloudsavvyit.com/15254/how-to-modify-the-configuration-of-running-docker-containers/ How to Modify the Configuration of Running Docker Containers] | |||
== Volume == | |||
* https://docs.docker.com/storage/volumes/ | |||
* [https://docs.docker.com/engine/reference/commandline/volume_create/ docker volume create] documentation | |||
* If we try to mount an empty dir on the host to a non-empty dir (eg mediawiki/extensions) in a container, it will mess up. | |||
* [https://www.melvinvivas.com/using-docker-data-volume-with-a-mysql-container/ Using Docker Data Volume with a MySQL container] | |||
* [https://www.cloudsavvyit.com/7500/what-are-docker-volumes-and-how-do-you-use-them/ What Are Docker Volumes, and How Do You Use Them?] | |||
=== Examples of host's volume locations === | |||
<pre> | |||
/home/$USER/docker/$PROJECT/$SUB-DIRECTORY | |||
</pre> | |||
=== PUID, PGID, share volume permission/owner === | |||
<ul> | |||
<li>[https://docs.linuxserver.io/general/understanding-puid-and-pgid Understanding PUID and PGID] (or the [https://github.com/linuxserver/docker-documentation/blob/master/general/understanding-puid-and-pgid.md source]) | |||
<li>You should use the -e PUID and -e PGID options when creating a container from a Docker image to map the container’s internal user to a user on the host machine. This is useful because Docker runs all of its containers under the '''root''' user domain, which means that processes running inside your containers also run as '''root'''. '''This kind of elevated access is not ideal for day-to-day use and can potentially give applications access to things they shouldn’t.''' By using PUID and PGID, you can ensure that files and directories created during the container’s lifespan are owned by a user on the host machine instead of root. | |||
<li>'''Please note that not all Docker images support the PUID and PGID environment variables. The Docker image must be designed to use these variables.''' If you’re using an image that doesn’t support these variables, you may need to create a Dockerfile to build a new image that does. | |||
<li>The following works. The '''--user''' option is a built-in Docker feature that sets the user (and optionally the group) that is used to run the container. This option works regardless of whether the Docker image uses any specific environment variables. PS. "docker" user has been defined in the r-base's [https://github.com/rocker-org/rocker/blob/master/r-base/4.4.0/Dockerfile Dockerfile]. | |||
<syntaxhighlight lang='sh'> | |||
docker run --rm -ti --user docker \ | |||
-v "$(pwd)":/workspace r-base | |||
> setwd("/workspace") | |||
> save(iris, file="iris.rda") | |||
> system("ls -lt") # docker docker instead of $USER $USER | |||
> unlink("iris.rda") | |||
</syntaxhighlight> | |||
<li>Similarly, the '''--user''' option works with rocker/rstudio image and ubuntu. | |||
<syntaxhighlight lang='sh'> | |||
docker run --rm -ti --user rstudio \ | |||
-v "$(pwd)":/workspace rocker/rstudio R | |||
> setwd("/workspace") | |||
> save(iris, file="iris.rda") | |||
> system("ls -lt") | |||
> unlink("iris.rda") | |||
</syntaxhighlight> | |||
Note that the prompt is '''$''' rather than '''#'''. | |||
{{Pre}} | |||
docker run --rm -it -v $(pwd):/home --user ubuntu \ | |||
ubuntu bash | |||
$ id | |||
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev) | |||
$ cd /home | |||
$ echo "newfile" > newfile | |||
</pre> | |||
<syntaxhighlight lang='sh'> | |||
docker run --rm -it -v $(pwd):/home --user "$(id -u):$(id -g)" \ | |||
ubuntu bash | |||
$ cd /home | |||
$ echo "newfile" > newfile | |||
</syntaxhighlight> | |||
<li>In the article [https://github.com/rocker-org/rocker/wiki/Sharing-files-with-host-machine Sharing files with host machine] from the Rocker's project, users are instructed to use '''-e USERID''' variable if the host machine user has a UID other than 1000. But the generated file 'iris.rda' from the following example is still owned by root:( | |||
<syntaxhighlight lang='sh'> | |||
docker run --rm -ti -v "$(pwd)":/workspace -e USERID=$UID rocker/rstudio R | |||
</syntaxhighlight> | |||
<li>(Cont.) however, if we run the above command as a daemon and '''log in using the user "rstudio" ''', it works even we don't specify the "-e USERID" option. The lesson is we should use the user defined in the docker image. | |||
<pre> | |||
docker run --rm -v "$(pwd)":/workspace -p PASSWORD=123 rocker/rstudio | |||
</pre> | |||
Notice the prompt is '''#''' rather than '''$''' and the user id is 0. | |||
<pre> | |||
docker run --rm -it -v $(pwd):/home -e PUID=1000 -e PGID=1000 \ | |||
ubuntu bash | |||
# id | |||
uid=0(root) gid=0(root) groups=0(root) | |||
</pre> | |||
<li>In this video [https://youtu.be/oHC6J_aN4eQ?t=137 How to Install Calibre on OMV and Docker], it uses the command '''id admin''' where "admin" is the portainer user to get PUID (of "admin") and PGID (of "users") to find out the two ids. | |||
</ul> | |||
=== Back Up Your Docker Volumes === | |||
[https://www.howtogeek.com/devops/how-to-back-up-your-docker-volumes/ How to Back Up Your Docker Volumes] | |||
=== Two ways to achieve persistent data === | |||
* [https://codeblog.dotsandbrackets.com/persistent-data-docker-volumes/ Persistent data in Docker volumes] | |||
* [https://www.cloudsavvyit.com/3588/how-to-deal-with-docker-container-persistence-and-storage/ How to Deal with Docker Container Persistence and Storage]. Docker has two ways to achieve persistence: '''volume mounts''', and '''bind mounts'''. | |||
=== Inspect the 'Mountpoint' of a volume === | |||
<syntaxhighlight lang='bash'> | |||
$ docker volume create crv | |||
$ docker volume ls | |||
$ docker run -d \ | |||
--name mycloud \ | |||
-p 81:80 \ | |||
-v apps:/var/www/html/custom_apps \ | |||
nextcloud | |||
# docker inspect is not quite useful. It does not show how the volume was created | |||
# But we can examine (ls, du, ...) the directory contents | |||
$ docker inspect apps | |||
[ | |||
{ | |||
"CreatedAt": "2018-10-23T09:41:52-04:00", | |||
"Driver": "local", | |||
"Labels": null, | |||
"Mountpoint": "/var/lib/docker/volumes/apps/_data", | |||
"Name": "apps", | |||
"Options": null, | |||
"Scope": "local" | |||
} | |||
] | |||
</syntaxhighlight> | |||
=== Remove an an unnamed volume === | |||
I you want to automatically removes volumes when a container is removed, you can use the '''--rm''' flag when starting the container with the "docker run" command. This flag tells Docker to automatically remove the container and any '''anonymous volumes''' associated with it when the container exits. However, this flag does not affect '''named volumes'''. | |||
If you created an unnamed volume, it can be deleted at the same time as the container with the -v flag. Note that this only works with unnamed volumes. | |||
<syntaxhighlight lang='bash'> | |||
docker rm -v container_name | |||
</syntaxhighlight> | |||
If the volume is named, it stays present. To remove a named volume, use '''docker volume rm volume_name''' . | |||
=== Volumes created in docker-compose === | |||
When you use '''docker-compose''' to create and manage containers, volumes are handled slightly differently than when using the '''docker run''' command. | |||
In a "docker-compose.yml" file, you can specify named volumes using the volumes key at the top level of the file. These volumes are created when you run docker-compose up and are not automatically removed when you stop or remove the containers using docker-compose down. | |||
If you want to remove '''named volumes''' created by docker-compose, you can use the '''-v''' flag with the '''docker-compose down''' command. Here’s an example command that stops and removes all containers defined in a docker-compose.yml file and also removes any named volumes: | |||
<pre> | |||
docker-compose down -v | |||
</pre> | |||
This command stops and removes all containers defined in the docker-compose.yml file and also removes any named volumes specified in the file. All data stored in the volumes will be permanently deleted. | |||
'''Anonymous volumes''' created by docker-compose are automatically removed when you stop and remove the containers using docker-compose down, even if you don’t use the -v flag. | |||
=== [https://docs.docker.com/storage/volumes/#start-a-container-with-a-volume Start a container with a volume] === | |||
{| class="wikitable" | |||
! --mount | |||
! -v | |||
|- | |||
| docker run -d \ | |||
--name devtest \ <br/> | |||
--mount source=myvol2,target=/app \ <br/> | |||
nginx:latest | |||
| docker run -d \ | |||
--name devtest \ <br/> | |||
-v myvol2:/app \ <br/> | |||
nginx:latext | |||
|} | |||
Note | |||
* '''target''' in "--mount" can be replaced by '''destination''' or '''dst'''. | |||
* To use a read-only volume, add the ''',readonly''' option in "--mount" or the ''':ro''' option in "-v". | |||
* We cannot use "~/" to represent a local directory under HOME. We have to specify a full path in '''docker run'''. | |||
=== A simple example === | |||
From the book "Learn Docerk -Fundamentals of Docker 18.x". Chap 5. Data Volumes and System Management > Creating and mounting data volumes. | |||
<syntaxhighlight lang='bash'> | |||
# Create a volume | |||
docker volume create my-data | |||
docker volume inspect my-data | |||
# The host folder can be found in the output under 'Mountpoint' | |||
# In my case, | |||
# "Mountpoint": "/var/lib/docker/volumes/my-data/_data", | |||
# Mount a volume into a container | |||
docker run --name test -it -v my-data:/data alpine /bin/sh | |||
# cd /data | |||
# echo 'some data' > data.txt | |||
# echo 'more data' > data2.txt | |||
# exit | |||
docker inspect my-data | |||
sudo ls /var/lib/docker/volumes/my-data/_data | |||
# We can even try to output the content of say, the second file: | |||
sudo cat /var/lib/docker/volumes/my-data/_data/data2.txt | |||
# We can create a new file in this folder from the host and then use the volume with another container | |||
echo "the file is created on host" > sudo tee /var/lib/docker/volumes/my-data/_data/host-data | |||
# Let's delete the test container and run another one | |||
docker rm test | |||
# This time we are mounting our volume to a different container folder | |||
docker run --name test2 -it -v my-data:/app/data centos:7 /bin/bash | |||
# We are able to see three files: | |||
# ls /app/data | |||
# Remove volumes | |||
docker volume rm my-data # Or | |||
docker volume rm $(docker volume ls -q) | |||
# Remove all running containers to clean up the system, | |||
docker rm -f $(docker ls -aq) | |||
</syntaxhighlight> | |||
=== Sharing data between containers === | |||
[https://www.cloudsavvyit.com/15112/how-to-share-data-between-docker-containers/ How to Share Data Between Docker Containers] | |||
<syntaxhighlight lang='bash'> | |||
docker run -it --name writer -v shared-data:/data alpine /bin/sh | |||
# create a file inside it | |||
# echo 'my sample file' > /data/sample.txt | |||
# exit | |||
docker run -it --name reader -v shared-data:/app/data:ro ubuntu:17.04 /bin/bash | |||
# ls -l /app/data | |||
</syntaxhighlight> | |||
=== Using host volumes === | |||
Use volumes that mount a specific host folder | |||
* It may be possible for the "docker volume" command to mount a local directory to a volume. See [https://docs.docker.com/engine/reference/commandline/volume_create/#examples examples] in the "docker volume create" documentation. | |||
* Specifying a directory name instead of giving a volume name in the "docker run" 's '''-v''' option | |||
* Since we are specifying a directory name instead of letting docker to create a new volume, "docker volume ls" will not getting a new volume | |||
<syntaxhighlight lang='bash'> | |||
docker run -it --name test -v $(pwd)/src:/app/src alpine /bin/sh | |||
# Make a sample to demonstrate how that works | |||
mkdir ~/my-web; cd ~/my-web | |||
echo "<h1>My website</h1>" > index.html | |||
# Create 'Dockerfile' | |||
echo -e 'FROM nginx:alpine | |||
COPY . /usr/share/nginx/html' > Dockerfile | |||
docker image build -t my-website:1.0 . | |||
docker run -d -p 8080:80 --name my-site my-website:1.0 | |||
# Open http://localhost:8080. It looks good | |||
# Now modify index.html and refresh the website. It does not refresh | |||
# Let's stop and rm the container and rebuild using a volume | |||
docker rm -f my-site | |||
docker run -d -v $(pwd):/usr/share/nginx/html \ | |||
-p 8080:80 --name my-site my-website:1.0 | |||
# Now any changes on index.html will refresh on the website | |||
</syntaxhighlight> | |||
=== Define volumes in images === | |||
A few samples of volume definition | |||
<pre> | |||
VOLUME /app/data | |||
VOLUME /app/data, /app/profiles, /app/config | |||
VOLUME {"/app/data", "/app/profiles", "/app/config"] | |||
</pre> | |||
The first line defines a single volume to be mounted at ''/app/data''. | |||
We can use the ''docker image inspect'' command to get information about the volumes defined in the Dockerfile. | |||
<syntaxhighlight lang='bash'> | |||
docker image pull mongo:3.7 | |||
docker image inspect --format='{{json .ContainerConfig.Volumes}}' \ | |||
mongo:3.7 | jq | |||
# { | |||
# "/data/configdb": {}, | |||
# "/data/db": {} | |||
# } | |||
# now run an instance of MongoDB and inspect the volume information | |||
docker run --name my-mongo -d mongo:3.7 | |||
docker inspect --format '{{json .Mounts}}' my-mongo | jq | |||
# [ | |||
# { | |||
# "Type": "volume", | |||
# "Name": "535e0138b9a32e89f71380e9e73bb0de64ce0d1cad78fcda0ec1d49e11d76d7a", | |||
# "Source": "/var/lib/docker/volumes/535e0138b9a32e89f71380e9e73bb0de64ce0d1.../_data", | |||
# "Destination": "/data/configdb", | |||
# "Driver": "local", | |||
# "Mode": "", | |||
# "RW": true, | |||
# "Propagation": "" | |||
# }, | |||
# { | |||
# "Type": "volume", | |||
# SKIP | |||
</syntaxhighlight> | |||
=== Differences between VOLUME and '-v|--volume' === | |||
https://stackoverflow.com/a/25312719 | |||
=== Container Memory Limits, Setting Available CPUs, Allocating memory and CPU === | |||
* [https://medium.com/@nitesh.turaga/how-i-use-bioconductor-with-docker-part-2-more-memory-faster-bioconductor-with-docker-fd7e69dce2bf How I use Bioconductor with Docker (part 2): More memory, faster Bioconductor with Docker] | |||
: <syntaxhighlight lang='bash'> | |||
docker run \ | |||
-rm \ ## Automatically remove the container when it exits | |||
--memory=6g \ ## memory limit | |||
--cpus=1.5 \ ## number of CPUs | |||
-v /shared/data-store:/home/rstudio/data \ | |||
-v /shared/library-store:/usr/local/lib/R/host-site-library \ | |||
-e PASSWORD=bioc \ | |||
-p 8787:8787 \ | |||
bioconductor/bioconductor_full:devel | |||
</syntaxhighlight> | |||
* [https://docs.docker.com/docker-for-mac/ Get started with Docker Desktop for Mac], [https://docs.docker.com/docker-for-windows/ Windows] | |||
* [https://docs.docker.com/config/containers/resource_constraints/ Limit a container's resources] | |||
* [https://blog.docker.com/2018/12/top-5-post-docker-container-java/ TOP 5 BLOG OF 2018: IMPROVED DOCKER CONTAINER INTEGRATION WITH JAVA 10] | |||
* [https://www.jottr.org/2022/04/22/parallelly-1.31.1/ parallelly 1.31.1: Better at Inferring Number of CPU Cores with Cgroups and Linux Containers] | |||
* [https://www.thorsten-hans.com/limit-memory-for-docker-containers Docker Container Memory Limits Explained] | |||
* [https://www.howtogeek.com/devops/how-to-set-a-memory-limit-for-docker-containers/ How to Set a Memory Limit for Docker Containers] | |||
== Work with container images == | == Work with container images == | ||
https://docs.docker.com/userguide/dockerimages/ | * https://docs.docker.com/userguide/dockerimages/ | ||
=== List images by size or name === | |||
<pre> | |||
# by size | |||
docker images --format "{{.ID}}\t{{.Size}}\t{{.Repository}}" | sort -k 2 -h | |||
# by name | |||
docker images --format "{{.ID}}\t{{.Size}}\t{{.Repository}}" | sort -k 3 | |||
</pre> | |||
=== List specific columns === | |||
<pre> | |||
docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.Size}}' | |||
</pre> | |||
=== Create an image interactively using '''commit''' - Example 1 === | |||
The example is from the book 'Learn Docker - Fundamentals of Docker 18.x'. | |||
<syntaxhighlight lang='bash'> | |||
docker container run -it --name sample alpine /bin/sh | |||
# apk update && apk add iputils | |||
# ping 127.0.0.1 | |||
# exit | |||
docker container ls -a | grep sample | |||
docker container diff sample | |||
</syntaxhighlight> | |||
We can now use the ''docker container commit'' command to persist our modifications and create a new image from them | |||
<syntaxhighlight lang='bash'> | |||
docker container commit sample my-alpine | |||
docker images ls | |||
</syntaxhighlight> | |||
If we want to see how our custom image has been built, we can use the ''history'' command as follows: | |||
<syntaxhighlight lang='bash'> | |||
docker image history my-alpine | |||
# IMAGE CREATED CREATED BY SIZE COMMENT | |||
# 0f105057899b About a minute ago /bin/sh 1.55MB | |||
# 196d12cf6ab1 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B | |||
# <missing> 4 weeks ago /bin/sh -c #(nop) ADD file:25c10b1d1b41d46a1… 4.41MB | |||
</syntaxhighlight> | |||
The first layer in the preceding list is the one we just created by adding the iputils package. | |||
=== Create an image interactively using '''commit''' - Example 2 === | |||
* [https://www.cloudsavvyit.com/15489/how-to-create-a-docker-image-from-a-running-container/ How to Create a Docker Image From a Running Container]. Commit messages are displayed when you use the '''docker history''' command to view the layers in an image. | |||
* [http://www.techrepublic.com/article/how-to-commit-changes-to-a-docker-image/ How to commit changes to a docker image] | |||
<span style="color: red">Note that it is better/necessary to put the Dockerfile in an empty directory</span> to avoid the problem of taking a long time to build the image (''sending build context to Docker daemon ...GB '') since it will grab files from the current directory. | |||
<syntaxhighlight lang='bash'> | |||
sudo docker search sinatra | |||
sudo docker pull training/sinatra | |||
sudo docker run -t -i training/sinatra /bin/bash | |||
sudo docker commit -m="Added json gem" -a="Kate Smith" 0b2616b0e5a8 ouruser/sinatra:v2 | |||
sudo docker images | |||
mkdir sinatra | |||
cd sinatra | |||
touch Dockerfile | |||
sudo docker build -t="ouruser/sinatra:v2" . | |||
sudo docker push ouruser/sinatra | |||
sudo docker rmi training/sinatra | |||
</syntaxhighlight> | |||
* I get an error when I try to launch sinatra on my 32-bit ubuntu (Docker can only be installed through apt-get on 32-bit) | |||
<pre> | |||
$ sudo docker run -t -i training/sinatra /bin/bash | |||
2014/12/31 02:43:26 exec format error | |||
</pre> | |||
=== How to copy Docker images from one host to another without using a repository === | |||
https://stackoverflow.com/questions/23935141/how-to-copy-docker-images-from-one-host-to-another-without-using-a-repository | |||
<syntaxhighlight lang='bash'> | |||
docker save -o out.tar <image name> | |||
# Or better to compress the file | |||
docker save <docker image name> | gzip > out.tar.gz | |||
</syntaxhighlight> | |||
And restore | |||
<syntaxhighlight lang='bash'> | |||
docker load -i out.tar | |||
# Or decompress the file | |||
docker load < out.tar.gz | |||
</syntaxhighlight> | |||
=== Docker Image Manifest === | |||
[https://www.cloudsavvyit.com/12330/what-is-a-docker-image-manifest/ What Is a Docker Image Manifest?] | |||
=== Resources allocated to a container using docker? === | |||
https://stackoverflow.com/questions/16084741/how-do-i-set-resources-allocated-to-a-container-using-docker | |||
== hub.docker.com == | |||
* Note that Dockerfile is optional on https://registry.hub.docker.com. | |||
* For free account, we can have only [https://docs.docker.com/docker-hub/repos/ 1 free private repository]. If we want to create a new repository online, we can | |||
: <syntaxhighlight lang='bash'> | |||
docker tag local-image:tagname new-repo:tagname | |||
docker login | |||
docker push new-repo:tagname | |||
</syntaxhighlight> | |||
* [https://stackoverflow.com/a/28349540 How to push a docker image to a private repository] | |||
* [https://registry.hub.docker.com/repos/rocker/ rocker]. The Dockerfile is included there. Question: how to automatically build the image rather than uploading pre-built image binaries to Docker Hub? | |||
* Search all repositories related to [https://registry.hub.docker.com/search?q=r&searchfield= R] | |||
* [http://phusion.github.io/baseimage-docker/ baseimage-docker]. I can use ping command without special argument when I start phusion/baseimage. | |||
: <syntaxhighlight lang='bash'> | |||
docker pull phusion/baseimage | |||
docker run -ti phusion/baseimage /bin/bash | |||
</syntaxhighlight> | |||
* https://dockerfile.github.io/ which includes dockerfiles for different purposes. The ubuntu-desktop one also works well (client needs a vnc viewer in order to see the desktop). | |||
=== Set up a private Docker registry === | |||
* https://docs.docker.com/registry/ <syntaxhighlight lang='bash'> | |||
docker run -d -p 5000:5000 --name registry registry:2 | |||
docker pull ubuntu | |||
docker image tag ubuntu localhost:5000/myfirstimage | |||
docker push localhost:5000/myfirstimage | |||
docker pull localhost:5000/myfirstimage | |||
docker container stop registry && docker container rm -v registry | |||
</syntaxhighlight> | |||
* https://docs.docker.com/registry/deploying/ | |||
* [https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-14-04 Ubuntu 14.04] from digitalocean | |||
* [https://www.howtoforge.com/tutorial/how-to-setup-private-docker-registry-on-ubuntu-1804-lts/ How to Setup Private Docker Registry on Ubuntu 18.04 LTS] | |||
* [http://www.thegeekstuff.com/2017/01/secure-docker-registry/ How to Setup Secure Docker Registry on Linux using TLS SSL Certificate] | |||
* List repositories in the local registry. [https://docs.docker.com/registry/spec/api/#listing-image-tags Docker Registry HTTP API V2] and [https://stackoverflow.com/a/14978657 HTTP POST and GET using cURL in Linux]. | |||
: <syntaxhighlight lang='bash'> | |||
$ curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:5000/v2/_catalog | |||
$ OR | |||
$ curl -H "Accept: application/xml" -H "Content-Type: application/json" -X GET http://localhost:5000/v2/_catalog | |||
</syntaxhighlight> | |||
* [https://www.howtogeek.com/devops/how-to-login-to-docker-hub-and-private-registries-with-the-docker-cli/ How to Login to Docker Hub and Private Registries With The Docker CLI] | |||
=== Github registry === | |||
* [https://www.docker.com/blog/docker-support-for-the-new-github-container-registry/ Docker Support for the New GitHub Container Registry] | |||
* [https://docs.github.com/en/packages/guides/migrating-to-github-container-registry-for-docker-images Migrating to GitHub Container Registry for Docker images] | |||
* [https://www.cloudsavvyit.com/6871/how-to-get-started-with-githubs-new-docker-container-registry/ How to Get Started with Github’s New Docker Container Registry] | |||
* [https://nikiforovall.github.io/docker/2020/09/19/publish-package-to-ghcr.html Publish images to GitHub Container Registry (ghcr)] | |||
<pre> | |||
docker pull ghcr.io/OWNER/IMAGE_NAME:TAG | |||
# docker pull registry-url/image-name:tag | |||
</pre> | |||
=== Google Container Registry === | |||
<ul> | |||
<li>Authenticate with Google Cloud: ensure you have the Google Cloud SDK installed | |||
<pre> | |||
gcloud auth login | |||
gcloud auth configure-docker | |||
</pre> | |||
<li>Pull the image | |||
<pre> | |||
docker pull gcr.io/PROJECT_ID/IMAGE_NAME:TAG | |||
</pre> | |||
</ul> | |||
=== Google Artifact Registry === | |||
https://cloud.google.com/artifact-registry/ | |||
<ul> | |||
<li>Authenticate with Google Cloud: ensure you have the Google Cloud SDK installed | |||
<pre> | |||
gcloud auth login | |||
gcloud auth configure-docker us-central1-docker.pkg.dev | |||
</pre> | |||
<li>Pull the image | |||
<pre> | |||
docker pull us-central1-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME:TAG | |||
</pre> | |||
</ul> | |||
== Dockerfile == | |||
* A Dockerfile does not follow the YAML syntax or the shell syntax. It is a plain text file that contains instructions for building a Docker image, using its own specific syntax and keywords. | |||
* [https://docs.docker.com/reference/builder/ Dockerfile Reference] | |||
* [https://www.digitalocean.com/community/tutorials/docker-explained-using-dockerfiles-to-automate-building-of-images Using Dockerfiles to Automate Building of Images] from digitalocean.com. | |||
* <strike><span style="color: red">Remember to put the Dockerfile in an empty directory</span></strike>. | |||
* [https://medium.com/better-programming/what-goes-into-a-dockerfile-ff0ace591060 What goes into a Dockerfile] | |||
* Keywords | |||
** FROM. If we want to start from scratch, we can use ''FROM scratch''. | |||
** RUN. The argument for RUN is any valid Linux command. | |||
** [https://docs.docker.com/engine/reference/builder/#user USER]. This is useful if we want to create new files with a non-root owner privilege. For example, new files created under a binding directory with a non-root user ownership will belong to the current user in the host system. [https://github.com/jlintusaari/R-docker-report.git Here] is an example where we use Rmarkdown to create pdf output. The generated pdf file should not be own by root. [https://stackoverflow.com/a/27703359 How to add users to Docker container?] [https://biolitika.si/pin-r-package-versions-using-docker-and-renv.html Switch users]. | |||
** COPY & ADD. | |||
*** "COPY . /app" will copy all files and folders from the current directory recursively to the /app folder. We can use "ADD" too but "ADD" will automatically unpack tarballs. See [https://stackoverflow.com/a/24958548 What is the difference between the `COPY` and `ADD` commands in a Dockerfile?] | |||
*** "ADD sample.tar /app/bin" will unpack the ''sample.tar' file into the target folder | |||
*** "ADD <nowiki>http://example.com/sample.txt</nowiki> /data/" will copy the remote file sample.txt into the target file | |||
** WORKDIR. Define the working directory or context that is used when a container is run from the image. | |||
** CMD & ENTRYPOINT. These two are actually definitions of what will happen when a container is started from the image. | |||
*** Use CMD without ENTRYPOINT: "CMD command param1 param2". This form is called the '''shell''' form. | |||
*** If we use ENTRYPOINT + CMD, ENTRYPOINT defines the command and CMD defines parameters. The example above will run ''ping 8.8.8.8 -c 3''. This form is called the '''exec''' form. | |||
* [https://github.com/jamtur01/dockerbook-code The Docker Book] | |||
=== Examples of Dockerfile === | |||
* [https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#minimize-the-number-of-layers Only the instructions RUN, COPY, ADD create layers.] | |||
* A sample. Six layers (lines). The first line is the Base Layer. | |||
<pre> | |||
FROM python:2.7 | |||
RUN mkdir -p /app | |||
WORKDIR /app | |||
COPY ./requirements.txt /app/ | |||
RUN pip install -r requirements.txt | |||
CMD ["python", "main.py"] | |||
</pre> | |||
* Another example | |||
<pre> | |||
FROM alpine:latest | |||
ENTRYPOINT ["ping"] | |||
CMD ["8.8.8.8", "-c", "3"] | |||
</pre> | |||
* Another example from [https://github.com/rocker-org/rocker/blob/master/r-base/4.0.0/Dockerfile RStudio] | |||
<pre> | |||
FROM debian:testing | |||
RUN useradd docker \ | |||
&& mkdir /home/docker \ | |||
&& chown docker:docker /home/docker \ | |||
&& addgroup docker staff | |||
</pre> | |||
We can test it by "docker build -t mydebian . " and "docker run --rm -it --user docker -v /tmp:/home/docker mydebian". We can create a new file under /home/docker and the file will be accessible and belongs to the current host user once we quit the container. '''This actually is a huge security issue'''. | |||
The same technique does not work on alpine if I try to create a new file in the container. | |||
<pre> | |||
FROM alpine:latest | |||
# Create a group and user; not useful for creating files in host OS | |||
RUN addgroup -S appgroup && adduser -S appuser -G appgroup \ | |||
&& chown appuser:appgroup /home/appuser | |||
</pre> | |||
"docker build -t myalpine . " and "docker run --rm -it -v ~/Downloads/:/home/appuser:rw --user appuser myalpine". When I use the "id" command in the container, I see it returns 100 in alpine container and 1000 in debian container. The id returns 1000 on my host (Ubuntu/Pop_OS). So the solution is '''docker run --rm -it -v ~/Downloads/:/home/appuser --user 1000:1000 myalpine'''. So the local user and the created user home directory in the container are not needed. See | |||
<ul> | |||
<ul> | |||
<li> [https://jtreminio.com/blog/running-docker-containers-as-current-host-user/ Running Docker Containers as Current Host User] (Useful !)</li> | |||
<li> [https://stackoverflow.com/a/45673309 How to give non-root user in Docker container access to a volume mounted on the host] </li> | |||
</ul></ul> | |||
==== Rocker ==== | |||
* [https://github.com/rocker-org/rocker rocker (R and RStudio)] | |||
* [https://github.com/hrbrmstr/rdaradar rdaradar (RDA Radar)] | |||
<pre> | |||
FROM r-base:latest | |||
COPY check.R . | |||
CMD [ "Rscript", "check.R", "/unsafe.rda"] | |||
</pre> | |||
<pre> | |||
$ git clone https://github.com/hrbrmstr/rdaradar.git | |||
$ docker build -t rdaradar:0.1.0 -t rdaradar:latest . | |||
$ docker run --rm -v "$(pwd)/exploit.rda:/unsafe.rda" rdaradar | |||
</pre> | |||
==== Bioconductor ==== | |||
[https://github.com/Bioconductor/bioconductor_docker Bioconductor] | |||
==== Papers ==== | |||
* [https://github.com/amyfrancis97/DrivR-Base DrivR-Base], [https://f1000research.com/posters/12-1521 Poster], [https://academic.oup.com/bioinformatics/article/40/4/btae197/7644281 Paper] 2024 | |||
=== How to use Dockerfile === | |||
https://docs.docker.com/engine/reference/commandline/build/ | |||
[https://stackoverflow.com/a/55034787 The . simply means "current working directory"]. | |||
<syntaxhighlight lang='bash'> | |||
docker build -f Dockerfile -t arraytools/myimagename . | |||
docker build -t [myname] . | |||
# Multiple tags | |||
docker build -t arraytools/biospear:latest -t arraytools/biospear:3.6.0 . | |||
</syntaxhighlight> | |||
In the above example, we can create the image by | |||
<syntaxhighlight lang='bash'> | |||
docker image build -t pinger . | |||
</syntaxhighlight> | |||
We can run a container from the pinger image | |||
<syntaxhighlight lang='bash'> | |||
docker container run --rm -it pinger | |||
</syntaxhighlight> | |||
=== Docker Build Args === | |||
[https://www.howtogeek.com/devops/how-to-use-docker-build-args-to-configure-image-builds/ How to Use Docker Build Args to Configure Image Builds] | |||
=== Clean up after failed builds === | |||
[https://gist.github.com/kuznero/0c751283ea77177a1db9 Cleanup docker images and containers after failed builds] | |||
<pre> | |||
#!/bin/bash | |||
docker rm $(docker ps -aq) \ | |||
docker rmi $(docker images | grep "^<none>" | awk '{print $3}') | |||
</pre> | |||
=== ENTRYPOINT and CMD === | |||
* If your container acts like a command-line program, you can use '''ENTRYPOINT'''. If you are unsure, you can use '''CMD'''. | |||
* [https://blog.codeship.com/understanding-dockers-cmd-and-entrypoint-instructions/ Understanding Docker’s CMD and ENTRYPOINT Instructions]. It shows how to supply arguments to the command we like to execute in the container. | |||
* https://docs.docker.com/engine/reference/builder/#cmd | |||
** [https://dille.name/blog/2019/12/05/creating-advanced-entrypoints-for-containers/ Creating Advanced Entrypoints for Containers]. In this case CMD provides extra parameters to ENTRYPOINT. | |||
** The Dockerfile from [https://jlintusaari.github.io/2018/07/how-to-compile-rmarkdown-documents-using-docker/ How to compile R Markdown documents using Docker] uses both ENTRYPOINT and CMD where in this case CMD provides extra parameters to ENTRYPOINT. | |||
'''The advantage of using ENTRYPOINT + CMD''' (exec form) instead of using '''CMD''' alone (shell form) is we can override the ''CMD'' part that I have defined in the Dockerfile. | |||
<syntaxhighlight lang='bash'> | |||
docker container run --rm -it pinger -w 5 127.0.0.1 | |||
# ping the loopback for 5 seconds | |||
</syntaxhighlight> | |||
If we want to overwrite what's defined in the ''ENTRYPOINT'' in the Dockerfile, we need to use the ''--entrypoint'' parameter. | |||
<syntaxhighlight lang='bash'> | |||
docker container run --rm -it --entrypoint /bin/sh pinger | |||
# we'll be inside the container. Type exit to leave the container | |||
</syntaxhighlight> | |||
When we use the '''shell''' form, the '''ENTRYPOINT''' is have the default value of ''/bin/sh -c'' and whatever is the value of ''CMD'' will be passed as a string to the shell command. | |||
=== Temporary failure resolving 'deb.debian.org' when running "docker build" === | |||
Add "--net=host" to the docker build command. See [https://stackoverflow.com/questions/24991136/docker-build-could-not-resolve-archive-ubuntu-com-apt-get-fails-to-install-a Docker build “Could not resolve 'archive.ubuntu.com'” apt-get fails to install anything] | |||
=== Best practices for writing Dockerfiles === | |||
* https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ | |||
* [https://blog.docker.com/2019/07/intro-guide-to-dockerfile-best-practices/ Intro Guide to Dockerfile Best Practices] | |||
=== Use multi-stage builds === | |||
* https://docs.docker.com/develop/develop-images/multistage-build/ | |||
* [https://www.cloudsavvyit.com/9260/what-are-multi-stage-docker-builds/ What Are Multi-Stage Docker Builds?] | |||
With multi-stage builds, we have a single Dockerfile containing multiple FROM instructions. Each FROM instruction is a new '''build stage''' that can easily COPY artifacts from previous '''stages'''. | |||
[https://github.com/nigelpoulton/atsea-sample-shop-app An example] from the "Docker Deep Dive" book. | |||
=== tag after image was built === | |||
<pre> | |||
$ docker tag <imageID> <newName>/<repoName>:<tagName> | |||
</pre> | |||
=== About storage drivers === | |||
https://docs.docker.com/storage/storagedriver/#sharing-promotes-smaller-images | |||
=== Privileged versus Root user in Docker === | |||
* [https://www.cloudsavvyit.com/5211/privileged-vs-root-in-docker-whats-the-difference/ Privileged versus Root in Docker: What’s the Difference?] | |||
* [https://itnext.io/docker-and-kubernetes-root-vs-privileged-9d2a37453dec Docker and Kubernetes — root vs. privileged] | |||
=== .dockerignore === | |||
[https://devopsheaven.com/docker/dockerignore/2018/04/25/using-dockerignore.html Using .dockerignore files to build better Docker images] | |||
=== Dockerfile in One Line === | |||
<pre> | |||
FROM ubuntu | |||
</pre> | |||
Using This simple Dockerfile and the docker command '''sudo docker build -t scooby_snacks .''' will result in | |||
<pre> | |||
$ sudo docker images | |||
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE | |||
ubuntu 15.04 2427658c75a1 42 hours ago 117.5 MB | |||
ubuntu vivid 2427658c75a1 42 hours ago 117.5 MB | |||
ubuntu vivid-20150218 2427658c75a1 42 hours ago 117.5 MB | |||
ubuntu utopic-20150211 78949b1e1cfd 42 hours ago 194.4 MB | |||
ubuntu utopic 78949b1e1cfd 42 hours ago 194.4 MB | |||
ubuntu 14.10 78949b1e1cfd 42 hours ago 194.4 MB | |||
ubuntu 14.04 2d24f826cb16 42 hours ago 188.3 MB | |||
ubuntu 14.04.2 2d24f826cb16 42 hours ago 188.3 MB | |||
ubuntu trusty 2d24f826cb16 42 hours ago 188.3 MB | |||
ubuntu trusty-20150218.1 2d24f826cb16 42 hours ago 188.3 MB | |||
ubuntu latest 2d24f826cb16 42 hours ago 188.3 MB | |||
scooby_snacks latest 2d24f826cb16 42 hours ago 188.3 MB | |||
ubuntu precise 1f80e9ca2ac3 42 hours ago 131.5 MB | |||
ubuntu precise-20150212 1f80e9ca2ac3 42 hours ago 131.5 MB | |||
ubuntu 12.04.5 1f80e9ca2ac3 42 hours ago 131.5 MB | |||
ubuntu 12.04 1f80e9ca2ac3 42 hours ago 131.5 MB | |||
ubuntu 14.04.1 5ba9dab47459 3 weeks ago 188.3 MB | |||
ubuntu 12.10 c5881f11ded9 8 months ago 172.2 MB | |||
ubuntu quantal c5881f11ded9 8 months ago 172.2 MB | |||
ubuntu 13.04 463ff6be4238 8 months ago 169.4 MB | |||
ubuntu raring 463ff6be4238 8 months ago 169.4 MB | |||
ubuntu 13.10 195eb90b5349 8 months ago 184.7 MB | |||
ubuntu saucy 195eb90b5349 8 months ago 184.7 MB | |||
ubuntu 10.04 3db9c44f4520 10 months ago 183 MB | |||
ubuntu lucid 3db9c44f4520 10 months ago 183 MB | |||
</pre> | |||
== List all tags of an image == | |||
[https://stackoverflow.com/a/39454426 How can I list all tags for a Docker image on a remote registry?] | |||
=== Tag the image with the git commit ID === | |||
<pre> | |||
$ docker build -t REPOS/IMAGE:$(git rev-parse --verify HEAD) | |||
</pre> | |||
== Run a shell script on host == | |||
* https://docs.docker.com/engine/reference/commandline/run/ | |||
* [https://serverfault.com/questions/806812/docker-run-bash-script-then-remove-container This post] and [https://stackoverflow.com/questions/32163955/how-to-run-shell-script-on-host-from-docker-container this one] | |||
<pre style="white-space: pre-wrap; /* CSS 3 */ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ word-wrap: break-word; /* IE 5.5+ */ " > | |||
$ docker run -v /path/to/sample_script.sh:/sample_script.sh \ | |||
--rm ubuntu bash sample_script.sh | |||
# GATK container example | |||
# First we log in interactive and see where is the default location (/usr in this case) | |||
$ docker run --rm -i -t broadinstitute/gatk3:3.8-0 bash | |||
$ cat > tmp.sh << EOF | |||
> pwd | |||
> ls | |||
> java -jar GenomeAnalysisTK.jar --version | |||
> EOF | |||
$ docker run --rm -v $(pwd):/usr/my broadinstitute/gatk3:3.8-0 bash my/tmp.sh | |||
# ALTERNATIVELY, WE CAN PUT OUR SCRIPT IN THE TOP DIRECTORY (Hopefully the name is not duplicated) | |||
$ docker run --rm -v $(pwd)/tmp.sh:/tmp.sh broadinstitute/gatk3:3.8-0 bash /tmp.sh | |||
</pre> | |||
* https://askubuntu.com/questions/890533/how-can-i-run-docker-commands-after-docker-run-from-a-script (need to leave a container open) | |||
<pre> | |||
docker run -d -v$(pwd):/my SOMEIMAGE bash | |||
docker exec -d Test bash /my/script.sh | |||
</pre> | |||
* Create a Dockerfile https://forums.docker.com/t/how-to-run-bash-command-after-startup/21631/2 | |||
== Link containers together == | == Link containers together == | ||
https://docs.docker.com/userguide/dockerlinks/ | * https://docs.docker.com/userguide/dockerlinks/ | ||
* [https://hub.docker.com/r/simplyintricate/mediawiki/ Mediawiki example] | |||
== Manage data in containers == | == Manage data in containers == | ||
https://docs.docker.com/ | * https://docs.docker.com/storage/volumes/ | ||
* https://codereviewvideos.com/course/docker-tutorial-for-beginners/video/part-2-docker-volumes-volumes | |||
== Assign a static IP to a container == | |||
* [https://www.cloudsavvyit.com/14508/how-to-assign-a-static-ip-to-a-docker-container/ How to Assign a Static IP to a Docker Container] | |||
* https://stackoverflow.com/questions/27937185/assign-static-ip-to-docker-container <syntaxhighlight lang='bash'> | |||
# Step 1. create you own docker network (mynet123) | |||
docker network create --subnet=172.18.0.0/16 mynet123 | |||
# Step 2. simply run the image (I'll take ubuntu as example) | |||
docker run --rm --net mynet123 --ip 172.18.0.22 -it ubuntu bash | |||
# Check in the container shell | |||
# Note that the container CAN access internet | |||
apt install net-tools; ifconfig | |||
exit | |||
</syntaxhighlight> | |||
* https://docs.docker.com/engine/reference/commandline/network_create/#bridge-driver-options | |||
* [https://stackoverflow.com/questions/25529386/how-can-i-set-a-static-ip-address-in-a-docker-container Try using the --net=host option] (no a new IP was allocated; not a good solution) | |||
== Running Multiple Docker Services on the Same Server == | |||
[https://www.howtogeek.com/devops/how-to-run-multiple-docker-containers-on-different-ip-addresses/ How to Run Multiple Docker Containers on Different IP Addresses] | |||
== Firewall == | |||
[https://community.rstudio.com/t/rstudio-server-not-loading-taking-too-long-to-respond-in-browser/20786 Rstudio server not loading, taking too long to respond in browser]. On Ubuntu run ''sudo ufw allow PORTNUMBER''. | |||
== Docker DNS/internet problem == | |||
I got an error on resolving the debian server when I was creating an image from a Dockerfile that needs to run ''apt update'' and ''apt install'' commands. See [[#RStudio_in_Docker_.E2.80.93_now_share_your_R_code_effortlessly.21|RStudio in Docker – now share your R code effortlessly!]]. The problem happened on my Linux Mint Desktop but not on a VirtualBox VM (Ubuntu 18.04). | |||
[https://development.robinwinslow.uk/2016/06/23/fix-docker-networking-dns/ Fix Docker's networking DNS config] | |||
A temporary solution is to add the '''--dns''' option to ''docker run'' command. This works well when I use the IP from any one of my 2 DNS servers. It does not work however if I use the IP from google DNS or OpenDNS. | |||
A permanent solution is to create a new file '''/etc/docker/daemon.json''' and include the working DNS server IPs (these are obtained through the '''nmcli''' command or the NetworkManager GUI; see [[Linux#Query_DNS_server|Query DNS server]]). | |||
<pre> | |||
{ | |||
"dns": ["XXX.XX.XX.XX", "YYY.YY.YY.YY"] | |||
} | |||
</pre> | |||
Then restart the docker service: '''sudo service docker restart''' | |||
A quick test on the DNS problem is | |||
<syntaxhighlight lang='bash'> | |||
docker run --rm busybox nslookup google.com | |||
</syntaxhighlight> | |||
== Working with Docker hub == | == Working with Docker hub == | ||
https://docs.docker.com/userguide/dockerrepos/ | https://docs.docker.com/userguide/dockerrepos/ | ||
=== Github Actions === | |||
* [https://docs.github.com/en/actions/language-and-framework-guides/github-actions-for-docker GitHub Actions for Docker] | |||
* [https://docs.github.com/en/actions/language-and-framework-guides/publishing-docker-images Publishing Docker images] | |||
* See my [[Github#Github_Actions_.28GHA.29|Github]] page. | |||
== Enabling HTTPS/Let's encrypt == | |||
* [https://caddyserver.com/ Caddy] | |||
* https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion | |||
* [https://medium.com/bros/enabling-https-with-lets-encrypt-over-docker-9cad06bdb82b Enabling HTTPS with Let's Encrypt on Docker] | |||
* [https://www.humankode.com/ssl/how-to-set-up-free-ssl-certificates-from-lets-encrypt-using-docker-and-nginx How to Set Up Free SSL Certificates from Let's Encrypt using Docker and Nginx] and the [https://github.com/thecarlo/letsencrypt-docker-nginx source code]. | |||
* [http://www.56n.dk/setup-encrypted-rstudio-and-shiny-dashboard-solution-in-3-minutes/ Setup encrypted Rstudio and Shiny dashboard solution in 3 minutes] (2017). Not working now. ERROR: manifest for mikkelkrogsholm/rstudio:latest not found. After changing to use rocker/rstudio & rocker/shiny images, a new error came out <syntaxhighlight lang='bash'> | |||
ERROR: for nginx Cannot start service nginx: b'driver failed programming external connectivity on endpoint | |||
nginx (879b01885acd6a0778d9403f4220851e83bd2ff8de643ce91c21cecd25419f83): Error starting userland proxy: | |||
listen tcp 0.0.0.0:443: bind: address already in use' | |||
ERROR: Encountered errors while bringing up the project. | |||
</syntaxhighlight> | |||
* [https://medium.com/bros/enabling-https-with-lets-encrypt-over-docker-9cad06bdb82b Enabling HTTPS with Let's Encrypt on Docker] using Nginx. | |||
== Enabling HTTPS by self-sign certificates == | |||
* [https://www.johnmackenzie.co.uk/post/creating-self-signed-ssl-certificates-for-docker-and-nginx/ Creating Self-Signed SSL Certificates For Docker and Nginx] | |||
* [https://medium.com/@oliver.zampieri/self-signed-ssl-reverse-proxy-with-docker-dbfc78c05b41 Self-signed SSL Reverse proxy with Docker] | |||
* [https://codefresh.io/docker-tutorial/using-docker-generate-ssl-certificates/ Using Docker to Generate SSL Certificates] | |||
* [https://medium.com/@mannycodes/configure-self-signed-ssl-for-nginx-docker-from-a-scratch-7c2bcd5478c6 Configure Self-Signed SSL For Nginx Docker From A Scratch] | |||
* [https://smithtalkstech.com/2018/04/25/creating-a-self-signed-ssl-certificate-for-local-docker-development/ Creating a self-signed SSL certificate for local Docker development] | |||
== traefik: The Cloud Native Application Proxy == | |||
* https://traefik.io/traefik/ | |||
* [https://www.digitalocean.com/community/tutorials/how-to-use-traefik-as-a-reverse-proxy-for-docker-containers-on-ubuntu-18-04 How To Use Traefik as a Reverse Proxy for Docker Containers on Ubuntu 18.04] | |||
* [https://www.howtoforge.com/how-to-install-and-use-traefik-as-a-reverse-proxy-with-docker-on-centos-8/ How to Install and Use Traefik as a Reverse Proxy with Docker on CentOS 8] | |||
* [https://www.digitalocean.com/community/tutorials/how-to-use-traefik-v2-as-a-reverse-proxy-for-docker-containers-on-ubuntu-20-04 How To Use Traefik v2 as a Reverse Proxy for Docker Containers on Ubuntu 20.04] | |||
* [https://medium.com/accesto/docker-reverse-proxy-using-traefik-2657c0086a3d Docker reverse proxy using Traefik] | |||
* [https://blog.eleven-labs.com/en/using-traefik-as-a-reverse-proxy/ USING TRAEFIK AS A REVERSE PROXY] | |||
* [https://youtu.be/N5EmluXSbEg How to Install Traefik 2 on OMV and Docker] DB Tech 2020. Cloudflare, Portainer. Airsonic. | |||
* [https://youtu.be/liV3c9m_OX8 Put Wildcard Certificates and SSL on EVERYTHING - Traefik Tutorial] Apr 2021 | |||
* Raspberry Pi | |||
** [https://www.alexhyett.com/traefik-vs-nginx-docker-raspberry-pi Traefik vs Nginx for Reverse Proxy with Docker on a Raspberry Pi] | |||
** [https://codecaptured.com/blog/self-hosting-pi-hole-with-docker-and-traefik/ Self-Hosting Pi-hole with Docker and Traefik] | |||
** [https://blog.pankajgarg.com/helloaspnetcoreonpi/ Running ASP.NET core web application on Raspberry Pi] | |||
* [https://youtu.be/liV3c9m_OX8 Put Wildcard Certificates and SSL on EVERYTHING - Traefik Tutorial] (video) | |||
== Nginx proxy manager == | |||
* https://nginxproxymanager.com/ | |||
* [https://www.the-digital-life.com/nginx-proxy-manager/ NGINX Proxy Manager – How-To Installation and Configuration] | |||
* [https://youtu.be/CSbgLBcIuwE Access your internal websites! Nginx Reverse Proxy in Home Assistant] | |||
* [https://www.howtoforge.com/how-to-install-and-use-nginx-proxy-manager/ How to Install and Use Nginx Proxy Manager with Docker] 2022 | |||
* [https://www.the-digital-life.com/nginx-proxy-manager/ NGINX Proxy Manager – How-To Installation and Configuration] the-digital-life | |||
* https://hub.docker.com/r/jlesage/nginx-proxy-manager, [https://github.com/jlesage/docker-nginx-proxy-manager Github] | |||
* [https://dev.to/domysee/setting-up-a-reverse-proxy-with-nginx-and-docker-compose-29jg Setting up a Reverse-Proxy with Nginx and docker-compose] | |||
* [https://linoxide.com/containers/setup-nginx-reverse-proxy-docker/ How to Setup NGINX as Reverse Proxy Using Docker]. It works. | |||
** Download the code from https://github.com/a-magdy/nginx-reverse-proxy-docker. | |||
** On the step of modifying /etc/hosts, change the IP address from 172.31.30.78 to 127.0.0.1 for site1.test and site2.test. Or I can use '''docker inspect XXXX | grep IPAddress''' to find out the IP for site1_default and site2_default (these two names are defined in <docker-compose.yml>). | |||
** Before creating proxy container, though two web services are up and running inside container, we still cannot test site1.test and site2.test. | |||
** docker-compose build shows successful build. But where is the image? | |||
** ''curl site1.test'' and ''curl site2.test'' work fine. | |||
** We can also use a browser to check these two URLs. For https it still works though FF gives warnings for self signed certificates. | |||
** '''nmap localhost''' will show ports 80 & 443 are open. | |||
* [https://www.freecodecamp.org/news/docker-nginx-letsencrypt-easy-secure-reverse-proxy-40165ba3aee2/ How to set up an easy and secure reverse proxy with Docker, Nginx] | |||
* [http://littlebigextra.com/install-nginx-reverse-proxy-server-docker/ How to install Nginx as a reverse proxy server with Docker]. Note that http://microservice1:8080; needs to be changed to reflect the true IP whether it is from a docker container or not. Also it does not work when I modify the --link option to use site1_app_1 and site2_app_1. | |||
{{Pre}} | |||
docker: Error response from daemon: Cannot link to /site1_app_1, as it does not belong to the default network. | |||
</pre> | |||
* [https://phoenixnap.com/kb/docker-nginx-reverse-proxy How to Deploy NGINX Reverse Proxy on Docker] (multiple web services) | |||
* [https://www.howtoforge.com/how-to-install-and-use-portainer-for-docker-management-with-nginx-proxy-manager/ How to Install and Use Portainer for Docker management with Nginx Proxy Manager] | |||
== Running multiple web applications on a Docker host == | |||
* https://medium.com/@jmarhee/running-multiple-web-applications-on-a-docker-host-with-apache-85f673f02803. Tips: Enable proxy module in Apache. In the ''VirtualHost'' file, specify '''ProxyPass''' with a port number. No need to specify the DocumentRoot. | |||
* https://medium.com/@francoisromain/host-multiple-websites-with-https-inside-docker-containers-on-a-single-server-18467484ab95. Nginx reverse-proxy is used. | |||
* https://blog.florianlopes.io/host-multiple-websites-on-single-host-docker/. [https://github.com/jwilder/nginx-proxy jwilder/nginx-proxy] is used. No need (and should not to avoid a conflict of port 80) to install Nginx <syntaxhighlight lang='bash'> | |||
docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy | |||
sudo nano /etc/hosts # add blog.domain.com and jenkins.domain.com for our testing purpose | |||
docker run -d --expose 80 -e VIRTUAL_HOST=blog.domain.com wordpress | |||
docker run -d --name jenkinsci --expose 8080 -e VIRTUAL_HOST=jenkins.domain.com -e VIRTUAL_PORT=8080 jenkins | |||
</syntaxhighlight> | |||
** Use VIRTUAL_PORT if there are multiple ports associated with a container | |||
** Use VIRTUAL_HOST if there are multiple domains associated with a container | |||
** SSL and et al | |||
== Authentication: Authelia == | |||
[https://www.youtube.com/watch?v=4UKOh3ssQSU Additional Self-Hosted Security with Authelia on NGINX Proxy Manager] (video) | |||
== GUI apps == | |||
* [https://www.cloudsavvyit.com/10520/how-to-run-gui-applications-in-a-docker-container/ How to Run GUI Applications in a Docker Container] | |||
* https://github.com/mviereck/x11docker/ which was used by [https://github.com/ehough/docker-kodi Docker-kodi] | |||
* https://pelle.io/2014/07/11/delivering-gui-applications-with-docker/ Forward X11 approach | |||
* https://linuxmeerkat.wordpress.com/2014/10/17/running-a-gui-application-in-a-docker-container/ Forward X11 | |||
* http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/ Share X11 socket | |||
* https://github.com/rogaha/docker-desktop Xpra + Xephyr | |||
* https://github.com/fcwu/docker-ubuntu-vnc-desktop VNC approach | |||
=== Firefox example === | |||
[https://www.linkedin.com/pulse/running-gui-applications-docker-container-revathi-dhotre Running GUI Applications in Docker Container] | |||
<pre> | |||
From ubuntu:20.04 | |||
RUN apt update | |||
RUN apt install firefox -y | |||
RUN apt install python3-pip -y | |||
RUN pip3 install notebook | |||
CMD /usr/bin/firefox | |||
CMD jupyter-notebook --allow-root | |||
</pre> | |||
<pre> | |||
nano Dockerfile | |||
docker build -t gui . | |||
docker run --env="DISPLAY" --net=host --name=firefox gui | |||
</pre> | |||
It works. However, I need to use '''docker rm -f firefox''' to kill it since Ctrl+c does not work. | |||
=== Meld example, save a running container as an image === | |||
[https://www.janert.org/blog/2022/running-a-gui-application-in-a-docker-container1 Running a GUI Application in a Docker Container]. It works. Below is a modified version for creating the '''meld''' app. I can save file modified by ''meld''. To use the app, I need to place files in the ~/Documents/docker (defined in '''-v'''). Note that the RAM usage is very minimal. Unfortunately on macOS, I got an error something related to Gtk. | |||
<pre> | |||
host> docker image pull ubuntu:jammy # 22.04 | |||
host> docker container run --rm --net host -v /tmp/.X11-unix:/tmp/.X11-unix -it ubuntu:jammy | |||
container# apt update | |||
container# apt install -y meld | |||
host> xhost +local: | |||
container# export DISPLAY=:0 | |||
host> docker container ls # find the ID of the running container | |||
host> docker commit <ID> meld | |||
container# exit | |||
host> docker container run --rm --net host \ | |||
-v /tmp/.X11-unix:/tmp/.X11-unix \ | |||
-v ~/Documents/docker:/meld \ | |||
-e DISPLAY \ | |||
--name=meld \ | |||
meld meld | |||
</pre> | |||
=== R and httpgd package === | |||
<ul> | |||
<li>[https://nx10.github.io/httpgd/articles/b03_docker.html httpgd Docker vignette], [https://nx10.github.io/httpgd/ installation] from Github. | |||
<li>It works. However, currently "httpgs" is archived in CRAN (2023/1/25). So my temporary solution is | |||
<pre> | |||
$ docker run --rm -it r-base:4.2.2 bash | |||
# apt update | |||
# apt install libfontconfig1-dev | |||
# R | |||
> install.packages("remotes") | |||
> remotes::install_github("nx10/httpgd") | |||
## note if we try to run 'httpgd::hgd(host = "0.0.0.0", port = 8888)', it does not work. | |||
## The reason is we have not use "-p" option to expose a port in the previous "docker run" command | |||
## open another terminal and create a docker image based on the current container | |||
$ docker ps -a | head | |||
$ docker commit CONTAINER_ID httpgd:4.2.2 | |||
$ docker run --rm -it -p 8888:8888 httpgd:4.2.2 R | |||
> httpgd::hgd(host = "0.0.0.0", port = 8888) | |||
> plot(1:5) | |||
</pre> | |||
<li>It works when I tested it on a '''remote ubuntu server''' (R 4.4.0 & httpgd 2.0.1) (following the instruction on [https://cran.r-project.org/web/packages/httpgd/vignettes/b03_docker.html Docker vignette]). Either IP or hostname works but the hostname URL link given by httpgd::hgd() needs to be modified to include '''.local'''. | |||
<li>Some variation of using hgd() | |||
<pre> | |||
hgd(host="0.0.0.0", port = 8888) # allow connection from any one from any computer | |||
hgd() # default is host=127.0.0.1, port will be random | |||
hgd(token="secret") # define the token | |||
hgd_browse() | |||
hgd_close() | |||
hgd_details() | |||
hgd_url() | |||
hgd_view() | |||
</pre> | |||
<li>To use it with [https://github.com/Bioconductor/bioconductor_docker?tab=readme-ov-file Bioconductor] (the Bioconductor docker image will use p3m.dev to install binary R packages so it is fast to create images), we can do like this | |||
<pre> | |||
$ docker run --rm -it -p 8888:8888 bioconductor/bioconductor_docker:RELEASE_3_18 R | |||
> install.packages("httpgd") | |||
> httpgd::hgd(host = "0.0.0.0", port = 8888) | |||
</pre> | |||
OR use, for example, "bioconductor/bioconductor_docker:RELEASE_3_18" as the base image in the Dockerfile, and follow the same instruction from httpgd vignette to create a docker image. | |||
<pre> | |||
$ nano Dockerfile_httpgd | |||
$ docker build . -f Dockerfile_httpgd -t bioc-httpgd:RELEASE_3_18 | |||
$ docker images | |||
$ docker run --rm -it --user rstudio -p 8888:8888 bioc-httpgd:RELEASE_3_18 R | |||
</pre> | |||
<li>[[Biowulf#Singularity|Singularity]]. The following is a definition file that is using the bioconductor image + the '''httpgd''' package. | |||
<syntaxhighlight lang='sh'> | |||
Bootstrap: docker | |||
From: bioconductor/bioconductor_docker:RELEASE_3_18 | |||
%post | |||
apt-get update \ | |||
&& apt-get install -y --no-install-recommends \ | |||
libfontconfig1-dev \ | |||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* \ | |||
&& install2.r --error --skipinstalled --ncpu -1 \ | |||
httpgd \ | |||
&& rm -rf /tmp/downloaded_packages | |||
%runscript | |||
exec /usr/local/bin/R | |||
%environment | |||
export LC_ALL=C | |||
</syntaxhighlight> | |||
<syntaxhighlight lang='sh'> | |||
sudo singularity build bioc.sif bioc.def | |||
singularity run bioc.sif | |||
> httpgd::hgd(host = "0.0.0.0", port = 8888) | |||
</syntaxhighlight> | |||
After we copy the URL, we need to modify the IP or hostname. | |||
</ul> | |||
=== Docker-OSX === | |||
https://github.com/sickcodes/Docker-OSX | |||
== Delete/remove/'''prune''' unused resources == | |||
[https://docs.docker.com/config/pruning/ Prune unused Docker objects] | |||
<ul> | |||
<li>Prune build cache (seems most effective) | |||
<syntaxhighlight lang='bash'> | |||
docker builder prune | |||
docker system df -v # Check Docker disk usage | |||
sudo du -sh /var/lib/docker | |||
</syntaxhighlight> | |||
<li>Prune containers | |||
<syntaxhighlight lang='bash'> | |||
docker container prune # remove all containers that are not in ''running'' status | |||
# Docker will ask for confirmation before deleting the containers | |||
docker container prune -f | |||
docker container rm -f $(docker container ls -aq) # remove even the running containers | |||
</syntaxhighlight> | |||
<li>Prune '''dangling images''': Dangling images are images that aren’t tagged and aren’t referenced by any container. Normal but unused/unreferenced images are kept and won't be deleted. See [[#%3Cnone%3E:%3Cnone%3E_images|<none>:<none>images]]. | |||
<syntaxhighlight lang='bash'> | |||
docker image prune # unused image layers | |||
</syntaxhighlight> | |||
<li>Remove all '''unused images''': If you want to remove all images that aren’t used by any existing containers, you can use the -a flag. It will give a warning saying: '''this will remove all images without at least one container associated to them'''. "Exited" container like "hello-world" will not be deleted. | |||
<syntaxhighlight lang='bash'> | |||
docker image prune -a | |||
</syntaxhighlight> | |||
Used images means anyone shown by '''docker ps -a'''. | |||
<li>Prune volumes | |||
<syntaxhighlight lang='bash'> | |||
docker volume ls | |||
docker volume prune # unused volumes by at least one container | |||
docker volume prune --filter 'label=demo' | |||
docker volume prune --filter 'label=demo' --filter 'label=test' | |||
</syntaxhighlight> | |||
<li>Prune networks | |||
<syntaxhighlight lang='bash'> | |||
docker network prune | |||
</syntaxhighlight> | |||
<li>Prune everything. | |||
<syntaxhighlight lang='bash'> | |||
docker system prune | |||
</syntaxhighlight> | |||
</ul> | |||
== Plugins == | |||
[https://www.cloudsavvyit.com/15066/how-to-manage-docker-engine-plugins/ How to Manage Docker Engine Plugins] | |||
== Misc == | == Misc == | ||
=== LXC (raw Linux containers) === | |||
* https://help.ubuntu.com/lts/serverguide/lxc.html | |||
* https://help.ubuntu.com/community/LXC | |||
* https://askubuntu.com/questions/293275/what-is-lxc-and-how-to-get-started | |||
* [https://www.cyberciti.biz/faq/how-to-install-lxd-container-hypervisor-on-ubuntu-16-04-lts-server/ Setup Linux Container with LXC on Ubuntu 16.04] | |||
* [http://en.community.dell.com/techcenter/os-applications/w/wiki/6950.lxc-containers-in-ubuntu-server-14-04-lts LXC containers in Ubuntu Server 14.04 LTS] | |||
* [https://blog.simos.info/trying-out-lxd-containers-on-our-ubuntu/ Trying out LXD containers on our Ubuntu] | |||
==== LXC vs Docker ==== | |||
* https://diveintodocker.com/blog/why-i-got-started-with-docker | |||
* https://unix.stackexchange.com/questions/254956/what-is-the-difference-between-docker-lxd-and-lxc and https://i.stack.imgur.com/a5Neb.png | |||
=== Vagrant vs Docker === | |||
* http://stackoverflow.com/questions/16647069/should-i-use-vagrant-or-docker-io-for-creating-an-isolated-environment | |||
* https://deliciousbrains.com/vagrant-docker-wordpress-development/ | |||
** Vagrant is easier to understand and is easier to get up and running but can be very resource intensive (in terms of RAM and space). | |||
** Docker’s architecture is harder to understand and can be harder to get up and running but is much faster, uses much less CPU and RAM and potentially uses much less space than Vagrant VM’s. | |||
* https://youtu.be/9QGkJvbLpRA?t=3m22s | |||
** Docker uses container technology while vagrant uses virtual machines. | |||
** If security is a concern, use vagrant and virtual machine | |||
** For speeding development and sharing, use Docker. | |||
** Most teams use both to run a smooth operation | |||
=== Date/Time zone === | |||
* List of time zone. [https://docs.diladele.com/docker/timezones.html Setting Local Time in Docker]; e.g. "America/New_York" or "US/Eastern". | |||
* https://stackoverflow.com/questions/22800624/will-docker-container-auto-sync-time-with-the-host-machine | |||
<syntaxhighlight lang='bash'> | |||
docker run --rm -t -i -v /etc/localtime:/etc/localtime:ro ubuntu date | |||
</syntaxhighlight> | |||
* https://serverfault.com/questions/683605/docker-container-time-timezone-will-not-reflect-changes | |||
=== Access the internet from the container === | === Access the internet from the container === | ||
Run the container with the '--net=host' option | Run the container with the '--net=host' option | ||
<syntaxhighlight lang='bash'> | |||
sudo docker run --net=host -it ubuntu /bin/bash | |||
</syntaxhighlight> | |||
=== How to transfer/copy an image to another host === | |||
[https://stackoverflow.com/a/23938978 How to copy Docker images from one host to another without using a repository] | |||
<syntaxhighlight lang='bash'> | |||
# Step 1: save the Docker image as a tar file: | |||
docker save -o <path for generated tar file> <image name> | |||
# Step 2: copy your image to a new system with regular file transfer tools such as cp or scp. | |||
# Step 3: After that you will have to load the image into Docker: | |||
docker load -i <path to image tar file> | |||
</syntaxhighlight> | |||
The tar file size is the same as what we get from 'docker image'. If we use the 'gzip' utility, it can reduce the file size (e.g 2.7GB to 1.1GB). | |||
Or https://stackoverflow.com/a/39716019 | |||
<syntaxhighlight lang='bash'> | |||
# Step 1: | |||
docker save docker-image-name | gzip > my-image.tar.gz | |||
# Step 3: | |||
docker load < my-image.tar.gz | |||
</syntaxhighlight> | |||
=== Where are Docker containers/images stored on the host: /var/lib/docker === | |||
* http://stackoverflow.com/questions/19234831/where-are-docker-images-stored-on-the-host-machine | |||
* https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-storage-driver | |||
* http://stackoverflow.com/questions/21016210/function-of-docker-directory-structure-in-var-lib-docker | |||
* [https://foxutech.com/manage-docker-images-local-disk/ How to Manage Docker images on local disk] | |||
* [https://www.howtogeek.com/devops/how-to-store-docker-images-and-containers-on-an-external-drive/ How to Store Docker Images and Containers on an External Drive] | |||
* [https://linuxiac.com/how-to-change-docker-data-directory/ How to Change Docker’s Default Data Directory] | |||
The default is '''/var/lib/docker'''. The location can be changed by modifying the file '''/etc/default/docker'''. Three options if we are tight on the disk space. | |||
'''1. Create a softlinks''' for the Docker data directory (/var/lib/docker) and for /var/lib/docker/tmp as described at [https://docs.docker.com/engine/reference/commandline/dockerd/#miscellaneous-options miscellaneous-options]. See [https://stackoverflow.com/a/40919928 this]. See [https://stackoverflow.com/a/40192707 for how to stop docker daemon] on different OS. | |||
<syntaxhighlight lang='bash'> | |||
sudo service docker stop # or sudo systemctl stop docker | |||
sudo mv /var/lib/docker /a/new/location | |||
sudo ln -s /a/new/location /var/lib/docker # Create a symbolic link | |||
sudo service docker start # or sudo systemctl start docker | |||
</syntaxhighlight> | |||
'''2. Change the default location to another place'''. For example, | |||
<syntaxhighlight lang='bash'> | |||
sudo nano /etc/default/docker | |||
# Add a line DOCKER_OPTS="-g /home/brb/Docker" | |||
</syntaxhighlight> | |||
Then after running ''sudo service docker.io restart'' and then a simple pull '''sudo docker pull rocker/r-base''' or '''sudo docker run --rm -ti rocker/r-base''' (the Dockerfile of r-base is available on [https://github.com/rocker-org/rocker/blob/master/r-base/Dockerfile github.com], '''--rm''' option means Automatically remove the container when it exits), we will see something like this: | |||
<syntaxhighlight lang='bash'> | |||
$ docker run --rm -ti rocker/r-base | |||
$ docker images | |||
$ docker -v | |||
Docker version 1.0.1, build 990021a | |||
$ docker -D info | grep Root | |||
Root Dir: /home/brb/Docker/aufs | |||
</syntaxhighlight> | |||
=== Consuming Docker system events === | |||
<syntaxhighlight lang='bash'> | |||
# Open a new terminal | |||
docker system events | |||
# This command is a blocking command. | |||
# Thus, when you execute it in your terminal session the according session is blocked. | |||
# Open another terminal | |||
docker container run --rm alpine echo "Hello World" | |||
</syntaxhighlight> | |||
=== Monitor tools === | |||
* [https://www.2daygeek.com/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux/# cTop – A Command-Line Tool For Container Monitoring And Management In Linux], [https://github.com/bcicen/ctop ctop] | |||
== [https://docs.docker.com/machine/overview/ Docker Machine] == | |||
Docker Machine is a tool that lets you | |||
* Install Docker Engine on virtual hosts. You can use Machine (a unified way) to create Docker hosts on your local Mac or Windows box, on your company network, in your data center, or on cloud providers like Azure, AWS, or Digital Ocean. See the comment on [https://sreeninet.wordpress.com/2015/05/31/docker-machine/ here]. | |||
* Provision and manage multiple remote Docker hosts | |||
* Provision Swarm clusters | |||
Docker machine is not installed in Linux when you install Docker. See the instruction on [https://docs.docker.com/machine/install-machine/ here] to install it. | |||
My feeling is if we just want to play Docker on a local Linux machine, we don't really need to use Docker Machine (it just make life more complicated). But if we are working on Mac/Windows or we want to work on clouds or test on VirtualBox, we shall use Docker machines. | |||
[https://youtu.be/OWhhOQAiGt0 Use Docker-machine to Create Docker Servers]. Compare the Docker images on the local machine (server 1) & a new host (server 2) created by '''docker-machine'''. Question: 1. how to tell we are in the host/machine environment? 2. how to exit the host environment after we use ''eval $() command? docker-machine stop MachineName. | |||
<pre> | |||
$ docker-machine help | |||
$ docker-machine create --driver=virtualbox test | |||
# Follow its hint on the output, issue the following command | |||
$ docker-machine env test | |||
# Follow its hint on the output, issue the following command | |||
$ eval$(docker-machine env test) # will configure the docker CLI to connect to this docker machine 'test' | |||
# This is equivalent to running 4 export commands on the command line | |||
$ docker-machine ls # Very useful | |||
$ docker-machine stop test | |||
$ docker-machine ip test | |||
$ docker-machine start test | |||
$ docker-machine rm test | |||
</pre> | |||
[https://youtu.be/rnaLmSkZfKk Play Docker Machine on Mac with Virtualbox]. Docker can be used to create a virtual machine just like Vagrant. | |||
<pre> | |||
$ docker-machine create -d virtualbox demo | |||
$ docker-machine ls | |||
# first way to access a Docker host | |||
$ docker-machine ssh demo | |||
docker@demo:~$ docker images # empty for now | |||
# second way to access | |||
$ docker-machine env demo | |||
$ eval $(docker-machine env demo) | |||
$ docker version | |||
</pre> | |||
[http://rancher.com/rancher-os/ RancherOS demo video] used the '''docker-machine''' command to pull and run the RancherOS. | |||
<pre> | |||
docker-machine create -d virtualbox --virtualbox-boot2docker-url https://releases.rancher.com/os/latest/rancheros.iso demo | |||
docker-machine ssh demo | |||
ps | |||
docker ps | |||
sudo system-docker ps | |||
sudo ros help | |||
sudo ros console list | |||
sudo ros console switch ubunu | |||
apt-get help | |||
</pre> | |||
== Package CLI Applications == | |||
[https://www.cloudsavvyit.com/15713/how-to-use-docker-to-package-cli-applications/ How to Use Docker to Package CLI Applications] | |||
== Stack == | |||
* https://www.composerize.com/ | |||
* [https://youtu.be/-ttZjGBkLL8 Export Docker Container Settings as Docker Compose Stack], [https://github.com/Red5d/docker-autocompose docker-autocompose] (only x86) | |||
== Docker app == | |||
Docker App is an experimental Docker feature which lets you build and publish application stacks consisting of multiple containers. It aims to let you share '''Docker Compose''' stacks with the same ease of use as regular Docker containers. | |||
[https://www.cloudsavvyit.com/10673/how-to-use-docker-app-to-containerise-an-entire-application-stack/ How to Use 'Docker App' to Containerise an Entire Application Stack] | |||
== Docker Swarm == | |||
* https://www.linux.com/learn/how-use-docker-machine-create-swarm-cluster | |||
* [https://www.howtoforge.com/tutorial/ubuntu-docker-swarm-cluster/ How Setup and Configure Docker Swarm Cluster on Ubuntu] | |||
* [https://www.cloudsavvyit.com/13049/what-is-docker-swarm-mode-and-when-should-you-use-it/ What is Docker Swarm Mode and When Should You Use It?] | |||
== Security == | |||
<ul> | |||
<li>[https://cloudberry.engineering/article/dockerfile-security-best-practices/ Docker Security Best Practices from the Dockerfile] | |||
<li>[https://www.cloudsavvyit.com/12631/how-to-secure-sensitive-data-with-docker-compose-secrets/ How to Secure Sensitive Data With Docker Compose Secrets] | |||
<li>[https://docs.docker.com/scout/ Docker Scout]. Docker Scout lets users secure their software supply chain and continuously observe and improve their security posture. Docker Scout is free for up to 3 repositories. | |||
<pre> | |||
docker login | |||
docker scout enroll ORG_NAME | |||
docker scout scan my-web-app:latest | |||
docker scout repo enable --org ORG_NAME ORG_NAME/scout-demo | |||
# Docker Scout analyzes the image you built most recently by default, | |||
# so there's no need to specify the name of the image in this case. | |||
</pre> | |||
<li>[https://www.portainer.io/blog/is-docker-ce-ready-for-production-how-portainer-bridges-the-gaps Is Docker-CE Ready for Production? How Portainer Bridges the Gaps] | |||
</ul> | |||
== [https://mobyproject.org/ Moby Project] == | |||
[https://www.infoworld.com/article/3193904/containers/what-is-dockers-moby-project.html What is Docker's Moby Project?] | |||
== Windows container == | |||
[https://stackoverflow.com/questions/45380972/how-can-i-run-a-docker-windows-container-on-osx How can I run a docker windows container on osx?] | |||
== When Not to Use Docker == | |||
[https://www.cloudsavvyit.com/15446/when-not-to-use-docker-cases-where-containers-dont-help/ When Not to Use Docker: Cases Where Containers Don’t Help] | |||
= Docker Compose <docker-compose.yaml> = | |||
Docker Compose can help us out as it allows us to specify a single file in which we can define our entire environment structure and run it with a single command (much like a Vagrantfile works). | |||
* Tabs are not allowed in a Docker Compose YAML file. You should use spaces for indentation instead. | |||
* https://docs.docker.com/compose/ (the example will give an error when "RUN pip install -r requirements.txt") | |||
*# app.py | |||
*# requirements.txt | |||
*# Dockerfile | |||
*# docker-compose.yml | |||
* Some top-level '''keys''': version, services, networks, volumes | |||
* [https://stackoverflow.com/questions/38507446/docker-dockerfile-vs-docker-compose-yml Dockerfile vs docker-compose.yml] | |||
* A simple example of running [https://www.tutorialspoint.com/docker/docker_compose.htm nginx & mysqsl] | |||
* [https://youtu.be/Qw9zlE3t8Ko Docker Compose in 12 Minutes] | |||
* https://deliciousbrains.com/vagrant-docker-wordpress-development/ | |||
* https://github.com/kristophjunge/docker-mediawiki | |||
* [https://www.howtoforge.com/tutorial/docker-guide-dockerizing-python-django-application/ Docker Guide: Dockerizing Python Django Application] (cannot follow) | |||
* Examples: | |||
** [https://github.com/haroldtreen/epub-press EpubPress] local server | |||
** Running [https://github.com/nextcloud/docker nextcloud], [https://blog.ouseful.info/2017/06/16/rolling-your-own-jupyter-and-rstudio-data-analysis-environment-around-apache-drill-using-docker-compose/ Jupyter and RStudio] | |||
** [https://github.com/dceoy/docker-rstudio-server Rstudio] | |||
* [https://readmedium.com/docker-compose-for-beginners-working-with-multiple-containers-ee0727aab687 Docker Compose For Beginners: Working With Multiple Containers] | |||
** image, container_name | |||
** image, container_name, environment | |||
** image, container_name, environment, volumes, ports | |||
== YAML validator == | |||
https://codebeautify.org/yaml-validator | |||
== Download binary == | |||
<ul> | |||
<li>https://github.com/docker/compose/releases for macOS (x86/arm), Linux (aarch64 or armv6 or armv7). | |||
<li>New instruction [https://docs.docker.com/compose/install/linux/ Install the Compose plugin]. In short, we will use '''docker compose''' (new) instead of "docker-compose" (deprecated) command. There is no need to install the original "docker-compose" tool. "docker-compose --version" | |||
</ul> | |||
== Difference of "docker compose" and "docker-compose" == | |||
* Docker-compose is the original '''Python-based''' command-line tool that was released in 2014. Docker compose is a newer '''Go-based''' command-line tool that is integrated into the Docker CLI platform and supports the compose-spec. Docker compose is meant to be a drop-in replacement for docker-compose, but it may have some behavior differences and new features. Docker compose is currently a tech preview, but it will eventually replace docker-compose as the recommended way to use Compose. | |||
* https://docs.docker.com/compose/migrate/. From July 2023 Compose V1 stopped receiving updates. It’s also no longer available in new releases of Docker Desktop. | |||
* [https://forums.docker.com/t/docker-compose-vs-docker-compose/137884 Docker-compose vs docker compose] | |||
* [https://stackoverflow.com/a/66516826 Difference between "docker compose" and "docker-compose"] | |||
== Simple examples == | |||
Create a file '''docker-compose.yml''' and run '''docker-compose up''' after creating the file. | |||
'''[https://hub.docker.com/_/hello-world hello-world]''': 9kB | |||
<pre> | |||
version: "3" | |||
services: | |||
hello: | |||
image: hello-world | |||
</pre> | |||
'''[https://hub.docker.com/_/alpine alpine]''': 7.73MB | |||
<pre> | |||
version: "3" | |||
services: | |||
server: | |||
image: alpine | |||
container_name: my_container | |||
command: sh -c "echo 'hello' && echo 'docker'" | |||
</pre> | |||
'''[https://hub.docker.com/_/nginx Nginx]''': 135MB | |||
<pre> | |||
mkdir src | |||
echo "Hello world!" > src/index.html | |||
</pre> | |||
<pre> | |||
version: "3" | |||
services: | |||
client: | |||
image: nginx | |||
ports: | |||
- 8000:80 | |||
volumes: | |||
- ./src:/usr/share/nginx/html | |||
</pre> | |||
== Composerize/convert a docker command into a docker compose file == | |||
* Copilot/ChatGPT/... | |||
* https://www.composerize.com/ | |||
* [https://ostechnix.com/convert-docker-run-commands-into-docker-compose-files/ Convert Docker Run Commands Into Docker-Compose Files] | |||
== An example from 'Fundamentals of Docker' == | |||
<syntaxhighlight lang='bash'> | |||
git clone https://github.com/fundamentalsofdocker/labs.git | |||
cd labs/ch08 | |||
docker-compose up | |||
# Open http://localhost:3000/pet | |||
</syntaxhighlight> | |||
The images do not show up:( The terminal shows what has happened under the hood. So the problem is the http links for images do not exist. | |||
We can also run the application in the background | |||
<syntaxhighlight lang='bash'> | |||
docker-compose up -d | |||
</syntaxhighlight> | |||
To stop and clean up the application, [https://www.thegeekstuff.com/2016/04/docker-compose-up-stop-rm/ Howto use docker-compose to Start, Stop, Remove Docker Containers] | |||
<syntaxhighlight lang='bash'> | |||
docker-compose down # Stop and remove containers, networks, images, and unnamed volumes | |||
# defined in the docker-compose.yml flie | |||
# OR | |||
docker-compose down -v # similar to above but remove named volumes defined in yml file | |||
# OR | |||
docker-compose stop && docker-compose rm -f | |||
docker-compose rm -v | |||
</syntaxhighlight> | |||
If we also want to remove the volume for the database | |||
<syntaxhighlight lang='bash'> | |||
docker volume rm ch08_pets-data | |||
</syntaxhighlight> | |||
== An example from "How to Setup NGINX as Reverse Proxy Using Docker" == | |||
See [[#Nginx_reverse_proxy|here]]. Only nginx is used. | |||
== An example from "Docker Deep Dive" (flask + redis) == | |||
'''Note''' that on [https://docs.docker.com/compose/gettingstarted/#step-7-update-the-application Get started with Docker Compose] it mounts the current directory to ''/code'' inside the container. So after we modify ''app.py'', we don't need to copy it to the container. | |||
Another one [https://takacsmark.com/docker-compose-tutorial-beginners-by-example-basics/ Docker compose tutorial for beginners by example] | |||
<syntaxhighlight lang='bash'> | |||
$ git clone https://github.com/nigelpoulton/counter-app.git | |||
$ cd counter-app | |||
$ ls | |||
app.py docker-compose.yml Dockerfile README.md requirements.txt | |||
$ cat requirements.txt | |||
flask | |||
$ cat Dockerfile | |||
FROM python:3.4-alpine | |||
ADD . /code | |||
WORKDIR /code | |||
RUN pip install -r requirements.txt | |||
CMD ["python", "app.py"] | |||
$ cat docker-compose.yml | |||
version: "3.5" | |||
services: | |||
web-fe: | |||
build: . | |||
command: python app.py | |||
ports: | |||
- target: 5000 | |||
published: 5000 | |||
networks: | |||
- counter-net | |||
volumes: | |||
- type: volume | |||
source: counter-vol | |||
target: /code | |||
redis: | |||
image: "redis:alpine" | |||
networks: | |||
counter-net: | |||
networks: | |||
counter-net: | |||
volumes: | |||
counter-vol: | |||
$ docker-compose up & | |||
$ docker container ls | |||
$ docker network ls | |||
NETWORK ID NAME DRIVER SCOPE | |||
2acef6dabde6 bridge bridge local | |||
a2d42bc482ff counterapp_counter-net bridge local | |||
e1e093b64282 host host local | |||
7ecd0a6a9ebd none null local | |||
# Open the browser http://localhost:5000 | |||
$ docker-compose ps | |||
Name Command State Ports | |||
------------------------------------------------------------------------------------- | |||
counterapp_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp | |||
counterapp_web-fe_1 python app.py Up 0.0.0.0:5000->5000/tcp | |||
$ docker-compose stop | |||
$ docker-compose ps | |||
# We can see stopping a Compose app does not delete the application | |||
$ docker container ls -a | |||
$ docker-compose rm # delete a stopped Compose app | |||
# images, volumes and source code remain | |||
$ docker-compose restart | |||
# If you made changes to your Compose app since stopping, | |||
# these changes will not appear in the restarted app. | |||
# You need to re-deploy the app to get the changes. | |||
$ docker-compose ps | |||
$ docker-compose down # stop and delete the app | |||
# images, volumes and source code remain | |||
$ docker-compose down --volumes # remove the data volume used by the Redis container | |||
$ docker-compose up -d | |||
$ docker volume ls | |||
$ docker-compose | |||
# We can make changes to files in the volume, from the host side, | |||
# and have them reflected immediately in the app. | |||
$ nano app.py # do some changes | |||
$ docker volume inspect counterapp_counter-vol | grep Mount | |||
$ sudo cp app.py \ | |||
/var/lib/docker/volumes/counterapp_counter-vol/_data/app.py | |||
# Our changes should be reflected | |||
$ docker-compose --help | |||
</syntaxhighlight> | |||
== Create Compose Files From Running Docker Containers == | |||
[https://www.makeuseof.com/create-docker-compose-files-from-running-docker-containers/ How to Automatically Create Compose Files From Running Docker Containers] | |||
== Docker-Compose persistent data MySQL == | |||
https://stackoverflow.com/questions/39175194/docker-compose-persistent-data-mysql | |||
== Connect to Docker daemon over ssh using docker-compose == | |||
[https://medium.com/@sujaypillai/dockertips-connect-to-docker-daemon-over-ssh-using-docker-compose-f4b189dd8951 #DockerTips: Connect to Docker daemon over ssh using docker-compose] | |||
== Dockerfile + docker-compose == | |||
[https://stackoverflow.com/a/29487120 Docker Compose vs. Dockerfile - which is better?] | |||
The Compose file describes the container in its running state, leaving the details on how to build the container to Dockerfiles. | |||
== How to deploy on remote Docker hosts with docker-compose == | |||
[https://www.docker.com/blog/how-to-deploy-on-remote-docker-hosts-with-docker-compose/ How to deploy on remote Docker hosts with docker-compose] | |||
== logs == | |||
<pre> | |||
docker-compose logs -f | |||
# Ctrl + c | |||
</pre> | |||
= GUI/TUI interface manager = | |||
[https://www.tecmint.com/docker-tools/ 11 Must-Have Docker Tools To Simplify Your Workflow]: | |||
* LazyDocker - Command-Line Docker Management | |||
* Dive - Analyze Docker Image Layers | |||
* Portainer – Simplify Docker Management | |||
* Watchtower – Automated Docker Container Updates | |||
* Dockly – Interactive Docker Management Tool | |||
* Docker Compose – Define and Run Multi-Container Apps | |||
* Dry – Real-time Docker Container Monitoring | |||
* Sliplane – Cloud-Based Docker Management Tool | |||
* Orbstack (closed source) - manage VM and Docker containers | |||
* Docker Desktop – A Graphical Interface for Docker | |||
* Visual Studio Code (VS Code) Docker Extension | |||
== [https://github.com/moncho/dry Dry] == | |||
[https://www.2daygeek.com/dry-an-interactive-cli-manager-for-docker-containers/ Dry – An Interactive CLI Manager For Docker Containers]. The TUI is built on top of [https://github.com/gizak/termui termui]; a cross-platform, easy-to-compile, and fully-customizable terminal dashboard. It is inspired by [https://github.com/yaronn/blessed-contrib blessed-contrib], but purely in Go. | |||
== LazyDocker (TUI) == | |||
* [https://github.com/jesseduffield/lazydocker Github] | |||
* [https://www.linuxuprising.com/2019/07/lazydocker-new-docker-and-docker.html?m=1 LazyDocker: New Docker And Docker Compose Terminal UI] | |||
* It works on ARM devices too. | |||
* Video by [https://youtu.be/xb99lgO5Mw0?t=1083 Awesome open source] | |||
== Dockly (TUI) == | |||
[https://www.ostechnix.com/dockly-manage-docker-containers-from-terminal/ Dockly – Manage Docker Containers From Terminal] | |||
== DockStation == | |||
It is not open source. It works with remote Docker containers. | |||
* [https://github.com/DockStation/dockstation DockStation] | |||
* [https://www.upnxtblog.com/index.php/2018/01/17/top-6-gui-tools-for-managing-docker-environments/ TOP 6 GUI tools for managing Docker environments] 2018 | |||
* [https://www.how2shout.com/tools/4-best-docker-gui-tools-to-manage-containers-graphically.html 4 Best Docker GUI tools to manage containers graphically] 2019 | |||
== DockSTARTer: get started with home server apps running in Docker == | |||
* https://dockstarter.com/ | |||
* [https://www.makeuseof.com/tag/setup-linux-media-server/ How to Set Up a Linux Media Server in Under One Hour] | |||
== [https://portainer.io/ Portainer]* (nice) == | |||
<ul> | |||
<li>Username: admin. Password: at least 12 characters long</li> | |||
<li>[https://github.com/portainer/portainer/issues/5406 Hardware minimum requirements] 100MB RAM. That's why 1GB ram of Raspberry Pi works fine. | |||
<li>[https://docs.portainer.io/start/install-ce/server/docker Install CE], [https://docs.portainer.io/ Documentation] | |||
<pre> | |||
docker volume create portainer_data | |||
docker run -d -p 8000:8000 -p 9443:9443 \ | |||
--name portainer \ | |||
--restart=always \ | |||
-v /var/run/docker.sock:/var/run/docker.sock \ | |||
-v portainer_data:/data portainer/portainer-ce:latest | |||
</pre> | |||
By default, Portainer Server will expose the UI over port 9443 and expose a TCP tunnel server over port 8000. The latter is optional and is only required if you plan to use the Edge compute features with Edge agents. | |||
</li> | |||
<li>Access https://localhost:9443 </li> | |||
<li>Portainer itself is a docker application. </li> | |||
<li>[https://docs.portainer.io/advanced/reset-admin Reset the admin user's password].</li> | |||
<li>[https://youtu.be/M365jgJ0O2E How to Update Portainer Fast, Simple, and Easy Guide]. docker stop + docker rm + docker rmi + docker run. | |||
</li> | |||
<li>[https://dbtechreviews.com/2020/08/update-portainer-to-version-2-0-super-easy/ Update Portainer to Version 2.0 – Super Easy!]. When the first time accessing http://localhost:9000, you need to create a password (at least <s>8</s> 12 characters long) for the default user "admin". | |||
{{Pre}} | |||
$ docker volume create portainer_data | |||
$ docker run -d -p 9000:9000 -p 8000:8000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce | |||
</pre> | |||
* [https://youtu.be/2oi4IQF7VnE Raspberry Pi Home Server Episode 5: Remote Access with NGINX Proxy Manager] | |||
* [https://youtu.be/ji0kgXhXR6g Raspberry Pi Home Server Episode 8: BitWardenRS - Password Manager with Remote Access] (video) | |||
* [https://dbtechreviews.com/2020/07/install-nextcloud-on-a-raspberry-pi-4-with-openmediavault-and-docker/ Install NextCloud on a Raspberry Pi 4 with OpenMediaVault and Docker] | |||
</li> | |||
<li>Update from 2.11 to 2.13 (The password must be at least 12 characters long) | |||
<ul> | |||
<li>Step 1: [https://dbtechreviews.com/2021/08/how-to-update-portainer-to-the-newest-version/ How to Update Portainer to the Newest Version] | |||
<pre> | <pre> | ||
sudo docker run -- | sudo docker stop portainer && sudo docker rm portainer | ||
docker pull portainer/portainer-ce:latest | |||
</pre> | |||
</li> | |||
<li>Step 2: [https://docs.portainer.io/start/upgrade/docker Upgrading on Docker Standalone] | |||
{{Pre}} | |||
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest | |||
</pre> | |||
</li> | |||
</ul> | |||
</ul> | |||
* [https://github.com/portainer/portainer-docs/issues/91 Why port 8000 is needed to be published?], [https://forums.portainer.io/t/what-port-8000-used-for-do-i-need-to-expose-it/210 What port 8000 used for? Do I need to expose it?] | |||
* [https://dzone.com/articles/a-comparison-of-docker-guis A Comparison of Docker GUIs]. A username/password is required to access the page unless we use the '''--no-auth''' option; see [https://portainer.readthedocs.io/en/stable/configuration.html Configuration]. | |||
* [https://www.howtoforge.com/tutorial/ubuntu-docker-portainer/ How to Manage Docker Containers using Portainer on Ubuntu 16.04]. Go to Local. It will show the status of all local stacks, containers, volumes and images. Very Cool! | |||
* [https://www.linuxtechi.com/monitor-manage-docker-containers-portainer-part1/ Monitor and Manage Docker Containers with Portainer.io (GUI tool) – Part-1] 2019 | |||
* [https://www.cloudsavvyit.com/8911/how-to-get-started-with-portainer-a-web-ui-for-docker/ How to Get Started With Portainer, a Web UI for Docker] | |||
* [https://www.linuxtechi.com/monitor-manage-docker-containers-portainer-io-part-2/ Monitor and Manage Docker Containers with Portainer.io (GUI tool) – Part-2] | |||
* [https://collabnix.com/portainer-vs-rancher/ Portainer Vs Rancher] | |||
* [https://youtu.be/XYcKmPi4McA How-to: Deploy Portainer on MicroK8s] (video) | |||
* [https://www.portainer.io/blog/from-zero-to-production-with-fedora-coreos-portainer-and-wordpress-in-7-easy-steps From Zero to Production with Fedora CoreOS, Portainer, and WordPress in 7 Easy Steps]. Virtualbox was used | |||
=== IP address 0.0.0.0 === | |||
[https://www.reddit.com/r/docker/comments/rkq7o8/comment/hpbb13k/ How to setup ip address in portainer to access containers?] </BR> | |||
(Left hand side) Administration -> Environment-related -> Environments > local (or whatever your environment is named) -> '''Public ip'''. | |||
=== Templates === | |||
* [https://dbtechreviews.com/2020/09/using-application-templates-in-portainer-2-0/ Using Application Templates in Portainer 2.0] | |||
* [https://youtu.be/BwgKd6LohQo Install 80+ Docker Images In Seconds Using This Portainer App Template] (video) | |||
* [https://www.reddit.com/r/portainer/comments/v3uyo3/best_and_most_uptodate_portainer_app_template_for/?utm_source=share&utm_medium=web2x&context=3 Best and most up-to-date Portainer app template for selfhosting?] 2022-06-03 | |||
** [https://github.com/mycroftwilde/portainer_templates mycroftwilde] | |||
* [https://youtu.be/BwgKd6LohQo Install 80+ Docker Images In Seconds Using This Portainer App Template] (video, 2020) | |||
** Default on my Portainer 2.0.1 (see logs for version number) https://raw.githubusercontent.com/portainer/templates/master/templates-2.0.json | |||
** https://raw.githubusercontent.com/SelfhostedPro/selfhosted_templates/portainer-2.0/Template/template.json (working), [https://github.com/SelfhostedPro/selfhosted_templates Github] | |||
** https://raw.githubusercontent.com/nashosted/self-hosted-template/master/template.json (working) | |||
** Alternative: [https://github.com/Taisun-Docker/taisun taisun] | |||
== Yacht == | |||
* https://yacht.sh/Installation/yacht/ | |||
* Yacht's [https://yacht.sh/docs/Pages/Dashboard Dashboard] page shows the resources used by each docker application (it seems Portainer can't) | |||
* [https://youtu.be/KstIS5DstTE Yacht Installed on Docker - Portainer Alternative] (video) | |||
* [https://youtu.be/c4rKWrH88F0?t=166 What's on my Home Server? MUST HAVE Services] (video) | |||
== cockpit-docker == | |||
* [https://www.hostwinds.com/guide/installing-and-using-cockpit-docker-linux-vps/ Installing And Using Cockpit-Docker] | |||
* The default port is 9090. | |||
* Not useful for manager docker containers. | |||
<pre> | |||
sudo apt-get -y install cockpit-docker | |||
sudo systemctl restart cockpit | |||
</pre> | |||
== [https://github.com/crosbymichael/dockerui DockerUI] (Deprecated, Development continues at Portainer) == | |||
https://github.com/kevana/ui-for-docker. A quick start: | |||
# Run: <syntaxhighlight lang='bash'> | |||
docker run -d -p 9000:9000 --privileged \ | |||
-v /var/run/docker.sock:/var/run/docker.sock uifd/ui-for-docker | |||
</syntaxhighlight> where '''-v''' means to bind mount a volume. | |||
# Open your browser to http://<dockerd host ip>:9000 | |||
Note: Anyone in the local network can access the website without any authentication. | |||
== Rancher == | |||
* https://rancher.com/quick-start/. The doc above is not good enough to follow. Search Google for tutorial or get started guide including screenshots. | |||
* [https://www.howtoforge.com/tutorial/ubuntu-rancher-docker-container-manager/ How to Manage Docker Containers with Rancher on Ubuntu 16.04] | |||
* [https://hackernoon.com/creating-a-scalable-application-using-docker-rancher-rancheros-cattle-5feb83a3e743 Creating A Scalable Application Using Docker + Rancher + RancherOs + Cattle] | |||
* Initial setup video https://youtu.be/1EMW1y7529Y | |||
* Training from Rancher Labs https://youtu.be/8K14A_CZFdI. It seems Rancher is complicated but powerful. The whole operation is like Amazon Cloud. | |||
* [https://gist.github.com/lmmendes/fbed32a452cf02d2a1095658795cb3d2 Running Rancher locally (with two hosts) using MacOS Docker and VirtualBox] | |||
* To allow UDP port | |||
<syntaxhighlight lang='bash'> | |||
$ sudo apt-get install ufw | |||
$ sudo ufw allow 4500/udp | |||
$ sudo ufw allow 500/udp | |||
</syntaxhighlight> | |||
* discoposse.com | |||
** [http://discoposse.com/2015/11/08/rancher-part-1-installing-rancher-and-setting-access-control/ Part 1] Installing Rancher and Setting Access Control | |||
** [http://discoposse.com/2015/11/09/rancher-part-2-adding-a-docker-host-to-rancher/ Part 2] Adding a Docker Host to Rancher | |||
** [http://discoposse.com/2015/11/12/rancher-part-3-adding-the-dockerhub-to-our-rancher-registry/ Part 3] Adding the DockerHub to our Rancher Registry | |||
** [http://discoposse.com/2015/11/13/rancher-part-4-using-the-catalog-example-with-glusterfs/ Part 4] Using the Catalog Example with GlusterFS | |||
== [https://github.com/tobegit3hub/seagull Seagull] == | |||
https://youtu.be/TuT5gb8oRw8 | |||
<pre> | |||
docker run -d -p 127.0.0.1:10086:10086 -v /var/run/docker.sock:/var/run/docker.sock tobegit3hub/seagull | |||
</pre> | |||
The only issue is there is no username/password to protect other people to access the web GUI. The solution of binding to localhost to restrict the access does not work for remote administration. | |||
That is, the tool is suitable for home use. | |||
== [https://kitematic.com/ Kitematic] (Mac, Windows and Ubuntu) == | |||
Owned by Docker. Available for Mac OS X 10.8+ and Windows 7+ (64-bit) and Ubuntu. https://github.com/docker/kitematic/releases/ | |||
Run containers through a simple, yet powerful graphical user interface. | |||
It can not connect to remote docker machines. | |||
A [https://www.r-bloggers.com/share-your-shiny-apps-with-docker-and-kitematic/ Share your Shiny Apps with Docker and Kitematic!] | |||
== [https://github.com/shipyard/shipyard Shipyard] (retired) == | |||
* [https://www.sumologic.com/blog/code/managing-containers-docker-shipyard/ Managing Containers with Docker Shipyard] | |||
* Three alternatives: | |||
** [http://rancher.com/ Rancher] | |||
** [https://github.com/kevana/ui-for-docker Docker UI] | |||
** [https://portainer.io/ Portainer] | |||
== VS Code == | |||
* [https://youtu.be/i7ABlHngi1Q Docker For Beginners: From Docker Desktop to Deployment] | |||
* [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers Visual Studio Code Remote - Containers] | |||
* [https://www.docker.com/blog/how-to-develop-inside-a-container-using-visual-studio-code-remote-containers/ How to Develop Inside a Container Using Visual Studio Code Remote Containers] | |||
* [https://www.cloudsavvyit.com/12837/how-to-edit-code-in-docker-containers-with-visual-studio-code/ How to Edit Code in Docker Containers With Visual Studio Code] | |||
= Applications = | |||
[[Docker_Applications|Docker Applications]] | |||
== CasaOS == | |||
Every app is based on a Docker application | |||
* https://casaos.io/ | |||
** https://wiki.casaos.io/en/get-started. It also supports arm64, armv7. | |||
** http://casaos.local | |||
** https://docs.zimaboard.com/docs/index.html Default login casaos/casaos. For a new user, the password has to be at least 5 characters. | |||
* [https://youtu.be/FwJByjTdKks Revisiting CasaOS After A Few Months] 2022-6-14 | |||
* [https://youtu.be/w44CypRO5l4 Home Servers Have NEVER Been This Easy: CasaOS + ZimaBoard] 4/23/2023 | |||
* [https://github.com/xp1ode/new/blob/506bf428592a9604c4d8ca4cc6d0426280805b48/Screenshot%20from%202022-11-15%2006-12-55.png List of apps] 2022/11 | |||
= Orchestrator = | |||
== [https://www.docker.com/kubernetes Kubernete] == | |||
* [https://www.zdnet.com/article/kubernetes-dropping-docker-is-not-that-big-of-a-deal/ Kubernetes dropping Docker is not that big of a deal] | |||
* [https://www.freecodecamp.org/news/kubernetes-vs-docker-whats-the-difference-explained-with-examples/ Kubernetes VS Docker: What's the Difference? Explained With Examples] | |||
* [https://kodekloud.com/p/kubernetes-for-the-absolute-beginners-hands-on Kubernetes For The Absolute Beginner - Hands On] from kodekloud.com | |||
* [http://docker-k8s-lab.readthedocs.io/en/latest/ Docker Kubernetes Lab Handbook] by Peng Xiao. The github page is on https://github.com/xiaopeng163/docker-k8s-lab. | |||
* [https://youtu.be/2G-A6Knjrvo Introducing Kubernetes] by Marc Sluiter. Kubenetes can be used to schedule, run and manage containers in a cluster of virtual or physical machines. | |||
** Starting by Google in 2014 | |||
** Pods: smallest unit of deployment. small group of tightly coupled containers. share network and data volumes. routable IP address. multiple pods per node. | |||
* [https://youtu.be/6xJwQgDnMFE Create a 2-node Kubernetes cluster in 10 minutes] | |||
** [https://github.com/kubernetes/dashboard Kubernetes Dashboard] | |||
* [https://youtu.be/_vHTaIJm9uY Kubernetes Webinar Series - Getting Started with Kubernetes] | |||
** https://thenewstack.io/tutorial-configuring-ultimate-development-environment-kubernetes/ | |||
** https://github.com/janakiramm/Kubernetes-dev-env | |||
* [https://www.oreilly.com/ideas/how-to-manage-docker-containers-in-kubernetes-with-java Deploying Java Applications with Docker and Kubernetes] | |||
* [https://blog.alexellis.io/docker-for-mac-with-kubernetes/ First impressions: Docker for Mac with Kubernetes] | |||
* [https://github.com/kubernetes/minikube Minikube]: run Kubernetes locally | |||
** [https://www.howtoforge.com/tutorial/how-to-install-kubernetes-with-minikube-on-ubuntu-1804-lts/ How to Install Kubernetes with Minikube on Ubuntu 18.04 LTS] | |||
** [https://opensource.com/article/19/12/kubernetes-namespaces Kubernetes namespaces for beginners]. You need to have Minikube, Helm, and the kubectl command line installed. | |||
* [https://www.biorxiv.org/content/10.1101/488643v2?rss=1 Galaxy-Kubernetes integration: scaling bioinformatics workflows in the cloud] Moreno et al 2019 | |||
* [https://seandavi.github.io/2019/03/helm-on-google-kubernetes-engine/ Helm on Google Kubernetes Engine] by Sean Davis | |||
* [https://microk8s.io/ MicroK8s] | |||
** [https://github.com/CanonicalLtd/multipass Multipass] | |||
** [https://itnext.io/microk8s-on-macos-98f1de3aa63e MicroK8s on MacOS] | |||
* [https://www.howtoforge.com/resource-limits-in-kuberenetes/ Resource Limits in Kuberenetes] | |||
* [https://github.com/seandavi/Orchestra?s=09 Orchestra] and [https://eurobioc2020.bioconductor.org/workshops?s=09 European Bioconductor Meeting 2020] | |||
* [https://www.cloudsavvyit.com/9783/kubernetes-alternatives-to-docker-commands/ Kubernetes Alternatives to Docker Commands] | |||
* [https://www.makeuseof.com/what-is-kubernetes/ What Is Kubernetes and What Is It Used For?] | |||
== Kubernete vs Docker swarm == | |||
* https://platform9.com/blog/kubernetes-docker-swarm-compared/ | |||
* [https://www.ithome.com.tw/news/124290 DigitalOcean容器應用開發大調查:近半數開發者已採用] | |||
== k3s: Lightweight Kubernetes == | |||
[https://opensource.com/article/20/3/kubernetes-raspberry-pi-k3s Run Kubernetes on a Raspberry Pi with k3s] | |||
== Kubeflow == | |||
* [https://www.kubeflow.org/ The Machine Learning Toolkit for Kubernetes] | |||
= Other containers = | |||
== [https://sylabs.io/ Singularity] and HPC systems == | |||
* Old URL at [http://singularity.lbl.gov/ singularity.lbl.gov] | |||
* Singularity enables users to have full control of their environment; Singularity containers let users run applications in a Linux environment of their choosing. No 'sudo' is needed in general unless you want to build a container from a recipe. | |||
* Containers are more like an executable file for you to use | |||
* Containers are stored under the current location. It does not have a centre location (like /etc/default/docker if we use docker) to store images. | |||
* Can convert Docker containers to Singularity and run containers directly from Docker Hub | |||
* These bind points cannot be created unless the path already exists within the container. To ensure access to these storage spaces and remedy bind point errors, create these directories in the %post section of your Bootstrap file. | |||
* [https://singularity-hub.org/ Singularity Hub] | |||
Ref: | |||
* [https://hpc.nih.gov/apps/singularity.html Singularity] at NIH/Biowulf. It needs to run 'module load singularity' first to load related commands. | |||
* NIH-HPC | |||
** [https://singularity-tutorial.github.io/ Tutorial] and its [https://github.com/NIH-HPC/Singularity-Tutorial Github] source ('''valuable''') | |||
** [https://github.com/nih-byob/presentations/tree/master/2019/01_bioinformatics_tips Bioinformatics advice I wish I learned 10 years ago] | |||
** [https://github.com/NIH-HPC/singularity-def-files NIH HPC Singularity Definition Files] | |||
* [https://tin6150.github.io/psg/blogger_container_hpc.html DOCKER VS SINGULARITY VS SHIFTER VS UGE CONTAINER EDITION] | |||
* [https://github.com/data61/gossamer xenome] case where the build instruction is good for Ubuntu 16.04. If we try to build under Ubuntu 14.04 (tested using docker run), we will get an error message '' CMake 3.1 or higher is required. You are running version 2.8.12.2''. | |||
* https://github.com/NIH-HPC/singularity-examples/blob/master/rnaseq/Singularity.rnaseq | |||
'''Comparison of docker and singularity commands:''' | |||
{| class="wikitable" | |||
|- | |||
! [https://docs.docker.com/edge/engine/reference/commandline/docker/ docker] !! [http://singularity.lbl.gov/user-guide singularity] | |||
|- | |||
| $ docker pull ubuntu:latest <br/>$ docker pull broadinstitute/gatk3:3.8-0 || $ singularity pull docker://ubuntu:latest<br/>$ singularity pull docker://broadinstitute/gatk3:3.8-0 | |||
|- | |||
| $ docker build -t myname/myapp:latest -f Dockerfile || $ singularity build myapp.sif myapp.def | |||
|- | |||
| $ docker shell (not exist) || $ singularity shell docker://broadinstitute/gatk3-3.8-0<br/> $ singularity shell gatk3-3.8-0.img<br/> > ls # the default location depends on the host system<br/> | |||
> ls /usr # this is from the container <br/><br/>$ singularity shell --bind ~/Downloads:/mnt XXX.img<br/>$ singularity shell docker://ubuntu:latest<br/># container is ephemeral | |||
|- | |||
| $ docker run --name test -it ubuntu date <br/><br/># <span style="color: red">The next example is similar to 'singularity exec'</span><br/>$ docker run --rm -i -t \<br/> -v $(pwd):/usr/my_data \<br/> broadinstitute/gatk3:3.8-0 \<br/> bash /usr/my_data/myscript.sh || $ singularity run gatk3-3.8-0.img date | |||
|- | |||
| $ docker run --name ubuntu_bash --rm -i -t ubuntu bash<br/>$ docker exec -d ubuntu_bash touch /tmp/execWorks || # <span style="color: red">Most useful</span><br>$ singularity exec gatk3-3.8-0.img java -version <br/>$ singularity exec xxx.img cat /etc/*release<br>$ singularity exec docker://rocker/tidyverse:latest R <br/>$ singularity exec docker://rocker/tidyverse:latest Rscript myScript.R<br/> | |||
|} | |||
=== Cache === | |||
When we run ''singularity exec docker://rocker/tidyverse:latest R'', it will save something in the cache in our system. | |||
It seems to be OK after I manually delete the directory $HOME/.singularity (tested in Biowulf). | |||
=== RStudio === | |||
* [https://rviews.rstudio.com/2017/03/29/r-and-singularity/ R and Singularity] by Bryan Lewis | |||
* [https://archive.sylabs.io/2018/10/rstudio-ide-and-server/ RStudio – IDE and Server powered by Singularity] by Jason Stover | |||
* https://github.com/nickjer/singularity-rstudio and https://github.com/nickjer/singularity-r | |||
* https://www.rocker-project.org/use/singularity/. It also includes how to run a SLURM job script. | |||
* https://njstem.wordpress.com/2018/08/02/r-script-seurat-with-a-singularity-container-using-slurm/ | |||
* https://journal.r-project.org/archive/2017/RJ-2017-065/RJ-2017-065.pdf | |||
<syntaxhighlight lang='bash'> | |||
$ singularity exec docker://rocker/tidyverse:latest R | |||
$ singularity exec docker://rocker/tidyverse:latest Rscript myScript.R | |||
</syntaxhighlight> | |||
== [https://github.com/scanon/shifter Shifter] == | |||
= [https://conda.io/docs/ Conda] = | |||
* [https://www.quora.com/What-is-the-difference-between-conda-and-Docker What is the difference between conda and Docker?] | |||
== Anaconda == | |||
* [https://hub.docker.com/r/continuumio/anaconda3 Getting started with Anaconda & Docker] using continuumio/anaconda3 | |||
== Bioconda == | |||
* https://bioconda.github.io/ | |||
* https://anaconda.org/bioconda | |||
* https://www.biorxiv.org/content/early/2017/10/27/207092 | |||
* https://zhuanlan.zhihu.com/p/25085567 | |||
* [http://slides.com/olexschoen/snakemake-bioconda#/ Snakemake: Reproducible and scalable data analysis] | |||
* https://chrisconlan.com/installing-r-python-anaconda-biologists/. Note that the R version is 3.4.2 but the latest one should be 3.4.3. | |||
* [https://davetang.github.io/reproducible_bioinformatics/conda.html Introduction to Conda] Dave Tang | |||
Using docker to install conda (https://conda.io/docs/user-guide/tutorials/index.html) | |||
<syntaxhighlight lang='bash'> | |||
$ docker run -t -i --name test --net=host ubuntu bash | |||
# apt-get update | |||
# apt-get install -y wget bzip2 python | |||
# wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh | |||
# wget https://repo.continuum.io/archive/Anaconda2-5.1.0-Linux-x86_64.sh | |||
# bash Miniconda2-latest-Linux-x86_64.sh | |||
# bash Anaconda2-5.1.0-Linux-x86_64.sh | |||
# exit | |||
$ docker start test | |||
$ docker exec -i -t test bash | |||
# conda list # WORKS! | |||
# conda config --add channels r | |||
# conda config --add channels defaults | |||
# conda config --add channels conda-forge | |||
# conda config --add channels bioconda | |||
# conda install bwa (Segmentation fault. Core dumped) | |||
# which bwa | |||
/root/anaconda2/bin/bwa | |||
# conda install r (Only get 3.4.2 but the latest is 3.4.3.) | |||
# conda install bowtie | |||
# bowtie --version | |||
# conda install gatk (https://bioconda.github.io/recipes/gatk/README.html) | |||
(Due to license restrictions, this recipe cannot distribute and install GATK directly) | |||
(R is downgraded to 3.2.2:( ) | |||
(Segmentation fault. Core dumped) | |||
# exit | |||
# docker stop test | |||
# docker rm test | |||
</syntaxhighlight> | |||
Get miniconda image instead of using a Ubuntu image | |||
<syntaxhighlight lang='bash'> | |||
$ docker pull continuumio/miniconda | |||
$ docker run -i -t continuumio/miniconda /bin/bash | |||
# conda install r (get 3.4.2) | |||
# conda config --add channels bioconda | |||
# conda install bwa (OK, no error) | |||
# conda install gatk (R was downgraded to 3.2.2, install openjdk 8.0.121) | |||
# which gatk | |||
/opt/conda/bin/gatk | |||
# gatk -h | |||
GATK jar file not found. Have you run "gatk-register"? | |||
</syntaxhighlight> | |||
Issues: | |||
* R version is not up to date | |||
* '''So the problem is installing GATK requires an installation of R and the current R was affected.''' | |||
= [https://coreos.com/ CoreOS] = | |||
* Redhat has acquired CoreOS 1/31/2018. | |||
* [https://coreos.com/os/eol/ End-of-life announcement for CoreOS Container Linux] | |||
== Installation == | |||
* [https://coreos.com/os/docs/latest/quickstart.html Quick Start] | |||
* [https://youtu.be/vy6hWsOuCh8 Installing CoreOS on a bare metal or virtual machine] from the user Format C: in youtube | |||
* [https://youtu.be/M0TYqVDnNAI Assigning Static IP to a CoreOS Server] | |||
* [https://www.youtube.com/watch?v=6LOiIH8s3xM Mounting storage in CoreOS] | |||
* [https://www.youtube.com/watch?v=InLmXWgPzBs Installing, Deploying Docker containers with Fig / Docker Compose on boot2docker or CoreOS] | |||
* [https://www.youtube.com/watch?v=S9kfP2WYV_I Running a Private Docker Registry Container] | |||
We first boot a liveCD from any OS (CentOS works but Ubuntu 16.04 gave errors). In Virtualbox, we choose 'Red Hat' if we use CentOS. | |||
Once the VM is created. We go to the settings. Create a bridged network or host-only network first (even we can get files from the host without creating a host-only network). Storage: choose CentOS-7. | |||
# Get the [https://coreos.com/os/docs/latest/installing-to-disk.html install script] from Github and create <'''coreos_install.sh'''> and chmod +x | |||
# create <'''cloud-config.yaml'''> file which will include ssh_authorized_keys generated from another machine. It should also contain a new token for the cluster from https://discovery.etcd.io/new. | |||
# ls -l /dev/sd* | |||
# run '''sudo ./coreos_install.sh -d /dev/sda -C stable -c cloud-config.yaml'''. It will download the latest stable CoreOS, install to the HD | |||
# Don't leave the VM or it will freeze. Issue '''sudo shutdown -h now''' once we see the word 'Success' at the last line of the output. | |||
# Remove CentOS from the VM storage. Boot the coreOS VM. | |||
The new screen shows ''corebm1 login'' with an IP. Go back to another machine and type '''ssh -i /tmp/CoreOSBM_rsa [email protected]'''. Inside CoreOS, we can type '''docker images'''. | |||
The '''cloud-config.yaml'' file has to follow the format in https://coreos.com/os/docs/latest/cloud-config.html. Use the online validator https://coreos.com/validate/ to correct. At first I use the file from the youtube video. There is no error coming out when I ran the installation script. But I cannot connect to coreOS. The cloud-config.yaml file I use is (pay attention to '-', double quotes and indent characters) | |||
<pre> | |||
#cloud-config | |||
# | |||
# set hostname | |||
hostname: CoreBM1 | |||
# Set ssh key | |||
ssh_authorized_keys: | |||
- "ssh-rsa AAAAB3 ..... brb@T3600" | |||
coreos: | |||
etcd: | |||
discovery: "https://discovery.etcd.io/d3e95 .... " | |||
# sudo ./installos -d /dev/sda -C stable -c cloud-config.yaml | |||
</pre> | |||
== CoreOS exploration == | |||
<syntaxhighlight lang='bash'> | |||
brb@T3600 /tmp $ ssh -i /tmp/id_rsa [email protected] | |||
Enter passphrase for key '/tmp/id_rsa': | |||
CoreOS stable (1010.6.0) | |||
core@CoreBM1 ~ $ | |||
core@CoreBM1 ~ $ docker images | |||
REPOSITORY TAG IMAGE ID CREATED SIZE | |||
core@CoreBM1 ~ $ df -h | |||
Filesystem Size Used Avail Use% Mounted on | |||
devtmpfs 1.4G 0 1.4G 0% /dev | |||
tmpfs 1.4G 0 1.4G 0% /dev/shm | |||
tmpfs 1.4G 340K 1.4G 1% /run | |||
tmpfs 1.4G 0 1.4G 0% /sys/fs/cgroup | |||
/dev/sda9 18G 23M 17G 1% / | |||
/dev/sda3 985M 589M 345M 64% /usr | |||
tmpfs 1.4G 0 1.4G 0% /media | |||
/dev/sda1 128M 37M 92M 29% /boot | |||
tmpfs 1.4G 0 1.4G 0% /tmp | |||
/dev/sda6 108M 52K 99M 1% /usr/share/oem | |||
core@CoreBM1 ~ $ free -m | |||
total used free shared buffers cached | |||
Mem: 2713 187 2525 0 9 109 | |||
-/+ buffers/cache: 68 2644 | |||
Swap: 0 0 0 | |||
core@CoreBM1 ~ $ lsb_release -a | |||
-bash: lsb_release: command not found | |||
core@CoreBM1 ~ $ docker pull ubuntu | |||
Using default tag: latest | |||
latest: Pulling from library/ubuntu | |||
f069f1d21059: Pull complete | |||
ecbeec5633cf: Pull complete | |||
ea6f18256d63: Pull complete | |||
54bde7b02897: Pull complete | |||
Digest: sha256:bbfd93a02a8487edb60f20316ebc966ddc7aa123c2e609185450b96971020097 | |||
Status: Downloaded newer image for ubuntu:latest | |||
core@CoreBM1 ~ $ docker images | |||
REPOSITORY TAG IMAGE ID CREATED SIZE | |||
ubuntu latest 0f192147631d 7 days ago 132.7 MB | |||
core@CoreBM1 ~ $ | |||
</syntaxhighlight> | |||
== CoreOS cluster discovery == | |||
https://coreos.com/os/docs/latest/cluster-discovery.html | |||
== etcd == | |||
* https://coreos.com/etcd/ | |||
== fleet == | |||
* https://coreos.com/using-coreos/clustering/ | |||
= TryGhost = | |||
https://github.com/TryGhost/Ghost | |||
= Firecracker = | |||
[https://jvns.ca/blog/2021/01/23/firecracker--start-a-vm-in-less-than-a-second/ Firecracker: start a VM in less than a second] | |||
= Self-hosting = | |||
[https://www.reddit.com/r/selfhosted/comments/uvq1x3/tools_and_resources_for_selfhosting/ Tools and Resources for Self-Hosting] | |||
= Linux in browser = | |||
<ul> | |||
<li>Webtop, https://hub.docker.com/r/linuxserver/webtop#! | |||
* [[#Play_with_Docker_.28PWD.29|Play with Docker]] | |||
* [https://www.linuxserver.io/blog/2021-05-05-meet-webtops-a-linux-desktop-environment-in-your-browser Meet Webtops A Linux Desktop Environment In Your Browser] | |||
* [https://shownotes.opensourceisawesome.com/webtops/ Webtops - Linux Desktops in Docker] | |||
<pre> | |||
--- | |||
version: "2.1" | |||
services: | |||
webtop: | |||
image: lscr.io/linuxserver/webtop:ubuntu-mate | |||
container_name: webtop | |||
security_opt: | |||
- seccomp:unconfined #optional | |||
environment: | |||
- PUID=1000 | |||
- PGID=1000 | |||
- TZ=America/Chicago | |||
- SUBFOLDER=/ #optional | |||
- KEYBOARD=en-us-qwerty #optional | |||
- TITLE=Webtop #optional | |||
volumes: | |||
- ./data:/config | |||
- /var/run/docker.sock:/var/run/docker.sock #optional | |||
ports: | |||
- 3000:3000 | |||
devices: | |||
- /dev/dri:/dev/dri #optional | |||
shm_size: "1gb" #optional | |||
restart: unless-stopped | |||
</pre> | |||
<pre> | |||
$ nano docker-compose.yml | |||
$ docker-compose up -d | |||
$ ls data # files in this directory will be shared between the container and the host | |||
# Open http://localhost:3000 | |||
</pre> | |||
If we remove 'ubuntu-mate', it will create alpine linux instead. | |||
In the alpine linux ([https://www.tecmint.com/apk-command-examples/ 13 Apk Commands for Alpine Linux Package Management]), we can use the following commands to install a package. However, meld is not responding from my testing in the setup. | |||
<pre> | |||
sudo apk update | |||
sudo apk add meld nano htop neofetch | |||
</pre> | </pre> | ||
</li> | |||
<li>[https://www.kasmweb.com/ Kasm Workspaces], https://hub.docker.com/r/kasmweb/desktop/#! | |||
* [https://youtu.be/go7n0FmNqh4 KASM: Isolated Disposable Remote Workspace Via Your Browser] (video) | |||
* [https://www.youtube.com/watch?v=hXkZVqqAg7c Kasm Workspaces: Your Solution for Remote Desktops?] (video) | |||
* [https://youtu.be/_ur59HHoRGc?t=442 Desktop Apps in Docker Containers with Kasm Workspaces] (you cannot install any software there) | |||
</li> | |||
</ul> | |||
= Podman = | |||
* [https://podman.io/docs/installation Podman Installation Instructions] | |||
** [https://ostechnix.com/install-podman-desktop-in-linux/ How To Install Podman Desktop In Linux] | |||
** Raspberry Pi OS use the standard Debian's repositories, so it is fully compatible with Debian's arm64 repository. You can simply follow the steps for Debian to install Podman. | |||
* [https://linuxhandbook.com/docker-vs-podman/ Podman vs docker]: | |||
** One of the main differences between Podman and Docker is their architecture. Docker uses a client-server architecture with a central daemon that manages containers. In contrast, Podman is daemonless and uses a fork-exec model to manage containers. | |||
** '''Podman is designed to run containers without requiring root privileges or the use of sudo'''. This is one of the key differences between Podman and Docker, as Docker requires root privileges to run containers. | |||
** Both Podman and Docker are compatible with the Open Container Initiative (OCI) container specification, which means that they can run the same container images. However, '''Podman is more closely aligned with Kubernetes''' and its native container runtime, while Docker also works with its own orchestration tool, Docker Swarm. | |||
** Podman provides several '''benefits''' over Docker. For example, Podman is daemon-less, which means that if the Docker daemon crashes, the containers are in an uncertain state. This is prevented by making Podman daemon-less. You can also use systemd to manage your containers with Podman, which gives you virtually unlimited configurability compared to Docker. Hooking Podman with systemd allows you to update running containers with minimal downtime and recover from any bad updates. | |||
* Podman is a project from Red Hat | |||
* [https://www.howtogeek.com/devops/getting-started-with-podman-desktop-an-open-source-docker-desktop-alternative/ Getting Started With Podman Desktop, an Open Source Docker Desktop Alternative] | |||
* [https://phoenixnap.com/kb/podman-compose Podman Compose - Managing Containers] | |||
:<syntaxhighlight lang='bash'> | |||
pip3 install podman-compose | |||
</syntaxhighlight> | |||
:But it seems the compatibility is an issue even I tried a small example based on alpine image. | |||
* Nginx example (works) | |||
:<syntaxhighlight lang='bash'> | |||
podman run -it --rm -d -p 8080:80 \ | |||
--name web \ | |||
-v /mnt/Podman/site-content:/usr/share/nginx/html \ | |||
docker.io/libary/nginx | |||
</syntaxhighlight> | |||
* [https://developers.redhat.com/articles/2023/05/23/podman-desktop-now-generally-available Podman Desktop 1.0]: Local container development made easy. | |||
* [https://dzone.com/articles/podman-for-docker-users Podman for Docker Users] | |||
** Prerequisites | |||
** Moving Images from Docker to Podman | |||
** Creating a Basic Nuxt.js Project | |||
** Building a Container Image for Your Nuxt.JS Project | |||
** Push Your Podman Image to Quay.io | |||
** '''Run Your Podman Image with Docker''' | |||
** Creating Pods | |||
** Generate a Kubernetes Pod Spec with Podman | |||
** Create a Kubernetes Cluster with Kind (Optional) | |||
** Deploying to Kubernetes | |||
* Podman, Docker and Singularity all support OCI container format images. | |||
* [https://appsilon.com/docker-vs-podman-vs-singularity/ Docker vs. Podman vs. Singularity: Which Containerization Platform is Best for R Shiny?] | |||
= Resource = | |||
== Internet == | |||
* [https://opensource.com/article/19/11/microservices-cheat-sheet A guide to open source for microservices] from opensource.com | |||
* [https://github.com/rainsworth/osip2019-containerisation-workshop/ Reproducible Research through Containerisation: Docker and Singularity] from rainsworth. | |||
* [https://youtu.be/fqMOX6JJhGo Docker Tutorial for Beginners - A Full DevOps Course on How to Run Applications in Containers] from freeCodeCamp.org | |||
* [https://www.howtogeek.com/733522/docker-for-beginners-everything-you-need-to-know/ Docker for Beginners: Everything You Need to Know] | |||
== Books == | |||
* The Docker Book: Containerization is the new virtualization | |||
* Orchestrating Docker | |||
* Docker Hands on: Deploy, Administer Docker Platform | |||
* [https://www.oreilly.com/library/view/learn-docker-/9781788997027/?afsrc=1 Learn Docker - Fundamentals of Docker] 18.x by Gabriel N. Schenker. Release Date: April 2018. https://github.com/fundamentalsofdocker/labs | |||
* [https://www.amazon.com/Docker-Deep-Dive-Nigel-Poulton/dp/1521822808 Docker Deep Dive] by by Nigel Poulton. 2017 | |||
* Master Docker (2nd, 2017) by Russ McKendrick, Scott Gallagher. Source code on [https://github.com/PacktPublishing/Mastering-Docker-Second-Edition github]. | |||
== Blogs == | |||
* collabnix | |||
** [https://dockerlabs.collabnix.com/ Welcome to Docker Labs] | |||
** [https://dockerlabs.collabnix.com/intermediate/workshop/ Docker Workshop for Intermediate Users] | |||
* http://blog.thoward37.me/articles/where-are-docker-images-stored/ | |||
* [http://www.ithome.com.tw/people/109065 Docker容器架構最大儲存挑戰是,你根本不知道資料存在何處] | |||
* [https://blog.quickmediasolutions.com/2017/08/23/running-everything-in-docker.html Running Everything in Docker]. Docker Compose was used. Several applications were illustrated: mediawiki, Jenkins, Gogs & caddy-docker. | |||
== Tips/trouble shooting == | |||
* [https://nickjanetakis.com/blog/docker-tip-64-dealing-with-unexplained-docker-errors Dealing with Unexplained Docker Errors] and other [https://nickjanetakis.com/blog/tag/docker-tips-tricks-and-tutorials tips and tricks] | |||
* [https://medium.com/lucjuggery/running-a-container-with-a-non-root-user-e35830d1f42a Running a container with a non root user] | |||
* [https://stackoverflow.com/a/49941240 Error: Cannot start container: port has already been allocated]. '''sudo service docker restart''' | |||
== Play with Docker (PWD) == | |||
* http://labs.play-with-docker.com/ | |||
* http://training.play-with-docker.com/, [https://training.play-with-docker.com/alacart/ A full list of labs] | |||
* https://blog.docker.com/2017/07/best-way-learn-docker-free-play-docker-pwd/ | |||
* One session is 4 hours. Each session can have multiple instance. Each instance will be allocated 4GB mem. Each docker image is stored in memory. | |||
* '''df -h''' shows there is only 4.7G space for /var/lib/docker directory | |||
* It is based on Alpine Linux. To install htop, do '''apk add htop'''. But '''htop''' command shows the resource from the host, not from the user's account. | |||
* '''ctrl + insert''' to copy and '''shift + insert''' to paste | |||
* [https://github.com/play-with-docker/play-with-docker/issues/238 connect to a play-with-docker instance]. Answer: You just need to create a random private key. [https://kostislab.blogspot.com/2019/03/play-with-play-with-docker-form-your.html Play with "Play with Docker" from your terminal!]. | |||
* Some applications I've tested. | |||
** webtop (OK) | |||
** r-base:3.6.3, r-base:4.1.0, r-base:4.1.1 (OK) | |||
** r-base:4.1.2, r-base:4.2.0 (ERROR: R_HOME ('/usr/lib/R') not found). Maybe the docker version there is too old. | |||
== Alternatives == | |||
[https://www.makeuseof.com/best-docker-alternatives/ The 9 Best Docker Alternatives for Container Management] | |||
= | == Serverless computing == | ||
* | * [https://en.wikipedia.org/wiki/Serverless_computing Serverless computing] | ||
* [https://seandavi.github.io/post/cloud-run-notes/ Build and deploy an NCBI GEO metadata fetch API] | |||
* [https://medium.com/@TechMagic/serverless-vs-docker-what-to-choose-in-2019-80cb80f4b680 Serverless vs Docker Containers— what to choose in 2019?] |
Latest revision as of 21:34, 21 November 2024
Official web page http://docker.io.
Docker is both a client and a server: the server is a daemon that runs on Linux. The normal approach was that you used docker on the same server the daemon was running on - however it was possible to connect the docker client to a remote docker daemon.
Installation
Which OS to install?
- Which OS Is Best for Docker? Here’s How to Decide
- Container OS Comparison
- CoreOS. See 12 Best Linux Server Operating Systems and Who Should Use Them
- RancherOS
- Snappy Ubuntu Core
- RedHat Project Atomic
- Mesosphere DCOS
- VMware Photon. Photon Could Be Your New Favorite Container OS
Containers vs virtual machines
- Differences: https://youtu.be/BFKNwr_wllc
- Work together: https://youtu.be/BFKNwr_wllc
KubeVirt
- KubeVirt brings VMs into containerized workflows by converting the VMs into containers, where they run with the benefits of containerized applications. 6 container concepts you need to understand
OS containers vs application containers
- https://blog.risingstack.com/operating-system-containers-vs-application-containers/
- OpenVZ Versus Docker And More On Linux System Container Platforms
- Docker vs OpenVZ
Differences:
- OS containers: LXC, OpenVZ, Linux VServer, BSD Jails and Solaris zones. The container acts as VPS.
- App containers: Docker, Rocket. The container acts as an application.
Current release version
- https://docs.docker.com/release-notes/docker-ce/ (stable release)
- https://github.com/docker/docker-ce/releases (stable & pre-release, could be newer than the above release-notes)
Ubuntu x86 and Mint
- https://docs.docker.com/install/linux/docker-ce/ubuntu/
# Uninstall old versions $ sudo apt-get remove docker docker-engine docker.io # Install using the repository $ sudo apt-get update $ sudo apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg $ echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null $ sudo apt-get update $ sudo apt-get install docker-ce docker-ce-cli containerd.io # Verify $ sudo docker run hello-world
Install docker-compose https://docs.docker.com/compose/install/
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose $ docker-compose --version
- How to Install and Configure Kubernetes and Docker on Ubuntu 18.04 LTS
- How install docker in Mint?
One-line script
https://github.com/docker/docker-install, https://docs.docker.com/engine/install/ubuntu/, https://twitter.com/portainerio/status/1650171336864550912
Note that 1) the one-liner is a huge security issue. 2) but how will you add the current user to docker group and then logout and log back in. 3) Linux Mint does not work.
$ curl -fsSL https://get.docker.com | bash ... Client: Docker Engine - Community Version: 24.0.7 API version: 1.43 Go version: go1.20.10 Git commit: afdd53b Built: Thu Oct 26 09:08:17 2023 OS/Arch: linux/amd64 Context: default Server: Docker Engine - Community Engine: Version: 24.0.7 API version: 1.43 (minimum version 1.12) Go version: go1.20.10 Git commit: 311b9ff Built: Thu Oct 26 09:08:17 2023 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.6.26 GitCommit: 3dd1e886e55dd695541fdcd67420c2888645a495 runc: Version: 1.1.10 GitCommit: v1.1.10-0-g18a0cb0 docker-init: Version: 0.19.0 GitCommit: de40ad0 --------------- To run Docker as a non-privileged user, consider setting up the Docker daemon in rootless mode for your user: dockerd-rootless-setuptool.sh install Visit https://docs.docker.com/go/rootless/ to learn about rootless mode. To run the Docker daemon as a fully privileged service, but granting non-root users access, refer to https://docs.docker.com/go/daemon-access/ WARNING: Access to the remote API on a privileged Docker daemon is equivalent to root access on the host. Refer to the 'Docker daemon attack surface' documentation for details: https://docs.docker.com/go/attack-surface/ -------------- $ # sudo groupadd docker $ sudo usermod -aG docker $USER; newgrp docker $ docker run hello-world
The newgrp docker command in Linux is used to switch the current user’s group ID during a login session. Specifically, it changes the user’s primary group to the docker group without logging out and back in. This is particularly useful when you need to gain the permissions associated with the docker group to run Docker commands.
$ id -gn docker
Docker Desktop
- https://docs.docker.com/desktop/linux/install/
- The Magic of Docker Desktop is Now Available on Linux
- A Beginners Manual To Docker Desktop For Linux
Without sudo, Post-installation
To use docker without sudo, follow the instruction on the official guide.
# Add the docker group if it doesn't already exist. # sudo groupadd docker # Add your user to the docker group. sudo usermod -aG docker $USER # Log out and log in
After running this command, you need to log out and log back in for the changes to take effect. This is because group membership is determined at login time. When you log in, the system reads the group membership information and assigns the appropriate permissions to your user account.
Upgrade Docker Desktop
It seems it does not affect running containers (e.g. RStudio on Mac).
Is it fine to upgrade Docker-ce while a container is running?
Doesn't matter. Your system will stop the container if you update docker.
Is there a way to hibernate a docker container
- https://stackoverflow.com/a/45170070
- Reference for docker checkpoint (This command is experimental)
Live restore
- Can I save my running containers when upgrading from `docker` to `docker-ce`?
- Docker's Live Restore feature Docker provides a feature that keeps containers running when Daemon is unavailable, thus reducing container downtime when Daemon is upgraded or has problems. That feature is called Live Restore.
Rate limits for GitHub Apps
When I tried several times of docker build, I finally got a message
Downloading GitHub repo XXX/XXXXX@HEAD Error: Failed to install 'unknown package' from GitHub: HTTP error 403. API rate limit exceeded for XXX.XX.XXX.X. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.) Rate limit remaining: 0/60 Rate limit reset at: 2021-04-12 20:32:28 UTC To increase your GitHub API rate limit - Use `usethis::browse_github_pat()` to create a Personal Access Token. - Use `usethis::edit_r_environ()` and add the token as `GITHUB_PAT`. Execution halted
CentOS
- https://docs.docker.com/engine/installation/linux/docker-ce/centos/. Note that Centos 9 Stream is required. I have tried to follow this to install on Oracle 7/8 and it does not work now. A possible workaround is either download RPM packages manually (CentOS 7, CentOS 8) or Install Docker Engine from binaries.
sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo systemctl start docker sudo systemctl enable docker.service sudo systemctl enable containerd.service sudo docker run hello-world sudo usermod -aG docker $USER newgrp docker
- How to install specific version of Docker on Centos?
sudo yum list docker-ce.x86_64 --showduplicates | sort -r
Boot2Docker
For Windows and OS operation systems, we have to use Boot2Docker. Boot2Docker is a local virtual machine with its own network interface and IP address. To find the Boot2Docker IP address you can check the value of the DOCKER_HOST environment variable. You're be prompted to set this variable when you start or install Boot2Docker the first time. You can find the IP address by running boot2docker ip command.
Note that since Windows and OS X don't share a file system as Linux, the command 'docker run' with '-v' flag to mount a local directory into a Docker container will not work with Boot2Docker release prior to 1.3. The support for volumes is now available for OS X but is not yet present for Windows with the release of Boot2Docker 1.3.
Windows
Note many of the information here have not been updated.
Docker can be run on Windows 10 Pro as a native application; see
- https://docs.docker.com/engine/installation/windows/.
- Run Linux containers on Windows & Chinese translation
The information below is based on running Docker on Windows 7.1 and 8. Your processor needs to support hardware virtualization.
- Windows Installer includes msys-git, Virtualbox, Boot2Docker-cli management tool and Boot2Docker ISO.
- Installation instruction for Windows OS. It will install Boot2Docker management tool with the boot2docker iso (based on Tiny Core Linux), Virtualbox and MYSYS-git UNIX tools.
- Docker needs Admin right to be installed. However, Virtualbox can be installed by user's account.
- If the installer detects a version of VirtualBox installed, the VirtualBox checkbox will not be checked by default (Windows OS). The VirtualBox cannot be used anymore after updating my VB from 4.3.18 to 4.3.20. The error may be related to Windows update according to Virtualbox forum.
Error in supR3HardenedWinReSpawn
- Note that boot2docker cannot be installed/run inside a Windows guest machine. See this post and my Virtualbox wiki here. If we try to launch boot2docker-vm from Virtualbox, we will see a message "This kernel requires an x86-64 CPU, but only detected an i686 CPU."
- After I switch back to an old version of virtualbox, every thing works again. I can even install Docker successfully.
- Boot2Docker Start icon cannot be run directly because Notepad++ will automatically open it. A possible solution is to go to control panel and change default program for .sh file from Notepad++ to C:\Program Files (x86)\Git\bin\bash.exe.
- The above step does not work well since a terminal appears and disappears quickly.
- A working approach is to open Git Bash from Start menu. And run /c/Program Files/Boot2DockerforWindows/start.sh (or boot2docker start or boot2docer init)
- A new VM called 'boot2docker-vm' will be created (we can open VirtualBox Manager to check). But I got an error error in run: Failed to start machine "boot2docker-vm" (run again with -v for details). The VM has an error on Network>Adapter2>VirtualBox Host-Only Ethernet Adapter #2. So I open the setting of <boot2docker-vm>, go to Network > Adapter 2 and change the dropdown list of Name from VirtualBox Host-Only Ethernet Adapter #2 to VirtualBox Host-Only Ethernet Adapter.
- Now it works either I directly click boot2docker-vm VM from VB Manager or use the command start.sh from Git Bash.
$ # boot2docker is in the PATH variable, so there is not need to cd to the folder. $ boot2docker start initializing... Virtual machine boot2docker-vm already exists starting... Waiting for VM and Docker daemon to start... ........o Started. Writing c:\Users\brb\.boot2docker\certs\boot2docker-vm\ca.pem Writing c:\Users\brb\.boot2docker\certs\boot2docker-vm\cert.pem Writing c:\Users\brb\.boot2docker\certs\boot2docker-vm\key.pem Docker client does not run on Windows for now. Please use "c:\Program files\Boot2Docker for Windows\boot2docker.exe" ssh to SSH into the VM instead. 192.168.56.101 connecting... ## . ## ## ## == ## ## ## ## === /""""""""""""""""\___/ === ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~ \______ o __/ \ \ __/ \____\______/ _ _ ____ _ _ | |__ ___ ___ | |_|___ \ __| | ___ ___| | _____ _ __ | '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__| | |_) | (_) | (_) | |_ / __/ (_| | (_) | (__| < __/ | |_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_| Boot2Docker version 1.4.1, build master : 86f7ec8 - Tue Dec 16 23:11:29 UTC 2014 Docker version 1.4.1, build 5bc2ff8 docker@boot2docker:~$ docker Usage: docker [OPTIONS] COMMAND [arg...] A self-sufficient runtime for linux containers. Options: --api-enable-cors=false Enable CORS headers in the remote API -b, --bridge="" Attach containers to a pre-existi ng network bridge ... Run 'docker COMMAND --help' for more information on a command. docker@boot2docker:~$ docker run hello-world Unable to find image 'hello-world:latest' locally hello-world:latest: The image you are pulling has been verified 511136ea3c5a: Pull complete 31cbccb51277: Pull complete e45a5af57b00: Pull complete Status: Downloaded newer image for hello-world:latest Hello from Docker. This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (Assuming it was not already locally available.) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash For more examples and ideas, visit: http://docs.docker.com/userguide/ docker@boot2docker:~$ ls boot2docker, please format-me docker@boot2docker:~$ pwd /home/docker docker@boot2docker:~$ ls / bin/ dev/ home/ lib/ mnt/ proc/ run/ sys/ usr/ c/ etc/ init linuxrc opt/ root/ sbin/ tmp var/ docker@boot2docker:~$ docker run hello-world Hello from Docker. This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (Assuming it was not already locally available.) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash For more examples and ideas, visit: http://docs.docker.com/userguide/ docker@boot2docker:~$ docker@boot2docker:~$ docker@boot2docker:~$ docker@boot2docker:~$ docker run -it ubuntu bash Unable to find image 'ubuntu:latest' locally ubuntu:latest: The image you are pulling has been verified 53f858aaaf03: Pull complete 837339b91538: Pull complete 615c102e2290: Pull complete b39b81afc8ca: Pull complete 511136ea3c5a: Already exists Status: Downloaded newer image for ubuntu:latest root@ea7e3289a01a:/# pwd / root@ea7e3289a01a:/# df -h Filesystem Size Used Avail Use% Mounted on rootfs 19G 269M 17G 2% / none 19G 269M 17G 2% / tmpfs 1005M 0 1005M 0% /dev shm 64M 0 64M 0% /dev/shm /dev/sda1 19G 269M 17G 2% /etc/hosts tmpfs 1005M 0 1005M 0% /proc/kcore root@ea7e3289a01a:/# ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr root@ea7e3289a01a:/# exit exit docker@boot2docker:~$ pwd /home/docker docker@boot2docker:~$ ls boot2docker, please format-me docker@boot2docker:~$ exit [Press any key to exit] brb@NCI-01825357 /c/Program files/Boot2Docker for Windows $ boot2docker down brb@NCI-01825357 /c/Program files/Boot2Docker for Windows $ $ boot2docker --help Usage: c:\Program files\Boot2Docker for Windows\boot2docker.exe [<options>] <command> [<args>] Boot2Docker management utility. Commands: init Create a new Boot2Docker VM. up|start|boot Start VM from any states. ssh [ssh-command] Login to VM via SSH. save|suspend Suspend VM and save state to disk. down|stop|halt Gracefully shutdown the VM. restart Gracefully reboot the VM. poweroff Forcefully power off the VM (may corrupt disk image). reset Forcefully power cycle the VM (may corrupt disk image). delete|destroy Delete Boot2Docker VM and its disk image. config|cfg Show selected profile file settings. info Display detailed information of VM. ip Display the IP address of the VM's Host-only network. shellinit Display the shell commands to set up the Docker client. status Display current state of VM. download Download Boot2Docker ISO image. upgrade Upgrade the Boot2Docker ISO image (restart if running). version Display version information. Options: --basevmdk="": Path to VMDK to use as base for persistent partition --clobber=false: overwrite Docker client binary on boot2docker upgrade --dhcp=true: enable VirtualBox host-only network DHCP. --dhcpip=192.168.59.99: VirtualBox host-only network DHCP server address. .... -v, --verbose=false: display verbose command invocations. --vm="boot2docker-vm": virtual machine name. --waittime=300: Time in milliseconds to wait between port knocking retries during 'start' error in run: config error: pflag: help requested brb@NCI-01825357 /c/Program files/Boot2Docker for Windows
The big picture
start.sh docker run -it ubuntu bash Git Bash Git Bash ----------> boot2docker-vm -------------> ubuntu docker@boot2docker: <------- <---------- <------------- boot2docker down exit exit (shutdown boot2docker) (boot2docker-vm is still on) | | | boot2docker up (start boot2docker) | | boot2docker ssh (log into docker acct) | v boot2docker-vm docker@boot2docker
Increase boot2docker vmdk space
https://docs.docker.com/articles/b2d_volume_resize/
Install utilities in Boot2docker VM
http://blog.tutum.co/2014/11/05/how-to-use-docker-on-windows/
For example, to install cifs-utils,
wget http://distro.ibiblio.org/tinycorelinux/5.x/x86/tcz/cifs-utils.tcz tce-load -i cifs-utils.tcz
WSL2
- Docker on Windows without Hyper-V
- Manual installation steps for older versions of WSL. I got this page when I installed Docker Desktop v4.9.0 (2022/6/14) on Windows 10.
Mac
- https://docs.docker.com/desktop/mac/
- Alternatives to Docker Desktop for Mac? Rancher is recommended. 2022-06-08
- Vagrant method. If you have Mac, you don't have to use boot2docker (iso & its management tool). You can use other Linux which comes with docker pre-installed. See this post.
- To avoid the message Error: `brew cask` is no longer a `brew` command. Use `brew <command> --cask` instead, use
brew install --cask docker
Raspberry Pi
- Resin.io (now called balenaCloud). They are supporting Docker on very low performance devices like Raspberry Pi 1 Zero or Beaglebone Black (512MB RAM, 1GHz ARM® Cortex-A8).
- Another option is to use QEMU which allows Docker to create a container based on ARM. Creating a docker container from a Raspberry Pi Zero image... and the other way around
- Docker on Raspberry Pi - Installation/uninstall Guide
- Getting Started With Docker On Raspberry Pi (Full Guide)
ARM architeture from hub.docker.com
- Getting started with Docker for Arm on Linux
- Raspberry Pi
curl -sSL https://get.docker.com | sh
- UDOO Quad running Armbian 20.04
- The instruction on official Docker website does not work
- The curl command method above does not work
- sudo apt-get install -y docker.io works (docker -v shows it is 19.03.8). After that, run sudo usermod -aG docker $USER and log out/in.
- See Odroid magazine 2015 January and 2015 February. Note that the current versions of Docker and Docker Hub are not aware of the architecture for which the image has been built. All standard images are intended for the x86 architecture, and the autobuild feature offered by the Docker registry is only available for x86.
- NVIDIA Jetson Nano Developer Kit - Introduction, Redis running inside Docker container on NVIDIA Jetson Nano
sudo apt install curl curl -sSL https://get.docker.com/ | sh
docker-compose
- https://docs.docker.com/compose/install/. The binary version is only available for x86. So for raspi, see the Alternative Install Options where it suggests to use virtualenv. See also Python → virtualenv.
- Docker and Docker Compose on Raspberry Pi OS
sudo apt update sudo apt install -y python3-pip libffi-dev # Install Docker Compose from pip (using Python3) # This might take a while sudo pip3 install docker-compose
Some examples*
Not I use the arm64 image on my Pi3b+.
Images from https://www.linuxserver.io/. Some indices include number of pulls and stars.
List of tz database time zones
Portainer. The port number is 9000. Note the stack will be deployed using the equivalent of docker-compose. Only Compose file format version 2 is supported at the moment.
Samba. Tested on iOS, Ubuntu & Windows 10.
mkdir -p /mnt/usb/share/{data,backups} mkdir /mnt/usb/share/data/{alice,bob,documents} touch /mnt/usb/share/backups/backupsfile touch /mnt/usb/share/data/bob/bobfile touch /mnt/usb/share/data/documents/documentfile docker run -d -p 445:445 \ -v /mnt/usb/share/data:/share/data \ -v /mnt/usb/share/backups:/share/backups \ --name rpi-samba trnape/rpi-samba \ -u "alice:abc123" \ -u "bob:secret" \ -u "guest:guest" \ -s "Backup directory:/share/backups:rw:alice,bob" \ -s "Bob (private):/share/data/bob:rw:bob" \ -s "Documents (readonly):/share/data/documents:ro:guest,alice,bob"
On Windows, 1) right click on 'This PC' and choose 'Add a network location'. 2) type \\192.168.1.249\ and the dropdown list will populate all available folders. 3) choose the one (e.g. Bob) and then enter the credential. Done. On Ubuntu, just type smb://192.168.1.249/. It will then populate the available folders.
mkdir -p /mnt/usb/docker-nginx/html echo "hello world" >> /mnt/usb/docker-nginx/html/index.html nano /mnt/usb/docker-nginx/html/sharefile docker run --name rpi-nginx -p 8086:80 \ --restart always \ -v /mnt/usb/docker-nginx/html:/usr/share/nginx/html \ -d nginx:stable-alpine # Or a stack file version: '2' services: nginx: container_name: rpi-nginx ports: - '8086:80' restart: always volumes: - '/mnt/usb/docker-nginx/html:/usr/share/nginx/html' image: nginx:stable-alpine
Note consider to use a samba share folder (see above) as a nginx document root.
cp /mnt/usb/docker-nginx/html/* /mnt/usb/share/data/bob/ rm -rf /mnt/usb/docker-nginx/html ln -s /mnt/usb/share/data/bob/ /mnt/usb/docker-nginx/html
Rpi-monitor. I need to change /dev/vcsm to /dev/vcsm-cma. But the temperature part is not working. I am using 64-bit Raspberry Pi OS and it does not show attached USB disks. The port number is 8888.
--- version: "2.1" services: code-server: image: ghcr.io/linuxserver/code-server container_name: code-server environment: - PUID=1000 - PGID=1000 - TZ=America/New_York - PASSWORD=password #optional - SUDO_PASSWORD=password #optional volumes: - /mnt/usb/code-server:/config ports: - 8443:8443 restart: unless-stopped
mstream Music streaming. Works great.
emby does not work on arm64. It works on x86 though. Even I copy a mp4 file to movies directory the movie does not show up:(
version: '2.1' services: embyserver: container_name: emby network_mode: bridge restart: always environment: - VERSION=latest - UID=1000 - GID=1000 - TZ=America/Denver volumes: - /media/crucial/emby/config:/config - /media/crucial/emby/tv:/mnt/tv - /media/crucial/emby/movies:/mnt/movies ports: - 8096:8096 image: 'emby/embyserver:latest'
jellyfin Jellyfin is descended from Emby's 3.5.2 release and ported to the .NET Core framework to enable full cross-platform support. How to Install Jellyfin on Docker with Portainer
plex We can access the plex server via http://IP:32400/web. Note that in the first server setup, we need to add Library' by choosing the new library name (eg Other Videos) shown on plex & the data source (eg /data) so our own media can be found. After we added new media files we can rescan by clicking the vertical 3 dots icon and selecting scan library files. Pi3b+ is still a little weak since I can see all threads are busy when I played a mp4 file.
mkdir -p /mnt/usb/plex/{config,data} cp FILENAme.mp4 /mnt/usb/plex/data docker run \ -d \ --name plex \ --net host \ -p 32400:32400 \ --restart always \ --volume /mnt/usb/plex/config:/config \ --volume /mnt/usb/plex/data:/data \ greensheep/plex-server-docker-rpi:latest WARNING: The requested image's platform (linux/arm) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
sudo mkdir -p /srv/dev-disk-by-label-Files/Databases/NextCloud sudo mkdir -p /srv/dev-disk-by-label-Files/Config/Nextcloud
After that, copy and paste the stack into portainer. Wait for a few minutes on RPi3. The port number is 8080. Now we can create the admin username/password such as nextcloud/nextcloud. Click the little triangle next to "Storage and Database". Change to MySQL. In the next part we enter nextcloud/nextcloud/nextcloud/db (note the "db" replaces localhost b/c we use "db" as the service name). Again, wait for a few minutes.
Heimdall (Dashboard for web apps). I keep the PUID (1000) and PGID (1000). The instruction says it is from the admin user account but I don't find admin account? Change the volume to /srv/dev-disk-by-label-Files/Config/Heimdall (use sudo mkdir to create the directory on terminal). Change the port to 83 & remove port 443. Define the endpoint from Portainer -> Endpoints -> local -> Public IP as raspberrypi.local (depending on your hostname). We need to wait a little bit. Now go to the container and find heimdall and click the port in order to open the website correctly (instead 0.0.0.0). I can add apps like nextcloud, portainer, pi-hole, other servers, etc. The Application Type entry has a good list of popular apps and it will pre-populate the button icon and the background color for our app.
taisun The default port is 3000
yacht. The default login is [email protected] and pass. The name shown on portainer is pedantic_hermann
docker volume create yacht docker run -d -p 8001:8000 -v /var/run/docker.sock:/var/run/docker.sock -v yacht:/config selfhostedpro/yacht
CloudFlare DDNS - Update CloudFlare with Your Dynamic IP Address
bitwardenrs. Use the terminal to create a volume first. The port number is 8100. This is straightforward.
Duplicati for backup.
photoshow. It works. It has a slideshow button. PhotoShow only displays videos in WebM.
R. r-base provide arm64 image but not not 32-bit arm architecture.
# 64-bit OS docker pull r-base docker run -it --rm r-base # enter R directly
rocker/rstudio DOES NOT work on arm64 even I can pull. WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
I build a 32-bit armv7 image for r-base v4.0.2. This image works on either 32-bit or 64-bit arm OS (tested on 32-/64-bit Raspberry Pi and other 32-bit SBC devices).
docker pull arraytools/r402armv7 docker run -it --rm arraytools/r402armv7 R docker pull r-base # Using default tag: latest # latest: Pulling from library/r-base # no matching manifest for linux/arm/v7 in the manifest list entries
How and Why to Use A Remote Docker Host
Backup
- Backup, restore, or migrate data volumes
- Backup a running Docker container?
- How to Copy/Move a Docker Container to Another Host
- Is backing up `/var/lib/docker/volumes` a good way to back up your Docker containers? If not, what is?
Usage
Basics, docs, cheatsheet, introduction
- https://docs.docker.com/articles/basics/
- 81 Docker Command Cheat Sheet with Description
- https://coderwall.com/p/2es5jw/docker-cheat-sheet-with-examples
- https://github.com/wsargent/docker-cheat-sheet
- How to use Docker in a practical way
- https://hackernoon.com/introduction-to-docker-a7d9e1f6c0b3#.tezit0hkq
- Docker快速入门
- Docker: The Fun and Easy Way
- A Gentle Introduction to Docker. docker build & renv.
Note that we need sudo is needed unless it is on a Mac OS.
If docker cannot find an image, it will try to pull it from its repository.
$ sudo docker run -it ubuntu /bin/bash Unable to find image 'ubuntu' locally Pulling repository ubuntu 04c5d3b7b065: Download complete 511136ea3c5a: Download complete c7b7c6419568: Download complete 70c8faa62a44: Download complete d735006ad9c1: Download complete root@ec83b3ac878d:/#
purpose | command |
---|---|
run a container | docker container run -d -p 80:80 httpd |
list running cotainer | docker container ls |
view logs of Docker container | docker container logs cranky_cori |
identify Docker container process? | docker container top cranky_cori |
stop Docker container? | docker container stop cranky_cori |
list stopped or not running Docker containers | docker container ls -a |
start Docker container | docker container start c46f2e9e4690 |
remove Docker container | docker container rm cranky_cori |
list Docker images | docker images |
remove Docker image | docker rmi iman/touch |
Restart docker daemon
When I try the Chap5 > Continuous integration (Jenkins) of the Docker Book, I found I cannot stop/kill the container. See others' report here. The solution is to restart the docker daemon.
sudo service docker start
After that, I can stop and rm the container.
sudo docker stop jenkins sudo docker rm jenkins sudo docker ps -a
images vs containers
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE iman latest 6e0f5644b2fd About a minute ago 460.4 MB iman/touch latest 77b9ac5951c2 4 minutes ago 460.4 MB <none> <none> aaa75e64ddf0 5 weeks ago 188.3 MB ouruser/sinatra v2 ea8c9f407a8d 5 weeks ago 447 MB ubuntu 14.04 ed5a78b7b42b 5 weeks ago 188.3 MB ubuntu latest ed5a78b7b42b 5 weeks ago 188.3 MB eddelbuettel/docker-ubuntu-r add-r-devel-san 3c19d078c5d9 3 months ago 460.4 MB hello-world latest ef872312fe1b 4 months ago 910 B training/sinatra latest f0f4ab557f95 8 months ago 447 MB $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8fbdbcdb5126 iman/touch:latest "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago thirsty_engelbart dc9e82f2c00a eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 9 minutes ago Exited (0) 3 minutes ago kickass_bardeen 532a90f36aa8 eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 18 hours ago Exited (0) 18 hours ago happy_lalande 7634024ee0bf eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 18 hours ago Exited (0) 18 hours ago insane_mclean 14034a9720cb eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 18 hours ago Exited (0) 18 hours ago naughty_lumiere ca90954628db eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 19 hours ago Exited (130) 18 hours ago sick_hawking 8bbdcb7c339f eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 19 hours ago Exited (0) 19 hours ago modest_davinci e8e24f80f0dd aaa75e64ddf0 "/bin/sh -c 'apt-get 5 weeks ago Exited (100) 5 weeks ago berserk_hodgkin d41959e0eb55 aaa75e64ddf0 "/bin/sh -c 'apt-get 5 weeks ago Exited (100) 5 weeks ago jovial_curie b408c0e2805b aaa75e64ddf0 "/bin/sh -c 'apt-get 5 weeks ago Exited (100) 5 weeks ago lonely_tesla 72a551e4b492 ouruser/sinatra:v2 "/bin/bash" 5 weeks ago Exited (0) 5 weeks ago jolly_meitner 75fd6cc4658b training/sinatra:latest "/bin/bash" 5 weeks ago Exited (0) 5 weeks ago evil_yalow cc8886f5a02e training/sinatra:latest "/bin/bash" 5 weeks ago Exited (130) 5 weeks ago elegant_curie 0585e4f5fecd eddelbuettel/docker-ubuntu-r:add-r-devel-san "/bin/bash" 5 weeks ago Exited (0) 5 weeks ago elated_euclid brb@brbweb4:~/Downloads$
When we want to delete a container, we use the container's CONTAINER ID or NAME (last column output from docker ps -a). But when we want to delete an image, we use the image's REPOSITORY or IMAGE ID (2nd column output from docker images)
$ sudo docker rm thirsty_engelbart # iman/touch $ sudo docker rm dc9e82f2c00a # eddelbuettel/docker-ubuntu-r:add-r-devel-san $ sudo docker ps -a # check to see the container is gone now $ sudo docker rmi 6e0f5644b2fd $ sudo docker rmi iman/touch $ sudo docker images # check to see the images are gone now
Command line interface, CLI
https://docs.docker.com/engine/reference/commandline/cli/ Docker command line
$ docker Usage: docker COMMAND A self-sufficient runtime for containers Options: --config string Location of client config files (default "/home/brb/.docker") -D, --debug Enable debug mode -H, --host list Daemon socket(s) to connect to -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") --tls Use TLS; implied by --tlsverify --tlscacert string Trust certs signed only by this CA (default "/home/brb/.docker/ca.pem") --tlscert string Path to TLS certificate file (default "/home/brb/.docker/cert.pem") --tlskey string Path to TLS key file (default "/home/brb/.docker/key.pem") --tlsverify Use TLS and verify the remote -v, --version Print version information and quit Management Commands: config Manage Docker configs container Manage containers image Manage images network Manage networks node Manage Swarm nodes plugin Manage plugins secret Manage Docker secrets service Manage services swarm Manage Swarm system Manage Docker trust Manage trust on Docker images volume Manage volumes Commands: attach Attach local standard input, output, and error streams to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes cp Copy files/folders between a container and the local filesystem create Create a new container diff Inspect changes to files or directories on a container's filesystem events Get real time events from the server exec Run a command in a running container export Export a container's filesystem as a tar archive history Show the history of an image images List images import Import the contents from a tarball to create a filesystem image info Display system-wide information inspect Return low-level information on Docker objects kill Kill one or more running containers load Load an image from a tar archive or STDIN login Log in to a Docker registry logout Log out from a Docker registry logs Fetch the logs of a container pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container ps List containers pull Pull an image or a repository from a registry push Push an image or a repository to a registry rename Rename a container restart Restart one or more containers rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save one or more images to a tar archive (streamed to STDOUT by default) search Search the Docker Hub for images start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers version Show the Docker version information wait Block until one or more containers stop, then print their exit codes Run 'docker COMMAND --help' for more information on a command.
Version, system information
Docker version
$ docker version Client: Version: 18.06.1-ce API version: 1.38 Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:24:51 2018 OS/Arch: linux/amd64 Experimental: false Server: Engine: Version: 18.06.1-ce API version: 1.38 (minimum version 1.12) Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:23:15 2018 OS/Arch: linux/amd64 Experimental: false
System information.
- what mode the Docker engine is operating in (swarm mode or not)
- what storage drive is used for the union filesystem
- what version of the Linux kernel we have on our host
- et al
$ docker system info Containers: 2 Running: 0 Paused: 0 Stopped: 2 Images: 10 Server Version: 18.06.1-ce Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog Swarm: inactive Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: 468a545b9edcd5932818eb9de8e72413e616e86e runc version: 69663f0bd4b60df09991c08812a60108003fa340 init version: fec3683 Security Options: apparmor seccomp Profile: default Kernel Version: 4.15.0-33-generic Operating System: Ubuntu 18.04.1 LTS OSType: linux Architecture: x86_64 CPUs: 4 Total Memory: 7.674GiB Name: t420s ID: VLWB:6BN3:U7KB:L4T4:GQIB:54F3:YZKJ:PAIR:HEUM:UQIC:XLZU:3IFJ Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false WARNING: No swap limit support
List resource consumption
$ docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 10 2 2.58GB 1.519GB (58%) Containers 2 0 304B 304B (100%) Local Volumes 2 0 314.7MB 314.7MB (100%) Build Cache 0 0 0B 0B $ docker system df -v # more detailed information # We can use the information to clean up our system
A brief intro to docker virtualization
docker search --help docker search redis docker search -s 100 redis docker pull --help docker pull ubuntu # download all versions of ubuntu docker images # available local container images docker pull centos:latest docker run --help cat /etc/issue # look at the current distr name before running docker docker run -it centos:latest /bin/bash # create a container & execute as a sudo cat /etc/redhat-release yum cd /home touch temp.txt ls exit docker ps # current running processes docker ps -a # show all processes including closed docker restart c85850ed0e13 docker ps # container c85850ed0e13 is running docker attach c85850ed0e13 # log into the system ls /home exit docker ps -a docker rm c85850ed0e13 # delete the container
Note: Following the discussion, using attach can only launch one instance of shell. If we use exec, we can launch multiple instances.
sudo docker exec -i -t c85850ed0e13 bash #by ID or $ sudo docker exec -i -t loving_heisenberg bash #by Name
Rootless mode
- Run the Docker daemon as a non-root user (Rootless mode)
- The data dir is set to ~/.local/share/docker by default. The data dir should not be on NFS.
- Setup on Ubuntu 22.04
curl -fsSL https://get.docker.com | bash sudo apt install -y uidmap dockerd-rootless-setuptool.sh install nano ~/.bashrc source ~/.bashrc systemctl --user start docker systemctl --user enable docker sudo loginctl enable-linger $(whoami) docker run hello-world docker run --rm -ti r-base:4.4.1
- Unfortunately, Rocker/rstudio does not work. I am not able to log in using username/password. It keeps saying incorrect username/password.
- Limitations:
- Performance Overhead
- OverlayFS Limitations: Rootless Docker uses fuse-overlayfs instead of OverlayFS by default, which can be slower.
- Resource Limits: The performance might be slightly lower compared to running Docker with root privileges due to additional user namespace operations.
- Network Restrictions
- Network Drivers: Only the bridge and host network drivers are supported. macvlan and overlay network drivers are not supported.
- Port Binding: Binding to ports below 1024 is not allowed. Only non-privileged ports (1024 and above) can be used.
- File System
- Volume Permissions: Issues with file permissions can arise when mounting volumes from the host, as the files created by rootless Docker processes will be owned by the user running Docker, not root.
- NFS and Other Filesystems: Certain filesystems like NFS might have compatibility issues with rootless Docker due to permission and ownership constraints.
- Compatibility
- Certain Features: Some Docker features might not be fully supported or behave differently. For example, checkpoint/restore and cgroup v1 are not supported.
- Security Features: Some security features like AppArmor, SELinux, and seccomp might have limited functionality or require additional configuration.
- Configuration Complexity
- Troubleshooting
- Performance Overhead
- What's the difference between rootless Docker, running a container as a non-root user, and Podman?
- Docker Running In Rootless Mode
- Going rootless with Docker and Containers
- How to Run Rootless Docker Containers
docker pull
https://docs.docker.com/engine/reference/commandline/pull/
$ docker pull ubuntu:zesty $ docker run -ti --rm ubuntu:zesty /bin/bash # lsb_release -a bash: lsb_release: command not found # cat /etc/*release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=17.04 DISTRIB_CODENAME=zesty DISTRIB_DESCRIPTION="Ubuntu 17.04" NAME="Ubuntu" VERSION="17.04 (Zesty Zapus)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 17.04" VERSION_ID="17.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=zesty UBUNTU_CODENAME=zesty
Update/upgrade images
- I have an image called 'rocker/tidyverse:latest' that was pulled sometime ago. I ran docker pull rocker/tidyverse:latest' again. It will pull the latest image. The old image was not deleted and it has a new tag <none>.
- How to remove a signed image with a <none> tag
- Same thing happened today. I run docker pull r-base to upgrade my r-base from v3.6.3 to v4.0.0. After the upgrade, the old image has a tag <none>. I can use docker rmi command to remove the <none> image.
- How to update all pulled Docker images that are tagged as latest
- What's Wrong With The Docker :latest Tag? Do not run any container with the latest tag.
- How to upgrade container properly? "docker-compose pull" to update all your service and "docker-compose up -d" to start them all. docker swarm is even better because you can achieve zero downtme rolling upgrades.
- The following two are equivalent
docker compose pull && docker compose up -d docker compose up --pull always -d
<none>:<none> images
Exit/detach from a container without stopping it
$ docker container run -it ubuntu:latest /bin/bash # Ctrl+p, Ctrl+q to exit the container without terminating it $ docker ps -a # showing the container 70c5aceb5512 is running in the background # You can reattach your terminal to it with the "docker container exec" command $ docker container exec -it 70c5aceb5512 bash
How to start a stopped Docker container with a different command
How to start a stopped Docker container with a different command?
Clean shutdown DOCKER containers before reboot
- Clean shutdown DOCKER containers before reboot or shutdown OMV systemctl stop docker
- How to Stop Docker Containers docker ps -q | xargs docker stop
Dockerizing Applications/Detached mode
$ sudo docker run -d --name insane_babbage ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done" $ sudo docker ps -l $ sudo docker logs insane_babbage $ sudo docker stop insane_babbage $ sudo docker ps
The -d flag tells Docker to run the container and put it in the background, to daemonize it.
According to https://docs.docker.com/engine/reference/run/#detached-vs-foreground, containers started in detached mode exit when the root process used to run the container exits, unless you also specify the --rm option. If you use -d with --rm, the container is removed when it is stopped, exits or when the daemon exits, whichever happens first.
Automatically restart after reboot
Add a --restart=always parameter. It will always restart a stopped container unless it has been explicitly stopped, such as via a "docker container stop" command. See the following
- https://docs.docker.com/engine/reference/commandline/run/#restart-policies-restart
- https://docs.docker.com/engine/admin/start-containers-automatically/#restart-policy-details
$ docker run -d --restart always myCustomeDocker $ docker container run --name neverdie -it --restart always ubuntu /bin/bash # exit $ docker ps -a # the container is still ther $ docker stop neverdie $ docker ps -a
Working with Containers
$ sudo docker run -i -t ubuntu /bin/bash $ sudo docker version $ sudo docker $ sudo docker attach --help
Environment variables
- Passing Environment Variables to Docker Containers
- Environment variables in Compose
- An example: Docker github runner
Docker container ID
- The full container ID is a hexadecimal string of 64 characters.
- The minimum number of characters required for a Docker ID is 4.
- We can use a shorter ID in docker command if that ID uniquely determined the container. For example, docker exec -it 9608 bash or even docker exec -it 9 bash works.
Alpine image
- Alpine Linux: A Breath of Fresh Mountain Air for Linux Experts
- A minimal Docker image based on Alpine Linux with a complete package index and only 5 MB in size!
- Container Tutorials > Getting Started with Alpine
- The 3 Biggest Wins When Using Alpine as a Base Docker Image
- 10 Alpine Linux apk Command Examples
apk add htop
Running a Web Application
$ sudo docker run -d -P training/webapp python app.py
Alpine linux is 6MB. It is a good OS to run a web application. See the demo here.
Viewing our Web Application Container
$ sudo docker ps -l $ sudo docker run -d -p 5000:5000 training/webapp python app.py
Check container status (docker status) - CPU, Memory usage
- How to Check Memory and CPU Utilization of Docker Container, How to Check Docker Container RAM and CPU Usage
docker stats # ctrl + c to quit docker stats CONTAINER # multiple 'ctrl + c' to quit docker stats --no-stream docker stats --no-stream CONTAINER
- docker stats
Container networking
- https://docs.docker.com/network/
- Use user-defined bridge networks
$ docker network create MyNewNetworkName $ docker network ls NETWORK ID NAME DRIVER SCOPE abae0010bf2c MyNewNetworkName bridge local bf4e73473028 bridge bridge local 7dac0804bc33 host host local dbe7f0daef6d none null local $ docker network remove MyNewNetworkName # OR docker network rm MyNewNetworkName
- https://youtu.be/Ox5mZBwc92E
- Use dig to find out the IP and run DNS query. Docker Compose: a nice way to set up a dev environment
- Mastering the Docker networking
Host network
- If you use the host network driver for a container, that container’s network stack is not isolated from the Docker host. For instance, if you run a container which binds to port 80 and you use host networking, the container’s application will be available on port 80 on the host’s IP address.
- One good example is if I want to use tailscale network from my host in Uptime Kuma container. See HERE.
- Considerations. While host networking can be powerful, it's important to consider:
- Security implications: Host networking reduces network isolation, potentially increasing security risks.
- Port conflicts: Services using host networking may conflict with other applications running on the host machine.
- Platform limitations: Host network mode only works on Linux hosts, not on Docker Desktop for Mac or Windows.
ping, ifconfig and ip commands not found in Ubuntu container
apt update apt install iputils-ping # ping apt install net-tools # ifconfig apt install iproute2 # ip
Network Port Shortcut
$ sudo docker port nostalgic_morse 5000
Access Ports on the Host from a Docker Container
How to Access Ports on the Host from a Docker Container
Multiple NICs
containers in docker to use public ip addresses directly
Viewing the Web Application's Logs
- Installing Dozzle: A Superb Real-Time Docker’s Logs Viewer, Dozzle docker image.
- Command line
$ sudo docker logs -f nostalgic_morse
Clear Logs of Running Docker Containers
- How to Clear Logs of Running Docker Containers
- Reducing Docker Logs Size: A Practical Guide to Log Management
Looking at our Web Application Container's processes
$ sudo docker top nostalgic_morse
Inspecting our Web Application Container
$ sudo docker inspect nostalgic_morse
Obtain the container's IP address, log into a running server
PS. Portainer web interface can show the IP addresses.
$ docker inspect <container id> | grep "IPAddress"
We don't need the IP address if we just want to log into a running server,
$ docker exec -it <contianer id> bash
How to Secure Docker’s TCP Socket
How to Secure Docker’s TCP Socket with TLS
docker attach
Suppose I run docker run -it --user rstudio bioconductor/bioconductor_docker:devel R and I use q() to quit the container. The container is still there. To re-enter the R in the container, I use
docker start XXXXXXXX # restart it in the background docker attach XXXXXXXX # reattach the terminal to a running container
If we want the latest created container, then we use
docker start `docker ps -q -l` && docker attach `docker ps -q -l`
docker exec: SSH into a running container
Run a command in a running container
- Usage:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
- Examples:
$ docker exec -d ubuntu_bash touch /tmp/execWorks # do st in the background $ docker exec -it ubuntu_bash bash $ docker exec -it -e VAR=1 ubuntu_bash bash # set an environment variable $ docker exec -it ubuntu_bash pwd $ docker exec -it -w /root ubuntu_bash pwd # change the working directory
- How to Run a Command on a Running Docker Container
- How to Use the Docker exec Command. nginx container is used as an example.
docker run --name docker-nginx -p 8080:80 -d nginx # method 1. Access the Running Container’s Shell docker exec -it ID /bin/bash apt-get update apt-get upgrade -y exit # method 2. Run a Command from Outside the Container docker exec ID apt-get update && apt-get upgrade docker exec ID cat /usr/share/nginx/html/index.html docker cp index.html ID:/usr/share/nginx/html/ docker exec ID cat /usr/share/nginx/html/index.html
docker cp
- https://docs.docker.com/engine/reference/commandline/cp/
- https://linuxhandbook.com/docker-cp-example/
Copy files/folders between a container and the local filesystem.
Restart an exited Container
- https://docs.docker.com/engine/reference/commandline/start/
- https://www.linuxnix.com/docker-start-exited-container/
$ docker start nostalgic_morse OR $ docker restart nostalgic_morse
For an interactive container, use docker start -ai CONTAINER which is equal to run "docker start CONTAINER" and "docker attach CONTAINER".
Rename a container
docker container rename CONTAINER NEW_NAME
Inspect container images and their metadata
Know the container size
docker ps -s
- The "size" information shows the amount of data (on disk) that is used for the writable layer of each container
- The "virtual size" is the amount of disk-space used for the read-only image data used by the container.
Removing our Web Application Container
$ sudo docker stop nostalgic_morse $ sudo docker rm nostalgic_morse
Note: Always remember that deleting a container is final!
Dockerize an SSH service
https://docs.docker.com/engine/examples/running_ssh_service/#environment-variables
Remove old docker containers
This post on stackoverflow.com.
$ sudo docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs --no-run-if-empty sudo docker rm
Similarly to remove all exited containers
$ sudo docker ps -a | grep Exit | awk '{print $1}' | xargs sudo docker rm
To kill/stop (not delete) all running containers
$ sudo docker kill $(sudo docker ps -q)
To delete all stopped containers
$ sudo docker rm $(sudo docker ps -a -q) OR $ sudo docker rm `sudo docker ps -a -q`
It is also helpful to create bash aliases for these commands by editing ~/.bash_aliases file.
docker create vs docker run
https://stackoverflow.com/questions/37744961/docker-run-vs-create
docker create is similar to docker run -d except the container is never started.
Retrieve docker run command
https://stackoverflow.com/a/32774347. See the github page of runlike. So it is better to put the docker run in a stack. Then for example the Portainer has an Editor tab to show the compose file.
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ assaflavie/runlike -p CONTAINER_NAME
The -p option splits the output into pretty lines.
docker run -it and -d together
- Practically, what is the difference between docker run -dit(-itd) vs docker run -d?
- "docker run -dit" vs "docker run -d" #10632
How to Modify the Configuration of Running Docker Containers
How to Modify the Configuration of Running Docker Containers
Volume
- https://docs.docker.com/storage/volumes/
- docker volume create documentation
- If we try to mount an empty dir on the host to a non-empty dir (eg mediawiki/extensions) in a container, it will mess up.
- Using Docker Data Volume with a MySQL container
- What Are Docker Volumes, and How Do You Use Them?
Examples of host's volume locations
/home/$USER/docker/$PROJECT/$SUB-DIRECTORY
- Understanding PUID and PGID (or the source)
- You should use the -e PUID and -e PGID options when creating a container from a Docker image to map the container’s internal user to a user on the host machine. This is useful because Docker runs all of its containers under the root user domain, which means that processes running inside your containers also run as root. This kind of elevated access is not ideal for day-to-day use and can potentially give applications access to things they shouldn’t. By using PUID and PGID, you can ensure that files and directories created during the container’s lifespan are owned by a user on the host machine instead of root.
- Please note that not all Docker images support the PUID and PGID environment variables. The Docker image must be designed to use these variables. If you’re using an image that doesn’t support these variables, you may need to create a Dockerfile to build a new image that does.
- The following works. The --user option is a built-in Docker feature that sets the user (and optionally the group) that is used to run the container. This option works regardless of whether the Docker image uses any specific environment variables. PS. "docker" user has been defined in the r-base's Dockerfile.
docker run --rm -ti --user docker \ -v "$(pwd)":/workspace r-base > setwd("/workspace") > save(iris, file="iris.rda") > system("ls -lt") # docker docker instead of $USER $USER > unlink("iris.rda")
- Similarly, the --user option works with rocker/rstudio image and ubuntu.
docker run --rm -ti --user rstudio \ -v "$(pwd)":/workspace rocker/rstudio R > setwd("/workspace") > save(iris, file="iris.rda") > system("ls -lt") > unlink("iris.rda")
Note that the prompt is $ rather than #.
docker run --rm -it -v $(pwd):/home --user ubuntu \ ubuntu bash $ id uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev) $ cd /home $ echo "newfile" > newfile
docker run --rm -it -v $(pwd):/home --user "$(id -u):$(id -g)" \ ubuntu bash $ cd /home $ echo "newfile" > newfile
- In the article Sharing files with host machine from the Rocker's project, users are instructed to use -e USERID variable if the host machine user has a UID other than 1000. But the generated file 'iris.rda' from the following example is still owned by root:(
docker run --rm -ti -v "$(pwd)":/workspace -e USERID=$UID rocker/rstudio R
- (Cont.) however, if we run the above command as a daemon and log in using the user "rstudio" , it works even we don't specify the "-e USERID" option. The lesson is we should use the user defined in the docker image.
docker run --rm -v "$(pwd)":/workspace -p PASSWORD=123 rocker/rstudio
Notice the prompt is # rather than $ and the user id is 0.
docker run --rm -it -v $(pwd):/home -e PUID=1000 -e PGID=1000 \ ubuntu bash # id uid=0(root) gid=0(root) groups=0(root)
- In this video How to Install Calibre on OMV and Docker, it uses the command id admin where "admin" is the portainer user to get PUID (of "admin") and PGID (of "users") to find out the two ids.
Back Up Your Docker Volumes
How to Back Up Your Docker Volumes
Two ways to achieve persistent data
- Persistent data in Docker volumes
- How to Deal with Docker Container Persistence and Storage. Docker has two ways to achieve persistence: volume mounts, and bind mounts.
Inspect the 'Mountpoint' of a volume
$ docker volume create crv $ docker volume ls $ docker run -d \ --name mycloud \ -p 81:80 \ -v apps:/var/www/html/custom_apps \ nextcloud # docker inspect is not quite useful. It does not show how the volume was created # But we can examine (ls, du, ...) the directory contents $ docker inspect apps [ { "CreatedAt": "2018-10-23T09:41:52-04:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/apps/_data", "Name": "apps", "Options": null, "Scope": "local" } ]
Remove an an unnamed volume
I you want to automatically removes volumes when a container is removed, you can use the --rm flag when starting the container with the "docker run" command. This flag tells Docker to automatically remove the container and any anonymous volumes associated with it when the container exits. However, this flag does not affect named volumes.
If you created an unnamed volume, it can be deleted at the same time as the container with the -v flag. Note that this only works with unnamed volumes.
docker rm -v container_name
If the volume is named, it stays present. To remove a named volume, use docker volume rm volume_name .
Volumes created in docker-compose
When you use docker-compose to create and manage containers, volumes are handled slightly differently than when using the docker run command.
In a "docker-compose.yml" file, you can specify named volumes using the volumes key at the top level of the file. These volumes are created when you run docker-compose up and are not automatically removed when you stop or remove the containers using docker-compose down.
If you want to remove named volumes created by docker-compose, you can use the -v flag with the docker-compose down command. Here’s an example command that stops and removes all containers defined in a docker-compose.yml file and also removes any named volumes:
docker-compose down -v
This command stops and removes all containers defined in the docker-compose.yml file and also removes any named volumes specified in the file. All data stored in the volumes will be permanently deleted.
Anonymous volumes created by docker-compose are automatically removed when you stop and remove the containers using docker-compose down, even if you don’t use the -v flag.
Start a container with a volume
--mount | -v |
---|---|
docker run -d \
--name devtest \ |
docker run -d \
--name devtest \ |
Note
- target in "--mount" can be replaced by destination or dst.
- To use a read-only volume, add the ,readonly option in "--mount" or the :ro option in "-v".
- We cannot use "~/" to represent a local directory under HOME. We have to specify a full path in docker run.
A simple example
From the book "Learn Docerk -Fundamentals of Docker 18.x". Chap 5. Data Volumes and System Management > Creating and mounting data volumes.
# Create a volume docker volume create my-data docker volume inspect my-data # The host folder can be found in the output under 'Mountpoint' # In my case, # "Mountpoint": "/var/lib/docker/volumes/my-data/_data", # Mount a volume into a container docker run --name test -it -v my-data:/data alpine /bin/sh # cd /data # echo 'some data' > data.txt # echo 'more data' > data2.txt # exit docker inspect my-data sudo ls /var/lib/docker/volumes/my-data/_data # We can even try to output the content of say, the second file: sudo cat /var/lib/docker/volumes/my-data/_data/data2.txt # We can create a new file in this folder from the host and then use the volume with another container echo "the file is created on host" > sudo tee /var/lib/docker/volumes/my-data/_data/host-data # Let's delete the test container and run another one docker rm test # This time we are mounting our volume to a different container folder docker run --name test2 -it -v my-data:/app/data centos:7 /bin/bash # We are able to see three files: # ls /app/data # Remove volumes docker volume rm my-data # Or docker volume rm $(docker volume ls -q) # Remove all running containers to clean up the system, docker rm -f $(docker ls -aq)
Sharing data between containers
How to Share Data Between Docker Containers
docker run -it --name writer -v shared-data:/data alpine /bin/sh # create a file inside it # echo 'my sample file' > /data/sample.txt # exit docker run -it --name reader -v shared-data:/app/data:ro ubuntu:17.04 /bin/bash # ls -l /app/data
Using host volumes
Use volumes that mount a specific host folder
- It may be possible for the "docker volume" command to mount a local directory to a volume. See examples in the "docker volume create" documentation.
- Specifying a directory name instead of giving a volume name in the "docker run" 's -v option
- Since we are specifying a directory name instead of letting docker to create a new volume, "docker volume ls" will not getting a new volume
docker run -it --name test -v $(pwd)/src:/app/src alpine /bin/sh # Make a sample to demonstrate how that works mkdir ~/my-web; cd ~/my-web echo "<h1>My website</h1>" > index.html # Create 'Dockerfile' echo -e 'FROM nginx:alpine COPY . /usr/share/nginx/html' > Dockerfile docker image build -t my-website:1.0 . docker run -d -p 8080:80 --name my-site my-website:1.0 # Open http://localhost:8080. It looks good # Now modify index.html and refresh the website. It does not refresh # Let's stop and rm the container and rebuild using a volume docker rm -f my-site docker run -d -v $(pwd):/usr/share/nginx/html \ -p 8080:80 --name my-site my-website:1.0 # Now any changes on index.html will refresh on the website
Define volumes in images
A few samples of volume definition
VOLUME /app/data VOLUME /app/data, /app/profiles, /app/config VOLUME {"/app/data", "/app/profiles", "/app/config"]
The first line defines a single volume to be mounted at /app/data.
We can use the docker image inspect command to get information about the volumes defined in the Dockerfile.
docker image pull mongo:3.7 docker image inspect --format='{{json .ContainerConfig.Volumes}}' \ mongo:3.7 | jq # { # "/data/configdb": {}, # "/data/db": {} # } # now run an instance of MongoDB and inspect the volume information docker run --name my-mongo -d mongo:3.7 docker inspect --format '{{json .Mounts}}' my-mongo | jq # [ # { # "Type": "volume", # "Name": "535e0138b9a32e89f71380e9e73bb0de64ce0d1cad78fcda0ec1d49e11d76d7a", # "Source": "/var/lib/docker/volumes/535e0138b9a32e89f71380e9e73bb0de64ce0d1.../_data", # "Destination": "/data/configdb", # "Driver": "local", # "Mode": "", # "RW": true, # "Propagation": "" # }, # { # "Type": "volume", # SKIP
Differences between VOLUME and '-v|--volume'
https://stackoverflow.com/a/25312719
Container Memory Limits, Setting Available CPUs, Allocating memory and CPU
docker run \ -rm \ ## Automatically remove the container when it exits --memory=6g \ ## memory limit --cpus=1.5 \ ## number of CPUs -v /shared/data-store:/home/rstudio/data \ -v /shared/library-store:/usr/local/lib/R/host-site-library \ -e PASSWORD=bioc \ -p 8787:8787 \ bioconductor/bioconductor_full:devel
- Get started with Docker Desktop for Mac, Windows
- Limit a container's resources
- TOP 5 BLOG OF 2018: IMPROVED DOCKER CONTAINER INTEGRATION WITH JAVA 10
- parallelly 1.31.1: Better at Inferring Number of CPU Cores with Cgroups and Linux Containers
- Docker Container Memory Limits Explained
- How to Set a Memory Limit for Docker Containers
Work with container images
List images by size or name
# by size docker images --format "{{.ID}}\t{{.Size}}\t{{.Repository}}" | sort -k 2 -h # by name docker images --format "{{.ID}}\t{{.Size}}\t{{.Repository}}" | sort -k 3
List specific columns
docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.Size}}'
Create an image interactively using commit - Example 1
The example is from the book 'Learn Docker - Fundamentals of Docker 18.x'.
docker container run -it --name sample alpine /bin/sh # apk update && apk add iputils # ping 127.0.0.1 # exit docker container ls -a | grep sample docker container diff sample
We can now use the docker container commit command to persist our modifications and create a new image from them
docker container commit sample my-alpine docker images ls
If we want to see how our custom image has been built, we can use the history command as follows:
docker image history my-alpine # IMAGE CREATED CREATED BY SIZE COMMENT # 0f105057899b About a minute ago /bin/sh 1.55MB # 196d12cf6ab1 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B # <missing> 4 weeks ago /bin/sh -c #(nop) ADD file:25c10b1d1b41d46a1… 4.41MB
The first layer in the preceding list is the one we just created by adding the iputils package.
Create an image interactively using commit - Example 2
- How to Create a Docker Image From a Running Container. Commit messages are displayed when you use the docker history command to view the layers in an image.
- How to commit changes to a docker image
Note that it is better/necessary to put the Dockerfile in an empty directory to avoid the problem of taking a long time to build the image (sending build context to Docker daemon ...GB ) since it will grab files from the current directory.
sudo docker search sinatra sudo docker pull training/sinatra sudo docker run -t -i training/sinatra /bin/bash sudo docker commit -m="Added json gem" -a="Kate Smith" 0b2616b0e5a8 ouruser/sinatra:v2 sudo docker images mkdir sinatra cd sinatra touch Dockerfile sudo docker build -t="ouruser/sinatra:v2" . sudo docker push ouruser/sinatra sudo docker rmi training/sinatra
- I get an error when I try to launch sinatra on my 32-bit ubuntu (Docker can only be installed through apt-get on 32-bit)
$ sudo docker run -t -i training/sinatra /bin/bash 2014/12/31 02:43:26 exec format error
How to copy Docker images from one host to another without using a repository
docker save -o out.tar <image name> # Or better to compress the file docker save <docker image name> | gzip > out.tar.gz
And restore
docker load -i out.tar # Or decompress the file docker load < out.tar.gz
Docker Image Manifest
What Is a Docker Image Manifest?
Resources allocated to a container using docker?
hub.docker.com
- Note that Dockerfile is optional on https://registry.hub.docker.com.
- For free account, we can have only 1 free private repository. If we want to create a new repository online, we can
docker tag local-image:tagname new-repo:tagname docker login docker push new-repo:tagname
- How to push a docker image to a private repository
- rocker. The Dockerfile is included there. Question: how to automatically build the image rather than uploading pre-built image binaries to Docker Hub?
- Search all repositories related to R
- baseimage-docker. I can use ping command without special argument when I start phusion/baseimage.
docker pull phusion/baseimage docker run -ti phusion/baseimage /bin/bash
- https://dockerfile.github.io/ which includes dockerfiles for different purposes. The ubuntu-desktop one also works well (client needs a vnc viewer in order to see the desktop).
Set up a private Docker registry
- https://docs.docker.com/registry/
docker run -d -p 5000:5000 --name registry registry:2 docker pull ubuntu docker image tag ubuntu localhost:5000/myfirstimage docker push localhost:5000/myfirstimage docker pull localhost:5000/myfirstimage docker container stop registry && docker container rm -v registry
- https://docs.docker.com/registry/deploying/
- Ubuntu 14.04 from digitalocean
- How to Setup Private Docker Registry on Ubuntu 18.04 LTS
- How to Setup Secure Docker Registry on Linux using TLS SSL Certificate
- List repositories in the local registry. Docker Registry HTTP API V2 and HTTP POST and GET using cURL in Linux.
$ curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:5000/v2/_catalog $ OR $ curl -H "Accept: application/xml" -H "Content-Type: application/json" -X GET http://localhost:5000/v2/_catalog
Github registry
- Docker Support for the New GitHub Container Registry
- Migrating to GitHub Container Registry for Docker images
- How to Get Started with Github’s New Docker Container Registry
- Publish images to GitHub Container Registry (ghcr)
docker pull ghcr.io/OWNER/IMAGE_NAME:TAG # docker pull registry-url/image-name:tag
Google Container Registry
- Authenticate with Google Cloud: ensure you have the Google Cloud SDK installed
gcloud auth login gcloud auth configure-docker
- Pull the image
docker pull gcr.io/PROJECT_ID/IMAGE_NAME:TAG
Google Artifact Registry
https://cloud.google.com/artifact-registry/
- Authenticate with Google Cloud: ensure you have the Google Cloud SDK installed
gcloud auth login gcloud auth configure-docker us-central1-docker.pkg.dev
- Pull the image
docker pull us-central1-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME:TAG
Dockerfile
- A Dockerfile does not follow the YAML syntax or the shell syntax. It is a plain text file that contains instructions for building a Docker image, using its own specific syntax and keywords.
- Dockerfile Reference
- Using Dockerfiles to Automate Building of Images from digitalocean.com.
Remember to put the Dockerfile in an empty directory.- What goes into a Dockerfile
- Keywords
- FROM. If we want to start from scratch, we can use FROM scratch.
- RUN. The argument for RUN is any valid Linux command.
- USER. This is useful if we want to create new files with a non-root owner privilege. For example, new files created under a binding directory with a non-root user ownership will belong to the current user in the host system. Here is an example where we use Rmarkdown to create pdf output. The generated pdf file should not be own by root. How to add users to Docker container? Switch users.
- COPY & ADD.
- "COPY . /app" will copy all files and folders from the current directory recursively to the /app folder. We can use "ADD" too but "ADD" will automatically unpack tarballs. See What is the difference between the `COPY` and `ADD` commands in a Dockerfile?
- "ADD sample.tar /app/bin" will unpack the sample.tar' file into the target folder
- "ADD http://example.com/sample.txt /data/" will copy the remote file sample.txt into the target file
- WORKDIR. Define the working directory or context that is used when a container is run from the image.
- CMD & ENTRYPOINT. These two are actually definitions of what will happen when a container is started from the image.
- Use CMD without ENTRYPOINT: "CMD command param1 param2". This form is called the shell form.
- If we use ENTRYPOINT + CMD, ENTRYPOINT defines the command and CMD defines parameters. The example above will run ping 8.8.8.8 -c 3. This form is called the exec form.
- The Docker Book
Examples of Dockerfile
- Only the instructions RUN, COPY, ADD create layers.
- A sample. Six layers (lines). The first line is the Base Layer.
FROM python:2.7 RUN mkdir -p /app WORKDIR /app COPY ./requirements.txt /app/ RUN pip install -r requirements.txt CMD ["python", "main.py"]
- Another example
FROM alpine:latest ENTRYPOINT ["ping"] CMD ["8.8.8.8", "-c", "3"]
- Another example from RStudio
FROM debian:testing RUN useradd docker \ && mkdir /home/docker \ && chown docker:docker /home/docker \ && addgroup docker staff
We can test it by "docker build -t mydebian . " and "docker run --rm -it --user docker -v /tmp:/home/docker mydebian". We can create a new file under /home/docker and the file will be accessible and belongs to the current host user once we quit the container. This actually is a huge security issue.
The same technique does not work on alpine if I try to create a new file in the container.
FROM alpine:latest # Create a group and user; not useful for creating files in host OS RUN addgroup -S appgroup && adduser -S appuser -G appgroup \ && chown appuser:appgroup /home/appuser
"docker build -t myalpine . " and "docker run --rm -it -v ~/Downloads/:/home/appuser:rw --user appuser myalpine". When I use the "id" command in the container, I see it returns 100 in alpine container and 1000 in debian container. The id returns 1000 on my host (Ubuntu/Pop_OS). So the solution is docker run --rm -it -v ~/Downloads/:/home/appuser --user 1000:1000 myalpine. So the local user and the created user home directory in the container are not needed. See
Rocker
FROM r-base:latest COPY check.R . CMD [ "Rscript", "check.R", "/unsafe.rda"]
$ git clone https://github.com/hrbrmstr/rdaradar.git $ docker build -t rdaradar:0.1.0 -t rdaradar:latest . $ docker run --rm -v "$(pwd)/exploit.rda:/unsafe.rda" rdaradar
Bioconductor
Papers
- DrivR-Base, Poster, Paper 2024
How to use Dockerfile
https://docs.docker.com/engine/reference/commandline/build/
The . simply means "current working directory".
docker build -f Dockerfile -t arraytools/myimagename . docker build -t [myname] . # Multiple tags docker build -t arraytools/biospear:latest -t arraytools/biospear:3.6.0 .
In the above example, we can create the image by
docker image build -t pinger .
We can run a container from the pinger image
docker container run --rm -it pinger
Docker Build Args
How to Use Docker Build Args to Configure Image Builds
Clean up after failed builds
Cleanup docker images and containers after failed builds
#!/bin/bash docker rm $(docker ps -aq) \ docker rmi $(docker images | grep "^<none>" | awk '{print $3}')
ENTRYPOINT and CMD
- If your container acts like a command-line program, you can use ENTRYPOINT. If you are unsure, you can use CMD.
- Understanding Docker’s CMD and ENTRYPOINT Instructions. It shows how to supply arguments to the command we like to execute in the container.
- https://docs.docker.com/engine/reference/builder/#cmd
- Creating Advanced Entrypoints for Containers. In this case CMD provides extra parameters to ENTRYPOINT.
- The Dockerfile from How to compile R Markdown documents using Docker uses both ENTRYPOINT and CMD where in this case CMD provides extra parameters to ENTRYPOINT.
The advantage of using ENTRYPOINT + CMD (exec form) instead of using CMD alone (shell form) is we can override the CMD part that I have defined in the Dockerfile.
docker container run --rm -it pinger -w 5 127.0.0.1 # ping the loopback for 5 seconds
If we want to overwrite what's defined in the ENTRYPOINT in the Dockerfile, we need to use the --entrypoint parameter.
docker container run --rm -it --entrypoint /bin/sh pinger # we'll be inside the container. Type exit to leave the container
When we use the shell form, the ENTRYPOINT is have the default value of /bin/sh -c and whatever is the value of CMD will be passed as a string to the shell command.
Temporary failure resolving 'deb.debian.org' when running "docker build"
Add "--net=host" to the docker build command. See Docker build “Could not resolve 'archive.ubuntu.com'” apt-get fails to install anything
Best practices for writing Dockerfiles
- https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
- Intro Guide to Dockerfile Best Practices
Use multi-stage builds
- https://docs.docker.com/develop/develop-images/multistage-build/
- What Are Multi-Stage Docker Builds?
With multi-stage builds, we have a single Dockerfile containing multiple FROM instructions. Each FROM instruction is a new build stage that can easily COPY artifacts from previous stages.
An example from the "Docker Deep Dive" book.
tag after image was built
$ docker tag <imageID> <newName>/<repoName>:<tagName>
About storage drivers
https://docs.docker.com/storage/storagedriver/#sharing-promotes-smaller-images
Privileged versus Root user in Docker
- Privileged versus Root in Docker: What’s the Difference?
- Docker and Kubernetes — root vs. privileged
.dockerignore
Using .dockerignore files to build better Docker images
Dockerfile in One Line
FROM ubuntu
Using This simple Dockerfile and the docker command sudo docker build -t scooby_snacks . will result in
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 15.04 2427658c75a1 42 hours ago 117.5 MB ubuntu vivid 2427658c75a1 42 hours ago 117.5 MB ubuntu vivid-20150218 2427658c75a1 42 hours ago 117.5 MB ubuntu utopic-20150211 78949b1e1cfd 42 hours ago 194.4 MB ubuntu utopic 78949b1e1cfd 42 hours ago 194.4 MB ubuntu 14.10 78949b1e1cfd 42 hours ago 194.4 MB ubuntu 14.04 2d24f826cb16 42 hours ago 188.3 MB ubuntu 14.04.2 2d24f826cb16 42 hours ago 188.3 MB ubuntu trusty 2d24f826cb16 42 hours ago 188.3 MB ubuntu trusty-20150218.1 2d24f826cb16 42 hours ago 188.3 MB ubuntu latest 2d24f826cb16 42 hours ago 188.3 MB scooby_snacks latest 2d24f826cb16 42 hours ago 188.3 MB ubuntu precise 1f80e9ca2ac3 42 hours ago 131.5 MB ubuntu precise-20150212 1f80e9ca2ac3 42 hours ago 131.5 MB ubuntu 12.04.5 1f80e9ca2ac3 42 hours ago 131.5 MB ubuntu 12.04 1f80e9ca2ac3 42 hours ago 131.5 MB ubuntu 14.04.1 5ba9dab47459 3 weeks ago 188.3 MB ubuntu 12.10 c5881f11ded9 8 months ago 172.2 MB ubuntu quantal c5881f11ded9 8 months ago 172.2 MB ubuntu 13.04 463ff6be4238 8 months ago 169.4 MB ubuntu raring 463ff6be4238 8 months ago 169.4 MB ubuntu 13.10 195eb90b5349 8 months ago 184.7 MB ubuntu saucy 195eb90b5349 8 months ago 184.7 MB ubuntu 10.04 3db9c44f4520 10 months ago 183 MB ubuntu lucid 3db9c44f4520 10 months ago 183 MB
List all tags of an image
How can I list all tags for a Docker image on a remote registry?
Tag the image with the git commit ID
$ docker build -t REPOS/IMAGE:$(git rev-parse --verify HEAD)
Run a shell script on host
$ docker run -v /path/to/sample_script.sh:/sample_script.sh \ --rm ubuntu bash sample_script.sh # GATK container example # First we log in interactive and see where is the default location (/usr in this case) $ docker run --rm -i -t broadinstitute/gatk3:3.8-0 bash $ cat > tmp.sh << EOF > pwd > ls > java -jar GenomeAnalysisTK.jar --version > EOF $ docker run --rm -v $(pwd):/usr/my broadinstitute/gatk3:3.8-0 bash my/tmp.sh # ALTERNATIVELY, WE CAN PUT OUR SCRIPT IN THE TOP DIRECTORY (Hopefully the name is not duplicated) $ docker run --rm -v $(pwd)/tmp.sh:/tmp.sh broadinstitute/gatk3:3.8-0 bash /tmp.sh
- https://askubuntu.com/questions/890533/how-can-i-run-docker-commands-after-docker-run-from-a-script (need to leave a container open)
docker run -d -v$(pwd):/my SOMEIMAGE bash docker exec -d Test bash /my/script.sh
- Create a Dockerfile https://forums.docker.com/t/how-to-run-bash-command-after-startup/21631/2
Link containers together
Manage data in containers
- https://docs.docker.com/storage/volumes/
- https://codereviewvideos.com/course/docker-tutorial-for-beginners/video/part-2-docker-volumes-volumes
Assign a static IP to a container
- How to Assign a Static IP to a Docker Container
- https://stackoverflow.com/questions/27937185/assign-static-ip-to-docker-container
# Step 1. create you own docker network (mynet123) docker network create --subnet=172.18.0.0/16 mynet123 # Step 2. simply run the image (I'll take ubuntu as example) docker run --rm --net mynet123 --ip 172.18.0.22 -it ubuntu bash # Check in the container shell # Note that the container CAN access internet apt install net-tools; ifconfig exit
- https://docs.docker.com/engine/reference/commandline/network_create/#bridge-driver-options
- Try using the --net=host option (no a new IP was allocated; not a good solution)
Running Multiple Docker Services on the Same Server
How to Run Multiple Docker Containers on Different IP Addresses
Firewall
Rstudio server not loading, taking too long to respond in browser. On Ubuntu run sudo ufw allow PORTNUMBER.
Docker DNS/internet problem
I got an error on resolving the debian server when I was creating an image from a Dockerfile that needs to run apt update and apt install commands. See RStudio in Docker – now share your R code effortlessly!. The problem happened on my Linux Mint Desktop but not on a VirtualBox VM (Ubuntu 18.04).
Fix Docker's networking DNS config
A temporary solution is to add the --dns option to docker run command. This works well when I use the IP from any one of my 2 DNS servers. It does not work however if I use the IP from google DNS or OpenDNS.
A permanent solution is to create a new file /etc/docker/daemon.json and include the working DNS server IPs (these are obtained through the nmcli command or the NetworkManager GUI; see Query DNS server).
{ "dns": ["XXX.XX.XX.XX", "YYY.YY.YY.YY"] }
Then restart the docker service: sudo service docker restart
A quick test on the DNS problem is
docker run --rm busybox nslookup google.com
Working with Docker hub
https://docs.docker.com/userguide/dockerrepos/
Github Actions
- GitHub Actions for Docker
- Publishing Docker images
- See my Github page.
Enabling HTTPS/Let's encrypt
- Caddy
- https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion
- Enabling HTTPS with Let's Encrypt on Docker
- How to Set Up Free SSL Certificates from Let's Encrypt using Docker and Nginx and the source code.
- Setup encrypted Rstudio and Shiny dashboard solution in 3 minutes (2017). Not working now. ERROR: manifest for mikkelkrogsholm/rstudio:latest not found. After changing to use rocker/rstudio & rocker/shiny images, a new error came out
ERROR: for nginx Cannot start service nginx: b'driver failed programming external connectivity on endpoint nginx (879b01885acd6a0778d9403f4220851e83bd2ff8de643ce91c21cecd25419f83): Error starting userland proxy: listen tcp 0.0.0.0:443: bind: address already in use' ERROR: Encountered errors while bringing up the project.
- Enabling HTTPS with Let's Encrypt on Docker using Nginx.
Enabling HTTPS by self-sign certificates
- Creating Self-Signed SSL Certificates For Docker and Nginx
- Self-signed SSL Reverse proxy with Docker
- Using Docker to Generate SSL Certificates
- Configure Self-Signed SSL For Nginx Docker From A Scratch
- Creating a self-signed SSL certificate for local Docker development
traefik: The Cloud Native Application Proxy
- https://traefik.io/traefik/
- How To Use Traefik as a Reverse Proxy for Docker Containers on Ubuntu 18.04
- How to Install and Use Traefik as a Reverse Proxy with Docker on CentOS 8
- How To Use Traefik v2 as a Reverse Proxy for Docker Containers on Ubuntu 20.04
- Docker reverse proxy using Traefik
- USING TRAEFIK AS A REVERSE PROXY
- How to Install Traefik 2 on OMV and Docker DB Tech 2020. Cloudflare, Portainer. Airsonic.
- Put Wildcard Certificates and SSL on EVERYTHING - Traefik Tutorial Apr 2021
- Raspberry Pi
- Put Wildcard Certificates and SSL on EVERYTHING - Traefik Tutorial (video)
Nginx proxy manager
- https://nginxproxymanager.com/
- NGINX Proxy Manager – How-To Installation and Configuration
- Access your internal websites! Nginx Reverse Proxy in Home Assistant
- How to Install and Use Nginx Proxy Manager with Docker 2022
- NGINX Proxy Manager – How-To Installation and Configuration the-digital-life
- https://hub.docker.com/r/jlesage/nginx-proxy-manager, Github
- Setting up a Reverse-Proxy with Nginx and docker-compose
- How to Setup NGINX as Reverse Proxy Using Docker. It works.
- Download the code from https://github.com/a-magdy/nginx-reverse-proxy-docker.
- On the step of modifying /etc/hosts, change the IP address from 172.31.30.78 to 127.0.0.1 for site1.test and site2.test. Or I can use docker inspect XXXX | grep IPAddress to find out the IP for site1_default and site2_default (these two names are defined in <docker-compose.yml>).
- Before creating proxy container, though two web services are up and running inside container, we still cannot test site1.test and site2.test.
- docker-compose build shows successful build. But where is the image?
- curl site1.test and curl site2.test work fine.
- We can also use a browser to check these two URLs. For https it still works though FF gives warnings for self signed certificates.
- nmap localhost will show ports 80 & 443 are open.
- How to set up an easy and secure reverse proxy with Docker, Nginx
- How to install Nginx as a reverse proxy server with Docker. Note that http://microservice1:8080; needs to be changed to reflect the true IP whether it is from a docker container or not. Also it does not work when I modify the --link option to use site1_app_1 and site2_app_1.
docker: Error response from daemon: Cannot link to /site1_app_1, as it does not belong to the default network.
- How to Deploy NGINX Reverse Proxy on Docker (multiple web services)
- How to Install and Use Portainer for Docker management with Nginx Proxy Manager
Running multiple web applications on a Docker host
- https://medium.com/@jmarhee/running-multiple-web-applications-on-a-docker-host-with-apache-85f673f02803. Tips: Enable proxy module in Apache. In the VirtualHost file, specify ProxyPass with a port number. No need to specify the DocumentRoot.
- https://medium.com/@francoisromain/host-multiple-websites-with-https-inside-docker-containers-on-a-single-server-18467484ab95. Nginx reverse-proxy is used.
- https://blog.florianlopes.io/host-multiple-websites-on-single-host-docker/. jwilder/nginx-proxy is used. No need (and should not to avoid a conflict of port 80) to install Nginx
docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy sudo nano /etc/hosts # add blog.domain.com and jenkins.domain.com for our testing purpose docker run -d --expose 80 -e VIRTUAL_HOST=blog.domain.com wordpress docker run -d --name jenkinsci --expose 8080 -e VIRTUAL_HOST=jenkins.domain.com -e VIRTUAL_PORT=8080 jenkins
- Use VIRTUAL_PORT if there are multiple ports associated with a container
- Use VIRTUAL_HOST if there are multiple domains associated with a container
- SSL and et al
Authentication: Authelia
Additional Self-Hosted Security with Authelia on NGINX Proxy Manager (video)
GUI apps
- How to Run GUI Applications in a Docker Container
- https://github.com/mviereck/x11docker/ which was used by Docker-kodi
- https://pelle.io/2014/07/11/delivering-gui-applications-with-docker/ Forward X11 approach
- https://linuxmeerkat.wordpress.com/2014/10/17/running-a-gui-application-in-a-docker-container/ Forward X11
- http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/ Share X11 socket
- https://github.com/rogaha/docker-desktop Xpra + Xephyr
- https://github.com/fcwu/docker-ubuntu-vnc-desktop VNC approach
Firefox example
Running GUI Applications in Docker Container
From ubuntu:20.04 RUN apt update RUN apt install firefox -y RUN apt install python3-pip -y RUN pip3 install notebook CMD /usr/bin/firefox CMD jupyter-notebook --allow-root
nano Dockerfile docker build -t gui . docker run --env="DISPLAY" --net=host --name=firefox gui
It works. However, I need to use docker rm -f firefox to kill it since Ctrl+c does not work.
Meld example, save a running container as an image
Running a GUI Application in a Docker Container. It works. Below is a modified version for creating the meld app. I can save file modified by meld. To use the app, I need to place files in the ~/Documents/docker (defined in -v). Note that the RAM usage is very minimal. Unfortunately on macOS, I got an error something related to Gtk.
host> docker image pull ubuntu:jammy # 22.04 host> docker container run --rm --net host -v /tmp/.X11-unix:/tmp/.X11-unix -it ubuntu:jammy container# apt update container# apt install -y meld host> xhost +local: container# export DISPLAY=:0 host> docker container ls # find the ID of the running container host> docker commit <ID> meld container# exit host> docker container run --rm --net host \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -v ~/Documents/docker:/meld \ -e DISPLAY \ --name=meld \ meld meld
R and httpgd package
- httpgd Docker vignette, installation from Github.
- It works. However, currently "httpgs" is archived in CRAN (2023/1/25). So my temporary solution is
$ docker run --rm -it r-base:4.2.2 bash # apt update # apt install libfontconfig1-dev # R > install.packages("remotes") > remotes::install_github("nx10/httpgd") ## note if we try to run 'httpgd::hgd(host = "0.0.0.0", port = 8888)', it does not work. ## The reason is we have not use "-p" option to expose a port in the previous "docker run" command ## open another terminal and create a docker image based on the current container $ docker ps -a | head $ docker commit CONTAINER_ID httpgd:4.2.2 $ docker run --rm -it -p 8888:8888 httpgd:4.2.2 R > httpgd::hgd(host = "0.0.0.0", port = 8888) > plot(1:5)
- It works when I tested it on a remote ubuntu server (R 4.4.0 & httpgd 2.0.1) (following the instruction on Docker vignette). Either IP or hostname works but the hostname URL link given by httpgd::hgd() needs to be modified to include .local.
- Some variation of using hgd()
hgd(host="0.0.0.0", port = 8888) # allow connection from any one from any computer hgd() # default is host=127.0.0.1, port will be random hgd(token="secret") # define the token hgd_browse() hgd_close() hgd_details() hgd_url() hgd_view()
- To use it with Bioconductor (the Bioconductor docker image will use p3m.dev to install binary R packages so it is fast to create images), we can do like this
$ docker run --rm -it -p 8888:8888 bioconductor/bioconductor_docker:RELEASE_3_18 R > install.packages("httpgd") > httpgd::hgd(host = "0.0.0.0", port = 8888)
OR use, for example, "bioconductor/bioconductor_docker:RELEASE_3_18" as the base image in the Dockerfile, and follow the same instruction from httpgd vignette to create a docker image.
$ nano Dockerfile_httpgd $ docker build . -f Dockerfile_httpgd -t bioc-httpgd:RELEASE_3_18 $ docker images $ docker run --rm -it --user rstudio -p 8888:8888 bioc-httpgd:RELEASE_3_18 R
- Singularity. The following is a definition file that is using the bioconductor image + the httpgd package.
Bootstrap: docker From: bioconductor/bioconductor_docker:RELEASE_3_18 %post apt-get update \ && apt-get install -y --no-install-recommends \ libfontconfig1-dev \ && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* \ && install2.r --error --skipinstalled --ncpu -1 \ httpgd \ && rm -rf /tmp/downloaded_packages %runscript exec /usr/local/bin/R %environment export LC_ALL=C
sudo singularity build bioc.sif bioc.def singularity run bioc.sif > httpgd::hgd(host = "0.0.0.0", port = 8888)
After we copy the URL, we need to modify the IP or hostname.
Docker-OSX
https://github.com/sickcodes/Docker-OSX
Delete/remove/prune unused resources
- Prune build cache (seems most effective)
docker builder prune docker system df -v # Check Docker disk usage sudo du -sh /var/lib/docker
- Prune containers
docker container prune # remove all containers that are not in ''running'' status # Docker will ask for confirmation before deleting the containers docker container prune -f docker container rm -f $(docker container ls -aq) # remove even the running containers
- Prune dangling images: Dangling images are images that aren’t tagged and aren’t referenced by any container. Normal but unused/unreferenced images are kept and won't be deleted. See <none>:<none>images.
docker image prune # unused image layers
- Remove all unused images: If you want to remove all images that aren’t used by any existing containers, you can use the -a flag. It will give a warning saying: this will remove all images without at least one container associated to them. "Exited" container like "hello-world" will not be deleted.
docker image prune -a
Used images means anyone shown by docker ps -a.
- Prune volumes
docker volume ls docker volume prune # unused volumes by at least one container docker volume prune --filter 'label=demo' docker volume prune --filter 'label=demo' --filter 'label=test'
- Prune networks
docker network prune
- Prune everything.
docker system prune
Plugins
How to Manage Docker Engine Plugins
Misc
LXC (raw Linux containers)
- https://help.ubuntu.com/lts/serverguide/lxc.html
- https://help.ubuntu.com/community/LXC
- https://askubuntu.com/questions/293275/what-is-lxc-and-how-to-get-started
- Setup Linux Container with LXC on Ubuntu 16.04
- LXC containers in Ubuntu Server 14.04 LTS
- Trying out LXD containers on our Ubuntu
LXC vs Docker
- https://diveintodocker.com/blog/why-i-got-started-with-docker
- https://unix.stackexchange.com/questions/254956/what-is-the-difference-between-docker-lxd-and-lxc and https://i.stack.imgur.com/a5Neb.png
Vagrant vs Docker
- http://stackoverflow.com/questions/16647069/should-i-use-vagrant-or-docker-io-for-creating-an-isolated-environment
- https://deliciousbrains.com/vagrant-docker-wordpress-development/
- Vagrant is easier to understand and is easier to get up and running but can be very resource intensive (in terms of RAM and space).
- Docker’s architecture is harder to understand and can be harder to get up and running but is much faster, uses much less CPU and RAM and potentially uses much less space than Vagrant VM’s.
- https://youtu.be/9QGkJvbLpRA?t=3m22s
- Docker uses container technology while vagrant uses virtual machines.
- If security is a concern, use vagrant and virtual machine
- For speeding development and sharing, use Docker.
- Most teams use both to run a smooth operation
Date/Time zone
- List of time zone. Setting Local Time in Docker; e.g. "America/New_York" or "US/Eastern".
- https://stackoverflow.com/questions/22800624/will-docker-container-auto-sync-time-with-the-host-machine
docker run --rm -t -i -v /etc/localtime:/etc/localtime:ro ubuntu date
Access the internet from the container
Run the container with the '--net=host' option
sudo docker run --net=host -it ubuntu /bin/bash
How to transfer/copy an image to another host
How to copy Docker images from one host to another without using a repository
# Step 1: save the Docker image as a tar file: docker save -o <path for generated tar file> <image name> # Step 2: copy your image to a new system with regular file transfer tools such as cp or scp. # Step 3: After that you will have to load the image into Docker: docker load -i <path to image tar file>
The tar file size is the same as what we get from 'docker image'. If we use the 'gzip' utility, it can reduce the file size (e.g 2.7GB to 1.1GB).
Or https://stackoverflow.com/a/39716019
# Step 1: docker save docker-image-name | gzip > my-image.tar.gz # Step 3: docker load < my-image.tar.gz
Where are Docker containers/images stored on the host: /var/lib/docker
- http://stackoverflow.com/questions/19234831/where-are-docker-images-stored-on-the-host-machine
- https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-storage-driver
- http://stackoverflow.com/questions/21016210/function-of-docker-directory-structure-in-var-lib-docker
- How to Manage Docker images on local disk
- How to Store Docker Images and Containers on an External Drive
- How to Change Docker’s Default Data Directory
The default is /var/lib/docker. The location can be changed by modifying the file /etc/default/docker. Three options if we are tight on the disk space.
1. Create a softlinks for the Docker data directory (/var/lib/docker) and for /var/lib/docker/tmp as described at miscellaneous-options. See this. See for how to stop docker daemon on different OS.
sudo service docker stop # or sudo systemctl stop docker sudo mv /var/lib/docker /a/new/location sudo ln -s /a/new/location /var/lib/docker # Create a symbolic link sudo service docker start # or sudo systemctl start docker
2. Change the default location to another place. For example,
sudo nano /etc/default/docker # Add a line DOCKER_OPTS="-g /home/brb/Docker"
Then after running sudo service docker.io restart and then a simple pull sudo docker pull rocker/r-base or sudo docker run --rm -ti rocker/r-base (the Dockerfile of r-base is available on github.com, --rm option means Automatically remove the container when it exits), we will see something like this:
$ docker run --rm -ti rocker/r-base $ docker images $ docker -v Docker version 1.0.1, build 990021a $ docker -D info | grep Root Root Dir: /home/brb/Docker/aufs
Consuming Docker system events
# Open a new terminal docker system events # This command is a blocking command. # Thus, when you execute it in your terminal session the according session is blocked. # Open another terminal docker container run --rm alpine echo "Hello World"
Monitor tools
Docker Machine
Docker Machine is a tool that lets you
- Install Docker Engine on virtual hosts. You can use Machine (a unified way) to create Docker hosts on your local Mac or Windows box, on your company network, in your data center, or on cloud providers like Azure, AWS, or Digital Ocean. See the comment on here.
- Provision and manage multiple remote Docker hosts
- Provision Swarm clusters
Docker machine is not installed in Linux when you install Docker. See the instruction on here to install it.
My feeling is if we just want to play Docker on a local Linux machine, we don't really need to use Docker Machine (it just make life more complicated). But if we are working on Mac/Windows or we want to work on clouds or test on VirtualBox, we shall use Docker machines.
Use Docker-machine to Create Docker Servers. Compare the Docker images on the local machine (server 1) & a new host (server 2) created by docker-machine. Question: 1. how to tell we are in the host/machine environment? 2. how to exit the host environment after we use eval $() command? docker-machine stop MachineName.
$ docker-machine help $ docker-machine create --driver=virtualbox test # Follow its hint on the output, issue the following command $ docker-machine env test # Follow its hint on the output, issue the following command $ eval$(docker-machine env test) # will configure the docker CLI to connect to this docker machine 'test' # This is equivalent to running 4 export commands on the command line $ docker-machine ls # Very useful $ docker-machine stop test $ docker-machine ip test $ docker-machine start test $ docker-machine rm test
Play Docker Machine on Mac with Virtualbox. Docker can be used to create a virtual machine just like Vagrant.
$ docker-machine create -d virtualbox demo $ docker-machine ls # first way to access a Docker host $ docker-machine ssh demo docker@demo:~$ docker images # empty for now # second way to access $ docker-machine env demo $ eval $(docker-machine env demo) $ docker version
RancherOS demo video used the docker-machine command to pull and run the RancherOS.
docker-machine create -d virtualbox --virtualbox-boot2docker-url https://releases.rancher.com/os/latest/rancheros.iso demo docker-machine ssh demo ps docker ps sudo system-docker ps sudo ros help sudo ros console list sudo ros console switch ubunu apt-get help
Package CLI Applications
How to Use Docker to Package CLI Applications
Stack
- https://www.composerize.com/
- Export Docker Container Settings as Docker Compose Stack, docker-autocompose (only x86)
Docker app
Docker App is an experimental Docker feature which lets you build and publish application stacks consisting of multiple containers. It aims to let you share Docker Compose stacks with the same ease of use as regular Docker containers.
How to Use 'Docker App' to Containerise an Entire Application Stack
Docker Swarm
- https://www.linux.com/learn/how-use-docker-machine-create-swarm-cluster
- How Setup and Configure Docker Swarm Cluster on Ubuntu
- What is Docker Swarm Mode and When Should You Use It?
Security
- Docker Security Best Practices from the Dockerfile
- How to Secure Sensitive Data With Docker Compose Secrets
- Docker Scout. Docker Scout lets users secure their software supply chain and continuously observe and improve their security posture. Docker Scout is free for up to 3 repositories.
docker login docker scout enroll ORG_NAME docker scout scan my-web-app:latest docker scout repo enable --org ORG_NAME ORG_NAME/scout-demo # Docker Scout analyzes the image you built most recently by default, # so there's no need to specify the name of the image in this case.
- Is Docker-CE Ready for Production? How Portainer Bridges the Gaps
Moby Project
What is Docker's Moby Project?
Windows container
How can I run a docker windows container on osx?
When Not to Use Docker
When Not to Use Docker: Cases Where Containers Don’t Help
Docker Compose <docker-compose.yaml>
Docker Compose can help us out as it allows us to specify a single file in which we can define our entire environment structure and run it with a single command (much like a Vagrantfile works).
- Tabs are not allowed in a Docker Compose YAML file. You should use spaces for indentation instead.
- https://docs.docker.com/compose/ (the example will give an error when "RUN pip install -r requirements.txt")
- app.py
- requirements.txt
- Dockerfile
- docker-compose.yml
- Some top-level keys: version, services, networks, volumes
- Dockerfile vs docker-compose.yml
- A simple example of running nginx & mysqsl
- Docker Compose in 12 Minutes
- https://deliciousbrains.com/vagrant-docker-wordpress-development/
- https://github.com/kristophjunge/docker-mediawiki
- Docker Guide: Dockerizing Python Django Application (cannot follow)
- Examples:
- EpubPress local server
- Running nextcloud, Jupyter and RStudio
- Rstudio
- Docker Compose For Beginners: Working With Multiple Containers
- image, container_name
- image, container_name, environment
- image, container_name, environment, volumes, ports
YAML validator
https://codebeautify.org/yaml-validator
Download binary
- https://github.com/docker/compose/releases for macOS (x86/arm), Linux (aarch64 or armv6 or armv7).
- New instruction Install the Compose plugin. In short, we will use docker compose (new) instead of "docker-compose" (deprecated) command. There is no need to install the original "docker-compose" tool. "docker-compose --version"
Difference of "docker compose" and "docker-compose"
- Docker-compose is the original Python-based command-line tool that was released in 2014. Docker compose is a newer Go-based command-line tool that is integrated into the Docker CLI platform and supports the compose-spec. Docker compose is meant to be a drop-in replacement for docker-compose, but it may have some behavior differences and new features. Docker compose is currently a tech preview, but it will eventually replace docker-compose as the recommended way to use Compose.
- https://docs.docker.com/compose/migrate/. From July 2023 Compose V1 stopped receiving updates. It’s also no longer available in new releases of Docker Desktop.
- Docker-compose vs docker compose
- Difference between "docker compose" and "docker-compose"
Simple examples
Create a file docker-compose.yml and run docker-compose up after creating the file.
hello-world: 9kB
version: "3" services: hello: image: hello-world
alpine: 7.73MB
version: "3" services: server: image: alpine container_name: my_container command: sh -c "echo 'hello' && echo 'docker'"
Nginx: 135MB
mkdir src echo "Hello world!" > src/index.html
version: "3" services: client: image: nginx ports: - 8000:80 volumes: - ./src:/usr/share/nginx/html
Composerize/convert a docker command into a docker compose file
- Copilot/ChatGPT/...
- https://www.composerize.com/
- Convert Docker Run Commands Into Docker-Compose Files
An example from 'Fundamentals of Docker'
git clone https://github.com/fundamentalsofdocker/labs.git cd labs/ch08 docker-compose up # Open http://localhost:3000/pet
The images do not show up:( The terminal shows what has happened under the hood. So the problem is the http links for images do not exist.
We can also run the application in the background
docker-compose up -d
To stop and clean up the application, Howto use docker-compose to Start, Stop, Remove Docker Containers
docker-compose down # Stop and remove containers, networks, images, and unnamed volumes # defined in the docker-compose.yml flie # OR docker-compose down -v # similar to above but remove named volumes defined in yml file # OR docker-compose stop && docker-compose rm -f docker-compose rm -v
If we also want to remove the volume for the database
docker volume rm ch08_pets-data
An example from "How to Setup NGINX as Reverse Proxy Using Docker"
See here. Only nginx is used.
An example from "Docker Deep Dive" (flask + redis)
Note that on Get started with Docker Compose it mounts the current directory to /code inside the container. So after we modify app.py, we don't need to copy it to the container.
Another one Docker compose tutorial for beginners by example
$ git clone https://github.com/nigelpoulton/counter-app.git $ cd counter-app $ ls app.py docker-compose.yml Dockerfile README.md requirements.txt $ cat requirements.txt flask $ cat Dockerfile FROM python:3.4-alpine ADD . /code WORKDIR /code RUN pip install -r requirements.txt CMD ["python", "app.py"] $ cat docker-compose.yml version: "3.5" services: web-fe: build: . command: python app.py ports: - target: 5000 published: 5000 networks: - counter-net volumes: - type: volume source: counter-vol target: /code redis: image: "redis:alpine" networks: counter-net: networks: counter-net: volumes: counter-vol: $ docker-compose up & $ docker container ls $ docker network ls NETWORK ID NAME DRIVER SCOPE 2acef6dabde6 bridge bridge local a2d42bc482ff counterapp_counter-net bridge local e1e093b64282 host host local 7ecd0a6a9ebd none null local # Open the browser http://localhost:5000 $ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------- counterapp_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp counterapp_web-fe_1 python app.py Up 0.0.0.0:5000->5000/tcp $ docker-compose stop $ docker-compose ps # We can see stopping a Compose app does not delete the application $ docker container ls -a $ docker-compose rm # delete a stopped Compose app # images, volumes and source code remain $ docker-compose restart # If you made changes to your Compose app since stopping, # these changes will not appear in the restarted app. # You need to re-deploy the app to get the changes. $ docker-compose ps $ docker-compose down # stop and delete the app # images, volumes and source code remain $ docker-compose down --volumes # remove the data volume used by the Redis container $ docker-compose up -d $ docker volume ls $ docker-compose # We can make changes to files in the volume, from the host side, # and have them reflected immediately in the app. $ nano app.py # do some changes $ docker volume inspect counterapp_counter-vol | grep Mount $ sudo cp app.py \ /var/lib/docker/volumes/counterapp_counter-vol/_data/app.py # Our changes should be reflected $ docker-compose --help
Create Compose Files From Running Docker Containers
How to Automatically Create Compose Files From Running Docker Containers
Docker-Compose persistent data MySQL
https://stackoverflow.com/questions/39175194/docker-compose-persistent-data-mysql
Connect to Docker daemon over ssh using docker-compose
#DockerTips: Connect to Docker daemon over ssh using docker-compose
Dockerfile + docker-compose
Docker Compose vs. Dockerfile - which is better?
The Compose file describes the container in its running state, leaving the details on how to build the container to Dockerfiles.
How to deploy on remote Docker hosts with docker-compose
How to deploy on remote Docker hosts with docker-compose
logs
docker-compose logs -f # Ctrl + c
GUI/TUI interface manager
11 Must-Have Docker Tools To Simplify Your Workflow:
- LazyDocker - Command-Line Docker Management
- Dive - Analyze Docker Image Layers
- Portainer – Simplify Docker Management
- Watchtower – Automated Docker Container Updates
- Dockly – Interactive Docker Management Tool
- Docker Compose – Define and Run Multi-Container Apps
- Dry – Real-time Docker Container Monitoring
- Sliplane – Cloud-Based Docker Management Tool
- Orbstack (closed source) - manage VM and Docker containers
- Docker Desktop – A Graphical Interface for Docker
- Visual Studio Code (VS Code) Docker Extension
Dry
Dry – An Interactive CLI Manager For Docker Containers. The TUI is built on top of termui; a cross-platform, easy-to-compile, and fully-customizable terminal dashboard. It is inspired by blessed-contrib, but purely in Go.
LazyDocker (TUI)
- Github
- LazyDocker: New Docker And Docker Compose Terminal UI
- It works on ARM devices too.
- Video by Awesome open source
Dockly (TUI)
Dockly – Manage Docker Containers From Terminal
DockStation
It is not open source. It works with remote Docker containers.
- DockStation
- TOP 6 GUI tools for managing Docker environments 2018
- 4 Best Docker GUI tools to manage containers graphically 2019
DockSTARTer: get started with home server apps running in Docker
Portainer* (nice)
- Username: admin. Password: at least 12 characters long
- Hardware minimum requirements 100MB RAM. That's why 1GB ram of Raspberry Pi works fine.
- Install CE, Documentation
docker volume create portainer_data docker run -d -p 8000:8000 -p 9443:9443 \ --name portainer \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data portainer/portainer-ce:latest
By default, Portainer Server will expose the UI over port 9443 and expose a TCP tunnel server over port 8000. The latter is optional and is only required if you plan to use the Edge compute features with Edge agents.
- Access https://localhost:9443
- Portainer itself is a docker application.
- Reset the admin user's password.
- How to Update Portainer Fast, Simple, and Easy Guide. docker stop + docker rm + docker rmi + docker run.
- Update Portainer to Version 2.0 – Super Easy!. When the first time accessing http://localhost:9000, you need to create a password (at least
812 characters long) for the default user "admin".$ docker volume create portainer_data $ docker run -d -p 9000:9000 -p 8000:8000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
- Update from 2.11 to 2.13 (The password must be at least 12 characters long)
- Step 1: How to Update Portainer to the Newest Version
sudo docker stop portainer && sudo docker rm portainer docker pull portainer/portainer-ce:latest
- Step 2: Upgrading on Docker Standalone
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
- Step 1: How to Update Portainer to the Newest Version
- Why port 8000 is needed to be published?, What port 8000 used for? Do I need to expose it?
- A Comparison of Docker GUIs. A username/password is required to access the page unless we use the --no-auth option; see Configuration.
- How to Manage Docker Containers using Portainer on Ubuntu 16.04. Go to Local. It will show the status of all local stacks, containers, volumes and images. Very Cool!
- Monitor and Manage Docker Containers with Portainer.io (GUI tool) – Part-1 2019
- How to Get Started With Portainer, a Web UI for Docker
- Monitor and Manage Docker Containers with Portainer.io (GUI tool) – Part-2
- Portainer Vs Rancher
- How-to: Deploy Portainer on MicroK8s (video)
- From Zero to Production with Fedora CoreOS, Portainer, and WordPress in 7 Easy Steps. Virtualbox was used
IP address 0.0.0.0
How to setup ip address in portainer to access containers?
(Left hand side) Administration -> Environment-related -> Environments > local (or whatever your environment is named) -> Public ip.
Templates
- Using Application Templates in Portainer 2.0
- Install 80+ Docker Images In Seconds Using This Portainer App Template (video)
- Best and most up-to-date Portainer app template for selfhosting? 2022-06-03
- Install 80+ Docker Images In Seconds Using This Portainer App Template (video, 2020)
- Default on my Portainer 2.0.1 (see logs for version number) https://raw.githubusercontent.com/portainer/templates/master/templates-2.0.json
- https://raw.githubusercontent.com/SelfhostedPro/selfhosted_templates/portainer-2.0/Template/template.json (working), Github
- https://raw.githubusercontent.com/nashosted/self-hosted-template/master/template.json (working)
- Alternative: taisun
Yacht
- https://yacht.sh/Installation/yacht/
- Yacht's Dashboard page shows the resources used by each docker application (it seems Portainer can't)
- Yacht Installed on Docker - Portainer Alternative (video)
- What's on my Home Server? MUST HAVE Services (video)
cockpit-docker
- Installing And Using Cockpit-Docker
- The default port is 9090.
- Not useful for manager docker containers.
sudo apt-get -y install cockpit-docker sudo systemctl restart cockpit
DockerUI (Deprecated, Development continues at Portainer)
https://github.com/kevana/ui-for-docker. A quick start:
- Run:
docker run -d -p 9000:9000 --privileged \ -v /var/run/docker.sock:/var/run/docker.sock uifd/ui-for-docker
where -v means to bind mount a volume. - Open your browser to http://<dockerd host ip>:9000
Note: Anyone in the local network can access the website without any authentication.
Rancher
- https://rancher.com/quick-start/. The doc above is not good enough to follow. Search Google for tutorial or get started guide including screenshots.
- How to Manage Docker Containers with Rancher on Ubuntu 16.04
- Creating A Scalable Application Using Docker + Rancher + RancherOs + Cattle
- Initial setup video https://youtu.be/1EMW1y7529Y
- Training from Rancher Labs https://youtu.be/8K14A_CZFdI. It seems Rancher is complicated but powerful. The whole operation is like Amazon Cloud.
- Running Rancher locally (with two hosts) using MacOS Docker and VirtualBox
- To allow UDP port
$ sudo apt-get install ufw $ sudo ufw allow 4500/udp $ sudo ufw allow 500/udp
- discoposse.com
Seagull
docker run -d -p 127.0.0.1:10086:10086 -v /var/run/docker.sock:/var/run/docker.sock tobegit3hub/seagull
The only issue is there is no username/password to protect other people to access the web GUI. The solution of binding to localhost to restrict the access does not work for remote administration.
That is, the tool is suitable for home use.
Kitematic (Mac, Windows and Ubuntu)
Owned by Docker. Available for Mac OS X 10.8+ and Windows 7+ (64-bit) and Ubuntu. https://github.com/docker/kitematic/releases/
Run containers through a simple, yet powerful graphical user interface.
It can not connect to remote docker machines.
A Share your Shiny Apps with Docker and Kitematic!
Shipyard (retired)
- Managing Containers with Docker Shipyard
- Three alternatives:
VS Code
- Docker For Beginners: From Docker Desktop to Deployment
- Visual Studio Code Remote - Containers
- How to Develop Inside a Container Using Visual Studio Code Remote Containers
- How to Edit Code in Docker Containers With Visual Studio Code
Applications
CasaOS
Every app is based on a Docker application
- https://casaos.io/
- https://wiki.casaos.io/en/get-started. It also supports arm64, armv7.
- http://casaos.local
- https://docs.zimaboard.com/docs/index.html Default login casaos/casaos. For a new user, the password has to be at least 5 characters.
- Revisiting CasaOS After A Few Months 2022-6-14
- Home Servers Have NEVER Been This Easy: CasaOS + ZimaBoard 4/23/2023
- List of apps 2022/11
Orchestrator
Kubernete
- Kubernetes dropping Docker is not that big of a deal
- Kubernetes VS Docker: What's the Difference? Explained With Examples
- Kubernetes For The Absolute Beginner - Hands On from kodekloud.com
- Docker Kubernetes Lab Handbook by Peng Xiao. The github page is on https://github.com/xiaopeng163/docker-k8s-lab.
- Introducing Kubernetes by Marc Sluiter. Kubenetes can be used to schedule, run and manage containers in a cluster of virtual or physical machines.
- Starting by Google in 2014
- Pods: smallest unit of deployment. small group of tightly coupled containers. share network and data volumes. routable IP address. multiple pods per node.
- Create a 2-node Kubernetes cluster in 10 minutes
- Kubernetes Webinar Series - Getting Started with Kubernetes
- Deploying Java Applications with Docker and Kubernetes
- First impressions: Docker for Mac with Kubernetes
- Minikube: run Kubernetes locally
- How to Install Kubernetes with Minikube on Ubuntu 18.04 LTS
- Kubernetes namespaces for beginners. You need to have Minikube, Helm, and the kubectl command line installed.
- Galaxy-Kubernetes integration: scaling bioinformatics workflows in the cloud Moreno et al 2019
- Helm on Google Kubernetes Engine by Sean Davis
- MicroK8s
- Resource Limits in Kuberenetes
- Orchestra and European Bioconductor Meeting 2020
- Kubernetes Alternatives to Docker Commands
- What Is Kubernetes and What Is It Used For?
Kubernete vs Docker swarm
k3s: Lightweight Kubernetes
Run Kubernetes on a Raspberry Pi with k3s
Kubeflow
Other containers
Singularity and HPC systems
- Old URL at singularity.lbl.gov
- Singularity enables users to have full control of their environment; Singularity containers let users run applications in a Linux environment of their choosing. No 'sudo' is needed in general unless you want to build a container from a recipe.
- Containers are more like an executable file for you to use
- Containers are stored under the current location. It does not have a centre location (like /etc/default/docker if we use docker) to store images.
- Can convert Docker containers to Singularity and run containers directly from Docker Hub
- These bind points cannot be created unless the path already exists within the container. To ensure access to these storage spaces and remedy bind point errors, create these directories in the %post section of your Bootstrap file.
- Singularity Hub
Ref:
- Singularity at NIH/Biowulf. It needs to run 'module load singularity' first to load related commands.
- NIH-HPC
- Tutorial and its Github source (valuable)
- Bioinformatics advice I wish I learned 10 years ago
- NIH HPC Singularity Definition Files
- DOCKER VS SINGULARITY VS SHIFTER VS UGE CONTAINER EDITION
- xenome case where the build instruction is good for Ubuntu 16.04. If we try to build under Ubuntu 14.04 (tested using docker run), we will get an error message CMake 3.1 or higher is required. You are running version 2.8.12.2.
- https://github.com/NIH-HPC/singularity-examples/blob/master/rnaseq/Singularity.rnaseq
Comparison of docker and singularity commands:
docker | singularity |
---|---|
$ docker pull ubuntu:latest $ docker pull broadinstitute/gatk3:3.8-0 |
$ singularity pull docker://ubuntu:latest $ singularity pull docker://broadinstitute/gatk3:3.8-0 |
$ docker build -t myname/myapp:latest -f Dockerfile | $ singularity build myapp.sif myapp.def |
$ docker shell (not exist) | $ singularity shell docker://broadinstitute/gatk3-3.8-0 $ singularity shell gatk3-3.8-0.img > ls # the default location depends on the host system > ls /usr # this is from the container |
$ docker run --name test -it ubuntu date # The next example is similar to 'singularity exec' $ docker run --rm -i -t \ -v $(pwd):/usr/my_data \ broadinstitute/gatk3:3.8-0 \ bash /usr/my_data/myscript.sh |
$ singularity run gatk3-3.8-0.img date |
$ docker run --name ubuntu_bash --rm -i -t ubuntu bash $ docker exec -d ubuntu_bash touch /tmp/execWorks |
# Most useful $ singularity exec gatk3-3.8-0.img java -version $ singularity exec xxx.img cat /etc/*release $ singularity exec docker://rocker/tidyverse:latest R $ singularity exec docker://rocker/tidyverse:latest Rscript myScript.R |
Cache
When we run singularity exec docker://rocker/tidyverse:latest R, it will save something in the cache in our system.
It seems to be OK after I manually delete the directory $HOME/.singularity (tested in Biowulf).
RStudio
- R and Singularity by Bryan Lewis
- RStudio – IDE and Server powered by Singularity by Jason Stover
- https://github.com/nickjer/singularity-rstudio and https://github.com/nickjer/singularity-r
- https://www.rocker-project.org/use/singularity/. It also includes how to run a SLURM job script.
- https://njstem.wordpress.com/2018/08/02/r-script-seurat-with-a-singularity-container-using-slurm/
- https://journal.r-project.org/archive/2017/RJ-2017-065/RJ-2017-065.pdf
$ singularity exec docker://rocker/tidyverse:latest R $ singularity exec docker://rocker/tidyverse:latest Rscript myScript.R
Shifter
Conda
Anaconda
- Getting started with Anaconda & Docker using continuumio/anaconda3
Bioconda
- https://bioconda.github.io/
- https://anaconda.org/bioconda
- https://www.biorxiv.org/content/early/2017/10/27/207092
- https://zhuanlan.zhihu.com/p/25085567
- Snakemake: Reproducible and scalable data analysis
- https://chrisconlan.com/installing-r-python-anaconda-biologists/. Note that the R version is 3.4.2 but the latest one should be 3.4.3.
- Introduction to Conda Dave Tang
Using docker to install conda (https://conda.io/docs/user-guide/tutorials/index.html)
$ docker run -t -i --name test --net=host ubuntu bash # apt-get update # apt-get install -y wget bzip2 python # wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh # wget https://repo.continuum.io/archive/Anaconda2-5.1.0-Linux-x86_64.sh # bash Miniconda2-latest-Linux-x86_64.sh # bash Anaconda2-5.1.0-Linux-x86_64.sh # exit $ docker start test $ docker exec -i -t test bash # conda list # WORKS! # conda config --add channels r # conda config --add channels defaults # conda config --add channels conda-forge # conda config --add channels bioconda # conda install bwa (Segmentation fault. Core dumped) # which bwa /root/anaconda2/bin/bwa # conda install r (Only get 3.4.2 but the latest is 3.4.3.) # conda install bowtie # bowtie --version # conda install gatk (https://bioconda.github.io/recipes/gatk/README.html) (Due to license restrictions, this recipe cannot distribute and install GATK directly) (R is downgraded to 3.2.2:( ) (Segmentation fault. Core dumped) # exit # docker stop test # docker rm test
Get miniconda image instead of using a Ubuntu image
$ docker pull continuumio/miniconda $ docker run -i -t continuumio/miniconda /bin/bash # conda install r (get 3.4.2) # conda config --add channels bioconda # conda install bwa (OK, no error) # conda install gatk (R was downgraded to 3.2.2, install openjdk 8.0.121) # which gatk /opt/conda/bin/gatk # gatk -h GATK jar file not found. Have you run "gatk-register"?
Issues:
- R version is not up to date
- So the problem is installing GATK requires an installation of R and the current R was affected.
CoreOS
- Redhat has acquired CoreOS 1/31/2018.
- End-of-life announcement for CoreOS Container Linux
Installation
- Quick Start
- Installing CoreOS on a bare metal or virtual machine from the user Format C: in youtube
- Assigning Static IP to a CoreOS Server
- Mounting storage in CoreOS
- Installing, Deploying Docker containers with Fig / Docker Compose on boot2docker or CoreOS
- Running a Private Docker Registry Container
We first boot a liveCD from any OS (CentOS works but Ubuntu 16.04 gave errors). In Virtualbox, we choose 'Red Hat' if we use CentOS.
Once the VM is created. We go to the settings. Create a bridged network or host-only network first (even we can get files from the host without creating a host-only network). Storage: choose CentOS-7.
- Get the install script from Github and create <coreos_install.sh> and chmod +x
- create <cloud-config.yaml> file which will include ssh_authorized_keys generated from another machine. It should also contain a new token for the cluster from https://discovery.etcd.io/new.
- ls -l /dev/sd*
- run sudo ./coreos_install.sh -d /dev/sda -C stable -c cloud-config.yaml. It will download the latest stable CoreOS, install to the HD
- Don't leave the VM or it will freeze. Issue sudo shutdown -h now once we see the word 'Success' at the last line of the output.
- Remove CentOS from the VM storage. Boot the coreOS VM.
The new screen shows corebm1 login with an IP. Go back to another machine and type ssh -i /tmp/CoreOSBM_rsa [email protected]. Inside CoreOS, we can type docker images.
The 'cloud-config.yaml file has to follow the format in https://coreos.com/os/docs/latest/cloud-config.html. Use the online validator https://coreos.com/validate/ to correct. At first I use the file from the youtube video. There is no error coming out when I ran the installation script. But I cannot connect to coreOS. The cloud-config.yaml file I use is (pay attention to '-', double quotes and indent characters)
#cloud-config # # set hostname hostname: CoreBM1 # Set ssh key ssh_authorized_keys: - "ssh-rsa AAAAB3 ..... brb@T3600" coreos: etcd: discovery: "https://discovery.etcd.io/d3e95 .... " # sudo ./installos -d /dev/sda -C stable -c cloud-config.yaml
CoreOS exploration
brb@T3600 /tmp $ ssh -i /tmp/id_rsa [email protected] Enter passphrase for key '/tmp/id_rsa': CoreOS stable (1010.6.0) core@CoreBM1 ~ $ core@CoreBM1 ~ $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE core@CoreBM1 ~ $ df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 1.4G 0 1.4G 0% /dev tmpfs 1.4G 0 1.4G 0% /dev/shm tmpfs 1.4G 340K 1.4G 1% /run tmpfs 1.4G 0 1.4G 0% /sys/fs/cgroup /dev/sda9 18G 23M 17G 1% / /dev/sda3 985M 589M 345M 64% /usr tmpfs 1.4G 0 1.4G 0% /media /dev/sda1 128M 37M 92M 29% /boot tmpfs 1.4G 0 1.4G 0% /tmp /dev/sda6 108M 52K 99M 1% /usr/share/oem core@CoreBM1 ~ $ free -m total used free shared buffers cached Mem: 2713 187 2525 0 9 109 -/+ buffers/cache: 68 2644 Swap: 0 0 0 core@CoreBM1 ~ $ lsb_release -a -bash: lsb_release: command not found core@CoreBM1 ~ $ docker pull ubuntu Using default tag: latest latest: Pulling from library/ubuntu f069f1d21059: Pull complete ecbeec5633cf: Pull complete ea6f18256d63: Pull complete 54bde7b02897: Pull complete Digest: sha256:bbfd93a02a8487edb60f20316ebc966ddc7aa123c2e609185450b96971020097 Status: Downloaded newer image for ubuntu:latest core@CoreBM1 ~ $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 0f192147631d 7 days ago 132.7 MB core@CoreBM1 ~ $
CoreOS cluster discovery
https://coreos.com/os/docs/latest/cluster-discovery.html
etcd
fleet
TryGhost
https://github.com/TryGhost/Ghost
Firecracker
Firecracker: start a VM in less than a second
Self-hosting
Tools and Resources for Self-Hosting
Linux in browser
- Webtop, https://hub.docker.com/r/linuxserver/webtop#!
- Play with Docker
- Meet Webtops A Linux Desktop Environment In Your Browser
- Webtops - Linux Desktops in Docker
--- version: "2.1" services: webtop: image: lscr.io/linuxserver/webtop:ubuntu-mate container_name: webtop security_opt: - seccomp:unconfined #optional environment: - PUID=1000 - PGID=1000 - TZ=America/Chicago - SUBFOLDER=/ #optional - KEYBOARD=en-us-qwerty #optional - TITLE=Webtop #optional volumes: - ./data:/config - /var/run/docker.sock:/var/run/docker.sock #optional ports: - 3000:3000 devices: - /dev/dri:/dev/dri #optional shm_size: "1gb" #optional restart: unless-stopped
$ nano docker-compose.yml $ docker-compose up -d $ ls data # files in this directory will be shared between the container and the host # Open http://localhost:3000
If we remove 'ubuntu-mate', it will create alpine linux instead.
In the alpine linux (13 Apk Commands for Alpine Linux Package Management), we can use the following commands to install a package. However, meld is not responding from my testing in the setup.
sudo apk update sudo apk add meld nano htop neofetch
- Kasm Workspaces, https://hub.docker.com/r/kasmweb/desktop/#!
- KASM: Isolated Disposable Remote Workspace Via Your Browser (video)
- Kasm Workspaces: Your Solution for Remote Desktops? (video)
- Desktop Apps in Docker Containers with Kasm Workspaces (you cannot install any software there)
Podman
- Podman Installation Instructions
- How To Install Podman Desktop In Linux
- Raspberry Pi OS use the standard Debian's repositories, so it is fully compatible with Debian's arm64 repository. You can simply follow the steps for Debian to install Podman.
- Podman vs docker:
- One of the main differences between Podman and Docker is their architecture. Docker uses a client-server architecture with a central daemon that manages containers. In contrast, Podman is daemonless and uses a fork-exec model to manage containers.
- Podman is designed to run containers without requiring root privileges or the use of sudo. This is one of the key differences between Podman and Docker, as Docker requires root privileges to run containers.
- Both Podman and Docker are compatible with the Open Container Initiative (OCI) container specification, which means that they can run the same container images. However, Podman is more closely aligned with Kubernetes and its native container runtime, while Docker also works with its own orchestration tool, Docker Swarm.
- Podman provides several benefits over Docker. For example, Podman is daemon-less, which means that if the Docker daemon crashes, the containers are in an uncertain state. This is prevented by making Podman daemon-less. You can also use systemd to manage your containers with Podman, which gives you virtually unlimited configurability compared to Docker. Hooking Podman with systemd allows you to update running containers with minimal downtime and recover from any bad updates.
- Podman is a project from Red Hat
- Getting Started With Podman Desktop, an Open Source Docker Desktop Alternative
- Podman Compose - Managing Containers
pip3 install podman-compose
- But it seems the compatibility is an issue even I tried a small example based on alpine image.
- Nginx example (works)
podman run -it --rm -d -p 8080:80 \ --name web \ -v /mnt/Podman/site-content:/usr/share/nginx/html \ docker.io/libary/nginx
- Podman Desktop 1.0: Local container development made easy.
- Podman for Docker Users
- Prerequisites
- Moving Images from Docker to Podman
- Creating a Basic Nuxt.js Project
- Building a Container Image for Your Nuxt.JS Project
- Push Your Podman Image to Quay.io
- Run Your Podman Image with Docker
- Creating Pods
- Generate a Kubernetes Pod Spec with Podman
- Create a Kubernetes Cluster with Kind (Optional)
- Deploying to Kubernetes
- Podman, Docker and Singularity all support OCI container format images.
- Docker vs. Podman vs. Singularity: Which Containerization Platform is Best for R Shiny?
Resource
Internet
- A guide to open source for microservices from opensource.com
- Reproducible Research through Containerisation: Docker and Singularity from rainsworth.
- Docker Tutorial for Beginners - A Full DevOps Course on How to Run Applications in Containers from freeCodeCamp.org
- Docker for Beginners: Everything You Need to Know
Books
- The Docker Book: Containerization is the new virtualization
- Orchestrating Docker
- Docker Hands on: Deploy, Administer Docker Platform
- Learn Docker - Fundamentals of Docker 18.x by Gabriel N. Schenker. Release Date: April 2018. https://github.com/fundamentalsofdocker/labs
- Docker Deep Dive by by Nigel Poulton. 2017
- Master Docker (2nd, 2017) by Russ McKendrick, Scott Gallagher. Source code on github.
Blogs
- collabnix
- http://blog.thoward37.me/articles/where-are-docker-images-stored/
- Docker容器架構最大儲存挑戰是,你根本不知道資料存在何處
- Running Everything in Docker. Docker Compose was used. Several applications were illustrated: mediawiki, Jenkins, Gogs & caddy-docker.
Tips/trouble shooting
- Dealing with Unexplained Docker Errors and other tips and tricks
- Running a container with a non root user
- Error: Cannot start container: port has already been allocated. sudo service docker restart
Play with Docker (PWD)
- http://labs.play-with-docker.com/
- http://training.play-with-docker.com/, A full list of labs
- https://blog.docker.com/2017/07/best-way-learn-docker-free-play-docker-pwd/
- One session is 4 hours. Each session can have multiple instance. Each instance will be allocated 4GB mem. Each docker image is stored in memory.
- df -h shows there is only 4.7G space for /var/lib/docker directory
- It is based on Alpine Linux. To install htop, do apk add htop. But htop command shows the resource from the host, not from the user's account.
- ctrl + insert to copy and shift + insert to paste
- connect to a play-with-docker instance. Answer: You just need to create a random private key. Play with "Play with Docker" from your terminal!.
- Some applications I've tested.
- webtop (OK)
- r-base:3.6.3, r-base:4.1.0, r-base:4.1.1 (OK)
- r-base:4.1.2, r-base:4.2.0 (ERROR: R_HOME ('/usr/lib/R') not found). Maybe the docker version there is too old.
Alternatives
The 9 Best Docker Alternatives for Container Management