Docker Basic Notes
Docker Basis
Docker is process-level Linux virtual container:
- Namespace: IPC/network/PID/UTS/user isolation.
- Cgroup: resources control.
- rootfs: file system isolation.
// https://github.com/lizrice/containers-from-scratch
package main
import (
    "fmt"
    "io/ioutil"
    "os"
    "os/exec"
    "path/filepath"
    "strconv"
    "syscall"
)
// go run main.go run <cmd> <args>
func main() {
    switch os.Args[1] {
    case "run":
        run()
    case "child":
        child()
    default:
        panic("help")
    }
}
func run() {
    fmt.Printf("Running %v \n", os.Args[2:])
    cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags:   syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS,
        Unshareflags: syscall.CLONE_NEWNS,
    }
    must(cmd.Run())
}
func child() {
    fmt.Printf("Running %v \n", os.Args[2:])
    cg()
    cmd := exec.Command(os.Args[2], os.Args[3:]...)
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    must(syscall.Sethostname([]byte("container")))
    must(syscall.Chroot("/home/liz/ubuntufs"))
    must(os.Chdir("/"))
    must(syscall.Mount("proc", "proc", "proc", 0, ""))
    must(syscall.Mount("thing", "myTemp", "tmpfs", 0, ""))
    must(cmd.Run())
    must(syscall.Unmount("proc", 0))
    must(syscall.Unmount("thing", 0))
}
func cg() {
    cgroups := "/sys/fs/cgroup/"
    pids := filepath.Join(cgroups, "pids")
    os.Mkdir(filepath.Join(pids, "liz"), 0755)
    must(ioutil.WriteFile(filepath.Join(pids, "liz/pids.max"), []byte("20"), 0700))
    // Removes the new cgroup in place after the container exits
    must(ioutil.WriteFile(
        filepath.Join(pids, "liz/notify_on_release"),
        []byte("1"),
        0700
    ))
    must(ioutil.WriteFile(
        filepath.Join(pids, "liz/cgroup.procs"),
        []byte(strconv.Itoa(os.Getpid())),
        0700
    ))
}
func must(err error) {
    if err != nil {
        panic(err)
    }
}
Docker CLI Workflows
Docker Installation
 sudo apt-get update
 sudo apt-get install \
  apt-transport-https \
  ca-certificates \
  curl \
  gnupg \
  lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
  "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
curl -fsSL https://get.docker.com -o get-docker.sh
sudo DRY_RUN=1 sh get-docker.sh
sudo systemctl status docker
sudo usermod -aG docker $USER
Docker Uninstallation
docker container stop $(docker container ls -aq)
docker system prune -a --volumes
sudo apt purge docker-ce docker-ce-cli containerd.io
sudo apt autoremove
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
Get Docker Image
docker images
docker images -a
docker search <images>
docker pull <images:tag>
Build Docker Image
docker build . -t image-name
# use Dockerfile at the root of the repository
docker build <github-repo-url> -t image-name
Run Docker Container
- run.
- start.
- stop.
- restart.
# docker run -dp <host-port>:<container-port> [docker-image]
docker run -d -p 80:80 --name app-name docker/getting-started
docker run -d -p 80:80/tcp -p 80:80/udp --name app-name docker/getting-started
List Docker Container
docker ps
docker ps -l
docker ps -a
docker ps -q
Remove Docker Container
docker rm <container>
Dockerfile
Dockerfile Directives
- FROM: source image.
- ENV: set environment variable.
- WORKDIR: change directory.
- COPY: copy file.
- RUN: run command.
- CMD: final command.
- EXPOSE: expose port.
FROM centos:7
RUN yum -y install httpd
COPY index.html /usr/share/httpd/noindex/index.html
EXPOSE 80
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
FROM centos:7
RUN rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
RUN yum -y install nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]