-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathparams.json
More file actions
6 lines (6 loc) · 17 KB
/
Copy pathparams.json
File metadata and controls
6 lines (6 loc) · 17 KB
1
2
3
4
5
6
{
"name": "Docker Cheat Sheet",
"tagline": "Find, Copy and Paste, Anywhere.",
"body": "[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WZJTZ3V8KKARC)\r\n[](https://github.com/JensPiegsa/docker-cheat-sheet/edit/master/README.md#fork-destination-box)\r\n[](https://github.com/JensPiegsa/docker-cheat-sheet/issues)\r\n\r\nThis document is hosted at [docker.jens-piegsa.com](http://docker.jens-piegsa.com/).\r\n\r\n# Content\r\n\r\n* [1. Fundamentals](#1-fundamentals)\r\n\t* [1.1. Concepts](#11-concepts)\r\n\t* [1.2. Lifecycle](#12-lifecycle)\r\n* [2. Recipes](#2-recipes)\r\n\t* [2.1. Docker Engine](#21-docker-engine)\r\n\t\t* [2.1.1. Building Images](#211-building-images)\r\n\t\t* [2.1.2. Running Containers](#212-running-containers)\r\n\t\t* [2.1.3. Using Volumes](#213-using-volumes)\r\n\t* [2.2. Docker Machine](#22-docker-machine)\r\n\t* [2.3. Dockerfile](#23-dockerfile)\r\n* [3. Showcases](#3-showcases)\r\n\t* [3.1. Private Docker Registry](#31-private-docker-registry)\r\n\t* [3.2. Continuous Integration Tool Stack](#32-continuous-integration-tool-stack)\r\n* [4. Best Practices](#4-best-practices)\r\n* [5. Additional Material](#5-additional-material)\r\n\r\n# 1. Fundamentals\r\n\r\n# 1.1. Concepts\r\n\r\n* **Union file system (UFS)**: allows to overlay multiple file systems appearing as a single system whereby equal folders are merged and equally named files hide their previous versions\r\n* **Image**: a portable read-only file system layer optionally stacked on a parent image\r\n* **Dockerfile**: used to `build` an image and declare the command executed in the container\r\n* **Registry**: is the place where to `push` and `pull` from named / tagged images \r\n* **Container**: an instance of an image with a writable file system layer on top, virtual networking, ready to execute a single application \r\n* **Volume**: a directory outside the UFS that can be mounted inside containers for persistent and shared data \r\n* **Network**: acts as a namespace for containers\r\n* **Service**: a flexible number of container replicas running on a cluster of multiple hosts\r\n\r\n# 1.2. Lifecycle\r\n\r\n*A typical `docker` workflow:*\r\n\r\n* `build` an image based on a `Dockerfile`\r\n* `tag` and `push` the image to a *registry*\r\n* `login` to the registry from the runtime environment to `pull` the image\r\n* optionally `create` a `volume` or two to provide configuration files and hold data that needs to be persisted \r\n* `run` a container based on the image\r\n* `stop` and `start` the container if necessary\r\n* `commit` the container to turn it into an image\r\n* in exceptional situations, `exec` additional commands inside the container\r\n* to replace a container with an updated version \r\n\t* `pull` the new image from the registry\r\n\t* `stop` the running container\r\n\t* backup your volumes to be prepared for a potential rollback\r\n\t* `run` the newer one by specifying a temporary name\r\n\t* if successful, `remove` the old container and `rename` the new one accordingly\r\n \r\n# 2. Recipes\r\n\r\n## 2.1. Docker Engine\r\n\r\n### 2.1.1. Building Images\r\n\r\n#### Debug image build\r\n\r\n* `docker build` shows the IDs of all temporary containers and intermediate images\r\n* use `docker run -it IMAGE_ID` with the ID of the image resulting from the last successful build step and try the next command manually\r\n\r\n### 2.1.2. Running Containers\r\n\r\n#### Start container and run command inside\r\n\r\n```sh\r\ndocker run -it ubuntu:14.04 /bin/bash\r\n```\r\n\r\n#### Start a shell in a running container\r\n\r\n```sh\r\ndocker exec -it CONTAINER /bin/bash\r\n```\r\n\r\n#### Start a container as another user\r\n\r\n```sh\r\ndocker run -u root IMAGE\r\n```\r\n\r\n#### List all existing containers\r\n\r\n```sh\r\ndocker ps -a\r\n```\r\n\r\n#### List running processes inside a container\r\n\r\n```sh\r\ndocker top CONTAINER\r\n```\r\n \r\n#### Follow the logs\r\n\r\n```sh\r\ndocker -f --tail=1000 CONTAINER\r\n```\r\n\r\n#### Stop all running containers\r\n\r\n```sh\r\ndocker stop $(docker ps -q)\r\n```\r\n\r\n#### Remove all stopped containers, except those suffixed '-data':\r\n\r\n\r\n```sh\r\ndocker ps -a -f status=exited | grep -v '\\-data *$'| awk '{if(NR>1) print $1}' | xargs -r docker rm\r\n```\r\n\r\n#### Remove all stopped containers (warning: removes data-only containers too)\r\n\r\n```sh\r\ndocker rm $(docker ps -qa -f status=exited)\r\n```\r\n\r\n* *note: the filter flag `-f status=exited` may be omitted here since running containers can not be removed*\r\n\r\n#### List all images\r\n\r\n```sh\r\ndocker images -a\r\n```\r\n\r\n#### Remove all unused images\r\n\r\n```sh\r\ndocker rmi $(docker images -qa -f dangling=true)\r\n```\r\n\r\n#### Show image history of container\r\n\r\n```sh\r\ndocker history --no-trunc=true $(docker inspect -f '{{.Image}}' CONTAINER)\r\n```\r\n\r\n#### Show file system changes compared to the original image\r\n\r\n```sh\r\ndocker diff CONTAINER\r\n```\r\n\r\n#### Backup volume to host directory\r\n\r\n```sh\r\ndocker run -rm --volumes-from SOURCE_CONTAINER -v $(pwd):/backup busybox \\\r\n tar cvf /backup/backup.tar /data\r\n```\r\n\r\n#### Restore volume from host directory\r\n\r\n```sh\r\ndocker run -rm --volumes-from TARGET_CONTAINER -v $(pwd):/backup busybox tar xvf /backup/backup.tar\r\n```\r\n\r\n#### Show volumes\r\n\r\n```sh\r\ndocker inspect -f '{{range $v, $h := .Config.Volumes}}{{$v}}{{end}}' CONTAINER\r\n```\r\n\r\n#### Start all paused / stopped containers\r\n\r\n* does not work together with container dependencies\r\n\r\n#### Remove all containers and images\r\n\r\n```sh\r\ndocker stop $(docker ps -q) && docker rm $(docker ps -qa) && docker rmi $(docker images -qa)\r\n```\r\n\r\n#### Edit and update a file in a container\r\n\r\n```sh\r\ndocker cp CONTAINER:FILE /tmp/ && docker run --name=nano -it --rm -v /tmp:/tmp \\\r\n piegsaj/nano nano /tmp/FILE ; \\\r\ncat /tmp/FILE | docker exec -i CONTAINER sh -c 'cat > FILE' ; \\\r\nrm /tmp/FILE\r\n```\r\n\r\n#### Deploy war file to Apache Tomcat server instantly\r\n\r\n```sh\r\ndocker run -i -t -p 80:8080 -e WAR_URL=“<http://web-actions.googlecode.com/files/helloworld.war>” \\\r\n bbytes/tomcat7\r\n```\r\n\r\n#### Dump a Postgres database into current directory on the host\r\n\r\n```sh\r\necho \"postgres_password\" | sudo docker run -i --rm --link db:db -v $PWD:/tmp postgres:8 sh -c ' \\\r\n pg_dump -h ocdb -p $OCDB_PORT_5432_TCP_PORT -U postgres -F tar -v openclinica \\\r\n > /tmp/ocdb_pg_dump_$(date +%Y-%m-%d_%H-%M-%S).tar'\r\n```\r\n\r\n#### Backup data folder\r\n\r\n```sh\r\ndocker run --rm --volumes-from oc-data -v $PWD:/tmp piegsaj/openclinica \\\r\n tar cvf /tmp/oc_data_backup_$(date +%Y-%m-%d_%H-%M-%S).tar /tomcat/openclinica.data\r\n```\r\n\r\n#### Restore volume from data-only container\r\n\r\n```sh\r\ndocker run --rm --volumes-from oc-data2 -v $pwd:/tmp piegsaj/openclinica \\\r\n tar xvf /tmp/oc_data_backup_*.tar\r\n```\r\n\r\n#### Get the IP address of a container\r\n\r\n```sh\r\ndocker inspect container_id | grep IPAddress | cut -d '\"' -f 4\r\n```\r\n\r\n## 2.1.3. Using Volumes\r\n\r\n#### Declare a volume via Dockerfile\r\n\r\n```\r\nRUN mkdir /data && echo \"some content\" > /data/file && chown -R daemon:daemon /data\r\nVOLUME /data\r\n```\r\n\r\n* *note: after the `VOLUME` directive, its content can not be changed within the Dockerfile*\r\n\r\n#### Create a volume at runtime\r\n\r\n```sh\r\ndocker run -it -v /data debian /bin/bash\r\n```\r\n\r\n#### Create a volume at runtime bound to a host directory\r\n\r\n```sh\r\ndocker run --rm -v /tmp:/data debian ls -RAlph /data\r\n```\r\n\r\n#### Create a named volume and use it\r\n\r\n```sh\r\ndocker volume create --name=test\r\ndocker run --rm -v test:/data alpine sh -c 'echo \"Hello named volumes\" > /data/hello.txt'\r\ndocker run --rm -v test:/data alpine sh -c 'cat /data/hello.txt'\r\n```\r\n\r\n#### List the content of a volume\r\n\r\n```sh\r\ndocker run --rm -v data:/data alpine ls -RAlph /data\r\n```\r\n\r\n#### Copy a file from host to named volume\r\n\r\n```sh\r\necho \"debug=true\" > test.cnf && \\\r\ndocker volume create --name=conf && \\\r\ndocker run --rm -it -v $(pwd):/src -v conf:/dest alpine cp /src/test.cnf /dest/ && \\\r\nrm -f test.cnf && \\\r\ndocker run --rm -it -v conf:/data alpine cat /data/test.cnf\r\n```\r\n\r\n#### Copy content of existing named volume to a new named volume\r\n\r\n```sh\r\ndocker volume create --name vol_b\r\ndocker run --rm -v vol_a:/source/folder -v vol_b:/target/folder -it \\\r\n rawmind/alpine-base:0.3.4 cp -r /source/folder /target\r\n```\r\n\r\n#### Remove unused images\r\n\r\n```sh\r\ndocker volume rm $(docker volume ls -qf dangling=true)\r\n```\r\n\r\n## 2.2. Docker Machine\r\n\r\n### On a local VM\r\n\r\n#### Get the IP address of the virtual machine for access from host\r\n\r\n```\r\ndocker-machine ip default\r\n```\r\n\r\n#### Add persistent environment variable to boot2docker\r\n\r\n```sh\r\nsudo echo 'echo '\\''export ENVTEST=\"Hello Env!\"'\\'' > /etc/profile.d/custom.sh' | \\\r\nsudo tee -a /var/lib/boot2docker/profile > /dev/null\r\n```\r\n\r\nand restart with `docker-machine restart default`\r\n\r\n#### Install additional linux packages in boot2docker\r\n\r\n* create the file `/var/lib/boot2docker/bootsync.sh` with a content like:\r\n\r\n```sh\r\n#!/bin/sh\r\nsudo /bin/su - docker -c 'tce-load -wi nano'\r\n```\r\n\r\n#### Recreate any folders and files on boot2docker startup\r\n\r\n* store folders / files in `/var/lib/boot2docker/restore-on-boot` and\r\n* create the file `/var/lib/boot2docker/bootsync.sh` with a content like:\r\n\r\n```sh\r\n#!/bin/sh\r\nsudo mkdir -p /var/lib/boot2docker/restore-on-boot && \\\r\nsudo rsync -a /var/lib/boot2docker/restore-on-boot/ /\r\n```\r\n\r\n## 2.3. Dockerfile\r\n\r\n#### Add a periodic health check\r\n\r\n```\r\nHEALTHCHECK --interval=1m --timeout=3s --retries=5 \\\r\n CMD curl -f <http://localhost/> || exit 1\r\n```\r\n\r\n* see also: [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#/healthcheck)\r\n\r\n# 3. Showcases\r\n\r\n## 3.1. Private Docker Registry\r\n\r\n#### Setup with docker-machine / boot2docker\r\n\r\n``` sh\r\ndocker pull registry:2.5.1 ; \\\r\n\r\n# Prepare registry-cert volume\r\ndocker volume create --name=registry-cert && \\\r\nsudo mkdir -p /var/lib/boot2docker/certs/ && cd /var/lib/boot2docker/ && \\\r\nsudo openssl genrsa -out registry.key 4096 && \\\r\nsudo openssl req -new -nodes -sha256 -subj '/CN=localhost' -key registry.key -out registry.csr && \\\r\nsudo openssl x509 -req -days 3650 -signkey registry.key -in registry.csr -out certs/registry.pem && \\\r\ndocker run --rm -it -v /var/lib/boot2docker/:/b2d -v registry-cert:/certs --entrypoint sh registry \\\r\n -c 'cp /b2d/registry.key /certs/ && cp /b2d/certs/registry.pem /certs' && \\\r\n\r\n# Prepare registry-auth volume (please change 'reg_user' and 'reg_password')\r\ndocker volume create --name=registry-auth && \\\r\ndocker run --rm --entrypoint /bin/sh -v registry-auth:/auth registry \\\r\n -c 'htpasswd -Bbn reg_user reg_password > /auth/htpasswd' && \\\r\n\r\n# Prepare registry-data volume\r\ndocker volume create --name=registry-data && \\\r\n\r\n# Stop and remove existing container\r\n{ docker stop registry ; docker rm registry ; } >/dev/null 2>&1 ; \\\r\n\r\n# Create container\r\ndocker run --name registry -h registry -d -l type=app \"$ADD_HOST\" \\\r\n-v registry-data:/var/lib/registry \\\r\n-v registry-auth:/auth \\\r\n-v registry-cert:/certs \\\r\n--restart=always \\\r\n-p 5000:5000 \\\r\n-e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \\\r\n-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.pem \\\r\n-e REGISTRY_AUTH=htpasswd \\\r\n-e \"REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm\" \\\r\n-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \\\r\n-e REGISTRY_STORAGE_DELETE_ENABLED=true \\\r\nregistry\r\n```\r\n\r\n#### Usage example\r\n\r\n``` sh\r\ndocker pull alpine:latest && \\\r\ndocker login -u reg_user -p reg_password localhost:5000 && \\\r\ndocker tag alpine:latest localhost:5000/alpine:private && \\\r\ndocker rmi alpine:latest && \\\r\ndocker push localhost:5000/alpine:private && \\\r\ndocker rmi -f localhost:5000/alpine:private && \\\r\ndocker pull localhost:5000/alpine:private && \\\r\ndocker logout localhost:5000 && \\\r\ndocker images | grep alpine && \\\r\necho \"Deleting image from registry...\" && \\\r\ncurl -X DELETE -u reg_user:reg_password \\\r\nhttps://localhost:5000/v2/alpine/manifests/$(docker images --digests | grep localhost:5000/alpine | awk '{print $3}')\r\n```\r\n\r\n#### Removal\r\n\r\n``` sh\r\ndocker rm -f registry && \\\r\ndocker volume rm registry-data registry-cert registry-auth\r\n```\r\n\r\n## 3.2. Continuous Integration Tool Stack\r\n\r\n#### Setup with docker-machine / boot2docker\r\n\r\n* make a directory called `ci` in your home directory on your host system and change into it\r\n\r\n* create a file named `docker-compose.yml` with the following content:\r\n\r\n```yaml\r\nversion: '2'\r\n\r\nservices:\r\n\r\n jenkins:\r\n image: jenkins\r\n ports:\r\n - \"8082:8082\"\r\n - \"50000:50000\"\r\n restart: always\r\n env_file: .env\r\n environment:\r\n - \"JAVA_OPTS=-Dmail.smtp.starttls.enable=true -Dorg.apache.commons.jelly.tags.fmt.timeZone=Europe/Berlin\"\r\n - \"JENKINS_OPTS=--httpPort=8082\"\r\n volumes:\r\n - jenkins_home:/var/jenkins_home\r\n \r\n nexus:\r\n image: sonatype/nexus3\r\n ports:\r\n - \"8081:8081\"\r\n restart: always\r\n env_file: .env\r\n volumes:\r\n - nexus-data:/nexus-data\r\n \r\n sonarqube:\r\n image: sonarqube\r\n ports:\r\n - \"9000:9000\"\r\n restart: always\r\n env_file:\r\n - .env\r\n - sonarqube.env\r\n environment:\r\n - SONARQUBE_JDBC_URL=jdbc:postgresql://postgres:5432/sonar\r\n - SONARQUBE_JDBC_USERNAME=sonar\r\n volumes:\r\n - sonarqube_conf:/opt/sonarqube/conf\r\n - sonarqube_data:/opt/sonarqube/data\r\n - sonarqube_extensions:/opt/sonarqube/extensions\r\n - sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins\r\n links:\r\n - postgres\r\n\r\n postgres:\r\n image: postgres\r\n ports:\r\n - \"5432:5432\"\r\n restart: always\r\n env_file:\r\n - .env\r\n - sonarqube.env\r\n environment:\r\n - POSTGRES_USER=sonar\r\n volumes:\r\n - postgresql:/var/lib/postgresql\r\n - postgresql_data:/var/lib/postgresql/data\r\n\r\nvolumes:\r\n jenkins_home:\r\n nexus-data:\r\n sonarqube_conf:\r\n sonarqube_data:\r\n sonarqube_extensions:\r\n sonarqube_bundled-plugins:\r\n postgresql:\r\n postgresql_data:\r\n```\r\n\r\n* create a second file named `.env` that defines a timezone:\r\n\r\n```\r\nTZ=Europe/Berlin\r\n```\r\n\r\n* create a third file named `sonarqube.env` that holds the database passwords:\r\n\r\n```\r\nSONARQUBE_JDBC_PASSWORD=sonar\r\nPOSTGRES_PASSWORD=sonar\r\n```\r\n\r\n#### Usage\r\n\r\n* startup all containers:\r\n\r\n```\r\ndocker-compose up -d\r\n```\r\n\r\n* watch the logs, type `docker-compose logs` or `docker logs -f ci_jenkins_1`\r\n\r\n* access the web applications:\r\n\t* Jenkins on port 8082\r\n\t* Sonatype Nexus on port 8081 and\r\n\t* SonarQube on port 9000\r\n\r\n#### Removal\r\n\r\n* to remove the tool stack (incl. data), use:\r\n\r\n```\r\ndocker-compose stop && docker-compose rm -fav\r\n```\r\n\r\n# 4. Best Practices\r\n\r\n## Docker Engine\r\n\r\n* `docker exec` is your friend in development, but should be avoided in a production setup\r\n\r\n## Volumes\r\n\r\n* use *named volumes* to simplify maintenance by separating persistent data from the container and communicating the structure of a project in a more transparent manner\r\n\r\n## Dockerfile\r\n\r\n* always set the `USER` statement, otherwise the container will run as `root` user by default, which maps to the `root` user of the host machine\r\n* use `ENTRYPOINT` and `CMD` directives together to make container usage more convenient\r\n* combine consecutive `RUN` directives with `&&` to reduce the costs of a build and to avoid caching of instructions like `apt-get update`\r\n* use `EXPOSE` to document all needed ports\r\n\r\n# 5. Additional Material\r\n\r\n* [Mouat, A. (2015). *Using Docker: Developing and Deploying Software with Containers.* O'Reilly Media.](http://shop.oreilly.com/product/0636920035671.do) ([German Edition: *Docker. Software entwickeln und deployen mit Containern.* dpunkt.verlag](https://www.dpunkt.de/buecher/12553/9783864903847-docker.html))\r\n* [Official Docker Documentation](https://docs.docker.com/)\r\n* [Gupta, A. (2016). *Docker Container Anti Patterns.*](http://blog.arungupta.me/docker-container-anti-patterns/)\r\n* [StackOverflow Documentation](http://stackoverflow.com/documentation/docker/topics)\r\n\r\n---\r\n\r\n## Contribute\r\n\r\nFeel free to fork this project, send me pull requests, and issues through the project's [GitHub page](https://github.com/JensPiegsa/docker-cheat-sheet/).\r\n",
"note": "Don't delete this file! It's used internally to help with page regeneration."
}