[
  {
    "path": ".gitignore",
    "content": ".idea"
  },
  {
    "path": ".travis.yml",
    "content": "language: ruby\nrvm: 2.2\nbefore_script: gem install awesome_bot\nscript: awesome_bot README.md --allow-redirect --allow-dupe -w vagrantup.com\n"
  },
  {
    "path": "LICENSE",
    "content": "Attribution 4.0 International\n\n=======================================================================\n\nCreative Commons Corporation (\"Creative Commons\") is not a law firm and\ndoes not provide legal services or legal advice. Distribution of\nCreative Commons public licenses does not create a lawyer-client or\nother relationship. Creative Commons makes its licenses and related\ninformation available on an \"as-is\" basis. Creative Commons gives no\nwarranties regarding its licenses, any material licensed under their\nterms and conditions, or any related information. Creative Commons\ndisclaims all liability for damages resulting from their use to the\nfullest extent possible.\n\nUsing Creative Commons Public Licenses\n\nCreative Commons public licenses provide a standard set of terms and\nconditions that creators and other rights holders may use to share\noriginal works of authorship and other material subject to copyright\nand certain other rights specified in the public license below. The\nfollowing considerations are for informational purposes only, are not\nexhaustive, and do not form part of our licenses.\n\n     Considerations for licensors: Our public licenses are\n     intended for use by those authorized to give the public\n     permission to use material in ways otherwise restricted by\n     copyright and certain other rights. Our licenses are\n     irrevocable. Licensors should read and understand the terms\n     and conditions of the license they choose before applying it.\n     Licensors should also secure all rights necessary before\n     applying our licenses so that the public can reuse the\n     material as expected. Licensors should clearly mark any\n     material not subject to the license. This includes other CC-\n     licensed material, or material used under an exception or\n     limitation to copyright. More considerations for licensors:\n\twiki.creativecommons.org/Considerations_for_licensors\n\n     Considerations for the public: By using one of our public\n     licenses, a licensor grants the public permission to use the\n     licensed material under specified terms and conditions. If\n     the licensor's permission is not necessary for any reason--for\n     example, because of any applicable exception or limitation to\n     copyright--then that use is not regulated by the license. Our\n     licenses grant only permissions under copyright and certain\n     other rights that a licensor has authority to grant. Use of\n     the licensed material may still be restricted for other\n     reasons, including because others have copyright or other\n     rights in the material. A licensor may make special requests,\n     such as asking that all changes be marked or described.\n     Although not required by our licenses, you are encouraged to\n     respect those requests where reasonable. More considerations\n     for the public: \n\twiki.creativecommons.org/Considerations_for_licensees\n\n=======================================================================\n\nCreative Commons Attribution 4.0 International Public License\n\nBy exercising the Licensed Rights (defined below), You accept and agree\nto be bound by the terms and conditions of this Creative Commons\nAttribution 4.0 International Public License (\"Public License\"). To the\nextent this Public License may be interpreted as a contract, You are\ngranted the Licensed Rights in consideration of Your acceptance of\nthese terms and conditions, and the Licensor grants You such rights in\nconsideration of benefits the Licensor receives from making the\nLicensed Material available under these terms and conditions.\n\n\nSection 1 -- Definitions.\n\n  a. Adapted Material means material subject to Copyright and Similar\n     Rights that is derived from or based upon the Licensed Material\n     and in which the Licensed Material is translated, altered,\n     arranged, transformed, or otherwise modified in a manner requiring\n     permission under the Copyright and Similar Rights held by the\n     Licensor. For purposes of this Public License, where the Licensed\n     Material is a musical work, performance, or sound recording,\n     Adapted Material is always produced where the Licensed Material is\n     synched in timed relation with a moving image.\n\n  b. Adapter's License means the license You apply to Your Copyright\n     and Similar Rights in Your contributions to Adapted Material in\n     accordance with the terms and conditions of this Public License.\n\n  c. Copyright and Similar Rights means copyright and/or similar rights\n     closely related to copyright including, without limitation,\n     performance, broadcast, sound recording, and Sui Generis Database\n     Rights, without regard to how the rights are labeled or\n     categorized. For purposes of this Public License, the rights\n     specified in Section 2(b)(1)-(2) are not Copyright and Similar\n     Rights.\n\n  d. Effective Technological Measures means those measures that, in the\n     absence of proper authority, may not be circumvented under laws\n     fulfilling obligations under Article 11 of the WIPO Copyright\n     Treaty adopted on December 20, 1996, and/or similar international\n     agreements.\n\n  e. Exceptions and Limitations means fair use, fair dealing, and/or\n     any other exception or limitation to Copyright and Similar Rights\n     that applies to Your use of the Licensed Material.\n\n  f. Licensed Material means the artistic or literary work, database,\n     or other material to which the Licensor applied this Public\n     License.\n\n  g. Licensed Rights means the rights granted to You subject to the\n     terms and conditions of this Public License, which are limited to\n     all Copyright and Similar Rights that apply to Your use of the\n     Licensed Material and that the Licensor has authority to license.\n\n  h. Licensor means the individual(s) or entity(ies) granting rights\n     under this Public License.\n\n  i. Share means to provide material to the public by any means or\n     process that requires permission under the Licensed Rights, such\n     as reproduction, public display, public performance, distribution,\n     dissemination, communication, or importation, and to make material\n     available to the public including in ways that members of the\n     public may access the material from a place and at a time\n     individually chosen by them.\n\n  j. Sui Generis Database Rights means rights other than copyright\n     resulting from Directive 96/9/EC of the European Parliament and of\n     the Council of 11 March 1996 on the legal protection of databases,\n     as amended and/or succeeded, as well as other essentially\n     equivalent rights anywhere in the world.\n\n  k. You means the individual or entity exercising the Licensed Rights\n     under this Public License. Your has a corresponding meaning.\n\n\nSection 2 -- Scope.\n\n  a. License grant.\n\n       1. Subject to the terms and conditions of this Public License,\n          the Licensor hereby grants You a worldwide, royalty-free,\n          non-sublicensable, non-exclusive, irrevocable license to\n          exercise the Licensed Rights in the Licensed Material to:\n\n            a. reproduce and Share the Licensed Material, in whole or\n               in part; and\n\n            b. produce, reproduce, and Share Adapted Material.\n\n       2. Exceptions and Limitations. For the avoidance of doubt, where\n          Exceptions and Limitations apply to Your use, this Public\n          License does not apply, and You do not need to comply with\n          its terms and conditions.\n\n       3. Term. The term of this Public License is specified in Section\n          6(a).\n\n       4. Media and formats; technical modifications allowed. The\n          Licensor authorizes You to exercise the Licensed Rights in\n          all media and formats whether now known or hereafter created,\n          and to make technical modifications necessary to do so. The\n          Licensor waives and/or agrees not to assert any right or\n          authority to forbid You from making technical modifications\n          necessary to exercise the Licensed Rights, including\n          technical modifications necessary to circumvent Effective\n          Technological Measures. For purposes of this Public License,\n          simply making modifications authorized by this Section 2(a)\n          (4) never produces Adapted Material.\n\n       5. Downstream recipients.\n\n            a. Offer from the Licensor -- Licensed Material. Every\n               recipient of the Licensed Material automatically\n               receives an offer from the Licensor to exercise the\n               Licensed Rights under the terms and conditions of this\n               Public License.\n\n            b. No downstream restrictions. You may not offer or impose\n               any additional or different terms or conditions on, or\n               apply any Effective Technological Measures to, the\n               Licensed Material if doing so restricts exercise of the\n               Licensed Rights by any recipient of the Licensed\n               Material.\n\n       6. No endorsement. Nothing in this Public License constitutes or\n          may be construed as permission to assert or imply that You\n          are, or that Your use of the Licensed Material is, connected\n          with, or sponsored, endorsed, or granted official status by,\n          the Licensor or others designated to receive attribution as\n          provided in Section 3(a)(1)(A)(i).\n\n  b. Other rights.\n\n       1. Moral rights, such as the right of integrity, are not\n          licensed under this Public License, nor are publicity,\n          privacy, and/or other similar personality rights; however, to\n          the extent possible, the Licensor waives and/or agrees not to\n          assert any such rights held by the Licensor to the limited\n          extent necessary to allow You to exercise the Licensed\n          Rights, but not otherwise.\n\n       2. Patent and trademark rights are not licensed under this\n          Public License.\n\n       3. To the extent possible, the Licensor waives any right to\n          collect royalties from You for the exercise of the Licensed\n          Rights, whether directly or through a collecting society\n          under any voluntary or waivable statutory or compulsory\n          licensing scheme. In all other cases the Licensor expressly\n          reserves any right to collect such royalties.\n\n\nSection 3 -- License Conditions.\n\nYour exercise of the Licensed Rights is expressly made subject to the\nfollowing conditions.\n\n  a. Attribution.\n\n       1. If You Share the Licensed Material (including in modified\n          form), You must:\n\n            a. retain the following if it is supplied by the Licensor\n               with the Licensed Material:\n\n                 i. identification of the creator(s) of the Licensed\n                    Material and any others designated to receive\n                    attribution, in any reasonable manner requested by\n                    the Licensor (including by pseudonym if\n                    designated);\n\n                ii. a copyright notice;\n\n               iii. a notice that refers to this Public License;\n\n                iv. a notice that refers to the disclaimer of\n                    warranties;\n\n                 v. a URI or hyperlink to the Licensed Material to the\n                    extent reasonably practicable;\n\n            b. indicate if You modified the Licensed Material and\n               retain an indication of any previous modifications; and\n\n            c. indicate the Licensed Material is licensed under this\n               Public License, and include the text of, or the URI or\n               hyperlink to, this Public License.\n\n       2. You may satisfy the conditions in Section 3(a)(1) in any\n          reasonable manner based on the medium, means, and context in\n          which You Share the Licensed Material. For example, it may be\n          reasonable to satisfy the conditions by providing a URI or\n          hyperlink to a resource that includes the required\n          information.\n\n       3. If requested by the Licensor, You must remove any of the\n          information required by Section 3(a)(1)(A) to the extent\n          reasonably practicable.\n\n       4. If You Share Adapted Material You produce, the Adapter's\n          License You apply must not prevent recipients of the Adapted\n          Material from complying with this Public License.\n\n\nSection 4 -- Sui Generis Database Rights.\n\nWhere the Licensed Rights include Sui Generis Database Rights that\napply to Your use of the Licensed Material:\n\n  a. for the avoidance of doubt, Section 2(a)(1) grants You the right\n     to extract, reuse, reproduce, and Share all or a substantial\n     portion of the contents of the database;\n\n  b. if You include all or a substantial portion of the database\n     contents in a database in which You have Sui Generis Database\n     Rights, then the database in which You have Sui Generis Database\n     Rights (but not its individual contents) is Adapted Material; and\n\n  c. You must comply with the conditions in Section 3(a) if You Share\n     all or a substantial portion of the contents of the database.\n\nFor the avoidance of doubt, this Section 4 supplements and does not\nreplace Your obligations under this Public License where the Licensed\nRights include other Copyright and Similar Rights.\n\n\nSection 5 -- Disclaimer of Warranties and Limitation of Liability.\n\n  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE\n     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS\n     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF\n     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,\n     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,\n     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR\n     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,\n     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT\n     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT\n     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.\n\n  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE\n     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,\n     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,\n     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,\n     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR\n     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN\n     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR\n     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR\n     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.\n\n  c. The disclaimer of warranties and limitation of liability provided\n     above shall be interpreted in a manner that, to the extent\n     possible, most closely approximates an absolute disclaimer and\n     waiver of all liability.\n\n\nSection 6 -- Term and Termination.\n\n  a. This Public License applies for the term of the Copyright and\n     Similar Rights licensed here. However, if You fail to comply with\n     this Public License, then Your rights under this Public License\n     terminate automatically.\n\n  b. Where Your right to use the Licensed Material has terminated under\n     Section 6(a), it reinstates:\n\n       1. automatically as of the date the violation is cured, provided\n          it is cured within 30 days of Your discovery of the\n          violation; or\n\n       2. upon express reinstatement by the Licensor.\n\n     For the avoidance of doubt, this Section 6(b) does not affect any\n     right the Licensor may have to seek remedies for Your violations\n     of this Public License.\n\n  c. For the avoidance of doubt, the Licensor may also offer the\n     Licensed Material under separate terms or conditions or stop\n     distributing the Licensed Material at any time; however, doing so\n     will not terminate this Public License.\n\n  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public\n     License.\n\n\nSection 7 -- Other Terms and Conditions.\n\n  a. The Licensor shall not be bound by any additional or different\n     terms or conditions communicated by You unless expressly agreed.\n\n  b. Any arrangements, understandings, or agreements regarding the\n     Licensed Material not stated herein are separate from and\n     independent of the terms and conditions of this Public License.\n\n\nSection 8 -- Interpretation.\n\n  a. For the avoidance of doubt, this Public License does not, and\n     shall not be interpreted to, reduce, limit, restrict, or impose\n     conditions on any use of the Licensed Material that could lawfully\n     be made without permission under this Public License.\n\n  b. To the extent possible, if any provision of this Public License is\n     deemed unenforceable, it shall be automatically reformed to the\n     minimum extent necessary to make it enforceable. If the provision\n     cannot be reformed, it shall be severed from this Public License\n     without affecting the enforceability of the remaining terms and\n     conditions.\n\n  c. No term or condition of this Public License will be waived and no\n     failure to comply consented to unless expressly agreed to by the\n     Licensor.\n\n  d. Nothing in this Public License constitutes or may be interpreted\n     as a limitation upon, or waiver of, any privileges and immunities\n     that apply to the Licensor or You, including from the legal\n     processes of any jurisdiction or authority.\n\n\n=======================================================================\n\nCreative Commons is not a party to its public\nlicenses. Notwithstanding, Creative Commons may elect to apply one of\nits public licenses to material it publishes and in those instances\nwill be considered the “Licensor.” The text of the Creative Commons\npublic licenses is dedicated to the public domain under the CC0 Public\nDomain Dedication. Except for the limited purpose of indicating that\nmaterial is shared under a Creative Commons public license or as\notherwise permitted by the Creative Commons policies published at\ncreativecommons.org/policies, Creative Commons does not authorize the\nuse of the trademark \"Creative Commons\" or any other trademark or logo\nof Creative Commons without its prior written consent including,\nwithout limitation, in connection with any unauthorized modifications\nto any of its public licenses or any other arrangements,\nunderstandings, or agreements concerning use of licensed material. For\nthe avoidance of doubt, this paragraph does not form part of the\npublic licenses.\n\nCreative Commons may be contacted at creativecommons.org.\n"
  },
  {
    "path": "README.md",
    "content": "# Docker Cheat Sheet\n\n**Want to improve this cheat sheet?  See the [Contributing](#contributing) section!**\n\n## Table of Contents\n\n* [Why Docker](#why-docker)\n* [Prerequisites](#prerequisites)\n* [Installation](#installation)\n* [Containers](#containers)\n* [Images](#images)\n* [Networks](#networks)\n* [Registry and Repository](#registry--repository)\n* [Dockerfile](#dockerfile)\n* [Layers](#layers)\n* [Links](#links)\n* [Volumes](#volumes)\n* [Exposing Ports](#exposing-ports)\n* [Best Practices](#best-practices)\n* [Docker-Compose](#docker-compose)\n* [Security](#security)\n* [Tips](#tips)\n* [Contributing](#contributing)\n\n## Why Docker\n\n\"With Docker, developers can build any app in any language using any toolchain. “Dockerized” apps are completely portable and can run anywhere - colleagues’ OS X and Windows laptops, QA servers running Ubuntu in the cloud, and production data center VMs running Red Hat.\n\nDevelopers can get going quickly by starting with one of the 13,000+ apps available on Docker Hub. Docker manages and tracks changes and dependencies, making it easier for sysadmins to understand how the apps that developers build work. And with Docker Hub, developers can automate their build pipeline and share artifacts with collaborators through public or private repositories.\n\nDocker helps developers build and ship higher-quality applications, faster.\" -- [What is Docker](https://www.docker.com/what-docker#copy1)\n\n## Prerequisites\n\nI use [Oh My Zsh](https://github.com/ohmyzsh/oh-my-zsh) with the [Docker plugin](https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#docker) for autocompletion of docker commands. YMMV.\n\n### Linux\n\nThe 3.10.x kernel is [the minimum requirement](https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies) for Docker.\n\n### MacOS\n\n10.8 “Mountain Lion” or newer is required.\n\n### Windows 10\n\nHyper-V must be enabled in BIOS\n\nVT-D must also be enabled if available (Intel Processors).\n\n### Windows Server\n\nWindows Server 2016 is the minimum version required to install docker and docker-compose. Limitations exist on this version, such as multiple virtual networks and Linux containers. Windows Server 2019 and later are recommended. \n\n## Installation\n\n### Linux\n\nRun this quick and easy install script provided by Docker:\n\n```sh\ncurl -sSL https://get.docker.com/ | sh\n```\n\nIf you're not willing to run a random shell script, please see the [installation](https://docs.docker.com/engine/installation/linux/) instructions for your distribution.\n\nIf you are a complete Docker newbie, you should follow the [series of tutorials](https://docs.docker.com/engine/getstarted/) now.\n\n### macOS\n\nDownload and install [Docker Community Edition](https://www.docker.com/community-edition). if you have Homebrew-Cask, just type `brew install --cask docker`. Or Download and install [Docker Toolbox](https://docs.docker.com/toolbox/overview/).  [Docker For Mac](https://docs.docker.com/docker-for-mac/) is nice, but it's not quite as finished as the VirtualBox install.  [See the comparison](https://docs.docker.com/docker-for-mac/docker-toolbox/).\n\n> **NOTE** Docker Toolbox is legacy. You should to use Docker Community Edition, See [Docker Toolbox](https://docs.docker.com/toolbox/overview/).\n\nOnce you've installed Docker Community Edition, click the docker icon in Launchpad. Then start up a container:\n\n```sh\ndocker run hello-world\n```\n\nThat's it, you have a running Docker container.\n\nIf you are a complete Docker newbie, you should probably follow the [series of tutorials](https://docs.docker.com/engine/getstarted/) now.\n\n### Windows 10\n\nInstructions to install Docker Desktop for Windows can be found [here](https://docs.docker.com/desktop/windows/install/)\n\nOnce installed, open powershell as administrator and run:\n\n```powershell\n# Display the version of docker installed:\ndocker version\n\n# Pull, create, and run 'hello-world':\ndocker run hello-world\n```\n\nTo continue with this cheat sheet, right click the Docker icon in the system tray, and go to settings. In order to mount volumes, the C:/ drive will need to be enabled in the settings to that information can be passed into the containers (later described in this article). \n\nTo switch between Windows containers and Linux containers, right click the icon in the system tray and click the button to switch container operating system Doing this will stop the current containers that are running, and make them unaccessible until the container OS is switched back.\n\nAdditionally, if you have WSL or WSL2 installed on your desktop, you might want to install the Linux Kernel for Windows. Instructions can be found [here](https://techcommunity.microsoft.com/t5/windows-dev-appconsult/using-wsl2-in-a-docker-linux-container-on-windows-to-run-a/ba-p/1482133). This requires the Windows Subsystem for Linux feature. This will allow for containers to be accessed by WSL operating systems, as well as the efficiency gain from running WSL operating systems in docker. It is also preferred to use [Windows terminal](https://docs.microsoft.com/en-us/windows/terminal/get-started) for this.\n\n### Windows Server 2016 / 2019\n\nFollow Microsoft's instructions that can be found [here](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/deploy-containers-on-server#install-docker)\n\nIf using the latest edge version of 2019, be prepared to only work in powershell, as it is only a servercore image (no desktop interface). When starting this machine, it will login and go straight to a powershell window. It is recommended to install text editors and other tools using [Chocolatey](https://chocolatey.org/install).\n\nAfter installing, these commands will work:\n\n```powershell\n# Display the version of docker installed:\ndocker version\n\n# Pull, create, and run 'hello-world':\ndocker run hello-world\n```\n\nWindows Server 2016 is not able to run Linux images. \n\nWindows Server Build 2004 is capable of running both linux and windows containers simultaneously through Hyper-V isolation. When running containers, use the ```--isolation=hyperv``` command, which will isolate the container using a separate kernel instance. \n\n### Check Version\n\nIt is very important that you always know the current version of Docker you are currently running on at any point in time. This is very helpful because you get to know what features are compatible with what you have running. This is also important because you know what containers to run from the docker store when you are trying to get template containers. That said let see how to know which version of docker we have running currently.\n\n* [`docker version`](https://docs.docker.com/engine/reference/commandline/version/) shows which version of docker you have running.\n\nGet the server version:\n\n```console\n$ docker version --format '{{.Server.Version}}'\n1.8.0\n```\n\nYou can also dump raw JSON data:\n\n```console\n$ docker version --format '{{json .}}'\n{\"Client\":{\"Version\":\"1.8.0\",\"ApiVersion\":\"1.20\",\"GitCommit\":\"f5bae0a\",\"GoVersion\":\"go1.4.2\",\"Os\":\"linux\",\"Arch\":\"am\"}\n```\n\n## Containers\n\n[Your basic isolated Docker process](http://etherealmind.com/basics-docker-containers-hypervisors-coreos/). Containers are to Virtual Machines as threads are to processes. Or you can think of them as chroots on steroids.\n\n### Lifecycle\n\n* [`docker create`](https://docs.docker.com/engine/reference/commandline/create) creates a container but does not start it.\n* [`docker rename`](https://docs.docker.com/engine/reference/commandline/rename/) allows the container to be renamed.\n* [`docker run`](https://docs.docker.com/engine/reference/commandline/run) creates and starts a container in one operation.\n* [`docker rm`](https://docs.docker.com/engine/reference/commandline/rm) deletes a container.\n* [`docker update`](https://docs.docker.com/engine/reference/commandline/update/) updates a container's resource limits.\n\nNormally if you run a container without options it will start and stop immediately, if you want keep it running you can use the command, `docker run -td container_id` this will use the option `-t` that will allocate a pseudo-TTY session and `-d` that will detach automatically the container (run container in background and print container ID).\n\nIf you want a transient container, `docker run --rm` will remove the container after it stops.\n\nIf you want to map a directory on the host to a docker container, `docker run -v $HOSTDIR:$DOCKERDIR`. Also see [Volumes](https://github.com/wsargent/docker-cheat-sheet/#volumes).\n\nIf you want to remove also the volumes associated with the container, the deletion of the container must include the `-v` switch like in `docker rm -v`.\n\nThere's also a [logging driver](https://docs.docker.com/engine/admin/logging/overview/) available for individual containers in docker 1.10. To run docker with a custom log driver (i.e., to syslog), use `docker run --log-driver=syslog`.\n\nAnother useful option is `docker run --name yourname docker_image` because when you specify the `--name` inside the run command this will allow you to start and stop a container by calling it with the name the you specified when you created it.\n\n### Starting and Stopping\n\n* [`docker start`](https://docs.docker.com/engine/reference/commandline/start) starts a container so it is running.\n* [`docker stop`](https://docs.docker.com/engine/reference/commandline/stop) stops a running container.\n* [`docker restart`](https://docs.docker.com/engine/reference/commandline/restart) stops and starts a container.\n* [`docker pause`](https://docs.docker.com/engine/reference/commandline/pause/) pauses a running container, \"freezing\" it in place.\n* [`docker unpause`](https://docs.docker.com/engine/reference/commandline/unpause/) will unpause a running container.\n* [`docker wait`](https://docs.docker.com/engine/reference/commandline/wait) blocks until running container stops.\n* [`docker kill`](https://docs.docker.com/engine/reference/commandline/kill) sends a SIGKILL to a running container.\n* [`docker attach`](https://docs.docker.com/engine/reference/commandline/attach) will connect to a running container.\n\nIf you want to detach from a running container, use `Ctrl + p, Ctrl + q`.\nIf you want to integrate a container with a [host process manager](https://docs.docker.com/engine/admin/host_integration/), start the daemon with `-r=false` then use `docker start -a`.\n\nIf you want to expose container ports through the host, see the [exposing ports](#exposing-ports) section.\n\nRestart policies on crashed docker instances are [covered here](http://container42.com/2014/09/30/docker-restart-policies/).\n\n#### CPU Constraints\n\nYou can limit CPU, either using a percentage of all CPUs, or by using specific cores.  \n\nFor example, you can tell the [`cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint) setting.  The setting is a bit strange -- 1024 means 100% of the CPU, so if you want the container to take 50% of all CPU cores, you should specify 512.  See <https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/#_cpu> for more:\n\n```sh\ndocker run -it -c 512 agileek/cpuset-test\n```\n\nYou can also only use some CPU cores using [`cpuset-cpus`](https://docs.docker.com/engine/reference/run/#/cpuset-constraint).  See <https://agileek.github.io/docker/2014/08/06/docker-cpuset/> for details and some nice videos:\n\n```sh\ndocker run -it --cpuset-cpus=0,4,6 agileek/cpuset-test\n```\n\nNote that Docker can still **see** all of the CPUs inside the container -- it just isn't using all of them.  See <https://github.com/docker/docker/issues/20770> for more details.\n\n#### Memory Constraints\n\nYou can also set [memory constraints](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) on Docker:\n\n```sh\ndocker run -it -m 300M ubuntu:14.04 /bin/bash\n```\n\n#### Capabilities\n\nLinux capabilities can be set by using `cap-add` and `cap-drop`.  See <https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities> for details.  This should be used for greater security.\n\nTo mount a FUSE based filesystem, you need to combine both --cap-add and --device:\n\n```sh\ndocker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs\n```\n\nGive access to a single device:\n\n```sh\ndocker run -it --device=/dev/ttyUSB0 debian bash\n```\n\nGive access to all devices:\n\n```sh\ndocker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash\n```\n\nMore info about privileged containers [here](\nhttps://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities).\n\n### Info\n\n* [`docker ps`](https://docs.docker.com/engine/reference/commandline/ps) shows running containers.\n* [`docker logs`](https://docs.docker.com/engine/reference/commandline/logs) gets logs from container.  (You can use a custom log driver, but logs is only available for `json-file` and `journald` in 1.10).\n* [`docker inspect`](https://docs.docker.com/engine/reference/commandline/inspect) looks at all the info on a container (including IP address).\n* [`docker events`](https://docs.docker.com/engine/reference/commandline/events) gets events from container.\n* [`docker port`](https://docs.docker.com/engine/reference/commandline/port) shows public facing port of container.\n* [`docker top`](https://docs.docker.com/engine/reference/commandline/top) shows running processes in container.\n* [`docker stats`](https://docs.docker.com/engine/reference/commandline/stats) shows containers' resource usage statistics.\n* [`docker diff`](https://docs.docker.com/engine/reference/commandline/diff) shows changed files in the container's FS.\n\n`docker ps -a` shows running and stopped containers.\n\n`docker stats --all` shows a list of all containers, default shows just running.\n\n### Import / Export\n\n* [`docker cp`](https://docs.docker.com/engine/reference/commandline/cp) copies files or folders between a container and the local filesystem.\n* [`docker export`](https://docs.docker.com/engine/reference/commandline/export) turns container filesystem into tarball archive stream to STDOUT.\n\n### Executing Commands\n\n* [`docker exec`](https://docs.docker.com/engine/reference/commandline/exec) to execute a command in container.\n\nTo enter a running container, attach a new shell process to a running container called foo, use: `docker exec -it foo /bin/bash`.\n\n## Images\n\nImages are just [templates for docker containers](https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work).\n\n### Lifecycle\n\n* [`docker images`](https://docs.docker.com/engine/reference/commandline/images) shows all images.\n* [`docker import`](https://docs.docker.com/engine/reference/commandline/import) creates an image from a tarball.\n* [`docker build`](https://docs.docker.com/engine/reference/commandline/build) creates image from Dockerfile.\n* [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit) creates image from a container, pausing it temporarily if it is running.\n* [`docker rmi`](https://docs.docker.com/engine/reference/commandline/rmi) removes an image.\n* [`docker load`](https://docs.docker.com/engine/reference/commandline/load) loads an image from a tar archive as STDIN, including images and tags (as of 0.7).\n* [`docker save`](https://docs.docker.com/engine/reference/commandline/save) saves an image to a tar archive stream to STDOUT with all parent layers, tags & versions (as of 0.7).\n\n### Info\n\n* [`docker history`](https://docs.docker.com/engine/reference/commandline/history) shows history of image.\n* [`docker tag`](https://docs.docker.com/engine/reference/commandline/tag) tags an image to a name (local or registry).\n\n### Cleaning up\n\nWhile you can use the `docker rmi` command to remove specific images, there's a tool called [docker-gc](https://github.com/spotify/docker-gc) that will safely clean up images that are no longer used by any containers. As of docker 1.13, `docker image prune` is also available for removing unused images. See [Prune](#prune).\n\n### Load/Save image\n\nLoad an image from file:\n\n```sh\ndocker load < my_image.tar.gz\n```\n\nSave an existing image:\n\n```sh\ndocker save my_image:my_tag | gzip > my_image.tar.gz\n```\n\n### Import/Export container\n\nImport a container as an image from file:\n\n```sh\ncat my_container.tar.gz | docker import - my_image:my_tag\n```\n\nExport an existing container:\n\n```sh\ndocker export my_container | gzip > my_container.tar.gz\n```\n\n### Difference between loading a saved image and importing an exported container as an image\n\nLoading an image using the `load` command creates a new image including its history.  \nImporting a container as an image using the `import` command creates a new image excluding the history which results in a smaller image size compared to loading an image.\n\n## Networks\n\nDocker has a [networks](https://docs.docker.com/engine/userguide/networking/) feature. Docker automatically creates 3 network interfaces when you install it (bridge, host none). A new container is launched into the bridge network by default. To enable communication between multiple containers, you can create a new network and launch containers in it. This enables containers to communicate to each other while being isolated from containers that are not connected to the network. Furthermore, it allows to map container names to their IP addresses. See [working with networks](https://docs.docker.com/engine/userguide/networking/work-with-networks/) for more details.\n\n### Lifecycle\n\n* [`docker network create`](https://docs.docker.com/engine/reference/commandline/network_create/) NAME Create a new network (default type: bridge).\n* [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/) NAME Remove one or more networks by name or identifier. No containers can be connected to the network when deleting it.\n\n### Info\n\n* [`docker network ls`](https://docs.docker.com/engine/reference/commandline/network_ls/) List networks\n* [`docker network inspect`](https://docs.docker.com/engine/reference/commandline/network_inspect/) NAME Display detailed information on one or more networks.\n\n### Connection\n\n* [`docker network connect`](https://docs.docker.com/engine/reference/commandline/network_connect/) NETWORK CONTAINER Connect a container to a network\n* [`docker network disconnect`](https://docs.docker.com/engine/reference/commandline/network_disconnect/) NETWORK CONTAINER Disconnect a container from a network\n\nYou can specify a [specific IP address for a container](https://blog.jessfraz.com/post/ips-for-all-the-things/):\n\n```sh\n# create a new bridge network with your subnet and gateway for your ip block\ndocker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic\n\n# run a nginx container with a specific ip in that block\n$ docker run --rm -it --net iptastic --ip 203.0.113.2 nginx\n\n# curl the ip from any other place (assuming this is a public ip block duh)\n$ curl 203.0.113.2\n```\n\n## Registry & Repository\n\nA repository is a *hosted* collection of tagged images that together create the file system for a container.\n\nA registry is a *host* -- a server that stores repositories and provides an HTTP API for [managing the uploading and downloading of repositories](https://docs.docker.com/engine/tutorials/dockerrepos/).\n\nDocker.com hosts its own [index](https://hub.docker.com/) to a central registry which contains a large number of repositories.  Having said that, the central docker registry [does not do a good job of verifying images](https://titanous.com/posts/docker-insecurity) and should be avoided if you're worried about security.\n\n* [`docker login`](https://docs.docker.com/engine/reference/commandline/login) to login to a registry.\n* [`docker logout`](https://docs.docker.com/engine/reference/commandline/logout) to logout from a registry.\n* [`docker search`](https://docs.docker.com/engine/reference/commandline/search) searches registry for image.\n* [`docker pull`](https://docs.docker.com/engine/reference/commandline/pull) pulls an image from registry to local machine.\n* [`docker push`](https://docs.docker.com/engine/reference/commandline/push) pushes an image to the registry from local machine.\n\n### Run local registry\n\nYou can run a local registry by using the [docker distribution](https://github.com/docker/distribution) project and looking at the [local deploy](https://github.com/docker/docker.github.io/blob/master/registry/deploying.md) instructions.\n\nAlso see the [mailing list](https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution).\n\n## Dockerfile\n\n[The configuration file](https://docs.docker.com/engine/reference/builder/). Sets up a Docker container when you run `docker build` on it. Vastly preferable to `docker commit`.  \n\nHere are some common text editors and their syntax highlighting modules you could use to create Dockerfiles:\n\n* If you use [jEdit](http://jedit.org), I've put up a syntax highlighting module for [Dockerfile](https://github.com/wsargent/jedit-docker-mode) you can use.\n* [Sublime Text 2](https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting)\n* [Atom](https://atom.io/packages/language-docker)\n* [Vim](https://github.com/ekalinin/Dockerfile.vim)\n* [Emacs](https://github.com/spotify/dockerfile-mode)\n* [TextMate](https://github.com/docker/docker/tree/master/contrib/syntax/textmate)\n* [VS Code](https://github.com/Microsoft/vscode-docker)\n* Also see [Docker meets the IDE](https://domeide.github.io/)\n\n### Instructions\n\n* [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)\n* [FROM](https://docs.docker.com/engine/reference/builder/#from) Sets the Base Image for subsequent instructions.\n* [MAINTAINER (deprecated - use LABEL instead)](https://docs.docker.com/engine/reference/builder/#maintainer-deprecated) Set the Author field of the generated images.\n* [RUN](https://docs.docker.com/engine/reference/builder/#run) execute any commands in a new layer on top of the current image and commit the results.\n* [CMD](https://docs.docker.com/engine/reference/builder/#cmd) provide defaults for an executing container.\n* [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) informs Docker that the container listens on the specified network ports at runtime.  NOTE: does not actually make ports accessible.\n* [ENV](https://docs.docker.com/engine/reference/builder/#env) sets environment variable.\n* [ADD](https://docs.docker.com/engine/reference/builder/#add) copies new files, directories or remote file to container.  Invalidates caches. Avoid `ADD` and use `COPY` instead.\n* [COPY](https://docs.docker.com/engine/reference/builder/#copy) copies new files or directories to container.  By default this copies as root regardless of the USER/WORKDIR settings.  Use `--chown=<user>:<group>` to give ownership to another user/group.  (Same for `ADD`.)\n* [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) configures a container that will run as an executable.\n* [VOLUME](https://docs.docker.com/engine/reference/builder/#volume) creates a mount point for externally mounted volumes or other containers.\n* [USER](https://docs.docker.com/engine/reference/builder/#user) sets the user name for following RUN / CMD / ENTRYPOINT commands.\n* [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) sets the working directory.\n* [ARG](https://docs.docker.com/engine/reference/builder/#arg) defines a build-time variable.\n* [ONBUILD](https://docs.docker.com/engine/reference/builder/#onbuild) adds a trigger instruction when the image is used as the base for another build.\n* [STOPSIGNAL](https://docs.docker.com/engine/reference/builder/#stopsignal) sets the system call signal that will be sent to the container to exit.\n* [LABEL](https://docs.docker.com/config/labels-custom-metadata/) apply key/value metadata to your images, containers, or daemons.\n* [SHELL](https://docs.docker.com/engine/reference/builder/#shell) override default shell is used by docker to run commands.\n* [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#healthcheck) tells docker how to test a container to check that it is still working.\n\n### Tutorial\n\n* [Flux7's Dockerfile Tutorial](https://www.flux7.com/tutorial/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)\n\n### Examples\n\n* [Examples](https://docs.docker.com/engine/reference/builder/#dockerfile-examples)\n* [Best practices for writing Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)\n* [Michael Crosby](http://crosbymichael.com/) has some more [Dockerfiles best practices](http://crosbymichael.com/dockerfile-best-practices.html) / [take 2](http://crosbymichael.com/dockerfile-best-practices-take-2.html).\n* [Building Good Docker Images](http://jonathan.bergknoff.com/journal/building-good-docker-images) / [Building Better Docker Images](http://jonathan.bergknoff.com/journal/building-better-docker-images)\n* [Managing Container Configuration with Metadata](https://speakerdeck.com/garethr/managing-container-configuration-with-metadata)\n* [How to write excellent Dockerfiles](https://rock-it.pl/how-to-write-excellent-dockerfiles/)\n\n## Layers\n\nThe versioned filesystem in Docker is based on layers. They're like [git commits or changesets for filesystems](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/).\n\n## Links\n\nLinks are how Docker containers talk to each other [through TCP/IP ports](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/). [Atlassian](https://blogs.atlassian.com/2013/11/docker-all-the-things-at-atlassian-automation-and-wiring/) show worked examples. You can also resolve [links by hostname](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file).\n\nThis has been deprecated to some extent by [user-defined networks](https://docs.docker.com/network/).\n\nNOTE: If you want containers to ONLY communicate with each other through links, start the docker daemon with `-icc=false` to disable inter process communication.\n\nIf you have a container with the name CONTAINER (specified by `docker run --name CONTAINER`) and in the Dockerfile, it has an exposed port:\n\n```\nEXPOSE 1337\n```\n\nThen if we create another container called LINKED like so:\n\n```sh\ndocker run -d --link CONTAINER:ALIAS --name LINKED user/wordpress\n```\n\nThen the exposed ports and aliases of CONTAINER will show up in LINKED with the following environment variables:\n\n```sh\n$ALIAS_PORT_1337_TCP_PORT\n$ALIAS_PORT_1337_TCP_ADDR\n```\n\nAnd you can connect to it that way.\n\nTo delete links, use `docker rm --link`.\n\nGenerally, linking between docker services is a subset of \"service discovery\", a big problem if you're planning to use Docker at scale in production.  Please read [The Docker Ecosystem: Service Discovery and Distributed Configuration Stores](https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores) for more info.\n\n## Volumes\n\nDocker volumes are [free-floating filesystems](https://docs.docker.com/engine/tutorials/dockervolumes/). They don't have to be connected to a particular container. You can use volumes mounted from [data-only containers](https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e) for portability. As of Docker 1.9.0, Docker has named volumes which replace data-only containers. Consider using named volumes to implement it rather than data containers.\n\n### Lifecycle\n\n* [`docker volume create`](https://docs.docker.com/engine/reference/commandline/volume_create/)\n* [`docker volume rm`](https://docs.docker.com/engine/reference/commandline/volume_rm/)\n\n### Info\n\n* [`docker volume ls`](https://docs.docker.com/engine/reference/commandline/volume_ls/)\n* [`docker volume inspect`](https://docs.docker.com/engine/reference/commandline/volume_inspect/)\n\nVolumes are useful in situations where you can't use links (which are TCP/IP only). For instance, if you need to have two docker instances communicate by leaving stuff on the filesystem.\n\nYou can mount them in several docker containers at once, using `docker run --volumes-from`.\n\nBecause volumes are isolated filesystems, they are often used to store state from computations between transient containers. That is, you can have a stateless and transient container run from a recipe, blow it away, and then have a second instance of the transient container pick up from where the last one left off.\n\nSee [advanced volumes](http://crosbymichael.com/advanced-docker-volumes.html) for more details. [Container42](http://container42.com/2014/11/03/docker-indepth-volumes/) is also helpful.\n\nYou can [map MacOS host directories as docker volumes](https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume):\n\n```sh\ndocker run -v /Users/wsargent/myapp/src:/src\n```\n\nYou can use remote NFS volumes if you're [feeling brave](https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume).\n\nYou may also consider running data-only containers as described [here](http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/) to provide some data portability.\n\nBe aware that you can [mount files as volumes](#volumes-can-be-files).\n\n## Exposing ports\n\nExposing incoming ports through the host container is [fiddly but doable](https://docs.docker.com/engine/reference/run/#expose-incoming-ports).\n\nThis is done by mapping the container port to the host port (only using localhost interface) using `-p`:\n\n```sh\ndocker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT \\\n  --name CONTAINER \\\n  -t someimage\n```\n\nYou can tell Docker that the container listens on the specified network ports at runtime by using [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose):\n\n```Dockerfile\nEXPOSE <CONTAINERPORT>\n```\n\nNote that `EXPOSE` does not expose the port itself - only `-p` will do that. \n\nTo expose the container's port on your localhost's port, run:\n\n```sh\niptables -t nat -A DOCKER -p tcp --dport <LOCALHOSTPORT> -j DNAT --to-destination <CONTAINERIP>:<PORT>\n```\n\nIf you're running Docker in Virtualbox, you then need to forward the port there as well, using [forwarded_port](https://docs.vagrantup.com/v2/networking/forwarded_ports.html). Define a range of ports in your Vagrantfile like this so you can dynamically map them:\n\n```\nVagrant.configure(VAGRANTFILE_API_VERSION) do |config|\n  ...\n\n  (49000..49900).each do |port|\n    config.vm.network :forwarded_port, :host => port, :guest => port\n  end\n\n  ...\nend\n```\n\nIf you forget what you mapped the port to on the host container, use `docker port` to show it:\n\n```sh\ndocker port CONTAINER $CONTAINERPORT\n```\n\n## Best Practices\n\nThis is where general Docker best practices and war stories go:\n\n* [The Rabbit Hole of Using Docker in Automated Tests](http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/)\n* [Bridget Kromhout](https://twitter.com/bridgetkromhout) has a useful blog post on [running Docker in production](http://sysadvent.blogspot.co.uk/2014/12/day-1-docker-in-production-reality-not.html) at Dramafever.\n* There's also a best practices [blog post](http://developers.lyst.com/devops/2014/12/08/docker/) from Lyst.\n* [Building a Development Environment With Docker](https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/)\n* [Discourse in a Docker Container](https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container)\n\n## Docker-Compose\n\nCompose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the [list of features](https://docs.docker.com/compose/overview/#features).\n\nBy using the following command you can start up your application:\n\n```sh\ndocker-compose -f <docker-compose-file> up\n```\n\nYou can also run docker-compose in detached mode using -d flag, then you can stop it whenever needed by the following command:\n\n```sh\ndocker-compose stop\n```\n\nYou can bring everything down, removing the containers entirely, with the down command. Pass `--volumes` to also remove the data volume.\n\n## Security\n\nThis is where security tips about Docker go. The Docker [security](https://docs.docker.com/engine/security/security/) page goes into more detail.\n\nFirst things first: Docker runs as root. If you are in the `docker` group, you effectively [have root access](https://web.archive.org/web/20161226211755/http://reventlov.com/advisories/using-the-docker-command-to-root-the-host). If you expose the docker unix socket to a container, you are giving the container [root access to the host](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/).\n\nDocker should not be your only defense. You should secure and harden it.\n\nFor an understanding of what containers leave exposed, you should read [Understanding and Hardening Linux Containers](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/april/ncc_group_understanding_hardening_linux_containers-1-1.pdf) by [Aaron Grattafiori](https://twitter.com/dyn___). This is a complete and comprehensive guide to the issues involved with containers, with a plethora of links and footnotes leading on to yet more useful content. The security tips following are useful if you've already hardened containers in the past, but are not a substitute for understanding.\n\n### Security Tips\n\nFor greatest security, you want to run Docker inside a virtual machine. This is straight from the Docker Security Team Lead -- [slides](http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security) / [notes](http://www.projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/). Then, run with AppArmor / seccomp / SELinux / grsec etc to [limit the container permissions](http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/). See the [Docker 1.10 security features](https://blog.docker.com/2016/02/docker-engine-1-10-security/) for more details.\n\nDocker image ids are [sensitive information](https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4) and should not be exposed to the outside world. Treat them like passwords.\n\nSee the [Docker Security Cheat Sheet](https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc) by [Thomas Sjögren](https://github.com/konstruktoid): some good stuff about container hardening in there.\n\nCheck out the [docker bench security script](https://github.com/docker/docker-bench-security), download the [white papers](https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/).\n\nSnyk's [10 Docker Image Security Best Practices cheat sheet](https://snyk.io/blog/10-docker-image-security-best-practices/)\n\nYou should start off by using a kernel with unstable patches for grsecurity / pax compiled in, such as [Alpine Linux](https://en.wikipedia.org/wiki/Alpine_Linux). If you are using grsecurity in production, you should spring for [commercial support](https://grsecurity.net/business_support.php) for the [stable patches](https://grsecurity.net/announce.php), same as you would do for RedHat. It's $200 a month, which is nothing to your devops budget.\n\nSince docker 1.11 you can easily limit the number of active processes running inside a container to prevent fork bombs. This requires a linux kernel >= 4.3 with CGROUP_PIDS=y to be in the kernel configuration.\n\n```sb\ndocker run --pids-limit=64\n```\n\nAlso available since docker 1.11 is the ability to prevent processes from gaining new privileges. This feature have been in the linux kernel since version 3.5. You can read more about it in [this](http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/) blog post.\n\n```sh\ndocker run --security-opt=no-new-privileges\n```\n\nFrom the [Docker Security Cheat Sheet](http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf) (it's in PDF which makes it hard to use, so copying below) by [Container Solutions](http://container-solutions.com/is-docker-safe-for-production/):\n\nTurn off interprocess communication with:\n\n```sh\ndocker -d --icc=false --iptables\n```\n\nSet the container to be read-only:\n\n```sh\ndocker run --read-only\n```\n\nVerify images with a hashsum:\n\n```sh\ndocker pull debian@sha256:a25306f3850e1bd44541976aa7b5fd0a29be\n```\n\nSet volumes to be read only:\n\n```sh\ndocker run -v $(pwd)/secrets:/secrets:ro debian\n```\n\nDefine and run a user in your Dockerfile so you don't run as root inside the container:\n\n```Dockerfile\nRUN groupadd -r user && useradd -r -g user user\nUSER user\n```\n\n### User Namespaces\n\nThere's also work on [user namespaces](https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/) -- it is in 1.10 but is not enabled by default.\n\nTo enable user namespaces (\"remap the userns\") in Ubuntu 15.10, [follow the blog example](https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/).\n\n### Security Videos\n\n* [Using Docker Safely](https://youtu.be/04LOuMgNj9U)\n* [Securing your applications using Docker](https://youtu.be/KmxOXmPhZbk)\n* [Container security: Do containers actually contain?](https://youtu.be/a9lE9Urr6AQ)\n* [Linux Containers: Future or Fantasy?](https://www.youtube.com/watch?v=iN6QbszB1R8)\n\n### Security Roadmap\n\nThe Docker roadmap talks about [seccomp support](https://github.com/docker/docker/blob/master/ROADMAP.md#11-security).\nThere is an AppArmor policy generator called [bane](https://github.com/jfrazelle/bane), and they're working on [security profiles](https://github.com/docker/docker/issues/17142).\n\n## Tips\n\nSources:\n\n* [15 Docker Tips in 5 minutes](http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes)\n* [CodeFresh Everyday Hacks Docker](https://codefresh.io/blog/everyday-hacks-docker/)\n\n### Prune\n\nThe new [Data Management Commands](https://github.com/docker/docker/pull/26108) have landed as of Docker 1.13:\n\n* `docker system prune`\n* `docker volume prune`\n* `docker network prune`\n* `docker container prune`\n* `docker image prune`\n\n### df\n\n`docker system df` presents a summary of the space currently used by different docker objects.\n\n### Heredoc Docker Container\n\n```sh\ndocker build -t htop - << EOF\nFROM alpine\nRUN apk --no-cache add htop\nEOF\n```\n\n### Last IDs\n\n```sh\nalias dl='docker ps -l -q'\ndocker run ubuntu echo hello world\ndocker commit $(dl) helloworld\n```\n\n### Commit with command (needs Dockerfile)\n\n```sh\ndocker commit -run='{\"Cmd\":[\"postgres\", \"-too -many -opts\"]}' $(dl) postgres\n```\n\n### Get IP address\n\n```sh\ndocker inspect $(dl) | grep -wm1 IPAddress | cut -d '\"' -f 4\n```\n\nOr with [jq](https://stedolan.github.io/jq/) installed:\n\n```sh\ndocker inspect $(dl) | jq -r '.[0].NetworkSettings.IPAddress'\n```\n\nOr using a [go template](https://docs.docker.com/engine/reference/commandline/inspect):\n\n```sh\ndocker inspect -f '{{ .NetworkSettings.IPAddress }}' <container_name>\n```\n\nOr when building an image from Dockerfile, when you want to pass in a build argument:\n\n```sh\nDOCKER_HOST_IP=`ifconfig | grep -E \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1`\necho DOCKER_HOST_IP = $DOCKER_HOST_IP\ndocker build \\\n  --build-arg ARTIFACTORY_ADDRESS=$DOCKER_HOST_IP \n  -t sometag \\\n  some-directory/\n```\n\n### Get port mapping\n\n```sh\ndocker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <containername>\n```\n\n### Find containers by regular expression\n\n```sh\nfor i in $(docker ps -a | grep \"REGEXP_PATTERN\" | cut -f1 -d\" \"); do echo $i; done\n```\n\n### Get Environment Settings\n\n```sh\ndocker run --rm ubuntu env\n```\n\n### Kill running containers\n\n```sh\nif [ \"$(docker ps -q)\" ]; then docker kill $(docker ps -q); else echo \"No running containers.\"; fi\n\n```\n\n### Delete all containers (force!! running or stopped containers)\n\n```sh\nif [ \"$(docker ps -qa)\" ]; then docker rm -f $(docker ps -qa); else echo \"No containers to delete.\"; fi\n\n```\n\n### Delete old containers\n\n```sh\ndocker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm\n```\n\n### Delete stopped containers\n\n```sh\ndocker rm -v $(docker ps -a -q -f status=exited)\n```\n\n### Delete containers after stopping\n\n```sh\ndocker stop $(docker ps -aq) && docker rm -v $(docker ps -aq)\n```\n\n### Delete dangling images\n\n```sh\ndocker rmi $(docker images -q -f dangling=true)\n```\n\n### Delete all images\n\n```sh\ndocker rmi $(docker images -q)\n```\n\n### Delete dangling volumes\n\nAs of Docker 1.9:\n\n```sh\ndocker volume rm $(docker volume ls -q -f dangling=true)\n```\n\nIn 1.9.0, the filter `dangling=false` does _not_ work - it is ignored and will list all volumes.\n\n### Show image dependencies\n\n```sh\ndocker images -viz | dot -Tpng -o docker.png\n```\n\n### Slimming down Docker containers\n\n- Cleaning APT in a `RUN` layer - This should be done in the same layer as other `apt` commands. Otherwise, the previous layers still persist the original information and your images will still be fat.\n    ```Dockerfile\n    RUN {apt commands} \\\n      && apt-get clean \\\n      && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*\n    ```\n- Flatten an image\n    ```sh\n    ID=$(docker run -d image-name /bin/bash)\n    docker export $ID | docker import – flat-image-name\n    ```\n- For backup\n    ```sh\n    ID=$(docker run -d image-name /bin/bash)\n    (docker export $ID | gzip -c > image.tgz)\n    gzip -dc image.tgz | docker import - flat-image-name\n    ```\n\n### Monitor system resource utilization for running containers\n\nTo check the CPU, memory, and network I/O usage of a single container, you can use:\n\n```sh\ndocker stats <container>\n```\n\nFor all containers listed by ID:\n\n```sh\ndocker stats $(docker ps -q)\n```\n\nFor all containers listed by name:\n\n```sh\ndocker stats $(docker ps --format '{{.Names}}')\n```\n\nFor all containers listed by image:\n\n```sh\ndocker ps -a -f ancestor=ubuntu\n```\n\nRemove all untagged images:\n\n```sh\ndocker rmi $(docker images | grep “^” | awk '{split($0,a,\" \"); print a[3]}')\n```\n\nRemove container by a regular expression:\n\n```sh\ndocker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm -f\n```\n\nRemove all exited containers:\n\n```sh\ndocker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')\n```\n\n### Volumes can be files\n\nBe aware that you can mount files as volumes. For example you can inject a configuration file like this:\n\n```sh\n# copy file from container\ndocker run --rm httpd cat /usr/local/apache2/conf/httpd.conf > httpd.conf\n\n# edit file\nvim httpd.conf\n\n# start container with modified configuration\ndocker run --rm -it -v \"$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro\" -p \"80:80\" httpd\n```\n\n## Contributing\n\nHere's how to contribute to this cheat sheet.\n\n### Open README.md\n\nClick [README.md](https://github.com/wsargent/docker-cheat-sheet/blob/master/README.md) <-- this link\n\n![Click This](images/click.png)\n\n### Edit Page\n\n![Edit This](images/edit.png)\n\n### Make Changes and Commit\n\n![Change This](images/change.png)\n\n![Commit](images/commit.png)\n"
  },
  {
    "path": "es-es/README.md",
    "content": "# Docker Cheat Sheet\n\n**¿Quieres colaborar en este *cheat sheet*? ¡Revisa la sección de [Contribución](#contributing)!**\n\n## Tabla de Contenidos\n\n* [Por qué Docker](#por-qué-Docker)\n* [Prerrequisitos](#prerrequisitos)\n* [Instalación](#instalación)\n* [Contenedores](#contenedores)\n* [Imágenes](#imágenes)\n* [Redes](#redes)\n* [Registry y Repositorios](#Registry-y-Repositorios)\n* [Dockerfile](#dockerfile)\n* [Capas](#capas)\n* [Enlaces](#enlaces)\n* [Volúmenes](#volúmenes)\n* [Exponiendo Puertos](#Exponiendo-Puertos)\n* [Buenas prácticas](#buenas-prácticas)\n* [Docker-Compose](#docker-compose)\n* [Seguridad](#seguridad)\n* [Consejos](#consejos)\n* [Contribución](#contribución)\n\n## Por qué Docker\n\n\"Con Docker, los desarrolladores (y desarrolladoras) pueden construir cualquier aplicación en cualquier lenguaje usando cualquier herramienta. Las aplicaciones \"Dockerizadas\" son totalmente portables y pueden funcionar en cualquier lugar: En portátiles con OS X y Windows de compañeros; servidores de QA con Ubuntu en el cloud; y VMs de los datacenters de producción que funcionan con Red Hat.\n\nLos desarrolladores pueden empezar a trabajar rápidamente a partir de cualquiera de las más de 13.000 aplicaciones disponibles en Docker Hub. Docker gestiona y guarda los cambios y dependencias, facilitando el trabajo a los Administradores de Sistemas a la hora de entender cómo funcionan las aplicaciones hechas por los desarrolladores. Y, con Docker Hub, los desarrolladores puedes automatizar el despliegue y compartir el trabajo con colaboradores a través de repositorios públicos o privados.\n\nDocker ayuda a los desarrolladores a trabajar y conseguir aplicaciones de mejor calidad de forma más rápida.\" -- [Qué es docker](https://www.docker.com/what-docker#copy1)\n\n## Prerrequisitos\n\nDe forma opcional, se puede hacer utilizar [Oh My Zsh](https://github.com/ohmyzsh/oh-my-zsh) con el [plugin de Docker](https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#docker) para autocompletar los comandos de Docker.\n\n### Linux\n\n[El requisito mínimo](https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies) para Docker es utilizar una versión de Kernel (núcleo) posterior a la 3.10.x.\n\n### MacOS\n\nSe requiere de la versión 10.8 “Mountain Lion” o posterior.\n\n### Windows 10\n\nSe debe activar Hyper-V en la BIOS.\n\nEn caso de estar disponible, también se debe activar VT-D (Procesadores Intel).\n\n### Windows Server\n\nComo mínimo se requiere la versiín de Windows Server 2016 para instalar Docker y Docker Compose. No obstante, existen limitaciones en esta versión, como a la hora de utilizar redes virtualizadas y contenedores Linux.\n\nSe recomienda utilizar Windows Server 2019 o posteriores.\n\n## Instalación\n\n### Linux\n\nEjecuta este comando rápido y sencillo proporcionado por Docker:\n\n```sh\ncurl -sSL https://get.docker.com/ | sh\n```\n\nSi no estás dispuesto a ejecutar un shell script que no sabes lo que trae, por favor: revisa las instrucciones de [instalación](https://docs.docker.com/engine/installation/linux/) de tu distribución.\n\nSi eres totalmente nuevo en Docker, te recomendamos seguir esta [serie de tutoriales](https://docs.docker.com/engine/getstarted/).\n\n### macOS\n\nDescarga e instala [Docker Community Edition](https://www.docker.com/community-edition). Si tienes Homebrew-Cask, simplemente escribe `brew install --cask docker`. O descarga e instala [Docker Toolbox](https://docs.docker.com/toolbox/overview/). [Docker For Mac](https://docs.docker.com/docker-for-mac/) está bien, pero no está tan pulido como como la instalación de VirtualBox. [Revisa la comparación aquí](https://docs.docker.com/docker-for-mac/docker-toolbox/).\n\n> **NOTA:** Docker Toolbox está deprecado. Deberías utilizar Docker Community Edition, revisa [Docker Toolbox](https://docs.docker.com/toolbox/overview/).\n\nUna vez hayas instalado Docker Community Edition, haz click en el icono de docker en el Launchpad. Entonces inicia un contenedor:\n\n```sh\ndocker run hello-world\n```\n\n¡Y ya estaría! Ya tienes un contenedor de docker funcionando.\n\nSi eres totalmente nuevo en Docker, te recomendamos seguir esta [serie de tutoriales](https://docs.docker.com/engine/getstarted/).\n\n### Windows 10\n\nLas instrucciones para instalar Docker Desktop para Windows se encuentran [aquí](https://docs.docker.com/desktop/windows/install/)\n\nUna vez instalado, abre Powershell como administrador y ejecuta:\n\n```powershell\n# Muestra la versión de docker instalada:\ndocker version\n\n# Descarga, crea, y ejecuta 'hello-world':\ndocker run hello-world\n```\n\nPara continuar con esta chuleta, haz click derecho sobre el icono de Docker en la sección de notificaciones (abajo a la derecha), y ves a ajustes. Para montar volúmenes, el disco C:/ debe ser habilitado en ajustes para poder pasar la información a los contenedores (se detalla más adelante en este artículo).\n\nPara alternar entre contenedores Windows y Linux, haz botón derecho en el icono de Docker en la sección de notificaciones y haz click en el botón de cambiar el sistema operativo del contenedor. Hacer esto parará los contenedores que estén funcionando y serán inaccesibles hasta que el SO del contenedor vuelva a cambiar.\n\nAdicionalmente, si tienes WSL (Subsitema de Windows para Linux) o WSL2 instalado en tu equipo, quizás también quieras instalar el Kernel de Linux para Windows. Las instrucciones para ello pueden encontrarse [aquí](https://techcommunity.microsoft.com/t5/windows-dev-appconsult/using-wsl2-in-a-docker-linux-container-on-windows-to-run-a/ba-p/1482133). Esto requiere la característica de Subsistema de Windows para Linux. Esto permitirá que los contenedores sean accesibles desde los sistemas operativos WSL, así como mejorar la eficiencia ejecutando sistemas operaviso WSL en docker. También es preferible utilizar la [terminal de Windows](https://docs.microsoft.com/en-us/windows/terminal/get-started) para esto.\n\n### Windows Server 2016 / 2019\n\nSigue las instrucciones de Microsoft que puedes encontrar [aquí](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/deploy-containers-on-server#install-docker)\n\nSi haces uso de la última versión de 2019, prepárate para trabajar solo con powershell, dado que es solo una imágen del núcleo del servidor (sin interfaz de escritorio). Cuando inicies esta máquina, se logueará y mostrará una ventana de powerhell. Se recomienda instalar editores de texto y otras herramientas utilizando [Chocolatey](https://chocolatey.org/install)\n\nTras instalarlo, funcionarán los siguientes comandos:\n\n```powershell\n# Muestra la versión de docker instalada:\ndocker version\n\n# Descarga, crea, y ejecuta 'hello-world':\ndocker run hello-world\n```\n\nWindows Server 2016 no puede ejecutar imágenes de Linux.\n\nWindows Server Build 2004 es capaz de ejecutar contenedores de Linux y Windows simultáneamente a través del aislamiento de Hyper-V. Cuando se ejecuten los contenedores, utiliza el comando ```isolation=hyperv```, el cual lo aislará utilizando distintas instancias de kernel para cada contenedor.\n\n### Revisar la versión\n\nEs muy importante que siempre conozcas la versión de Docker que estás utilizando en cualquier momento. Es muy útil dado que permite saber las características compatibles con lo que estés ejecutando. Esto también es importante para conocer que contenedores puedes ejecutar de la docker store cuando estés intentando utilizar un contenedor como plantilla. Dicho esto, veamos como recuperar la versión de Docker que está ejecutándose actualmente.\n\n* [`docker version`](https://docs.docker.com/engine/reference/commandline/version/) muestra que versión de docker está ejecutándose.\n\nRecuperar la versión del servidor:\n\n```console\n$ docker version --format '{{.Server.Version}}'\n1.8.0\n```\n\nPuedes volcar la información en un JSON:\n\n```console\n$ docker version --format '{{json .}}'\n{\"Client\":{\"Version\":\"1.8.0\",\"ApiVersion\":\"1.20\",\"GitCommit\":\"f5bae0a\",\"GoVersion\":\"go1.4.2\",\"Os\":\"linux\",\"Arch\":\"am\"}\n```\n\n## Contenedores\n\n[Proceso básico del aislamiento en Docker](http://etherealmind.com/basics-docker-containers-hypervisors-coreos/). Los contenedores son a las máquinas virtuales lo que los threads son a los procesos. O puedes verlo como un *chroot* dopado.\n\n### Ciclo de vida\n\n* [`docker create`](https://docs.docker.com/engine/reference/commandline/create) crea un contenedor pero no lo inicia.\n* [`docker rename`](https://docs.docker.com/engine/reference/commandline/rename/) permite renombrar el nombre de un contenedor.\n* [`docker run`](https://docs.docker.com/engine/reference/commandline/run) crea e inicia un contenedor.\n* [`docker rm`](https://docs.docker.com/engine/reference/commandline/rm) elimina un contenedor.\n* [`docker update`](https://docs.docker.com/engine/reference/commandline/update/) actualiza los recursos máximos de un contenedor.\n\nSi ejecutas un contenedor sin opciones este se iniciará y detendrá automáticamente, si quieres mantenerlo funcionando puedes utilizar el comando `docker run -td container_id`, esto utilizará la opción `-t`, que habilitará una pseudo-sesión de TTY, y `-d`, que separará el contenedor automáticamente (lo ejecutará en segundo plano y mostrará la ID del contenedor)\n\nSi quieres un contenedor efímero, `docker run --rm` eliminará el contenedor en cuanto se detenga.\n\nSi quieres mapear un directorio del host al contenedor de docker, `docker run -v $HOSTDIR:$DOCKERDIR`. Revisa [Volúmenes](https://github.com/wsargent/docker-cheat-sheet/#volumes).\n\nSi al eliminar el contenedor también quieres borrar los volúmenes asociados, el borrado deberá contener `-v`, por ejemplo: `docker rm -v`.\n\nTambién existe un [driver de logs](https://docs.docker.com/engine/admin/logging/overview/) disponible para contenedores individuales en Docker 1.10. Para ejecutar docker con un driver de logs personalizado, ejecuta `docker run --log-driver=syslog`.\n\nOtra opciónútil es `docker run --name yourname docker_image` donde especificando la opción `--name` dentro del comando *run*, esto te permitirá iniciar y detener el contenedor utilizando el nombre especificado al crearlo.\n\n### Ejecutando y deteniendo\n\n* [`docker start`](https://docs.docker.com/engine/reference/commandline/start) inicia un contenedor.\n* [`docker stop`](https://docs.docker.com/engine/reference/commandline/stop) detiene un contenedor que esté iniciado.\n* [`docker restart`](https://docs.docker.com/engine/reference/commandline/restart) detiene y ejecuta un contenedor.\n* [`docker pause`](https://docs.docker.com/engine/reference/commandline/pause/) pausa un contenedor que se está ejecutando, congelándolo.\n* [`docker unpause`](https://docs.docker.com/engine/reference/commandline/unpause/) reactiva un contenedor.\n* [`docker wait`](https://docs.docker.com/engine/reference/commandline/wait) se bloquea hasta que el contenedor se detiene.\n* [`docker kill`](https://docs.docker.com/engine/reference/commandline/kill) envía una SIGKILL a un contenedor.\n* [`docker attach`](https://docs.docker.com/engine/reference/commandline/attach) se conecta a un contenedor.\n\nSi quieres despegarte de un contenedor, utiliza `Ctrl + p, Ctrl + q`.\n\nSi quieres integrar un contenedor con un [gestor de procesos](https://docs.docker.com/engine/admin/host_integration/), inicia el daemon con `-r=false`, después utiliza `docker start -a`.\n\nSi quieres exponer un puerto del contenedor a través del host, revisa la sección [exponiendo puertos](#exposing-ports).\n\nLas políticas de reinicio en una instancia bloqueada se [explica aquí](http://container42.com/2014/09/30/docker-restart-policies/).\n\n#### Restricciones de CPU\n\nPuedes limitar la CPU, ya sea especificando el porcentáge global de las CPU o definiendo el número de núcleos.\n\nPor ejemplo, puedes especificar la configuración de [`cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint). Este parámetro es un poco raro -- 1024 significa el 100% de la CPU, por lo que si quieres que el contenedor utilice el 50% de todas las CPU, deberás especificar 512. Revisa <https://docs.docker.com/engine/reference/run/#/cpu-share-constraint> para más información.\n\n```sh\ndocker run -it -c 512 agileek/cpuset-test\n```\n\nTambiés puedes utilizar únicamente algunos núcleos de la CPU utilizando [`cpuset-cpus`](https://docs.docker.com/engine/reference/run/#/cpuset-constraint). Revisa <https://agileek.github.io/docker/2014/08/06/docker-cpuset/> para más detalles y algunos vídeos guays:\n\n```sh\ndocker run -it --cpuset-cpus=0,4,6 agileek/cpuset-test\n```\n\nFíjate que Docker puede seguir **viendo** todas las CPU dentro del contenedor -- simplemente no la utiliza entera. Revisa <https://github.com/docker/docker/issues/20770> para más información.\n\n#### Restricciones de memoria\n\nTambién puedes especificar [restricciones de memoria](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) en Docker\n\n```sh\ndocker run -it -m 300M ubuntu:14.04 /bin/bash\n```\n\n#### Capacidades\n\nLas capacidades de linux se pueden establecer utilizando `cap-add` y `cap-drop`. Revisa <https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities> para más detalles. Debe usarse para una mejor seguridad.\n\nPara montar un sistema de ficheros basado en FUSE, debes combinar --cap-add con --device:\n\n```sh\ndocker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs\n```\n\nPara dar acceso a un único dispositivo:\n\n```sh\ndocker run -it --device=/dev/ttyUSB0 debian bash\n```\n\nPara dar acceso a todos los dispositivos:\n\n```sh\ndocker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash\n```\n\nMás información sobre contenedores con privilegios [aquí](\nhttps://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)\n\n### Información\n\n* [`docker ps`](https://docs.docker.com/engine/reference/commandline/ps) muestra los contenedores funcionando.\n* [`docker logs`](https://docs.docker.com/engine/reference/commandline/logs) recupera los logs del contenedor. (Puedes utilizar un driver personalizado para los logs, pero los logs solo están disponibles para `json-file` y `journald` en la versión 1.10).\n* [`docker inspect`](https://docs.docker.com/engine/reference/commandline/inspect) revisa toda la información del contenedor (incluyendo la dirección IP).\n* [`docker events`](https://docs.docker.com/engine/reference/commandline/events) recupera los eventos del contenedor.\n* [`docker port`](https://docs.docker.com/engine/reference/commandline/port) muestra los puertos abiertos al exterior del contenedor.\n* [`docker top`](https://docs.docker.com/engine/reference/commandline/top) muestra los procesos que se están ejecutando en el contenedor,\n* [`docker stats`](https://docs.docker.com/engine/reference/commandline/stats) Muestra las estadísticas del uso de recursos del contenedor.\n* [`docker diff`](https://docs.docker.com/engine/reference/commandline/diff) Muestra los archivos que han cambiado en el sistema de ficheros del contenedor.\n\n`docker ps -a` muestra todos los contenedores: que están funcionados o parados.\n\n`docker stats --all` lista todos los contenedores, por defecto solo los que están funcionando.\n\n### Import / Export\n\n* [`docker cp`](https://docs.docker.com/engine/reference/commandline/cp) copia los ficheros y carpetas de un contenedor al sistema de ficheros local.\n* [`docker export`](https://docs.docker.com/engine/reference/commandline/export) vuelca el sistema de ficheros de un contenedor como fichero .tar en el STDOUT.\n\n### Ejecuntando comandos\n\n* [`docker exec`](https://docs.docker.com/engine/reference/commandline/exec) ejecuta un comando en el contenedor.\n\nPara entrar a un contenedor que está funcionando, acopla un nuevo proceso de terminal al contenedor usando: `docker exec -it <ID/Nombre del contenedor> /bin/bash`.\n\n## Imágenes\n\n\nLas imágenes simplemente son [plantillas para contenedores de docker](https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work).\n\n### Ciclo de vida\n\n* [`docker images`](https://docs.docker.com/engine/reference/commandline/images) muestra todas las imágenes.\n* [`docker import`](https://docs.docker.com/engine/reference/commandline/import) crea una imágen a partir de un fichero .tar.\n* [`docker build`](https://docs.docker.com/engine/reference/commandline/build) crea una imágen a partir de un Dockerfile.\n* [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit) crea una imágen a partir de un contenedor, deteniéndolo temporalmente si está funcionando.\n* [`docker rmi`](https://docs.docker.com/engine/reference/commandline/rmi) elimina una imágen.\n* [`docker load`](https://docs.docker.com/engine/reference/commandline/load) carga una imágen a partir de un fichero .tar pasado como STDIN, incluyendo imágenes y etiquetas.\n* [`docker save`](https://docs.docker.com/engine/reference/commandline/save) guarda una imágen en un fichero .tar pasado como STDOUT con todas las capas superiores, etiquetas y versiones.\n\n### Información\n\n* [`docker history`](https://docs.docker.com/engine/reference/commandline/history) muestra el historial de una imágen.\n* [`docker tag`](https://docs.docker.com/engine/reference/commandline/tag) etiqueta una imágen (local o *registry*).\n\n### Limpiar\n\nPuedes utilizar el comando `docker rmi` para eliminar una imágen específica, pero también existe una herramienta alternativa llamada [docker-gc](https://github.com/spotify/docker-gc) que elimina de forma segura las imágenes que ya no están siendo utilizadas por ningún contenedor. En la versión 1.13 de docker, también existe el comando `docker image prine`, el cual elimina las imágenes que no están siendo utilizadas. Revisa [Prune](#prune)\n\n### Cargar/Guardar una imágen\n\nCarga una imágen a partir de un fichero:\n\n```sh\ndocker load < my_image.tar.gz\n```\n\nGuarda una imágen existente:\n\n```sh\ndocker save my_image:my_tag | gzip > my_image.tar.gz\n```\n\n### Importar/Exportar un contenedor\n\nImporta un contenedor como imágen a partir de un fichero:\n\n```sh\ncat my_container.tar.gz | docker import - my_image:my_tag\n```\n\nExporta un contenedor existente:\n\n```sh\ndocker export my_container | gzip > my_container.tar.gz\n```\n\n### Diferencia entre cargar y guardar una imágen e importar y exportar un contenedor como imágen\n\nCargar una imágen utilizando el comando `load` crea una nueva imágen incluyeno su historial.\nImportar un contenedor como imágen utilizando el comando `import` crea una nueva imágen excluyendo el historial, lo que se traduce en una imágen más ligera comparada con cargarla.\n\n## Redes\n\nDocker tiene la característica de [Redes](https://docs.docker.com/engine/userguide/networking/). Docker automáticamente crea tres interficies de red al instalarlo (puente, host, nula). Por defecto, cuando se lanza un nuevo contenedor es añadido la red puente. Para habilitar la comunicación entre varios contenedores puedes crear una nueva red y lanzar los contenedores en ella. Esto permite a los contenedores comunicarse entre ellos y aislarese de los contenedores que no están conectados a su misma red. Además, esto permite mapear nombres de contenedores a sus direcciones IP. Revisa *[working with networks](https://docs.docker.com/engine/userguide/networking/work-with-networks/)* para más información.\n\n### Ciclo de vida\n\n* [`docker network create`](https://docs.docker.com/engine/reference/commandline/network_create/) NAME Crea una nueva red (por defecto de tipo puente).\n* [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/) NAME Elimina una o más redes indicando el nombre o el identificador. No pueden haber contenedores conectados a la red al eliminarla.\n\n### Info\n\n* [`docker network ls`](https://docs.docker.com/engine/reference/commandline/network_ls/) Lista las redes creadas.\n* [`docker network inspect`](https://docs.docker.com/engine/reference/commandline/network_inspect/) NAME Muestra información detallada de una o más redes.\n\n### Connection\n\n* [`docker network connect`](https://docs.docker.com/engine/reference/commandline/network_connect/) NETWORK CONTAINER Conecta un contenedor a una red.\n* [`docker network disconnect`](https://docs.docker.com/engine/reference/commandline/network_disconnect/) NETWORK CONTAINER Desconecta un contenedor de una red.\n\nPuedes especificar una [ip específica a un contenedor](https://blog.jessfraz.com/post/ips-for-all-the-things/):\n\n```sh\n# crea una nueva red puente con la subnet y puerta de enlace específicada\ndocker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic\n\n# ejecuta un contenedor de nginx con al ip especificada en la red iptastic\n$ docker run --rm -it --net iptastic --ip 203.0.113.2 nginx\n\n# curl hacia la ip desde cualquier otro lugar (dando por hecho que es una ip pública hehe)\n$ curl 203.0.113.2\n```\n\n## Registry y Repositorios\n\n(Nota de traducción: Registry sería traducido como Regitro, pero nadie le llama así en el mundo real, así que...)\n\nUn repositorio es una colección *alojada* de imágenes enlazadas que unidas crean el sistema de ficheros para un contenedor.\n\nUn Registry es un *alojamiento* -- un servidor que almacena repositorios y provee de una API HTTP para [gestionar la actualización y descarga de repositorios](https://docs.docker.com/engine/tutorials/dockerrepos/).\n\nDocker.com posee su propio [índice](https://hub.docker.com) como un Registry centralizado que contiene un gran número de repositorios. Dicho esto, aclarar que el docker Registry [no hace un buen trabajo verificando imágenes](https://titanous.com/posts/docker-insecurity), por lo que quizás deberías evitarlo si te preocupa la seguridad.\n\n* [`docker login`](https://docs.docker.com/engine/reference/commandline/login) para loguear en un registry.\n* [`docker logout`](https://docs.docker.com/engine/reference/commandline/logout) para desloguear de un registry.\n* [`docker search`](https://docs.docker.com/engine/reference/commandline/search) busca en el registry por una imágen.\n* [`docker pull`](https://docs.docker.com/engine/reference/commandline/pull) recupera una imágen del registry a local.\n* [`docker push`](https://docs.docker.com/engine/reference/commandline/push) sube una imágen local al registry.\n\n### Ejecutar un registry local\n\nPuedes ejecutar un registry local utilizando el proyecto [distribución de docker](https://github.com/docker/distribution) y revisando las instrucciones de como realizar el [deploy local](https://github.com/docker/docker.github.io/blob/master/registry/deploying.md)\n\nAdicionalmente revisa la [mailing list](https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution)\n\n## Dockerfile\n\n[El archivo de configuración](https://docs.docker.com/engine/reference/builder/). Configura un contenedor de docker al ejecutar `docker build` en el. Mucho más preferible a `docker commit`.\n\nAquí tienes varios editores de textos comunes y módulos de resaltado de sintaxis que puedes usar para crear Dockerfiles:\n\n* Si utilizas [jEdit](http://jedit.org), puedes hacer uso del módulo de resaltado de sintaxis para [Dockerfile](https://github.com/wsargent/jedit-docker-mode).\n* [Sublime Text 2](https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting)\n* [Atom](https://atom.io/packages/language-docker)\n* [Vim](https://github.com/ekalinin/Dockerfile.vim)\n* [Emacs](https://github.com/spotify/dockerfile-mode)\n* [TextMate](https://github.com/docker/docker/tree/master/contrib/syntax/textmate)\n* [VS Code](https://github.com/Microsoft/vscode-docker)\n* Revisa [Docker meets the IDE](https://domeide.github.io/)\n\n### Instructions\n\n* [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)\n* [FROM](https://docs.docker.com/engine/reference/builder/#from) utiliza una imágen de base para las siguientes instrucciones.\n* [MAINTAINER (deprecated - use LABEL instead)](https://docs.docker.com/engine/reference/builder/#maintainer-deprecated) especifica el autor que ha generado las imágenes.\n* [RUN](https://docs.docker.com/engine/reference/builder/#run) ejecuta cualquier comando en una nueva capa de la imágen y guarda el estado resultante.\n* [CMD](https://docs.docker.com/engine/reference/builder/#cmd) proporcionar valores predeterminados para un contenedor en ejecución.\n* [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) informa a Docker que el contenedor estará escuchando los puertos especificados mientras se ejecute. NOTA: no hace que los puertos sean accesibles.\n* [ENV](https://docs.docker.com/engine/reference/builder/#env) define una variable de entorno.\n* [ADD](https://docs.docker.com/engine/reference/builder/#add) copia nuevos ficheros, directorios o archivos remotos al contenedor. Invalida cachés. Procura evitar usar `ADD` e intenta utilizar `COPY` en su lugar.\n* [COPY](https://docs.docker.com/engine/reference/builder/#copy) copia nuevos ficheros o directorios al contenedor. Por defecto los copia como *root* independientemente de la configuración de USER/WORKDIR. Utiliza `--chown=<user>:<group>` para cambiar el dueño. (Lo mismo aplica a `ADD`).\n* [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) configura un contenedor que funcionará como ejecutable.\n* [VOLUME](https://docs.docker.com/engine/reference/builder/#volume) crea un punto de montaje para volúmenes externos u otros contenedores.\n* [USER](https://docs.docker.com/engine/reference/builder/#user) especifica el usuario que ejecutará los próximos comandos de tipo RUN / CMD / ENTRYPOINTS.\n* [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) especifica el directorio de trabajo.\n* [ARG](https://docs.docker.com/engine/reference/builder/#arg) define una variable que estará disponible durante el build.\n* [ONBUILD](https://docs.docker.com/engine/reference/builder/#onbuild) añade una instrucción que será lanzada cuando la imágen sea utilizada como base de otro build.\n* [STOPSIGNAL](https://docs.docker.com/engine/reference/builder/#stopsignal) define la señal que será enviada al contenedor para detenerse.\n* [LABEL](https://docs.docker.com/config/labels-custom-metadata/) aplica metadatos de clave/valor para las imágenes, contenedores o daemons (servicios).\n* [SHELL](https://docs.docker.com/engine/reference/builder/#shell) reemplaza la shell por defecto que es utilizada por Docker para ejecutar los comandos.\n* [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#healthcheck) indica a docker como probar el contenedor para revisar que sigue funcionando.\n\n### Tutorial\n\n* [Flux7's Dockerfile Tutorial](https://www.flux7.com/tutorial/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)\n\n### Examples\n\n* [Ejemplos](https://docs.docker.com/engine/reference/builder/#dockerfile-examples)\n* [Buenas prácticas para escribir Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)\n* [Michael Crosby](http://crosbymichael.com/) tiene más consejos de [buenas prácticas para Dockerfile](http://crosbymichael.com/dockerfile-best-practices.html) / [toma 2](http://crosbymichael.com/dockerfile-best-practices-take-2.html).\n* [Construyendo buenas imágenes de Docker](http://jonathan.bergknoff.com/journal/building-good-docker-images) / [Construyendo mejores imágenes de Docker](http://jonathan.bergknoff.com/journal/building-better-docker-images)\n* [Gestionando la configuración de un contenedor utilizando metadatos](https://speakerdeck.com/garethr/managing-container-configuration-with-metadata)\n* [Cómo escribir excelentes Dockerfiles](https://rock-it.pl/how-to-write-excellent-dockerfiles/)\n\n## Capas\n\nLas veriones de los sitemas de ficheros en docker se basan en capas. Son similares a los [git commits o conjuntos de cambios para sistemas de ficheros](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/).\n\n## Enlaces\n\nLos enlaces definen como los contenedores de Docker se comunican entre ellos [mediante puertos TCP/IP](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/). [Atlassian](https://blogs.atlassian.com/2013/11/docker-all-the-things-at-atlassian-automation-and-wiring/) lo explica con ejemplos. También puedes resolver [enlaces con nombres de equipo](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file).\n\nEsto ha sido parcialmente deprecado por [redes definidas por los usuarios](https://docs.docker.com/network/).\n\nNOTA: Si ÚNICAMENTE quieres que los contenedores se comuniquen mediante enlaces, inicia el servicio de Docker con `-icc=false` para desactivar la comunicación entre procesos.\n\nSi tienes un contenedor con el nombre CONTAINER (especificado vía `docker run --name CONTAINER`) y, en el Dockerfile, explones un puerto:\n\n```\nEXPOSE 1337\n```\n\nY entonces creas otro contenedor llamado LINKED de la forma:\n\n```sh\ndocker run -d --link CONTAINER:ALIAS --name LINKED user/wordpress\n```\n\nEntonces los puertos expuertos y alias de CONTAINER se mostrarán en LINKED con las siguientes variables de entorno:\nThen the exposed ports and aliases of CONTAINER will show up in LINKED with the following environment variables:\n\n```sh\n$ALIAS_PORT_1337_TCP_PORT\n$ALIAS_PORT_1337_TCP_ADDR\n```\n\nY te puedes conectar a él de esta forma.\n\nPara eliminar los enlaces, utiliza `docker rm --link'.\n\nGeneralmente, enlazar mediante servicios de docker es un subgrupo de \"descrubrimiento de servicios\", un gran problema si tienes pensado utilizar Docker para escalar en producción. Por favor, lee [The Docker Ecosystem: Service Discovery and Distributed Configuration Stores](https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores) para más información.\n\n## Volúmenes\n\nLos volúmenes de Docker son [sitemas de archivos flotantes](https://docs.docker.com/engine/tutorials/dockervolumes/). Estos no se conectan a un contenedor en particular. Puedes utilizar los volúmenes montados de [contenedores de únicamente datos](https://medium.com/@ramangupta/). A partir de Docker 1.9.0, Docker ha nombrado volúmenes que reemplazan los contenedores de solo datos. Considere usar volúmenes con nombre para implementarlo en lugar de contenedores de datos.\n\n\n### Ciclo de vida\n\n* [`docker volume create`](https://docs.docker.com/engine/reference/commandline/volume_create/)\n* [`docker volume rm`](https://docs.docker.com/engine/reference/commandline/volume_rm/)\n\n### Información\n\n* [`docker volume ls`](https://docs.docker.com/engine/reference/commandline/volume_ls/)\n* [`docker volume inspect`](https://docs.docker.com/engine/reference/commandline/volume_inspect/)\n\nLos volúmenes son útiles en situaciones donde no puedes utilizar enlaces (los cuales son sólo TCP/IP). Por ejemplo, si necesitases tener dos instancias de docker comunicándose dejando datos en el sistema de ficheros.\n\nPuedes montarlos en distintos contenedores de docker a la vez, utilizando `docker run --volumes-from`.\n\nDadp que los volúmenes están aislados del sistema de ficheros, estos también son utilizados para almacenar el estado a partir de cálculos de contenedores temporales. Exacto, puedes tener un contenedor sin estado y temporal ejecutándose a partir de una receta,  destruírlo, y entonecs tener otra instancia temporal que pueda recuperar lo que ha dejado atrás el primer contenedor.\n\nRevisa [volúmenes avanzados](http://crosbymichael.com/advanced-docker-volumes.html) para más información. [Container42](http://container42.com/2014/11/03/docker-indepth-volumes/) también es de utilidad.\n\nPuedes [mapear directorios de MacOS como volúmenes de Docker](https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume):\n\n```sh\ndocker run -v /Users/wsargent/myapp/src:/src\n```\n\nPuedes utilizar un volúmen NFS remoto si [eres valiente](https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume)\n\nTambién puedes plantearme utilizar contenedores de solo datos como se describen [aquí](http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/) para tener portabilidad de datos.\n\nTen en cuenta que puedes montar [archivos como volúmenes](#volumes-can-be-files).\n\n## Exponiendo puertos\n\nExponer puertos de entrada a través de un contenedor es [complejo pero factible](https://docs.docker.com/engine/reference/run/#expose-incoming-ports).\n\nPuede hacerse a través del mapeo de puertos del contenedor hacia el host (utilizando únicamente la interficie de localhost) mediante el uso de `p`:\n\n```sh\ndocker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT \\\n  --name CONTAINER \\\n  -t algunaimágen\n```\nPuedes decirle a docker que el contenedor escucha en el puerto especificado utilizando [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose):\n\n```Dockerfile\nEXPOSE <CONTAINERPORT>\n```\n\nNótese que `EXPOSE` no expone el puerto por si mismo - solo `-p` lo hace.\n\nPara exponer el puerto de un contenedor en localhost, ejecuta:\n\n```sh\niptables -t nat -A DOCKER -p tcp --dport <LOCALHOSTPORT> -j DNAT --to-destination <CONTAINERIP>:<PORT>\n```\n\nSi estás ejecutando Docker en Virtualbox, también necesitarás hacer forward del puerto, utilizando [forwarded_port] (https://docs.vagrantup.com/v2/networking/forwarded_ports.html). Define un rango de puertos en tu Vagrantfile de la siguiente manera para mapearlos dinámicamente:\n\n```\nVagrant.configure(VAGRANTFILE_API_VERSION) do |config|\n  ...\n\n  (49000..49900).each do |port|\n    config.vm.network :forwarded_port, :host => port, :guest => port\n  end\n\n  ...\nend\n```\n\nSi te olvidas de los puertos que has mapeado, utiliza `docker port` para mostrarlo:\n\n```sh\ndocker port CONTAINER $CONTAINERPORT\n```\n\n## Buenas prácticas\n\nAquí tienes algunas buenas prácticas de Docker y algunas batallitas:\n\n* [The Rabbit Hole of Using Docker in Automated Tests](http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/)\n* [Bridget Kromhout](https://twitter.com/bridgetkromhout) has a useful blog post on [running Docker in production](http://sysadvent.blogspot.co.uk/2014/12/day-1-docker-in-production-reality-not.html) at Dramafever.\n* También tienes buenas prácticas en este [post](http://developers.lyst.com/devops/2014/12/08/docker/) de Lyst.\n* [Building a Development Environment With Docker](https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/)\n* [Discourse in a Docker Container](https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container)\n\n## Docker-Compose\n\nCompose es una herramienta para definir y ejecutar varias aplicaciones en contenedores de Docker. Con Compose, utilizas un archivo YAML para configurar tus servicios. Entonces, con un único comando, creas e inicias todos los servicios desde tus configuraciones. Para aprender más sobre las características de Compose, revisa la [lista de características](https://docs.docker.com/compose/overview/#features).\n\nUtilizando el siguiente comando puedes iniciar tu aplicación:\n\n```sh\ndocker-compose -f <docker-compose-file> up\n```\n\nTambién puedes ejecutar docker-compose en segundo plano utilizando el parámentro -d, entonces podrás detenerlo cuando lo necesitas con el comando:\n\n```sh\ndocker-compose stop\n```\n\nPuedes tirarlo todo, eliminando los contenedores completamente, con el comando down. Utiliza el parámetro `--volumes` para también eliminar los volúmenes de datos.\n\n## Seguridad\n\nAquí te dejamos algunso consejos de seguridad sobre como funciona Docker. La página de Docker de [seguridad]](https://docs.docker.com/engine/security/security/) lo explica en más detalle.\n\nLo primero: Docker se ejecuta como root. Si estás en el grupo `docker`, [tienes acceso root](https://web.archive.org/web/20161226211755/http://reventlov.com/advisories/using-the-docker-command-to-root-the-host). Si expones el socket de unix de docker a un contenedor, le estás dando al contenedor acceso [root a la máquina host](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/).\n\n\nDocker no debería ser tu única defensa. Deberías asegurarlo y protejerlo.\n\nPara entender como se exponen los contenedores, deberías leer [Entendiendo y endureciendo Contenedores Linux](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/april/ncc_group_understanding_hardening_linux_containers-1-1.pdf) de [Aaron Grattafiori](https://twitter.com/dyn___). Esta es una guía completa y entendible sobre los riesgos relacionados con los contenedores, con una gran cantidad de enlaces y notas a pié de página. Los siguientes consejos de seguridad son útiles si ya has protejido tus contenedores en el pasado, pero no son substitutos a entenderlo. \n\n### Consejos de seguridad\n\nPara mayor seguridad, puedes ejecutar Docker dentro de una máquina virtual. Esto es un consejo del Jefe del Equipo de Seguridad de Docker -- [diapositivas](http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security) / [notas](http://www.projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/). Entonces, ejecutalo con AppArmor / seccomp / SELinux /grsec etc. para [limitar los permisos del contenedor](http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/). Revisa [las características de seguridad de Docker 1.10](https://blog.docker.com/2016/02/docker-engine-1-10-security/) para más detalles.\n\nLos identificadores de las imágenes de Docker son [información sensible](https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4) y no deberían exponerse al mundo exterior. Trátalos como contraseñas.\n\nRevisa la [Chuleta de Seguridad de Docker](https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc) de [Thomas Sjögren](https://github.com/konstruktoid): ahí podrás encontrar buenos consejos sobre como protejerse.\n\nRevisa el [script de seguridad de Docker Bench](https://github.com/docker/docker-bench-security).\n\n\n[Las 10 Mejores Prácticas de Seguridad para Imágenes de Docker](https://snyk.io/blog/10-docker-image-security-best-practices/) de Snyk\n\nPuedes empezar utilizando un Kernel con parches inestables de *grsecurity* / *pax* compilados, como [Alpine Linux](https://en.wikipedia.org/wiki/Alpine_Linux). Si haces uso de *grsecurity* en producción, deberías buscar [soporte comercial](https://grsecurity.net/business_support.php) para los [parches estables](https://grsecurity.net/announce.php), de la misma forma que deberías hacer para RedHat. Son unos 200$ al mes, lo cual es insignificante para el presupuesto de devops.\n\nA partir de Docker 1.11, puedes limitar fácilmente el número de procesos que se ejecutan en un contenedor para evitar *fork bombs*. Esto requiere utilizar un Kernel de Linux >= 4.3 con CGROUP_PIDS=y en la configuración del kernel.\n\n```sb\ndocker run --pids-limit=64\n```\n\nA partir de Docker 1.11 también está disponible la posibilidad de evitar que los procesos ganen nuevos privilegios. Esta característica está en el Kernel de Linux desde la versión 3.5. Puedes leer más al respecto en [este](http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/) blog.\n\n```sh\ndocker run --security-opt=no-new-privileges\n```\n\nDe la [Chuleta de Seguridad de Docker](http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf) (es un PDF y es un poco complejo de usar, así que mejor copia de abajo) de [Container Solutions](http://container-solutions.com/is-docker-safe-for-production/):\n\nDesactiva la comunicación interproceso con:\n\n```sh\ndocker -d --icc=false --iptables\n```\n\nEstablece que el contenedor sea solo lectura:\n\n```sh\ndocker run --read-only\n```\n\nVerifica las imágenes con un *hashsum*:\n\n```sh\ndocker pull debian@sha256:a25306f3850e1bd44541976aa7b5fd0a29be\n```\n\nEstablece el volúmen como solo lectura:\n\n```sh\ndocker run -v $(pwd)/secrets:/secrets:ro debian\n```\n\nCrea y utiliza un usiario en el Dockerfile para evitar ejecutar como root dentro del contenedor: \n\n```Dockerfile\nRUN groupadd -r user && useradd -r -g user user\nUSER user\n```\n\n### Espacio de Nombres del Usuario (*User Namespaces*)\n\nTambién hay que trabajar con los [espacios de nombres de usuario](https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/) -- disponibles en la 1.10, pero no activados por defecto.\n\nPara activar esta característica (\"reasignar los usuarios\") en ubuntu 15.10, [sigue este ejemplo](https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/).\n\n### Videos de Seguridad\n\n* [Using Docker Safely](https://youtu.be/04LOuMgNj9U)\n* [Securing your applications using Docker](https://youtu.be/KmxOXmPhZbk)\n* [Container security: Do containers actually contain?](https://youtu.be/a9lE9Urr6AQ)\n* [Linux Containers: Future or Fantasy?](https://www.youtube.com/watch?v=iN6QbszB1R8)\n\n### Ruta de Seguridad\n\nLa ruta de Docker habla sobre [el soporte de *seccomp*](https://github.com/docker/docker/blob/master/ROADMAP.md#11-security).\n\nTambién hay una política de AppArmor llamada [base](https://github.com/jfrazelle/bane), y están trabajando en [perfiles de seguridad](https://github.com/docker/docker/issues/17142)\n\n## Consejos\n\nFuentes:\n\n* [15 Docker Tips in 5 minutes](http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes)\n* [CodeFresh Everyday Hacks Docker](https://codefresh.io/blog/everyday-hacks-docker/)\n\n### Prune\n\nLos nuevos [Comandos de manejo de datos](https://github.com/docker/docker/pull/26108) llegaron a Docker en la versión 1.13\n\n* `docker system prune`\n* `docker volume prune`\n* `docker network prune`\n* `docker container prune`\n* `docker image prune`\n\n### df\n\n`docker system df` muestra un resumen del espacio actualmente utilizado por los distintos elementos de Docker.\n\n### Heredoc Docker Container\n\n```sh\ndocker build -t htop - << EOF\nFROM alpine\nRUN apk --no-cache add htop\nEOF\n```\n\n### Últimas IDs\n\n```sh\nalias dl='docker ps -l -q'\ndocker run ubuntu echo hello world\ndocker commit $(dl) helloworld\n```\n\n### Commit con comando (necesita de Dockerfile)\n\n```sh\ndocker commit -run='{\"Cmd\":[\"postgres\", \"-too -many -opts\"]}' $(dl) postgres\n```\n\n### Recuperar la dirección IP\n\n```sh\ndocker inspect $(dl) | grep -wm1 IPAddress | cut -d '\"' -f 4\n```\n\nO, con [jq](https://stedolan.github.io/jq/) instalado:\n\n```sh\ndocker inspect $(dl) | jq -r '.[0].NetworkSettings.IPAddress'\n```\n\nO, utilizando una [plantilla](https://docs.docker.com/engine/reference/commandline/inspect):\n\n```sh\ndocker inspect -f '{{ .NetworkSettings.IPAddress }}' <container_name>\n```\n\nO, al construir la imágen desde un Dockerfile, cuando quieres pasar argumentos de compilación:\n\n```sh\nDOCKER_HOST_IP=`ifconfig | grep -E \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1`\necho DOCKER_HOST_IP = $DOCKER_HOST_IP\ndocker build \\\n  --build-arg ARTIFACTORY_ADDRESS=$DOCKER_HOST_IP\n  -t sometag \\\n  some-directory/\n```\n\n### Recuperar el mapping de puertos\n\n```sh\ndocker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <nombredecontenedor>\n```\n\n### Encontrar contenedores mediante expresiones regulares\n\n```sh\nfor i in $(docker ps -a | grep \"REGEXP_PATTERN\" | cut -f1 -d\" \"); do echo $i; done\n```\n\n### Recuperar la configuraciín del entorno\n\n```sh\ndocker run --rm ubuntu env\n```\n\n### Detener los contenedores en funcionamiento\n\n```sh\ndocker kill $(docker ps -q)\n```\n\n### Eliminar todos los contenedores (¡FORZANDO! Los borrará estén funcionando o parados)\n\n```sh\ndocker rm -f $(docker ps -qa)\n```\n\n### Eliminar los viejos contenedores\n\n```sh\ndocker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm\n```\n\n### Eliminar los contenedores detenidos\n\n```sh\ndocker rm -v $(docker ps -a -q -f status=exited)\n```\n\n### Eliminar los contenedores después de pararlos\n\n```sh\ndocker stop $(docker ps -aq) && docker rm -v $(docker ps -aq)\n```\n\n### Eliminar las imágenes colgadas\n\n```sh\ndocker rmi $(docker images -q -f dangling=true)\n```\n\n### Eliminar todas las imágenes\n\n```sh\ndocker rmi $(docker images -q)\n```\n\n### Eliminar los volúmenes colgados\n\nComo en Docker 1.9:\n\n```sh\ndocker volume rm $(docker volume ls -q -f dangling=true)\n```\n\nEn 1.90, el filtro `dangling=false` _no_ funciona - es ignorado y mostrará todos los volúmenes\n\n### Mostrar las dependencias de las imágenes\n\n```sh\ndocker images -viz | dot -Tpng -o docker.png\n```\n\n### Reducir el tamaño de los contenedores Docker\n\n- Limpiar el APT en una capa `RUN` - Esto debería hacerse en la misma capa que los otros comandos `apt`. Sino, las capas previas seguirán teniendo la información original y la imágen seguirá siendo pesada.\n    ```Dockerfile\n    RUN {apt commands} \\\n      && apt-get clean \\\n      && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*\n    ```\n- Aplanar una imágen\n    ```sh\n    ID=$(docker run -d image-name /bin/bash)\n    docker export $ID | docker import – flat-image-name\n    ```\n- Para las copias de seguridad\n    ```sh\n    ID=$(docker run -d image-name /bin/bash)\n    (docker export $ID | gzip -c > image.tgz)\n    gzip -dc image.tgz | docker import - flat-image-name\n    ```\n\n### Monitorizar los recursos del sistema utilizados por los contenedores en funcionamiento\n\nPara revisar el uso de CPU, memoria y E/S de red para un solo contenedor, puedes utilizar:\n\n```sh\ndocker stats <container>\n```\n\nPara todos los contenedores listados por ID:\n\n```sh\ndocker stats $(docker ps -q)\n```\n\nPara todos los contenedores listados por nombre:\n\n```sh\ndocker stats $(docker ps --format '{{.Names}}')\n```\n\nPara todos los contenedores listados por imágen:\n\n```sh\ndocker ps -a -f ancestor=ubuntu\n```\n\nEliminar todas las imágenes sin etiquetas:\n\n```sh\ndocker rmi $(docker images | grep “^” | awk '{split($0,a,\" \"); print a[3]}')\n```\n\nEliminar contenedores mediante una expresión regular:\n\n```sh\ndocker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm -f\n```\n\nElimina todos los contenedores en estado \"Exit\":\n\n```sh\ndocker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')\n```\n\n### Los volúmenes pueden ser ficheros\n\nTen encuenta que puedes montar ficheros como volúmenes. Por ejemplo, pueden inyectar un archivo de configuración así:\n\n```sh\n# copia el archivo del contenedor\ndocker run --rm httpd cat /usr/local/apache2/conf/httpd.conf > httpd.conf\n\n# edita el archivo\nvim httpd.conf\n\n# inicia el contenedor con la configuracion modificada\ndocker run --rm -it -v \"$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro\" -p \"80:80\" httpd\n```\n\n## Contribución\n\nAquí tienes como contribuír a esta chuleta.\n\n### Open README.md\n\nhack click en el [README.md](https://github.com/wsargent/docker-cheat-sheet/blob/master/README.md) <-- este link\n\n![Click](../images/click.png)\n\n### Edit Page\n\n![Edit](../images/edit.png)\n\n### Make Changes and Commit\n\n![Cambios](../images/change.png)\n\n![Commit](../images/commit.png)\n"
  },
  {
    "path": "pt-br/README.md",
    "content": "# Docker Cheat Sheet\n\n**Deseja melhorar este *cheat sheet*? Veja a seção de [Contribuição](#contribution)**\n\n## Conteúdo\n\n* [Porque usar docker](#why-docker)\n* [Pré-requisitos](#prerequisites)\n* [Instalação](#installation)\n* [Containers](#containers)\n* [Imagens](#images)\n* [Redes](#networks)\n* [Registro e Repositório](#registry--repository)\n* [Dockerfile](#dockerfile)\n* [Camadas](#layers)\n* [Links](#links)\n* [Volumes](#volumes)\n* [Expondo portas](#exposing-ports)\n* [Boas práticas](#best-practices)\n* [Docker-Compose](#docker-compose)\n* [Segurança](#security)\n* [Dicas](#tips)\n* [Contribuição](#contributing)\n\n## Porque usar Docker\n\n\"Com Docker, desenvolvedores podem construir qualquer app em qualquer linguagem usando qualquer conjunto de ferramentas. Apps *Dockerizados* são completamente portáveis e podem rodar em qualquer lugar -- OS X e Windows laptops, servidores QA rodando Ubuntu na nuvem e *data centers* em produção rodando Red Hat em Máquinas Virtuais.\n\nDesenvolverodes podem iniciar a utilizá-lo rapidamente com um dos mais de 13.000 apps disponíveis no Docker hub. Docker gerencia e rastreia alterações e dependências, tornando mais fácil para *sysadmins* o entendimento do funcionamento de apps construido pelos desenvolvedores. Além disso, com Docker Hub, desenvolvedores podem automatizar o pipeline de *build* e compartilhar *artifacts* com colaboradores através de repositórios públicos ou privados.\n\nDocker auxilia desenvolvedores a construir e entregar aplicações de alta qualidade de maneira mais rápida.\" -- [O que é Docker (*What is Docker*)](https://www.docker.com/what-docker#copy1)\n\n## Pré-requisitos\n\nEu utilizo [Oh My Zsh](https://github.com/ohmyzsh/oh-my-zsh) com [Docker plugin](https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#docker) para autocompletar os comandos do docker.\n\n### Linux\n\nO kernel 3.10.x é [o requisito mínimo](https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies) para o uso do Docker.\n\n### MacOS\n\nÉ necessário *“Mountain Lion”* 10.8 ou mais recente.\n\n### Windows 10\n\nÉ necessário que o *Hyper-V* esteja habilitado na BIOS. Além disso, para precessadores intel, o VT-D também precisa estar habilidado caso esteja disponível.\n\n### Windows Server\n\nWindows Server 2016 é a versão mínima necessária para instalar o docker e o docker-compose. Existem limitações nessa versão, como por exemplo múltiplas redes virtuais e containers Linux. Windows Server 2019 ou posterior é recomendado.\n\n## Instalação\n\n### Linux\n\nUm simples, fácil e rápido *script* é disponibilizado pelo Docker:\n\n```\ncurl -sSL https://get.docker.com/ | sh\n```\n\nSe você não deseja rodar um *shell script* aleatório de internet, basta acessar as [instruções de instalação](https://docs.docker.com/engine/installation/linux/) para a sua distribuição.\n\nSe você não sabe nada sobre Docker, provavelmente você deveria seguir essa [série de tutoriais](https://docs.docker.com/engine/getstarted/) antes de continuar.\n\n### macOS\n\nBaixe e instale o [*Docker Community Edition*](https://www.docker.com/community-edition). Se você possui o Homebrew-Cask, apenas utilize o comando `brew install --cask docker`. Ou baixe e instale o [*Docker Toolbox*](https://docs.docker.com/toolbox/overview/).  [Docker para Mac](https://docs.docker.com/docker-for-mac/) é ok, mas ele ainda não é tão pronto quanto a instalação da VirtualBox. [Veja a comparação](https://docs.docker.com/docker-for-mac/docker-toolbox/).\n\n> **NOTA** *Docker Toolbox* está no estado *legacy*. Você deveria usar o *Docker Community Edition*. Veja o [*Docker Toolbox*](https://docs.docker.com/toolbox/overview/).\n\nAssim que você instalar o *Docker Community Edition*, clique no ícone do Docker no *Launchpad*. Em seguida inicie um container:\n\n```\ndocker run hello-world\n```\n\nÉ isso! Agora você tem um Docker container rodando.\n\nSe você não sabe nada sobre Docker, provavelmente você deveria seguir essa [série de tutoriais](https://docs.docker.com/engine/getstarted/) antes de continuar.\n\n### Windows 10\n\nVocê encontra instruções para instalar o Docker Desktop para Windows [neste link](https://docs.docker.com/desktop/windows/install/).\n\nUma vez instalado, abra o *powershell* como administrador\n\n```powershell\n#Exibe a versão do docker instalado\ndocker version\n\n#Todos comandos pull, create, e run 'hello-world' em apenas um:\ndocker run hello-world\n\n```\n\nPara continuar as instruções neste *cheat sheet*, clique com botão direito do mouse no ícone do Docker -- no menu iniciar ou onde quer que seja -- e vá em configurações. Para montar volumes, você precisa habilitar o disco C:/ para que as informaçõe sejam transmitidas para os containers (que ainda será explicado neste artigo).\n\nPara trocar entre containers Windows e Linux, clique com o botão direito no icone do Docker e, na sequência, clique no botão para trocar sistema operacional dos containers. Após fazer isso, todos os containers ques estiveram rodando serão desligados e ficaram inacessíveis até que o SO do container ser trocado novamente.\n\n\nAlém disso, se você possui WSL ou WSL2 instalado no seu desktop, você pode instalar o Kernel do Linux para Windows. Instruções para executar tal tarefa podem ser encontradas [aqui] [here](https://techcommunity.microsoft.com/t5/windows-dev-appconsult/using-wsl2-in-a-docker-linux-container-on-windows-to-run-a/ba-p/1482133). Atente-se ao fato de que para isso, é necessário o recurso do Subsistema Windows para Linux. Isso permitirá que os containers sejam acessados pelos sistemas operacionais WSL, bem como o ganho de eficiêcia da execução dos sistemas operacionais WSL no Docker. Por fim, tamém é preferível o uso do [terminal Windows](https://docs.microsoft.com/en-us/windows/terminal/get-started) para tal tarefa.\n\n### Windows Server 2016 / 2019\n\nSiga as instruções da Microsoft disponíveis [aqui](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/deploy-containers-on-server#install-docker)\n\n\nSe estiver usando a última versão de 2019, esteja preparado para trabalhar com o *powershell*, uma vez que esta versão não possui interface desktop. Quando inciar a máquina, ela vai logar e ir direto para um janela *powershell*. É recomendado instalar um editor de texto dentre outras ferramentas utilizando [Chocolatey](https://chocolatey.org/install).\n\nApós a instalação, esses comandos devem funcionar:\n\n```powershell\n#Exibe a versão do docker instalado\ndocker version\n\n#Todos comandos pull, create, e run 'hello-world' em apenas um:\ndocker run hello-world\n\n```\n\nO Windows Server 2016 não é capar de rodar images Linux.\n\nO Windows Server Build 2004 é capar de rodar containers Linux e Windows simultâneamente através do isolamento *Hyper-V*. Quando rodar os containers, utilize o comando ```--isolation=hyperv``` que vai isolar o container utilizando uma instância de kernel separada.\n\n \n### Checando a versão\n\nÉ muito importante que você sempre saiba a versão do Docker que você está utilizando. Isso é muito útil porque você vai saber quais *features* são compatíveis com aquilo que você está rodado. Além disso, isso também é importante pois você saberá quais containers você deve rodar a partir da *Docker store* quando você estiver tentando usar *containers templates*. Sendo assim, vamos dar um olhar em como saber a versão do Docker que você está rodando no momento.\n\n\n* [`docker version`](https://docs.docker.com/engine/reference/commandline/version/): mostra a versão do Docker que você está rodando\n\nObtendo a versão do servidor:\n\n```\n$ docker version --format '{{.Server.Version}}'\n\n1.8.0\n```\n\nVocê também pode fazer um *dump* dos dados em JSON:\n\n```\n$ docker version --format '{{json .}}'\n\n{\"Client\":{\"Version\":\"1.8.0\",\"ApiVersion\":\"1.20\",\"GitCommit\":\"f5bae0a\",\"GoVersion\":\"go1.4.2\",\"Os\":\"linux\",\"Arch\":\"am\"}\n```\n\n## Containers\n\n[O processo básico isolado do Docker](http://etherealmind.com/basics-docker-containers-hypervisors-coreos/). Containers são para máquinas virtuais o que *threads* são para processos. Ou você pode imaginá-los como *chroots* com esteróides.\n\n### Ciclo de vida\n\n* [`docker create`](https://docs.docker.com/engine/reference/commandline/create) cria um container mas não o inicia.\n* [`docker rename`](https://docs.docker.com/engine/reference/commandline/rename/) permite renomear um container.\n* [`docker run`](https://docs.docker.com/engine/reference/commandline/run) cria e inicia um container em uma única operação\n* [`docker rm`](https://docs.docker.com/engine/reference/commandline/rm) deleta um container\n* [`docker update`](https://docs.docker.com/engine/reference/commandline/update/) atualiza os limites de recurso de um container.\n\nNormalmente, se você rodar um container sem utilizar nenhuma opção ele vai iniciar e parar imediatamente. Se você deseja que ele continue rodando você pode usar o comando `docker run -td <container_id>`. A opção `-t` vai alocar uma sessão pseudo-TTY e o `-d` vai desacomplar o container automaticamente (ou seja, vai rodar o container em background e imprimir o ID do container).\n\nSe você deseja um container transiente, `docker run --rm` vai remover o container assim que ele parar.\n\nSe você deseja mapear um diretório da máquina *host* para o container do Docker, `docker run -v $HOSTDIR:$DOCKERDIR`. Saiba mais em [Volumes](https://github.com/wsargent/docker-cheat-sheet/#volumes).\n\nSe você também deseja remover o  volume associado ao container, ao deletar o container você deve incluir a opção `-v`, por exemplo, `docker rm -v`.\n\nTambém existe o [*logging driver*](https://docs.docker.com/engine/admin/logging/overview/), disponível para containers individuais no docker 1.10. Para rodar o docker com um *log driver* customizado (ou seja, para syslog), use `docker run --log-driver=syslog`.\n\nOutra opção muito útil é o `docker run --name <yourname> <docker_image>` porque você pode especificar o `--name` dentro do comando `run` que vai lhe permite iniciar e parar o container através do nome que você especificou quando o criou.\n\n\n### Iniciando e parando \n\n* [`docker start`](https://docs.docker.com/engine/reference/commandline/start) inicia um container, então ele passa a rodar.\n* [`docker stop`](https://docs.docker.com/engine/reference/commandline/stop) para um container que esteja rodando.\n* [`docker restart`](https://docs.docker.com/engine/reference/commandline/restart) para e inicia um container.\n* [`docker pause`](https://docs.docker.com/engine/reference/commandline/pause/) pausa um container que esteja rodando, \"congelando\" ele da maneira que está.\n* [`docker unpause`](https://docs.docker.com/engine/reference/commandline/unpause/) vai despausar um container que estava rodando.\n* [`docker wait`](https://docs.docker.com/engine/reference/commandline/wait) bloqueia o container até que ele seja parado.\n* [`docker kill`](https://docs.docker.com/engine/reference/commandline/kill) envia um SIGKILL para um container que esteja rodando.\n* [`docker attach`](https://docs.docker.com/engine/reference/commandline/attach) vai se conectar a um container que esteja rodando.\n\nSe você deseja desacoplar um container que esteja rodando, utilize `Ctrl + p, Ctrl + q`. Se você deseja integrar um container com o [gerenciador de processos do host](https://docs.docker.com/engine/admin/host_integration/), inicialize o daemon com `-r=false` e depois use `docker start -a`.\n\nSe você deseja expor portas do container través do *host*, veja a seção [expondo portas](#exposing-ports).\n\nPolíticas de reinicialização para instâncias \"crashadas\" do docker são [cobridas aqui](http://container42.com/2014/09/30/docker-restart-policies/).\n\n#### Restrições de CPU \n\nVocê pode limitar o uso da CPU, seja usando uma porcentagem de todas as CPUs ou usando *cores* específicos.\n\nPor exemplo, você pode usar a configuração [`cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint). A configuração é um pouco estranha -- 1024 significa 100% da CPU, então se você quer um container que toma 50% de todos os *cores*, você deve utilizar 512. Veja <https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/#_cpu> para mais:\n\n```\ndocker run -it -c 512 agileek/cpuset-test\n```\n\nVocê também pode usar alguns *cores* de uma CPU com o comando [`cpuset-cpus`](https://docs.docker.com/engine/reference/run/#/cpuset-constraint).  Veja <https://agileek.github.io/docker/2014/08/06/docker-cpuset/> para mais detalhes e alguns vídeos bem legais:\n\n```\ndocker run -it --cpuset-cpus=0,4,6 agileek/cpuset-test\n```\n\nObserve que o Docker ainda pode **enxergar** todas as CPUs de dentro do container -- ele apenas não está usando todas elas. Veja <https://github.com/docker/docker/issues/20770> para mais detalhes.\n\n\n#### Restrições de memória\n\nVocê também pode setar [restrições de memória](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) no Docker:\n\n```\ndocker run -it -m 300M ubuntu:14.04 /bin/bash\n```\n\n#### *Capabilities*\n\nLinux *capabilities* podem ser setadas utilizand as opções `cap-add` e `cap-drop`. Veja See <https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities> para mais detalhes. Elas devem ser utilizadas para aumentar a seguraça do sistema.\n\nPara montar um *filesystem* baseado no FUSE, você precisa combinar tanto `--cap-add` quanto `--device`:\n\n```\ndocker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs\n```\n\nPara dar acesso a um único *device*:\n\n```\ndocker run -it --device=/dev/ttyUSB0 debian bash\n```\n\nPara dar acesso a todos os *devices*:\n\n```\ndocker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash\n```\n\nPara mais informações sobre privilégios em containers [clique aqui](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities).\n\n### Info\n\n* [`docker ps`](https://docs.docker.com/engine/reference/commandline/ps) motra os containers que estão rodando.\n* [`docker logs`](https://docs.docker.com/engine/reference/commandline/logs) obtém um log dos containers. (Você pode usar um log customizado, mas eles estão disponíveis apenas para `json-file` e `journald` na versão 1.10).\n* [`docker inspect`](https://docs.docker.com/engine/reference/commandline/inspect) olha para todas as informações de um container (incluindo o endereço IP).\n* [`docker events`](https://docs.docker.com/engine/reference/commandline/events) obtém os eventos de um container.\n* [`docker port`](https://docs.docker.com/engine/reference/commandline/port) mostra a porta pública de um container.\n* [`docker top`](https://docs.docker.com/engine/reference/commandline/top) mostra os processos rodando dentro de um container.\n* [`docker stats`](https://docs.docker.com/engine/reference/commandline/stats) mostra uma estatística dos recursos que o container está utilizando.\n* [`docker diff`](https://docs.docker.com/engine/reference/commandline/diff) mostra os arquivos alterados pelo FS de um container.\n\n`docker ps -a` mostra os containers que estão rodando e os que foram parados.\n\n`docker stats --all` mostra uma lista de todos os containers. O padrão é mostrar apenas os que estão rodando.\n\n### Importar / Exportar\n\n* [`docker cp`](https://docs.docker.com/engine/reference/commandline/cp) copia arquivos ou pastas entre o container e o *filesystem* local.\n* [`docker export`](https://docs.docker.com/engine/reference/commandline/export) transforma o *filesystem* do container em um fluxo de arquivo *tarball* para STDOUT.\n\n\n### Executando comandos\n\n* [`docker exec`](https://docs.docker.com/engine/reference/commandline/exec) executa um comando dentro do container.\n\nPor exemplo, para entrar em um container fictício, que esteja rodando, chamado foo, inclua um shell a ele da seguinte maneira: `docker exec -it foo /bin/bash`.\n\n## Imagens\n\nImagens são apenas [templates de um container docker](https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work).\n\n### Ciclo de vida\n\n* [`docker images`](https://docs.docker.com/engine/reference/commandline/images) mostra todas as imagens.\n* [`docker import`](https://docs.docker.com/engine/reference/commandline/import) cria uma imagem a partir de um *tarball*.\n* [`docker build`](https://docs.docker.com/engine/reference/commandline/build) cria uma imagem a partir de um Dockerfile.\n* [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit) cria uma imagem a partir de um container, pausando ele temporariamente caso ele esteja rodando.\n* [`docker rmi`](https://docs.docker.com/engine/reference/commandline/rmi) remove uma imagem.\n* [`docker load`](https://docs.docker.com/engine/reference/commandline/load) carrega uma imagem a partir de um arquivo tar no STDIN, incluindo imagess and tags (a partir da versão 0.7).\n* [`docker save`](https://docs.docker.com/engine/reference/commandline/save) salva uma imagem em um arquivo tar através do STDOUT com todas as camadas pais, tags e versões (a partir do 0.7).\n\n### Info\n\n* [`docker history`](https://docs.docker.com/engine/reference/commandline/history) mostra o histórico de todas as imagens.\n* [`docker tag`](https://docs.docker.com/engine/reference/commandline/tag) dar uma tag a uma imagem (local ou *registry*)\n\n\n### Fazendo uma limpeza\n\nVocê pode utilizar o comando `docker rmi` para remover imagens específicas, porém, existe uma ferramenta chamada [docker-gc](https://github.com/spotify/docker-gc), que de maneira segura, limpa as imagens que não está sendo utilizada por nenhum container. \n\n that will safely clean up images that are no longer used by any containers. A partir do docker 1.13, o comando `docker image prune` também está disponível para remover imagens que não estão sendo usadas. Veja a seção [Prune](#prune).\n\n### Carregar/Salvar imagens\n\nCarregue uma imagem a partir do arquivo:\n```\ndocker load < my_image.tar.gz\n```\n\nSalve uma imagem existente usando:\n```\ndocker save my_image:my_tag | gzip > my_image.tar.gz\n```\n\n### Importar/Exportar containers\n\n\nImporte um container com uma imagem a partir de um arquivo:\n```\ncat my_container.tar.gz | docker import - my_image:my_tag\n```\n\nExporte um container existente usando:\n```\ndocker export my_container | gzip > my_container.tar.gz\n```\n\n### Diferenças entre carregar uma imagem salva e importar um container exportado como uma imagem\n\nCarregar uma imagem usanfo o comando `load` cria uma nova imagem, incluindo o seu histórico. Importar um container como uma imagem usando o comando `import` cria uma nova imagem excluindo o seu histórico, o que resulta em uma imamgem de tamanho menor do que usando o comando anterior.\n\n## Rede\n\nO Docker possui *features* de [rede](https://docs.docker.com/engine/userguide/networking/). Automaticamente, ele cria 3 interfaces de rede quando você o instala (*bridge*, *host*, *none*). Um novo container é inicializado, por padrão, dentro da rede *bridge*. Para habilitar a comunicação entre multiplos containers, você pode criar uma nova rede e iniciarlizar o mesmo com ela. Isso vai habilitar a comunicação entre os containers dentro dela ao mesmo tempo que os isola dos outros containers que não estejam conectados nesta rede. Além disso, isso permite mapear os nomes dos containers com o seus respectivos endereços IP. Veja [trabalhando com redes](https://docs.docker.com/engine/userguide/networking/work-with-networks/) para mais detalhes.\n\n### Ciclo de vida\n\n* [`docker network create <name>`](https://docs.docker.com/engine/reference/commandline/network_create/)  cria uma nova rede (tipo padrão: *bridge*).\n* [`docker network rm <name>`](https://docs.docker.com/engine/reference/commandline/network_rm/) remode uma ou mais redes especificadas pelo nome ou identificador. Nenhum container pode se conectar em uma rede quando deletada.\n\n### Info\n\n* [`docker network ls`](https://docs.docker.com/engine/reference/commandline/network_ls/) lista todas as redes.\n* [`docker network inspect <name>`](https://docs.docker.com/engine/reference/commandline/network_inspect/) mostra informações detalhadas de uma ou mais redes.\n\n### Conexão\n\n* [`docker network connect <network> <container>`](https://docs.docker.com/engine/reference/commandline/network_connect/) Conecta um container a uma rede\n* [`docker network disconnect <network> <container>`](https://docs.docker.com/engine/reference/commandline/network_disconnect/) Desconecta um container de uma rede\n\nVocê pode especificar um [endereço IP para um container](https://blog.jessfraz.com/post/ips-for-all-the-things/):\n\n```\n# cria uma nova rede bridge com sua subnet e gateway para seu bloco de endereço IP\ndocker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic\n\n# roda um container nginx com um IP específico para o dado bloco\n$ docker run --rm -it --net iptastic --ip 203.0.113.2 nginx\n\n# da um culr no IP a partir de qualquer outro local (assumindo que este seja um IP público)\n$ curl 203.0.113.2\n```\n\n## Registry & Repositório\n\nUm repositório é uma coleção *hosteada* de imagens com tagas que juntas criam um sistema de arquivo para um container;\n\nUm *registry* é um *host* -- ou seja, um servidor que armazena repositórios e disponibiliza um API HTTP para [gerencias o upload e download dos repositórios](https://docs.docker.com/engine/tutorials/dockerrepos/).\n\nO Docker.com *hostea* seus prórpios [índices](https://hub.docker.com/) em uma central de *registries* qie contém um grande número de repositórios. Sendo assim, essa central [não é muito boa em verificar a procedência das imagens](https://titanous.com/posts/docker-insecurity) e deve ser evitada caso segurança seja algo crítico para você.\n \n\n* [`docker login`](https://docs.docker.com/engine/reference/commandline/login) efetua login em um *registry*.\n* [`docker logout`](https://docs.docker.com/engine/reference/commandline/logout) efetua logout de um *registry*.\n* [`docker search`](https://docs.docker.com/engine/reference/commandline/search) busca imagens dentro do *registry*.\n* [`docker pull`](https://docs.docker.com/engine/reference/commandline/pull) efetua um *pull* de uma imagem do *registry* para sua máquina local.\n* [`docker push`](https://docs.docker.com/engine/reference/commandline/push) efetua um *push* de uma imagem para o *registry* a partir da sua máquina local.\n\n### Rodando um *registry* local\n\nVocê pode rodar um *registry* local utilizando o projeto de [distribuição docker](https://github.com/docker/distribution) e seguindo as instruções de [*deploy* local](https://github.com/docker/docker.github.io/blob/master/registry/deploying.md).\n\nAlém disso, você pode se interessar pela [lista de emails](https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution).\n\n## Dockerfile\n\n[O arquivo de configuração](https://docs.docker.com/engine/reference/builder/). Prepara um container Docker quando você executa o comando `docker build`. A maioria das pessoas preferem este comando do que o `docker commit`.  \n\nEstes são alguns dos editores de texto que dão suporte, em termos de módulos que destacam a sintaxe, para criar Dockerfiles:\n* Se você utiliza o [jEdit](http://jedit.org), eu adicionei um módulo para destacar de sintaxe para o [Dockerfile](https://github.com/wsargent/jedit-docker-mode). Sinta-se livre para usar.\n* [Sublime Text 2](https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting)\n* [Atom](https://atom.io/packages/language-docker)\n* [Vim](https://github.com/ekalinin/Dockerfile.vim)\n* [Emacs](https://github.com/spotify/dockerfile-mode)\n* [TextMate](https://github.com/docker/docker/tree/master/contrib/syntax/textmate)\n* [VS Code](https://github.com/Microsoft/vscode-docker)\n* Veja também [Docker meets the IDE](https://domeide.github.io/)\n\n### Instruções\n\n* [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)\n* [FROM](https://docs.docker.com/engine/reference/builder/#from) Prepara a imagem base para as instruções subsequentes.\n* [MAINTAINER (depreciado - use a tag LABEL)](https://docs.docker.com/engine/reference/builder/#maintainer-deprecated) Define o autor que gerou a imagem.\n* [RUN](https://docs.docker.com/engine/reference/builder/#run) executa qualquer comando em uma nova camada em cima de uma imagem e *comita* o resultado.\n* [CMD](https://docs.docker.com/engine/reference/builder/#cmd) fornecer padrões para um container em execução.\n* [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) informa o Docker que o container pode escutar uma determinada porta de rede durante o tempo de execução. NOTA: isso não faz com que a porta seja acessível.\n* [ENV](https://docs.docker.com/engine/reference/builder/#env) define uma variável de ambiente.\n* [ADD](https://docs.docker.com/engine/reference/builder/#add) copia novos arquivos, diretórios, ou arquivos remotos em um container. Invalida cache. Evite usar `ADD` e use o comando `COPY`.\n* [COPY](https://docs.docker.com/engine/reference/builder/#copy) copia um novo arquivo ou diretórios para dentro do container. Por padrão copia como root independente das configurações do USER/WORKDIR. Utilize `--chown=<user>:<group>` para poderes de acesso a outros usuários/grupos. (o mesmo é válido para o comando `ADD`.)\n* [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) configura um container que vai rodar como um executável.\n* [VOLUME](https://docs.docker.com/engine/reference/builder/#volume) cria um ponto de montagem para montar volumes externos ou outros containers.\n* [USER](https://docs.docker.com/engine/reference/builder/#user) define o nome de usuário para os seguintes comandos: RUN / CMD / ENTRYPOINT.\n* [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) define o diretório de trabalho.\n* [ARG](https://docs.docker.com/engine/reference/builder/#arg) define uma variável que existe durante o tempo de execução do *build*.\n* [ONBUILD](https://docs.docker.com/engine/reference/builder/#onbuild) adicionar uma instrução alarme que dispara quando a imagem está sendo usada como base para outra *build*.\n* [STOPSIGNAL](https://docs.docker.com/engine/reference/builder/#stopsignal) define o sinal de alerta do sistema que vai ser enviado para sair do container.\n* [LABEL](https://docs.docker.com/config/labels-custom-metadata/) aplica uma chave/valor para suas imagens, containers, ou *daemons*.\n* [SHELL](https://docs.docker.com/engine/reference/builder/#shell) sobrecarrega o shell padrão para rodar os comandos do docker.\n* [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#healthcheck) informa docker como testar o container para testar se tudo está funcionando adequadamente.\n\n### Tutorial\n\n* [Tutorial do Flux7 para o Dockerfile](https://www.flux7.com/tutorial/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)\n\n### Exemplos\n\n* [Exemplos](https://docs.docker.com/engine/reference/builder/#dockerfile-examples)\n* [Boas práticas para escrever Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)\n* [Michael Crosby](http://crosbymichael.com/) tem mais algumas [boas práticas para criar Dockerfiles](http://crosbymichael.com/dockerfile-best-practices.html) / [parte 2](http://crosbymichael.com/dockerfile-best-practices-take-2.html).\n* [Construindo boas imagens Docker](http://jonathan.bergknoff.com/journal/building-good-docker-images) / [Construindo imagens Dockers ainda melhores](http://jonathan.bergknoff.com/journal/building-better-docker-images)\n* [Gerenciando a configuração de um container com metadados](https://speakerdeck.com/garethr/managing-container-configuration-with-metadata)\n* [Como escrever excelentes Dockerfiles](https://rock-it.pl/how-to-write-excellent-dockerfiles/)\n\n## Camadas\n\nO versionamento dos arquivos de sistema do docker é feito em camadas. Elas funcionam como [comits no git ou *changesets* para arquivos de sistemas](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/).\n\n## Links\n\nLinks são como os containers Docker conversam uns com os outros [através de portas TCP/IP](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/). [Atlassian](https://blogs.atlassian.com/2013/11/docker-all-the-things-at-atlassian-automation-and-wiring/) mostra alguns exemplos funcionais. Você também pode determinar [links pelo hostname](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file).\n\nEste está depreciado para estender algumas [redes definidas por usuário](https://docs.docker.com/network/).\n\nNOTA: se você deseja que os containers comuniquem uns com os outros apenas utilizando links, inicie o do docker daemon com `-icc=false` para desebilitar os processor de intra-comunicação. \n\nSe você possui um container com nome CONTAINER (especificado por `docker run --name CONTAINER`) e em um Dockerfile, ele possui uma porta exposta:\n\n```\nEXPOSE 1337\n```\n\nEntão, se nós criarmos qualquer outro container chamado LINKED como este:\n\n```\ndocker run -d --link CONTAINER:ALIAS --name LINKED user/wordpress\n```\n\nEntão, as portas expostas e os *aliases* do CONTAINER serão mostrados em LINKED com as seguintes variáveis de ambiente:\n\n```\n$ALIAS_PORT_1337_TCP_PORT\n$ALIAS_PORT_1337_TCP_ADDR\n```\n\nVocê pode se conectar nele dessa maneira.\n\nPara deletar os links, utilize o comando `docker rm --link`.\n\nGeralmente, a *linkagem* entre serviços docker é um subconjunto de um \"descobrimento de serviço\", um grande problema caso você esteja planejando usar Docker para escalar em produção. Você pode se referir ao livro [The Docker Ecosystem: Service Discovery and Distributed Configuration Stores](https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores) para mais informações.\n\n## Volumes\n\nOs volumes no Docker são [arquivos de sistemas flutuantes](https://docs.docker.com/engine/tutorials/dockervolumes/). Eles não possuem uma conexão particular com um container. Você pode usar volumes montados a partir de [container somente de dados](https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e) para fins de portabilidade. A partir do Docker 1.9.0, o Docker passou a nomear volumes que substituem containers apenas de dados. Considere usar volumes nomeados para implementar isso ao invés de containers de dados.\n\n### Ciclo de vidar\n\n* [`docker volume create`](https://docs.docker.com/engine/reference/commandline/volume_create/)\n* [`docker volume rm`](https://docs.docker.com/engine/reference/commandline/volume_rm/)\n\n### Informações\n\n* [`docker volume ls`](https://docs.docker.com/engine/reference/commandline/volume_ls/)\n* [`docker volume inspect`](https://docs.docker.com/engine/reference/commandline/volume_inspect/)\n\nVolumes são úteis em situações em que você não quer usar links (que são apenas TCP/IP). Por exemplo, se você precisar ter duas instancias docker comunicando através de algo deixado no arquivo de sistema.\n\nVocê pode montar vários containers docker de uma vez usando o comando `docker run --volumes-from`.\n\nComo os volumes são sistemas de arquivos isolados, frequentemente, eles são usados para armazenar estados de alguma computação que é transiente no container. Isto é, você pode ter um container sem estado e transiente continuado de ponto que útimo container deixou.\n\nVeja [volumes avançados](http://crosbymichael.com/advanced-docker-volumes.html) para mais detalhes. [Container42](http://container42.com/2014/11/03/docker-indepth-volumes/) também é bem útil.\n\nVocê pode [mapear diretórios hosts do MacOS como volumes docker](https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume):\n\n```\ndocker run -v /Users/wsargent/myapp/src:/src\n```\n\nVocê pode usar columes NFS remotos se você estiver se \nYou can use remote NFS volumes if you're [sentindo corajoso](https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume).\n\nVocê também pode considerar rodar containers apenas de dados como descrito [aqui](http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/) para obter uma certa portabilidade de dados.\n\nSaiba que você pode [montar arquivos como volumes](#volumes-can-be-files).\n\n## Expondo portas\n\n\nExpor as portas de entrada através do container *host* é [complicado, mas factível](https://docs.docker.com/engine/reference/run/#expose-incoming-ports).\n\nIsso é feito mapeando a porta do container para com a porta do *host* (apenas usando a interface *localhost*) usando a opção `-p`:\n\n```\ndocker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t ALGUMA_IMAGEM\n```\n\nVocê pode informar ao Docker que o container escuta uma porta de rede específica durante a execução ao usar o comando [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose):\n\n```\nEXPOSE <CONTAINERPORT>\n```\n\nNote que `EXPOSE` não expões a porta propriamente dita -- apenas a opção `-p` faz isso. Para expor uma porta do container na sua porta *localhost*:\n\n```\niptables -t nat -A DOCKER -p tcp --dport <LOCALHOSTPORT> -j DNAT --to-destination <CONTAINERIP>:<PORT>\n```\n\nSe você estiver rodando Docker em uma VirtualBox, então você precisa encaminha a porta para lá também usando uma [*forwarded_port*](https://docs.vagrantup.com/v2/networking/forwarded_ports.html). Defina um intervalo de portas que no seu *Vagrantfile* dessa maneira para que vcê possa mapeá-las dinamicamente:\n\n```\nVagrant.configure(VAGRANTFILE_API_VERSION) do |config|\n  ...\n\n  (49000..49900).each do |port|\n    config.vm.network :forwarded_port, :host => port, :guest => port\n  end\n\n  ...\nend\n```\n\nSe você esquecer o que você mapeou na porta do seu container *host*, utilize `docker port` para mostrar o que você fez:\n\n```\ndocker port CONTAINER $CONTAINERPORT\n```\n\n## Boas práticas\n\nÉ aqui onde boas práticas gerais do Docker uma discusão começa:\n\n* [A toca do coelho do uso do Docker em testes automatizados](http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/)\n* [Bridget Kromhout](https://twitter.com/bridgetkromhout) possui um post muito útil no  blog: [rodando Docker em produção](http://sysadvent.blogspot.co.uk/2014/12/day-1-docker-in-production-reality-not.html) no Dramafever.\n* Também tem o [blog post](http://developers.lyst.com/devops/2014/12/08/docker/) de boas práticas feito pela Lyst.\n* [Contruindo um ambiente de desenvolvimento com Docker](https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/)\n* [Discurso em um container Docker](https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container)\n\n## Docker-Compose\n\n*Compose* é uma ferramenta para definir e rodar aplicações em vários containers Docker. Com o *compose* você utiliza uma arquivo YAML para configurar os serviços de sua aplicação. Na sequência, com uum único comando, você cria e inicia todos os serviços a partir da sua configuração. Para aprender mais sobre todas as funcionalidades do *Compose*, veja a [lista de funcionalidades](https://docs.docker.com/compose/overview/#features).\n\nAo usar este comando, você inicia sua aplicação:\n\n```\ndocker-compose -f <docker-compose-file> up\n```\n\nVocê também pode rodar `docker-compose` de maneira desacoplada usando a opção `-d` e parar ele quando quiser utilizando o comando:\n\n```\ndocker-compose stop\n```\nVocê pode desligar tudo\nVocê pode desligar tudo, remover os containers inteiramente, com o comando `down`. Passe `--volumes` para remover também o dados.\n\n## Segurança\n\nAqui vão as dicas de segurança do Docker! A página sobre [segurança](https://docs.docker.com/engine/security/security/) do Docker fornece muito mais detalhes.\n\nComeçando do começo: Docker roda como root. Se você está dentro do `docker group`, você [possui acesso root](https://web.archive.org/web/20161226211755/http://reventlov.com/advisories/using-the-docker-command-to-root-the-host). Se você expor um unix socket do docker para um container, você está dando para este container [acesso root para o host](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/).\n\nDocker não pode ser sua única defesa. Você deve protegê-lo da melhor maneira possível.\n\nPara entender o que os containers deixam exposto, você deveria ler o tutorial [Entendendo e Protegendo Containers Linux](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/april/ncc_group_understanding_hardening_linux_containers-1-1.pdf) escrito por [Aaron Grattafiori](https://twitter.com/dyn___). Ele um guia completo e compreensível para as questões envolvendo containers com uma grande quantidade de links e notas de rodapés que te leva para conteúdos ainda mais úteis. As dicas de seguranças que vêm a seguir são úteis se você já vem aumentando a segurança dos seus conteiners. Entretanto, elas não substituem o conhecimento sobre o assunto.\n\n### Dicas de segurança\n\nPara a maior segurança possível, é desejável rodar o Docker dentro de uma máquina virtual. Essa dica vem direto do líder do time de segurança do Docker -- [slides](http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security) / [notas](http://www.projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/). \nNa sequência, rode ele com  AppArmor / seccomp / SELinux / grsec etc para [limitar as permissões do container](http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/). Veja as [funcionalidades de segurança do Docker 1.10](https://blog.docker.com/2016/02/docker-engine-1-10-security/) para mais detalhes.\n\nAs IDs de imagens do Docker são [informações sensíveis](https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4) e não devem serem expostas para o mundo. Trate elas como *passwords*.\n\nVeja o [*Cheat Sheet* de segurança do Docker](https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc) por [Thomas Sjögren](https://github.com/konstruktoid): tem bastante coisa boa sobre aumentar a segurança em containers lá.\n\nDê uma olhada no [script de segurança docker bench](https://github.com/docker/docker-bench-security), baixe os [*white papers*](https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/).\n\nVeja as [10 melhores práticas de segurança para imagens Docker](https://snyk.io/blog/10-docker-image-security-best-practices/) do Snyk.\n\n\nVocê deve começar usando *kernels* com *patches* estáveis do grsecurity / pax compilados, por exemplo, no [Linux Alpine ](https://en.wikipedia.org/wiki/Alpine_Linux). Se você está usando grsecurity em produção, você deve adquirir o [suporte comercial](https://grsecurity.net/business_support.php) para ter [*patches* estáveis](https://grsecurity.net/announce.php), da mesma forma que você faria para o RedHat. Ele custa $200 por mês, o que pe nada para o seu orçamento de DevOps.\n\nDesde o Docker 1.11, é fácil limitar o número de processos ativos rodando dentro do container para evitar *fork bombs*. É necessário um kernel Linux >= 4.3 com `CGROUP_PIDS=y` estar na configuração do Kernel.\n\n```\ndocker run --pids-limit=64\n```\n\nTambém está disponível, desde a versão 1.11, uma maneira de prevenir que processos ganhem novos privilégios. Essa funcionalidade está no *kernel* Linux desde a versão 3.5. Saiba mais sobre ela neste [post](http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/) blog post.\n\n```\ndocker run --security-opt=no-new-privileges\n```\n\nNo [*Chear sheet* de segurança do Docker](http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf) (está em PDF, o que o torna difícil de usar, então esta copiado na sequência) por [Soluções para containers](http://container-solutions.com/is-docker-safe-for-production/):\n\nDesligue a comunicação entre processor usando:\n\n\n```\ndocker -d --icc=false --iptables\n```\n\nDefina o container como apenas leitura:\n\n```\ndocker run --read-only\n```\n\nVerique as imagens usando `hashsum`:\n\n```\ndocker pull debian@sha256:a25306f3850e1bd44541976aa7b5fd0a29be\n```\n\nDefina os volumes como apenas leitura:\n\n```\ndocker run -v $(pwd)/secrets:/secrets:ro debian\n```\n\nDefina e roda um usuário no seu Dockerfile, assim você não vai rodar como root dentro do container:\n\n```\nRUN groupadd -r user && useradd -r -g user user\nUSER user\n```\n\n### Usando *Namespaces*\n\nTambém temos que trabalha no [*namespaces* do usuário](https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/) -- ele está na versão 1.1, mas não está disponível por padrão.\n\nPara habilitar os *namespaces* do usuário no Ubuntu 15.10, [siga o exemplo descrito neste blog](https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/).\n\n### Vídeos sobre segurança\n\n* [Usando Docker de maneira segura](https://youtu.be/04LOuMgNj9U)\n* [Protegendo suas aplicações usando Docker](https://youtu.be/KmxOXmPhZbk)\n* [Segurança do container: eles realmente a tem?](https://youtu.be/a9lE9Urr6AQ)\n* [Linux Containers: Futuro ou Fantasia?](https://www.youtube.com/watch?v=iN6QbszB1R8)\n\n### Roteiro da Segurança\n\nO roteiro do Docker fala sobre [suporte ao `secomp`] (https://github.com/docker/docker/blob/master/ROADMAP.md#11-security). Existe também o gerador de política AppArmor chamado [bane](https://github.com/jfrazelle/bane), e eles estão rodando dentro dos [perfis de segurança](https://github.com/docker/docker/issues/17142).\n\n## Dicas\n\nFontes:\n\n* [15 dicas do Docjer em 5 minutos](http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes)\n* [Docker CodeFresh: hacks para o Docker](https://codefresh.io/blog/everyday-hacks-docker/)\n\n### *Prune*\n\nOs novos [comandos de gerenciamento de dados](https://github.com/docker/docker/pull/26108) chegaram no Docker 1.13:\n\n* `docker system prune`\n* `docker volume prune`\n* `docker network prune`\n* `docker container prune`\n* `docker image prune`\n\n### df\n\n`docker system df` apresenta um resumo do espaço utilizado pelos objetos do Docker.\n\n### Heredoc Docker Container\n\n```\ndocker build -t htop - << EOF\nFROM alpine\nRUN apk --no-cache add htop\nEOF\n```\n\n### Últimos IDs\n\n```\nalias dl='docker ps -l -q'\ndocker run ubuntu echo hello world\ndocker commit $(dl) helloworld\n```\n\n### Comitar com comandos (precisa de um Dockerfile)\n\n```\ndocker commit -run='{\"Cmd\":[\"postgres\", \"-too -many -opts\"]}' $(dl) postgres\n```\n\n### Obter o endereço IP\n\n```\ndocker inspect $(dl) | grep -wm1 IPAddress | cut -d '\"' -f 4\n```\n\nou com [jq](https://stedolan.github.io/jq/) instalado:\n\n```\ndocker inspect $(dl) | jq -r '.[0].NetworkSettings.IPAddress'\n```\n\nou usando o [template go](https://docs.docker.com/engine/reference/commandline/inspect):\n\n```\ndocker inspect -f '{{ .NetworkSettings.IPAddress }}' <container_name>\n```\n\nou quando *buildando* um imagem com Dockerfile, quando você quiser passar um argumento de build:\n\n```\nDOCKER_HOST_IP=`ifconfig | grep -E \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1`\necho DOCKER_HOST_IP = $DOCKER_HOST_IP\ndocker build \\\n  --build-arg ARTIFACTORY_ADDRESS=$DOCKER_HOST_IP \n  -t sometag \\\n  some-directory/\n```\n\n### Obter mapeamento de porta \n\n```\ndocker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <containername>\n```\n\n### Encontrar container com expressão regular\n\n```\nfor i in $(docker ps -a | grep \"REGEXP_PATTERN\" | cut -f1 -d\" \"); do echo $i; done\n```\n\n### Obter configurações de ambiente\n\n```\ndocker run --rm ubuntu env\n```\n\n### Matar containers que estão rodando \n\n```\ndocker kill $(docker ps -q)\n```\n\n### Deletar todos os containers (Forçado!! containers que esteja parados ou rodando)\n\n```\ndocker rm -f $(docker ps -qa)\n```\n\n### Deletar containers antigos\n\n```\ndocker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm\n```\n\n### Deletar containers parados\n\n```\ndocker rm -v $(docker ps -a -q -f status=exited)\n```\n\n### Deletar containers depois de para-los\n\n```\ndocker stop $(docker ps -aq) && docker rm -v $(docker ps -aq)\n```\n\n### Deletar imagens pendentes\n\n```\ndocker rmi $(docker images -q -f dangling=true)\n```\n\n### Delete todas as imagens\n\n```\ndocker rmi $(docker images -q)\n```\n\n### Deletar volumes pendentes\n\nAs of Docker 1.9:\n\n```\ndocker volume rm $(docker volume ls -q -f dangling=true)\n```\n\nIn 1.9.0, the filter `dangling=false` does _not_ work - it is ignored and will list all volumes.\n\n### Mostrar dependências das imagens\n\n```\ndocker images -viz | dot -Tpng -o docker.png\n```\n\n### Reduzingo o tamanho dos containers\n\n- Limpando APT em uma camada RUN\n\nIsso deve ser feito na mesma camada dos outros comandos `apt`. Caso contrário, as camadas anteriores irão persistir e as informações originais das suas imagens vão contiuar grandes.\n\n```\nRUN {apt commands} \\\n  && apt-get clean \\\n  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*\n```\n\n- Achatar uma imagem\n```\nID=$(docker run -d image-name /bin/bash)\ndocker export $ID | docker import – flat-image-name\n```\n\n- Fazendo backup\n```\nID=$(docker run -d image-name /bin/bash)\n(docker export $ID | gzip -c > image.tgz)\ngzip -dc image.tgz | docker import - flat-image-name\n```\n\n### Monitorar os recursos utilizados pelos containers\n\nPara verificar CPU, memória, ou I/O de rede em um único container, você pode usar:\nTo check the CPU, memory, and network I/O usage of a single container, you can use:\n```\ndocker stats <container>\n```\n\nPara todos os containers listados por ID:\n```\ndocker stats $(docker ps -q)\n```\n\nPara todos os containers listados por nome:\n```\ndocker stats $(docker ps --format '{{.Names}}')\n```\n\nPara todos os containers listados por imagem:\n```\ndocker ps -a -f ancestor=ubuntu\n```\n\nRemover todas imagens sem tag:\n```\ndocker rmi $(docker images | grep “^” | awk '{split($0,a,\" \"); print a[3]}')\n```\n\nRemover um container usando expressão regular:\n```\ndocker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm -f\n```\n\nRemover todos os containers *exitados*:\n```\ndocker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')\n```\n\n### Volumes podem ser arquivos\n\nSaiba que você pode montar arquivos como volumes. Por exemplo, se você pode injetar uma configuração dessa forma:\n\n``` bash\n# copia o arquivo para o container\ndocker run --rm httpd cat /usr/local/apache2/conf/httpd.conf > httpd.conf\n\n# edita o arquivo\nvim httpd.conf\n\n# inicia o container com a configuração que foi modificada\ndocker run --rm -it -v \"$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro\" -p \"80:80\" httpd\n```\n\n## Contrinbuindo com este *chear sheet*\n\nAqui está um pequeno tutorial de como contribuir com este documento.\n\n### Abra o README.md\n\nClique em [README.md](https://github.com/wsargent/docker-cheat-sheet/blob/master/README.md) <-- neste link\n\n![Clique aqui](../images/click.png)\n\n### Edite a página\n\n![Edite aqui](../images/edit.png)\n\n### Faça as mudanças e commit elas\n\n![Mude aqui](../images/change.png)\n\n![Commit](../images/commit.png)\n"
  },
  {
    "path": "ru/README.md",
    "content": "# Docker Cheat Sheet\n\n**Want to improve this cheat sheet?  See the [Contributing](#contributing) section!**\n\n## Содержание\n\n* [Почему Docker](#Почему-Docker)\n* [Предпосылки](#Предпосылки)\n* [Установка](#Установка)\n* [Контейнеры](#Контейнеры)\n* [Образы](#Образы)\n* [Сеть](#Сеть)\n* [Реестр и репозиторий](#registry--repository)\n* [Dockerfile](#dockerfile)\n* [Слои](#layers)\n* [Ссылка](#links)\n* [Тома](#volumes)\n* [Отображение портов](#exposing-ports)\n* [Лучшая практика](#best-practices)\n* [Безопасность](#security)\n* [Советы](#tips)\n* [Содействие](#contributing)\n\n## Почему Docker\n\n\"С Docker разработчики могут создавать любое приложение на любом языке, используя любую инструментальную цепочку. Приложения помещаются в контейнер - становятся полностью переносимы и могут работать где угодно - на компьютерах под управлением OS X и Windows, серверах QA, работающих под управлением Ubuntu в облаке, и виртуальных машинах производственного центра обработки данных Red Hat.\n\nРазработчики могут быстро начать работу, начиная с одного из 13 000 приложений, доступных на Docker Hub. Docker управляет и отслеживает изменения и зависимости, что облегчает для системных администраторов понимание того, как работают приложения, созданные разработчиками. И с Docker Hub разработчики могут автоматизировать свой процес сборки и совместно использовать артефакты с сотрудниками через публичные или частные репозитории.\n\nDocker помогает разработчикам создавать и отправлять более качественные приложения быстрее \" -- [Что такое Docker](https://www.docker.com/what-docker#copy1)\n\n## Предпосылки\n\nЯ использую [Oh My Zsh](https://github.com/robbyrussell/oh-my-zsh) вместе с [Docker plugin](https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#docker) для автозаполнения команд docker. Возможно у вас другой подход.\n\n### Linux\n\nЯдро 3.10.x [минимальное требование](https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies) для Docker.\n\n### MacOS\n\n 10.8 “Mountain Lion” или более новый.\n\n## Установка\n\n### Linux\n\nБыстрый и простой скрипт установки, предоставляемый Docker:\n\n```\ncurl -sSL https://get.docker.com/ | sh\n```\n\nЕсли вы не хотите запускать случайный сценарий оболочки, см. [Инструкции](https://docs.docker.com/engine/installation/linux/) по установке на ваш дистрибутив.\n\nЕсли вы являетесь полноправным новичком Docker, вы должны следовать [сериям учебников](https://docs.docker.com/engine/getstarted/) сейчас.\n\n### macOS\nСкачать и установить [Docker Community Edition](https://www.docker.com/community-edition). если у вас есть Homebrew-Cask, просто введите `brew install --cask docker`.\nИли загрузите и установите [Docker Toolbox](https://docs.docker.com/toolbox/overview/).  [Docker для Mac](https://docs.docker.com/docker-for-mac/) это хорошо, но это не совсем так, как установка VirtualBox.  [\nСм. Сравнение](https://docs.docker.com/docker-for-mac/docker-toolbox/).\n\n> ** ПРИМЕЧАНИЕ ** Docker Toolbox является устаревшим. вы должны использовать Docker Community Edition, см. (Docker Toolbox)[https://docs.docker.com/toolbox/overview/]\n\nПосле установки Docker Community Edition щелкните значок докера. Затем запустите контейнер:\n\n```\ndocker run hello-world\n```\n\nВот и все, у вас есть работающий контейнер Docker.\n\n\nЕсли вы являетесь полноправным новичком докеров, вы должны, вероятно, исследовать [серию учебников] (https://docs.docker.com/engine/getstarted/) сейчас.\n\n## Контейнеры\n\n[Ваш основной изолированный процесс Докера](http://etherealmind.com/basics-docker-containers-hypervisors-coreos/). Контейнеры - это виртуальные машины, поскольку потоки относятся к процессам. Или вы можете думать о них как о chroot на стероидах.\n\n### Жизненный цикл\n\n\n* [`docker create`](https://docs.docker.com/engine/reference/commandline/create) создает контейнер, но не запускает его.\n* [`docker rename`](https://docs.docker.com/engine/reference/commandline/rename/) позволяет переименовать контейнер.\n* [`docker run`](https://docs.docker.com/engine/reference/commandline/run) создает и запускает контейнер за одну операцию.\n* [`docker rm`](https://docs.docker.com/engine/reference/commandline/rm) удаляет контейнер.\n* [`docker update`](https://docs.docker.com/engine/reference/commandline/update/) обновляет ограничения ресурсов контейнера.\n\nОбычно, если вы запускаете контейнер без параметров, он запускается и останавливается немедленно, если вы хотите его запустить, вы можете использовать команду, `docker run -td container_id` это будет использовать опцию `-t` который будет выделять псевдо-TTY сессию и `-d` который автоматически отсоединяет контейнер (запускает контейнер в фоновом режиме и показыват ID контейнера).\n\nЕсли вам нужен переходный контейнер, `docker run --rm` удалит контейнер после его остановки.\n\nЕсли вы хотите сопоставить каталог на хосте с контейнером докера, `docker run -v $HOSTDIR:$DOCKERDIR`. Также смотрите [Тома](https://github.com/wsargent/docker-cheat-sheet/#volumes).\n\nЕсли вы хотите удалить также тома, связанные с контейнером, удаление контейнера должно включать `-v` измените примерно так `docker rm -v`.\n\nСуществует также [логирование](https://docs.docker.com/engine/admin/logging/overview/) доступны для отдельных контейнеров в докерах 1.10. Чтобы запустить докер с помощью специального лог журнала (например, в syslog), используйте `docker run --log-driver=syslog`.\n\nДругим полезным вариантом является `docker run --name yourname docker_image` потому что, когда вы укажете `--name` внутри команды run это позволит вам запускать и останавливать контейнер, вызывая его с именем, которое вы указали при его создании.\n\n### Запуск и остановка\n\n* [`docker start`](https://docs.docker.com/engine/reference/commandline/start) запускает контейнер, чтобы он работал.\n* [`docker stop`](https://docs.docker.com/engine/reference/commandline/stop) останавливает запущенный контейнер.\n* [`docker restart`](https://docs.docker.com/engine/reference/commandline/restart) останавливается и запускает контейнер.\n* [`docker pause`](https://docs.docker.com/engine/reference/commandline/pause/)\nприостанавливает работу контейнера, \"замораживает\" его на месте.\n* [`docker unpause`](https://docs.docker.com/engine/reference/commandline/unpause/) снимает \"заморозку\" контейнера.\n* [`docker wait`](https://docs.docker.com/engine/reference/commandline/wait) блокирует до остановки контейнера.\n* [`docker kill`](https://docs.docker.com/engine/reference/commandline/kill) посылает SIGKILL к запущеннному контейнеру.\n* [`docker attach`](https://docs.docker.com/engine/reference/commandline/attach) будет подключаться к работающему контейнеру.\n\n\nЕсли вы хотите интегрировать контейнер с [диспетчером хостов](https://docs.docker.com/engine/admin/host_integration/), запустите демона с помощью `-r = false`, а затем используйте` docker start -a `.\n\nЕсли вы хотите открыть порты контейнера через хост, см. Раздел [раскрытие портов](#открытие-портов).\n\nПерезагрузка политик в разбитых экземплярах докеров [рассматривается здесь](http://container42.com/2014/09/30/docker-restart-policies/).\n\n#### Ограничения процессора\n\nВы можете ограничить процессор, используя либо процент от всех процессоров, либо используя определенные ядра.\n\nНапример, вы можете указать параметр [`cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint). Параметр немного странный - 1024 означает 100% CPU, поэтому, если вы хотите, чтобы контейнер занимал 50% всех ядер процессора, вы должны указать 512. См. https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/#_cpu для получения дополнительной информации:\n\n\n```\ndocker run -ti --c 512 agileek/cpuset-test\n```\nВы также можете использовать только некоторые ядра процессора, используя [`cpuset-cpus`](https://docs.docker.com/engine/reference/run/#/cpuset-constraint). См. https://agileek.github.io/docker/2014/08/06/docker-cpuset/ для получения дополнительной информации:\n\n\n```\ndocker run -ti --cpuset-cpus=0,4,6 agileek/cpuset-test\n```\nОбратите внимание, что Docker все еще может **видеть** все процессоры внутри контейнера -- он просто не использует все из них. Подробнее см. https://github.com/docker/docker/issues/20770.\n\n\n#### Ограничения памяти\n\nВы также можете установить [ограничения памяти](https://docs.docker.com/engine/reference/run/#/user-memory-constraints) на Docker:\n\n```\ndocker run -it -m 300M ubuntu:14.04 /bin/bash\n```\n\n#### Возможности\n\nВозможности Linux можно установить, используя `cap-add` и `cap-drop`.  См. https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities для подробностей.  Это должно использоваться для большей безопасности.\n\nЧтобы подключить файловую систему на основе FUSE, вам необходимо объединить оба --cap-add и --device:\n\n```\ndocker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs\n```\n\nОбеспечить доступ к одному устройству:\n\n```\ndocker run -it --device=/dev/ttyUSB0 debian bash\n```\n\nОбеспечить доступ ко всем устройствам:\n\n```\ndocker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash\n```\n\nподробнее о привилегированных контейнерах [здесь](\nhttps://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities)\n\n\n### Info\n\n* [`docker ps`](https://docs.docker.com/engine/reference/commandline/ps) показывает запущенные контейнеры.\n* [`docker logs`](https://docs.docker.com/engine/reference/commandline/logs) получает журналы из контейнера. (Вы можете использовать собственный драйвер журнала, но журналы доступны только для `json-file` и  `journald` в  1.10).\n* [`docker inspect`](https://docs.docker.com/engine/reference/commandline/inspect) просматривает всю информацию о контейнере (включая IP-адрес).\n* [`docker events`](https://docs.docker.com/engine/reference/commandline/events) получает события из контейнера.\n* [`docker port`](https://docs.docker.com/engine/reference/commandline/port) показывает открытый порт контейнера.\n* [`docker top`](https://docs.docker.com/engine/reference/commandline/top) показывает запущенные процессы в контейнере.\n* [`docker stats`](https://docs.docker.com/engine/reference/commandline/stats) показывает статистику использования ресурсов контейнеров.\n* [`docker diff`](https://docs.docker.com/engine/reference/commandline/diff) показывает измененные файлы в FS контейнера.\n\n`docker ps -a` показывает запущенные и остановленные контейнеры.\n\n`docker stats --all` показывает текущий список контейнеров.\n\n### Импорт / Экспорт\n\n* [`docker cp`](https://docs.docker.com/engine/reference/commandline/cp) копирует файлы или папки между контейнером и локальной файловой системой.\n* [`docker export`](https://docs.docker.com/engine/reference/commandline/export) экспортировать файловую систему контейнера в качестве tar-архива.\n\n### Выполнение команд\n\n* [`docker exec`](https://docs.docker.com/engine/reference/commandline/exec) для выполнения команды в контейнере.\n\n\nЧтобы войти в запущенный контейнер, присоедините новый процесс оболочки к запущенному контейнеру с именем foo, используйте:`docker exec -it foo /bin/bash`.\n\n## Образы\n\nОбразы - это просто [шаблоны для docker контейнеров](https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work).\n\n### Жизненный цикл\n\n* [`docker images`](https://docs.docker.com/engine/reference/commandline/images) показывает все образы.\n* [`docker import`](https://docs.docker.com/engine/reference/commandline/import) создает образ из архива.\n* [`docker build`](https://docs.docker.com/engine/reference/commandline/build) создает образ из Dockerfile.\n* [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit) создает образ из контейнера, временно приостанавливая его, если он запущен.\n* [`docker rmi`](https://docs.docker.com/engine/reference/commandline/rmi) удаляет образ.\n* [`docker load`](https://docs.docker.com/engine/reference/commandline/load) загружает образ из архива tar в качестве STDIN, включая образы и теги (начиная с 0.7).\n* [`docker save`](https://docs.docker.com/engine/reference/commandline/save) сохраняет образ в поток архива tar в STDOUT со всеми родительскими слоями, тегами и версиями (начиная с 0,7).\n\n### Info\n\n* [`docker history`](https://docs.docker.com/engine/reference/commandline/history) показывает историю образа.\n* [`docker tag`](https://docs.docker.com/engine/reference/commandline/tag) теги образа к имени (локальному или реестру).\n\n## Проверка версии Docker\n\nОчень важно, чтобы вы всегда знали текущую версию Docker, в которой вы сейчас работаете, в любой момент времени. Это очень полезно, потому что вы узнаете, какие функции совместимы с тем, что вы используете. Это также важно, потому что вы знаете, какие контейнеры запускать из хранилища докеров, когда вы пытаетесь получить контейнеры шаблонов. Это говорит о том, как узнать, какая версия докера у нас работает в настоящее время:\n\n\n* ['docker version'](https://docs.docker.com/engine/reference/commandline/version/)   проверьте, какая версия докера у вас запущена.\n* [docker version [OPTIONS]]\n\nПолучить версию сервера\n$ docker version --format '{{.Server.Version}}'\n\n1.8.0\nDump raw JSON data\n$ docker version --format '{{json .}}'\n\n{\"Client\":{\"Version\":\"1.8.0\",\"ApiVersion\":\"1.20\",\"GitCommit\":\"f5bae0a\",\"GoVersion\":\"go1.4.2\",\"Os\":\"linux\",\"Arch\":\"am\"}\n\n### Cleaning up\nХотя вы можете использовать команду `docker rmi` для удаления определенных образов, есть инструмент под названием [docker-gc](https://github.com/spotify/docker-gc), который будет безопасно очищать образы, которые больше не используются любыми контейнерами.\n\n### Загрузка/Сохранение образов\n\nЗагрузите образ из файла:\n```\ndocker load < my_image.tar.gz\n```\n\nСохранить существующий образ:\n```\ndocker save my_image:my_tag | gzip > my_image.tar.gz\n```\n### Импорт/Экспорт контейнера\n\nИмпортировать контейнер как образ из файла:\n```\ncat my_container.tar.gz | docker import - my_image:my_tag\n```\n\nЭкспортировать существующий контейнер:\n```\ndocker export my_container | gzip > my_container.tar.gz\n```\n\n\n### Разница между загрузкой сохраненного образа и импортом экспортированного контейнера в качестве образа\n\nЗагрузка изображения с помощью команды `load` создает новый образ, включая его историю.\nИмпорт контейнера в качестве образа с помощью команды `import` создает новый образ, исключая историю, которая приводит к меньшему размеру образов по сравнению с загрузкой образа.\n\n## Сети\nDocker имеет функцию [network](https://docs.docker.com/engine/userguide/networking/). Об этом мало что известно, поэтому это хорошее место для расширения чит-листа. Существует примечание, в котором говорится, что это хороший способ настроить контейнеры докеров, чтобы разговаривать друг с другом без использования портов. Подробнее см. [Работа с сетями](https://docs.docker.com/engine/userguide/networking/work-with-networks/).\n\n### Жизненный цикл\n\n* [`docker network create`](https://docs.docker.com/engine/reference/commandline/network_create/)\n* [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/)\n\n### Info\n\n* [`docker network ls`](https://docs.docker.com/engine/reference/commandline/network_ls/)\n* [`docker network inspect`](https://docs.docker.com/engine/reference/commandline/network_inspect/)\n\n### Connection\n\n* [`docker network connect`](https://docs.docker.com/engine/reference/commandline/network_connect/)\n* [`docker network disconnect`](https://docs.docker.com/engine/reference/commandline/network_disconnect/)\n\nВы можете указать [конкретный IP-адрес для контейнера](https://blog.jessfraz.com/post/ips-for-all-the-things/):\n\n```\n# создать новую сеть bridge с вашей подсетью и шлюзом для вашего ip-блока\ndocker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic\n\n# запустите контейнер nginx с определенным ip в этом блоке\n$ docker run --rm -it --net iptastic --ip 203.0.113.2 nginx\n\n# curl ip из любого другого места (при условии, что это общедоступный ip-блок)\n$ curl 203.0.113.2\n```\n\n## Реестр и репозиторий\n\nРепозиторий - это * размещенная * коллекция помеченных образов, которые вместе создают файловую систему для контейнера.\n\nРеестр - это * хост * - сервер, который хранит репозитории и предоставляет HTTP API для [управления загрузкой и загрузкой репозиториев](https://docs.docker.com/engine/tutorials/dockerrepos/).\n\nDocker.com размещает свой собственный [index](https://hub.docker.com/) в центральном реестре, который содержит большое количество репозиториев. Сказав это, центральный реестр докеров (не делает хорошую работу по проверке образов)(https://titanous.com/posts/docker-insecurity), и его следует избегать, если вас беспокоит безопасность.\n\n* [`docker login`](https://docs.docker.com/engine/reference/commandline/login) для входа в реестр.\n* [`docker logout`](https://docs.docker.com/engine/reference/commandline/logout) для выхода из реестра.\n* [`docker search`](https://docs.docker.com/engine/reference/commandline/search) ищет реестр для образа.\n* [`docker pull`](https://docs.docker.com/engine/reference/commandline/pull) вытаскивает образ из реестра на локальный компьютер.\n* [`docker push`](https://docs.docker.com/engine/reference/commandline/push) толкает образ в реестр с локальной машины.\n\n### Запуск локального реестра\n\nВы можете запустить локальный реестр с помощью проекта [docker distribution](https://github.com/docker/distribution) и посмотреть на [локальное развертывание](https://github.com/docker/docker.github.io/blob/master/registry/deploying.md) инструкци.\n\nТакже см. [Список рассылки](https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution).\n\n## Dockerfile\n\n[Файл конфигурации](https://docs.docker.com/engine/reference/builder/). Устанавливает контейнер Docker, когда вы запускаете на нем `docker build`. Крайне предпочтительнее `docker commit`.\n\nВот некоторые распространенные текстовые редакторы и их модули подсветки синтаксиса, которые вы могли бы использовать для создания Dockerfiles:\n* Если вы используете [jEdit](http://jedit.org), я установил модуль подсветки синтаксиса для [Dockerfile](https://github.com/wsargent/jedit-docker-mode) вы можете использовать.\n* [Sublime Text 2](https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting)\n* [Atom](https://atom.io/packages/language-docker)\n* [Vim](https://github.com/ekalinin/Dockerfile.vim)\n* [Emacs](https://github.com/spotify/dockerfile-mode)\n* [TextMate](https://github.com/docker/docker/tree/master/contrib/syntax/textmate)\n* [VS Code](https://github.com/Microsoft/vscode-docker)\n* Также см. [Docker meets the IDE](https://domeide.github.io/)\n\n### Инструкции\n\n* [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)\n* [FROM](https://docs.docker.com/engine/reference/builder/#from) Устанавливает базовое изображение для последующих инструкций.\n* [MAINTAINER (устаревший - вместо этого используйте LABEL)](https://docs.docker.com/engine/reference/builder/#maintainer-deprecated) Задайте поле Author созданных образов.\n* [RUN](https://docs.docker.com/engine/reference/builder/#run) выполнять любые команды в новом слое поверх текущего образа и фиксировать результаты.\n* [CMD](https://docs.docker.com/engine/reference/builder/#cmd) предоставлять значения по умолчанию для исполняемого контейнера.\n* [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) сообщает Docker, что контейнер прослушивает указанные сетевые порты во время выполнения. ПРИМЕЧАНИЕ: на самом деле не делает доступными порты.\n* [ENV](https://docs.docker.com/engine/reference/builder/#env) устанавливает переменную среды.\n* [ADD](https://docs.docker.com/engine/reference/builder/#add) копирует в контейнер новые файлы, каталоги или удаленный файл. Недействительный кеш. Избегайте `ADD` и вместо этого используйте` COPY`.\n* [COPY](https://docs.docker.com/engine/reference/builder/#copy) копирует в контейнер новые файлы или каталоги. Обратите внимание, что это копируется только с правами root, поэтому вы должны вручную управлять вне зависимости от настроек USER / WORKDIR. См. https://github.com/moby/moby/issues/30110\n* [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) настраивает контейнер, который будет запускаться как исполняемый файл.\n* [VOLUME](https://docs.docker.com/engine/reference/builder/#volume) создает точку монтирования для внешних томов или других контейнеров.\n* [USER](https://docs.docker.com/engine/reference/builder/#user) задает имя пользователя для следующих команд RUN / CMD / ENTRYPOINT.\n* [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) устанавливает рабочий каталог.\n* [ARG](https://docs.docker.com/engine/reference/builder/#arg) определяет переменную времени сборки.\n* [ONBUILD](https://docs.docker.com/engine/reference/builder/#onbuild) добавляет инструкцию триггера, когда изображение используется в качестве основы для другой сборки.\n* [STOPSIGNAL](https://docs.docker.com/engine/reference/builder/#stopsignal) устанавливает сигнал системного вызова, который будет отправлен в контейнер для выхода.\n* [LABEL](https://docs.docker.com/engine/userguide/labels-custom-metadata/) устанавливает сигнал системного вызова, который будет отправлен в контейнер для выхода.\n\n### Tutorial\n\n* [Учебник Flux7's Dockerfile\n](http://flux7.com/blogs/docker/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)\n\n### Примеры\n\n* [Примеры](https://docs.docker.com/engine/reference/builder/#dockerfile-examples)\n* [Рекомендации по написанию Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)\n* [Michael Crosby](http://crosbymichael.com/) has some more [Dockerfiles best practices](http://crosbymichael.com/dockerfile-best-practices.html) / [take 2](http://crosbymichael.com/dockerfile-best-practices-take-2.html).\n* [Building Good Docker Images](http://jonathan.bergknoff.com/journal/building-good-docker-images) / [Создание лучших образов docker](http://jonathan.bergknoff.com/journal/building-better-docker-images)\n* [Управление конфигурацией контейнера с метаданными](https://speakerdeck.com/garethr/managing-container-configuration-with-metadata)\n* [ Как написать отличный Dockerfiles](https://rock-it.pl/how-to-write-excellent-dockerfiles/)\n\n## Слои \n\nФайловая система с версией в Docker основана на слоях. Они похожи  на [git комиты или измекнения для файловой системы](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/).\n\n## Связи\nСсылки, как контейнеры Docker общаются друг с другом [через порты TCP/IP](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/). [Связь с Redis](https://docs.docker.com/engine/examples/running_redis_service/) и [Atlassian](https://blogs.atlassian.com/2013/11/docker-all-the-things-at-atlassian-automation-and-wiring/) показать приведенные примеры. Вы также можете разрешить [ссылки по имени хоста](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file).\n\nЭто в некоторой степени устарело [сетями определяемыми пользователем](https://docs.docker.com/engine/userguide/networking/#user-defined-networks).\n\nПРИМЕЧАНИЕ. Если вы хотите, чтобы контейнеры ТОЛЬКО связывались друг с другом по ссылкам, запустите демон docker с помощью `-icc = false`, чтобы отключить межпроцессное общение.\n\nЕсли у вас есть контейнер с именем CONTAINER (указанный `docker run -name CONTAINER`) и в Dockerfile, он имеет открытый порт:\n\n```\nEXPOSE 1337\n```\nТогда, если мы создадим еще один контейнер LINKED, например:\n\n```\ndocker run -d --link CONTAINER:ALIAS --name LINKED user/wordpress\n```\nЗатем открытые порты и псевдонимы CONTAINER будут отображаться в LINKED со следующими переменными среды:\n\n```\n$ALIAS_PORT_1337_TCP_PORT\n$ALIAS_PORT_1337_TCP_ADDR\n```\n\nИ вы можете подключиться к нему таким образом.\n\nЧтобы удалить ссылки, используйте `docker rm --link`.\n\nКак правило, связи между контейнерами Docker является подмножеством «обнаружения сервисов», что является большой проблемой, если вы планируете использовать Docker в производстве. Пожалуйста, прочитайте [The Docker Ecosystem: Service Discovery and Distributed Configuration Stores](https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores) или большей информации.\n\n## Тома\n\nТома Docker  - [свободно плавающие файловые системы](https://docs.docker.com/engine/tutorials/dockervolumes/).Они не обязательно должны быть подключены к конкретному контейнеру. Вы должны использовать тома, примонированные из [контейнеров только для данных](https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e) для переносимости. \n\n### Жизненный цикл\n\n* [`docker volume create`](https://docs.docker.com/engine/reference/commandline/volume_create/)\n* [`docker volume rm`](https://docs.docker.com/engine/reference/commandline/volume_rm/)\n\n### Info\n\n* [`docker volume ls`](https://docs.docker.com/engine/reference/commandline/volume_ls/)\n* [`docker volume inspect`](https://docs.docker.com/engine/reference/commandline/volume_inspect/)\n\nТома полезны в ситуациях, когда вы не можете использовать ссылки (которые только TCP / IP). Например, если вам нужно, чтобы два экземпляра docker обменивались данными, оставив результат в файловой системе.\n\nВы можете смонтировать их в нескольких контейнерах докеров сразу, используя `docker run --volumes-from`.\n\nПоскольку тома являются изолированными файловыми системами, они часто используются для хранения состояния из вычислений между переходными контейнерами. То есть, у вас может быть контейнер без учета состояния и переходный процесс, запускаемый из скрипта, сдуть его, а затем добавить второй экземпляр переходного контейнера, откуда он остановился.\n\n\nСм. [Расширенные тома](http://crosbymichael.com/advanced-docker-volumes.html) для больших подробностей. Container42 is [also helpful](http://container42.com/2014/11/03/docker-indepth-volumes/).\n\nYou can [map MacOS host directories as docker volumes](https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume):\n\n```\ndocker run -v /Users/wsargent/myapp/src:/src\n```\n\nYou can use remote NFS volumes if you're [feeling brave](https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume).\n\nYou may also consider running data-only containers as described [here](http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/) to provide some data portability.\n\n[Вы можете [сопоставлять каталоги хостов MacOS в виде докеровских томов]](#volumes-can-be-files)\n\n\n## Открытие портов\n\n\nExposing incoming ports through the host container is [fiddly but doable](https://docs.docker.com/engine/reference/run/#expose-incoming-ports).\n\nThis is done by mapping the container port to the host port (only using localhost interface) using `-p`:\n\n```\ndocker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage\n```\n\nYou can tell Docker that the container listens on the specified network ports at runtime by using [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose):\n\n```\nEXPOSE <CONTAINERPORT>\n```\n\nNote that EXPOSE does not expose the port itself -- only `-p` will do that. To expose the container's port on your localhost's port:\n\n```\niptables -t nat -A DOCKER -p tcp --dport <LOCALHOSTPORT> -j DNAT --to-destination <CONTAINERIP>:<PORT>\n```\n\nIf you're running Docker in Virtualbox, you then need to forward the port there as well, using [forwarded_port](https://docs.vagrantup.com/v2/networking/forwarded_ports.html). Define a range of ports in your Vagrantfile like this so you can dynamically map them:\n\n```\nVagrant.configure(VAGRANTFILE_API_VERSION) do |config|\n  ...\n\n  (49000..49900).each do |port|\n    config.vm.network :forwarded_port, :host => port, :guest => port\n  end\n\n  ...\nend\n```\n\nIf you forget what you mapped the port to on the host container, use `docker port` to show it:\n\n```\ndocker port CONTAINER $CONTAINERPORT\n```\n\n## Лучша практика\n\nThis is where general Docker best practices and war stories go:\n\n* [The Rabbit Hole of Using Docker in Automated Tests](http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/)\n* [Bridget Kromhout](https://twitter.com/bridgetkromhout) has a useful blog post on [running Docker in production](http://sysadvent.blogspot.co.uk/2014/12/day-1-docker-in-production-reality-not.html) at Dramafever.\n* There's also a best practices [blog post](http://developers.lyst.com/devops/2014/12/08/docker/) from Lyst.\n* [Building a Development Environment With Docker](https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/)\n* [Discourse in a Docker Container](https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container)\n\n## Безопасность\n\nThis is where security tips about Docker go. The Docker [security](https://docs.docker.com/engine/security/security/) page goes into more detail.\n\nFirst things first: Docker runs as root. If you are in the `docker` group, you effectively [have root access](http://reventlov.com/advisories/using-the-docker-command-to-root-the-host). If you expose the docker unix socket to a container, you are giving the container [root access to the host](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/).  \n\nDocker should not be your only defense. You should secure and harden it.\n\nFor an understanding of what containers leave exposed, you should read [Understanding and Hardening Linux Containers](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/april/ncc_group_understanding_hardening_linux_containers-1-1.pdf) by [Aaron Grattafiori](https://twitter.com/dyn___). This is a complete and comprehensive guide to the issues involved with containers, with a plethora of links and footnotes leading on to yet more useful content. The security tips following are useful if you've already hardened containers in the past, but are not a substitute for understanding.\n\n### Советы по безопасности\n\nFor greatest security, you want to run Docker inside a virtual machine. This is straight from the Docker Security Team Lead -- [slides](http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security) / [notes](http://www.projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/). Then, run with AppArmor / seccomp / SELinux / grsec etc to [limit the container permissions](http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/). See the [Docker 1.10 security features](https://blog.docker.com/2016/02/docker-engine-1-10-security/) for more details.\n\nDocker image ids are [sensitive information](https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4) and should not be exposed to the outside world. Treat them like passwords.\n\nSee the [Docker Security Cheat Sheet](https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc) by [Thomas Sjögren](https://github.com/konstruktoid): some good stuff about container hardening in there.\n\nCheck out the [docker bench security script](https://github.com/docker/docker-bench-security), download the [white papers](https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/) and subscribe to the [mailing lists](https://www.docker.com/docker-security) (unfortunately Docker does not have a unique mailing list, only dev / user).\n\nYou should start off by using a kernel with unstable patches for grsecurity / pax compiled in, such as [Alpine Linux](https://en.wikipedia.org/wiki/Alpine_Linux). If you are using grsecurity in production, you should spring for [commercial support](https://grsecurity.net/business_support.php) for the [stable patches](https://grsecurity.net/announce.php), same as you would do for RedHat. It's $200 a month, which is nothing to your devops budget.\n\nSince docker 1.11 you can easily limit the number of active processes running inside a container to prevent fork bombs. This requires a linux kernel >= 4.3 with CGROUP_PIDS=y to be in the kernel configuration.\n\n```\ndocker run --pids-limit=64\n```\n\nAlso available since docker 1.11 is the ability to prevent processes from gaining new privileges. This feature have been in the linux kernel since version 3.5. You can read more about it in [this](http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/) blog post.\n\n```\ndocker run --security-opt=no-new-privileges\n```\n\nFrom the [Docker Security Cheat Sheet](http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf) (it's in PDF which makes it hard to use, so copying below) by [Container Solutions](http://container-solutions.com/is-docker-safe-for-production/):\n\nОтключите межпроцессное взаимодействие с:\n\n```\ndocker -d --icc=false --iptables\n```\n\nУстановите контейнер только для чтения:\n\n```\ndocker run --read-only\n```\n\nПроверьте образы с помощью хэш-функции:\n\n```\ndocker pull debian@sha256:a25306f3850e1bd44541976aa7b5fd0a29be\n```\n\nУстановить тома только для чтения:\n\n```\ndocker run -v $(pwd)/secrets:/secrets:ro debian\n```\n\nОпределите и запустите пользователя в вашем файле Docker, чтобы вы не запускались как root внутри контейнера:\n\n```\nRUN groupadd -r user && useradd -r -g user user\nUSER user\n```\n\n### User Namespaces\n\nThere's also work on [user namespaces](https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/) -- it is in 1.10 but is not enabled by default.\n\nTo enable user namespaces (\"remap the userns\") in Ubuntu 15.10, [follow the blog example](https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/).\n\n### Security Videos\n\n* [Using Docker Safely](https://youtu.be/04LOuMgNj9U)\n* [Securing your applications using Docker](https://youtu.be/KmxOXmPhZbk)\n* [Container security: Do containers actually contain?](https://youtu.be/a9lE9Urr6AQ)\n* [Linux Containers: Future or Fantasy?](https://www.youtube.com/watch?v=iN6QbszB1R8)\n\n### Security Roadmap\n\nВ дорожной карте docker говорится о [поддержке seccomp]https://github.com/docker/docker/blob/master/ROADMAP.md#11-security).\nСуществует генератор политики AppArmor, называемый [bane](https://github.com/jfrazelle/bane), и они работают над [профилями безопасности](https://github.com/docker/docker/issues/17142).\n\n## Советы\n\nИсточники:\n\n* [15 Советы docker за 5 минут](http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes)\n* [CodeFresh Everyday Hacks Docker](https://codefresh.io/blog/everyday-hacks-docker/)\n\n### Prune\n\nНовые [Команды управления данными](https://github.com/docker/docker/pull/26108) Появились с Docker 1.13:\n\n* `docker system prune`\n* `docker volume prune`\n* `docker network prune`\n* `docker container prune`\n* `docker image prune`\n\n### df\n\n`docker system df` presents a summary of the space currently used by different docker objects.\n\n### Контейнер для докеров Heredoc\n\n```\ndocker build -t htop - << EOF\nFROM alpine\nRUN apk --no-cache add htop\nEOF\n```\n\n### Последние идентификаторы\n\n```\nalias dl='docker ps -l -q'\ndocker run ubuntu echo hello world\ndocker commit $(dl) helloworld\n```\n\n### Commit с командой (требуется Dockerfile)\n\n```\ndocker commit -run='{\"Cmd\":[\"postgres\", \"-too -many -opts\"]}' $(dl) postgres\n```\n\n### Получить IP-адрес\n\n```\ndocker inspect $(dl) | grep -wm1 IPAddress | cut -d '\"' -f 4\n```\n\nили установите [jq](https://stedolan.github.io/jq/):\n\n```\ndocker inspect $(dl) | jq -r '.[0].NetworkSettings.IPAddress'\n```\n\nили используя [go шаблон](https://docs.docker.com/engine/reference/commandline/inspect):\n\n```\ndocker inspect -f '{{ .NetworkSettings.IPAddress }}' <container_name>\n```\n\nили при создании обрзов из файла Docker, когда вы хотите передать аргумент построения:\n\n```\nDOCKER_HOST_IP=`ifconfig | grep -E \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1`\necho DOCKER_HOST_IP = $DOCKER_HOST_IP\ndocker build \\\n  --build-arg ARTIFACTORY_ADDRESS=$DOCKER_HOST_IP\n  -t sometag \\\n  some-directory/\n ```\n\n### Получить сопоставление портов\n\n```\ndocker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <containername>\n```\n\n### Поиск контейнеров путем регулярного выражения\n\n```\nfor i in $(docker ps -a | grep \"REGEXP_PATTERN\" | cut -f1 -d\" \"); do echo $i; done\n```\n\n### Получить настройки среды\n\n```\ndocker run --rm ubuntu env\n```\n\n### Убить запущенные контейнеры\n\n```\ndocker kill $(docker ps -q)\n```\n\n### Удалите все контейнеры (принудительные или запущенные контейнеры)\n\n```\ndocker rm -f $(docker ps -qa)\n```\n\n### Удалить старые контейнеры\n\n```\ndocker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm\n```\n\n### Удалить остановленные контейнеры\n\n```\ndocker rm -v $(docker ps -a -q -f status=exited)\n```\n\n### Удаление контейнеров после остановки\n\n```\ndocker stop $(docker ps -aq) && docker rm -v $(docker ps -aq)\n```\n\n### Удалить оборванные образы\n\n```\ndocker rmi $(docker images -q -f dangling=true)\n```\n\n### Удалить все образы\n\n```\ndocker rmi $(docker images -q)\n```\n\n### Удалить оборванные тома\n\nНачиная с Docker 1.9:\n\n```\ndocker volume rm $(docker volume ls -q -f dangling=true)\n```\n\nIn 1.9.0, the filter `dangling=false` does _not_ work - it is ignored and will list all volumes.\nВ 1.9.0, фильтр `dangling=false`  _не_ работает - он игнорируется и будет перечислять все тома.\n\n### Показать зависимости образов\n\n```\ndocker images -viz | dot -Tpng -o docker.png\n```\n\n### Похудение Docker контейнеров \n\n- Очистка APT на уровне RUN\n\nЭто должно быть сделано в том же слое, что и другие команды apt.\nВ противном случае предыдущие слои по-прежнему сохраняют исходную информацию, и ваши образы будут по-прежнему жирными.\n\n```\nRUN {apt commands} \\\n && apt-get clean \\\n && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*\n```\n\n- Сгладить образ\n```\nID=$(docker run -d image-name /bin/bash)\ndocker export $ID | docker import – flat-image-name\n```\n\n- Для резервного копирования\n```\nID=$(docker run -d image-name /bin/bash)\n(docker export $ID | gzip -c > image.tgz)\ngzip -dc image.tgz | docker import - flat-image-name\n```\n\n### Мониторинг использования ресурсов системы для запуска контейнеров\n\nЧтобы проверить использование ЦП, памяти и сетевого ввода-вывода в одном контейнере, вы можете использовать:\n\n```\ndocker stats <container>\n```\n\nДля всех контейнеров, перечисленных в id:\n\n```\ndocker stats $(docker ps -q)\n```\n\nДля всех контейнеров, перечисленных по имени:\n\n```\ndocker stats $(docker ps --format '{{.Names}}')\n```\n\nДля всех контейнеров, перечисленных по образам:\n\n```\ndocker ps -a -f ancestor=ubuntu\n```\n\nУдалить все непомеченные образы\n```\ndocker rmi $(docker images | grep “^” | awk '{split($0,a,\" \"); print a[3]}')\n```\n\nУдалить контейнер с помощью регулярного выражения\n```\ndocker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm -f\n```\nУдалить все завершенные контейнеры\n```\ndocker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')\n```\n\n### Томы могут быть файлами\n\nИмейте в виду, что вы можете монтировать файлы в виде томов. Например, вы можете ввести файл конфигурации следующим образом:\n\n``` bash\n# копировать файл из контейнера\ndocker run --rm httpd cat /usr/local/apache2/conf/httpd.conf > httpd.conf\n\n# редактировать файл\nvim httpd.conf\n\n# запускать контейнер с измененной конфигурацией\ndocker run --rm -ti -v \"$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro\" -p \"80:80\" httpd\n```\n\n## Содействие\n\nВот как внести свой вклад в этот чит-лист.\n\n### Открыть README.md\n\nClick [README.md](https://github.com/wsargent/docker-cheat-sheet/blob/master/README.md) <-- this link\n\n![Click This](../images/click.png)\n\n### Отредактировать страницу\n\n![Edit This](../images/edit.png)\n\n### Внести изменения и зафиксировать\n\n![Change This](../images/change.png)\n\n![Commit](../images/commit.png)\n"
  },
  {
    "path": "zh-cn/README.md",
    "content": "# Docker Cheat Sheet\n\n**想要一起来完善这份速查表吗？参见[贡献手册](#贡献手册contributing)部分吧！**\n\n> 译者注：以下部分链接需科学上网后使用。\n> \n> Due to GFW, varies links below could not be accessed in China Mainland.\n\n## 目录\n\n* [为何使用 Docker](#为何使用-docker)\n* [系统环境(Prerequisites)](#系统环境)\n* [安装(Installation)](#安装)\n* [容器(Containers)](#容器container)\n* [镜像(Images)](#镜像images)\n* [网络(Networks)](#网络networks)\n* [仓管中心和仓库(Registry & Repository)](#仓管中心和仓库registry--repository)\n* [Dockerfile](#dockerfile)\n* [层(Layers)](#层layers)\n* [链接(Links)](#链接links)\n* [卷标(Volumes)](#卷标volumes)\n* [暴露端口(Exposing Ports)](#暴露端口exposing-ports)\n* [最佳实践(Best Practices)](#最佳实践)\n* [安全(security)](#安全security)\n* [小贴士(Tips)](#小贴士)\n* [贡献手册(Contributing)](#贡献手册contributing)\n\n## 为何使用 Docker\n\n「通过 Docker，开发者可以使用任何语言任何工具创建任何应用。“Dockerized” 的应用是完全可移植的，能在任何地方运行 - 不管是同事的 OS X 和 Windows 笔记本，或是在云端运行的 Ubuntu QA 服务，还是在虚拟机运行的 Red Hat 产品数据中心。\n\nDocker Hub 上有 13000+ 的应用，开发者可以从中选取一个进行快速扩展开发。Docker 跟踪管理变更和依赖关系，让系统管理员能更容易理解开发人员是如何让应用运转起来的。而开发者可以通过 Docker Hub 的共有/私有仓库，构建他们的自动化编译，与其他合作者共享成果。\n\nDocker 帮助开发者更快地构建和发布高质量的应用。」—— [什么是 Docker](https://www.docker.com/what-docker/#copy1)\n\n## 系统环境\n\n我用的是 [Oh My Zsh](https://github.com/robbyrussell/oh-my-zsh) 和 [Docker 插件](https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins#docker)，它可以自动补全 Docker 命令。你的环境可能有所不同。\n\n### Linux\n\nDocker 对于 Linux 内核版本的 [最低要求](https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies) 为 `3.10.x`。\n\n### MacOS\n\n10.8「Mountain Lion」或更新版本。\n\n### 检查版本\n\n时刻关注你当前正在使用的 Docker 版本是十分重要的，这能够帮助你了解可用的特性。同时，可以让你在查找镜像时选择使用的版本。接下来让我们看看如何操作。\n\n* [`docker version`](https://docs.docker.com/engine/reference/commandline/version/) 查看你正在运行的 Docker 版本。\n\n获取 Docker 服务版本：\n\n```\n$ docker version --format '{{.Server.Version}}'\n\n1.8.0\n```\n\n你也可以输出原始的 JSON 数据：\n\n```\n$ docker version --format '{{json .}}'\n\n{\"Client\":{\"Version\":\"1.8.0\",\"ApiVersion\":\"1.20\",\"GitCommit\":\"f5bae0a\",\"GoVersion\":\"go1.4.2\",\"Os\":\"linux\",\"Arch\":\"am\"}\n```\n\n## 安装\n\n### Linux\n\nDocker 官方提供了快速、易用的安装脚本：\n\n```\ncurl -sSL https://get.docker.com/ | sh\n```\n\n如果你不想执行一个不明不白的 Shell 脚本，那么请看 [安装说明](https://docs.docker.com/engine/installation/linux/)，选择你在用的发行版本。\n\n如果你是一个 Docker 超新手，那么你应当先去看看 [系列教程](https://docs.docker.com/engine/getstarted/)。\n\n### macOS\n\n下载并安装 [Docker Community Edition](https://www.docker.com/community-edition)。如果你在使用 Homebrew-Cask，只需在命令行输入 `brew install --cask docker` 即可。下载安装 [Docker Toolbox](https://docs.docker.com/toolbox/overview/) 亦可。[Docker For Mac](https://docs.docker.com/docker-for-mac/) 很赞，但是它的安装过程与 VirtualBox 不太一样。详情请查阅 [比较](https://docs.docker.com/docker-for-mac/docker-toolbox/)。\n\n> **注意**：Docker Toolbox 已经过时。你应当使用 Docker Community Edition，详见 [Docker Toolbox](https://docs.docker.com/toolbox/overview/)\n\n安装好 Docker Community Edition 后，点击 Launchpad 内的 Docker 图标。接着即可启动容器了：\n\n```\ndocker run hello-world\n```\n\n好了，现在你有了一个运行中的 Docker 容器了。\n\n## 容器(Container)\n\n[关于 Docker 进程隔离的基础](http://etherealmind.com/basics-docker-containers-hypervisors-coreos/)。容器 (Container) 之于虚拟机 (Virtual Machine) 就好比线程之于进程。或者你可以把他们想成是「吃了类固醇的 chroots」。\n\n### 生命周期\n\n* [`docker create`](https://docs.docker.com/engine/reference/commandline/create) 创建容器但不启动它。\n* [`docker rename`](https://docs.docker.com/engine/reference/commandline/rename/) 用于重命名容器。\n* [`docker run`](https://docs.docker.com/engine/reference/commandline/run) 一键创建并同时启动该容器。\n* [`docker rm`](https://docs.docker.com/engine/reference/commandline/rm) 删除容器。\n* [`docker update`](https://docs.docker.com/engine/reference/commandline/update/) 调整容器的资源限制。\n\n通常情况下，不使用任何命令行选项启动一个容器，该容器将会立即启动并停止。若需保持其运行，你可以使用 `docker run -td container_id` 命令。选项 `-t` 表示分配一个 pseudo-TTY 会话，`-d` 表示自动将容器与终端分离（也就是说在后台运行容器，并输出容器 ID）。\n\n如果你需要一个临时容器，可使用 `docker run --rm` 会在容器停止之后删除它。\n\n如果你需要映射宿主机 (host) 的目录到 Docker 容器内，可使用 `docker run -v $HOSTDIR:$DOCKERDIR`。详见 [卷标(Volumes)](#卷标volumes) 一节。\n\n如果你想同时删除与容器相关联的卷标，那么在删除容器的时候必须包含 `-v` 选项，像这样 `docker rm -v`。\n\n从 Docker 1.10 起，其内置一套各容器独立的 [日志引擎](https://docs.docker.com/engine/admin/logging/overview/)，每个容器可以独立使用。你可以使用 `docker run --log-driver=syslog` 来自定义日志引擎（例如以上的 `syslog`）。\n\n### 启动和停止\n\n* [`docker start`](https://docs.docker.com/engine/reference/commandline/start) 启动已存在的容器。\n* [`docker stop`](https://docs.docker.com/engine/reference/commandline/stop) 停止运行中的容器。\n* [`docker restart`](https://docs.docker.com/engine/reference/commandline/restart) 重启容器。\n* [`docker pause`](https://docs.docker.com/engine/reference/commandline/pause/) 暂停运行中的容器，将其「冻结」在当前状态。\n* [`docker unpause`](https://docs.docker.com/engine/reference/commandline/unpause/) 结束容器暂停状态。\n* [`docker wait`](https://docs.docker.com/engine/reference/commandline/wait) 阻塞地等待某个运行中的容器直到停止。\n* [`docker kill`](https://docs.docker.com/engine/reference/commandline/kill) 向运行中的容器发送 SIGKILL 指令。\n* [`docker attach`](https://docs.docker.com/engine/reference/commandline/attach) 连接到运行中的容器。\n\n如果你想将容器的端口 (ports) 暴露至宿主机，请见 [暴露端口](#暴露端口exposing-ports) 一节。\n\n关于 Docker 实例崩溃后的重启策略，详见 [本文](http://container42.com/2014/09/30/docker-restart-policies/)。\n\n#### CPU 限制\n\n你可以限制 CPU 资源占用，无论是指定百分比，或是特定核心数。\n\n例如，你可以设置 [`cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint)。该配置看起来有点奇怪 -- 1024 表示 100% CPU，因此如果你希望容器使用所有 CPU 内核的 50%，应将其设置为 512：\n\n```\ndocker run -ti --c 512 agileek/cpuset-test\n```\n\n更多信息请参阅 <https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/#_cpu>。\n\n通过 [`cpuset-cpus`](https://docs.docker.com/engine/reference/run/#/cpuset-constraint) 可使用特定 CPU 内核。\n\n```\ndocker run -ti --cpuset-cpus=0,4,6 agileek/cpuset-test\n```\n\n请参阅 <https://agileek.github.io/docker/2014/08/06/docker-cpuset/> 获取更多细节以及一些不错的视频。\n\n注意，Docker 在容器内仍然能够 **看到** 全部 CPU -- 它仅仅是不使用全部而已。请参阅 <https://github.com/docker/docker/issues/20770> 获取更多细节。\n\n#### 内存限制\n\n同样，亦可给 Docker 设置 [内存限制](https://docs.docker.com/engine/reference/run/#/user-memory-constraints)：\n\n```\ndocker run -it -m 300M ubuntu:14.04 /bin/bash\n```\n\n#### 能力(Capabilities)\n\nLinux 的 Capability 可以通过使用 `cap-add` 和 `cap-drop` 设置。请参阅 <https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities> 获取更多细节。这有助于提高安全性。\n\n如需要挂载基于 FUSE 的文件系统，你需要结合 `--cap-add` 和 `--device` 使用：\n\n```\ndocker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs\n```\n\n授予对某个设备的访问权限：\n\n```\ndocker run -it --device=/dev/ttyUSB0 debian bash\n```\n\n授予对所有设备的访问权限：\n\n```\ndocker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash\n```\n\n有关容器特权的更多信息请参阅 [本文](https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities)。\n\n### 信息\n\n* [`docker ps`](https://docs.docker.com/engine/reference/commandline/ps) 查看运行中的所有容器。\n* [`docker logs`](https://docs.docker.com/engine/reference/commandline/logs) 从容器中读取日志。（你也可以使用自定义日志驱动，不过在 1.10 中，它只支持 `json-file` 和 `journald`）。\n* [`docker inspect`](https://docs.docker.com/engine/reference/commandline/inspect) 查看某个容器的所有信息（包括 IP 地址）。\n* [`docker events`](https://docs.docker.com/engine/reference/commandline/events) 从容器中获取事件 (events)。\n* [`docker port`](https://docs.docker.com/engine/reference/commandline/port) 查看容器的公开端口。\n* [`docker top`](https://docs.docker.com/engine/reference/commandline/top) 查看容器中活动进程。\n* [`docker stats`](https://docs.docker.com/engine/reference/commandline/stats) 查看容器的资源使用量统计信息。\n* [`docker diff`](https://docs.docker.com/engine/reference/commandline/diff) 查看容器文件系统中存在改动的文件。\n\n`docker ps -a` 将显示所有容器，包括运行中和已停止的。\n\n`docker stats --all` 同样将显示所有容器，默认仅显示运行中的容器。\n\n### 导入 / 导出\n\n* [`docker cp`](https://docs.docker.com/engine/reference/commandline/cp) 在容器和本地文件系统之间复制文件或目录。\n* [`docker export`](https://docs.docker.com/engine/reference/commandline/export) 将容器的文件系统打包为归档文件流 (tarball archive stream) 并输出至标准输出 (STDOUT)。\n\n### 执行命令\n\n* [`docker exec`](https://docs.docker.com/engine/reference/commandline/exec) 在容器内执行命令。\n\n例如，进入正在运行的 `foo` 容器，并连接 (attach) 到一个新的 Shell 进程：`docker exec -it foo /bin/bash`。\n\n## 镜像(Images)\n\n镜像是 [Docker 容器的模板](https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work)。\n\n### 生命周期\n\n* [`docker images`](https://docs.docker.com/engine/reference/commandline/images) 查看所有镜像。\n* [`docker import`](https://docs.docker.com/engine/reference/commandline/import) 从归档文件创建镜像。\n* [`docker build`](https://docs.docker.com/engine/reference/commandline/build) 从 Dockerfile 创建镜像。\n* [`docker commit`](https://docs.docker.com/engine/reference/commandline/commit) 为容器创建镜像，如果容器正在运行则会临时暂停。\n* [`docker rmi`](https://docs.docker.com/engine/reference/commandline/rmi) 删除镜像。\n* [`docker load`](https://docs.docker.com/engine/reference/commandline/load) 从标准输入 (STDIN) 加载归档包 (tar archive) 作为镜像，包括镜像本身和标签 (tags, 0.7 起)。\n* [`docker save`](https://docs.docker.com/engine/reference/commandline/save) 将镜像打包为归档包，并输出至标准输出 (STDOUT)，包括所有的父层、标签和版本 (parent layers, tags, versions, 0.7 起)。\n\n### 其它信息\n\n* [`docker history`](https://docs.docker.com/engine/reference/commandline/history) 查看镜像的历史记录。\n* [`docker tag`](https://docs.docker.com/engine/reference/commandline/tag) 给镜像打标签命名（本地或者仓库均可）。\n\n### 清理\n\n虽然你可以用 `docker rmi` 命令来删除指定的镜像，不过有个名为 [docker-gc](https://github.com/spotify/docker-gc) 的工具，它可以以一种安全的方式，清理掉那些不再被任何容器使用的镜像。Docker 1.13 起，使用 `docker image prune` 亦可删除未使用的镜像。参见 [清理](#清理)。\n\n### 加载 / 保存镜像\n\n从文件中加载镜像：\n```\ndocker load < my_image.tar.gz\n```\n\n保存既有镜像：\n```\ndocker save my_image:my_tag | gzip > my_image.tar.gz\n```\n\n### 导入 / 导出容器\n\n从文件中导入容器镜像：\n```\ncat my_container.tar.gz | docker import - my_image:my_tag\n```\n\n导出既有容器：\n```\ndocker export my_container | gzip > my_container.tar.gz\n```\n\n### 加载已保存的镜像 与 导入已导出为镜像的容器 的不同\n\n通过 `load` 命令来加载镜像，会创建一个新的镜像，并继承原镜像的所有历史。\n通过 `import` 将容器作为镜像导入，也会创建一个新的镜像，但并不包含原镜像的历史，因此会比使用 `load` 方式生成的镜像更小。\n\n## 网络(Networks)\n\nDocker 具备 [网络](https://docs.docker.com/engine/userguide/networking/) 功能。我并不是很了解它，所以这是一个扩展本文的好地方。文档 [使用网络](https://docs.docker.com/engine/userguide/networking/work-with-networks/) 指出，这是一种无需暴露端口即可实现 Docker 容器间通信的好方法。\n\n### 生命周期\n\n* [`docker network create`](https://docs.docker.com/engine/reference/commandline/network_create/)\n* [`docker network rm`](https://docs.docker.com/engine/reference/commandline/network_rm/)\n\n### 其它信息\n\n* [`docker network ls`](https://docs.docker.com/engine/reference/commandline/network_ls/)\n* [`docker network inspect`](https://docs.docker.com/engine/reference/commandline/network_inspect/)\n\n### 建立连接\n\n* [`docker network connect`](https://docs.docker.com/engine/reference/commandline/network_connect/)\n* [`docker network disconnect`](https://docs.docker.com/engine/reference/commandline/network_disconnect/)\n\n你可以 [为容器指定 IP 地址](https://blog.jessfraz.com/post/ips-for-all-the-things/)：\n\n```\n# 使用你自己的子网和网关创建一个桥接网络\ndocker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic\n\n# 基于以上创建的网络，运行一个 Nginx 容器并指定 IP\n$ docker run --rm -it --net iptastic --ip 203.0.113.2 nginx\n\n# 在其他地方使用 CURL 访问这个 IP（假设该 IP 为公网）\n$ curl 203.0.113.2\n```\n\n## 仓管中心和仓库(Registry & Repository)\n\n仓库 (repository) 是 *被托管(hosted)* 的已命名镜像 (tagged images) 的集合，这组镜像用于构建容器文件系统。\n\n仓管中心 (registry) 则是 *托管服务(host)* -- 用于存储仓库并提供 HTTP API，以便 [管理仓库的上传和下载](https://docs.docker.com/engine/tutorials/dockerrepos/)。\n\nDocker 官方托管着自己的 [仓管中心](https://hub.docker.com/)，包含着数量众多的仓库。不过话虽如此，这个仓管中心 [并没有很好地验证镜像](https://titanous.com/posts/docker-insecurity)，所以如果你担心安全问题的话，请尽量避免使用它。\n\n* [`docker login`](https://docs.docker.com/engine/reference/commandline/login) 登入仓管中心。\n* [`docker logout`](https://docs.docker.com/engine/reference/commandline/logout) 登出仓管中心。\n* [`docker search`](https://docs.docker.com/engine/reference/commandline/search) 从仓管中心检索镜像。\n* [`docker pull`](https://docs.docker.com/engine/reference/commandline/pull) 从仓管中心拉取镜像到本地。\n* [`docker push`](https://docs.docker.com/engine/reference/commandline/push) 从本地推送镜像到仓管中心。\n\n### 本地仓管中心\n\n你可以使用 [docker distribution](https://github.com/docker/distribution) 项目搭建本地的仓管中心，详情参阅 [本地发布 (local deploy)](https://github.com/docker/docker.github.io/blob/master/registry/deploying.md) 的介绍。\n\n科学上网后，也可以看看 [Google+ Group](https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution)。\n\n## Dockerfile\n\n当你执行 `docker build` 时，Docker 将会根据 [配置文件](https://docs.docker.com/engine/reference/builder/) 启动 Docker 容器。远优于使用 `docker commit`。\n\n以下是一些编写 Dockerfile 的常用编辑器，并链接到适配的语法高亮模块︰\n\n* 如果你在使用 [jEdit](http://jedit.org)，你可以使用我开发的 Dockerfile [语法高亮模块](https://github.com/wsargent/jedit-docker-mode)。\n* [Sublime Text 2](https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting)\n* [Atom](https://atom.io/packages/language-docker)\n* [Vim](https://github.com/ekalinin/Dockerfile.vim)\n* [Emacs](https://github.com/spotify/dockerfile-mode)\n* [TextMate](https://github.com/docker/docker/tree/master/contrib/syntax/textmate)\n* 更多信息请参阅 [Docker 遇上 IDE](https://domeide.github.io/)\n\n### 指令\n\n* [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)\n* [FROM](https://docs.docker.com/engine/reference/builder/#from) 为其他指令设置基础镜像 (Base Image)。\n* [MAINTAINER (deprecated - use LABEL instead)](https://docs.docker.com/engine/reference/builder/#maintainer-deprecated) 为生成的镜像设置作者字段。\n* [RUN](https://docs.docker.com/engine/reference/builder/#run) 在当前镜像的基础上生成一个新层并执行命令。\n* [CMD](https://docs.docker.com/engine/reference/builder/#cmd) 设置容器默认执行命令。\n* [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) 告知 Docker 容器在运行时所要监听的网络端口。注意：并没有实际上将端口设置为可访问。\n* [ENV](https://docs.docker.com/engine/reference/builder/#env) 设置环境变量。\n* [ADD](https://docs.docker.com/engine/reference/builder/#add) 将文件、目录或远程文件复制到容器中。缓存无效。请尽量用 `COPY` 代替 `ADD`。\n* [COPY](https://docs.docker.com/engine/reference/builder/#copy) 将文件或文件夹复制到容器中。注意：将使用 ROOT 用户复制文件，故无论 USER / WORKDIR 指令如何配置，你都需要手动修改其所有者（`chown`），`ADD` 也是一样。\n* [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint) 将容器设为可执行的。\n* [VOLUME](https://docs.docker.com/engine/reference/builder/#volume) 在容器内部创建挂载点 (mount point) 指向外部挂载的卷标或其他容器。\n* [USER](https://docs.docker.com/engine/reference/builder/#user) 设置随后执行 RUN / CMD / ENTRYPOINT 命令的用户名。\n* [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir) 设置工作目录 (working directory)。\n* [ARG](https://docs.docker.com/engine/reference/builder/#arg) 定义编译时 (build-time) 变量。\n* [ONBUILD](https://docs.docker.com/engine/reference/builder/#onbuild) 添加触发指令，当该镜像被作为其他镜像的基础镜像时该指令会被触发。\n* [STOPSIGNAL](https://docs.docker.com/engine/reference/builder/#stopsignal) 设置停止容器时，向容器内发送的系统调用信号 (system call signal)。\n* [LABEL](https://docs.docker.com/config/labels-custom-metadata/) 将键值对元数据 (key/value metadata) 应用到镜像、容器或是守护进程。\n\n### 教程\n\n* [Flux7's Dockerfile Tutorial](http://flux7.com/blogs/docker/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)\n\n### 例子\n\n* [Examples](https://docs.docker.com/engine/reference/builder/#dockerfile-examples)\n* [Best practices for writing Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)\n* [Michael Crosby](http://crosbymichael.com/) 还有更多的 [Dockerfiles best practices](http://crosbymichael.com/dockerfile-best-practices.html) / [take 2](http://crosbymichael.com/dockerfile-best-practices-take-2.html)\n* [Building Good Docker Images](http://jonathan.bergknoff.com/journal/building-good-docker-images) / [Building Better Docker Images](http://jonathan.bergknoff.com/journal/building-better-docker-images)\n* [Managing Container Configuration with Metadata](https://speakerdeck.com/garethr/managing-container-configuration-with-metadata)\n\n## 层(Layers)\n\nDocker 的版本化文件系统是基于层的。就像 [Git 的提交或文件变更系统](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/) 一样。\n\n## 链接(Links)\n\n链接 (links) [通过 TCP/IP 端口](https://docs.docker.com/userguide/dockerlinks/) 实现 Docker 容器之间的通讯。[Atlassian](https://blogs.atlassian.com/2013/11/docker-all-the-things-at-atlassian-automation-and-wiring/) 展示了可用的例子。你还可以 [通过主机名 (hostname) 链接](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file)。\n\n在某种意义上来说，该特性已经被 [自定义网络](https://docs.docker.com/network/) 所替代。\n\n注意: 如果你希望容器之间**只**通过链接进行通讯，在启动 Docker 守护进程时，请使用 `-icc=false` 来禁用内部进程通讯。\n\n假设你有一个名为 CONTAINER 的容器（通过 `docker run --name CONTAINER` 指定）并且在 Dockerfile 中，暴露了一个端口:\n\n```\nEXPOSE 1337\n```\n\n然后，我们创建另外一个名为 LINKED 的容器:\n\n```\ndocker run -d --link CONTAINER:ALIAS --name LINKED user/wordpress\n```\n\n然后 CONTAINER 暴露的端口和别名将会以如下的环境变量出现在 LINKED 中:\n\n```\n$ALIAS_PORT_1337_TCP_PORT\n$ALIAS_PORT_1337_TCP_ADDR\n```\n\n那么你便可以通过这种方式来连接它了。\n\n使用 `docker rm --link` 即可删除链接。\n\n通常，Docker 容器（亦可理解为「服务」）之间的链接，是「服务发现」的一个子集。如果你打算在生产中大规模使用 Docker，这将是一个很大的问题。请参阅[The Docker Ecosystem: Service Discovery and Distributed Configuration Stores](https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores) 获取更多信息。\n\n## 卷标(Volumes)\n\nDocker 的卷标 (volumes) 是 [独立的文件系统](https://docs.docker.com/engine/tutorials/dockervolumes/)。它们并非必须连接到特定的容器上。\n\n### 生命周期\n\n* [`docker volume create`](https://docs.docker.com/engine/reference/commandline/volume_create/)\n* [`docker volume rm`](https://docs.docker.com/engine/reference/commandline/volume_rm/)\n\n### 信息\n\n* [`docker volume ls`](https://docs.docker.com/engine/reference/commandline/volume_ls/)\n* [`docker volume inspect`](https://docs.docker.com/engine/reference/commandline/volume_inspect/)\n\n卷标在不能使用链接（只有 TCP/IP）的情况下非常有用。例如，如果你有两个 Docker 实例需要通讯并在文件系统上留下记录。\n\n你可以一次性将其挂载到多个 docker 容器上，通过 `docker run --volumes-from`。\n\n因为卷标是独立的文件系统，它们通常被用于存储各容器之间的瞬时状态。也就是说，你可以配置一个无状态临时容器，关掉之后，当你有第二个这种临时容器实例的时候，你可以从上一次保存的状态继续执行。\n\n查看 [卷标进阶](http://crosbymichael.com/advanced-docker-volumes.html) 来获取更多细节。[Container42](http://container42.com/2014/11/03/docker-indepth-volumes/) 非常有用。\n\n你可以 [将宿主 MacOS 的文件夹映射为 Docker 卷标](https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume)：\n\n```\ndocker run -v /Users/wsargent/myapp/src:/src\n```\n\n你也可以用远程 NFS 卷标，如果你觉得你 [有足够勇气](https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume)。\n\n还可以考虑运行一个纯数据容器，像 [这里](http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/) 所说的那样，提供可移植数据。\n\n记得，[文件也可以被挂载为卷标](#将文件挂载为卷标)。\n\n## 暴露端口(Exposing ports)\n\n通过宿主容器暴露输入端口相当 [繁琐但有效的](https://docs.docker.com/engine/reference/run/#expose-incoming-ports)。\n\n例如使用 `-p` 将容器端口映射到宿主端口上（只使用本地主机 (localhost) 接口）：\n\n```\ndocker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage\n```\n\n你可以使用 [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose) 告知 Docker，该容器在运行时监听指定的端口：\n\n```\nEXPOSE <CONTAINERPORT>\n```\n\n但是注意 EXPOSE 并不会直接暴露端口，你需要用参数 `-p` 。比如说你要在 localhost 上暴露容器的端口:\n\n```\niptables -t nat -A DOCKER -p tcp --dport <LOCALHOSTPORT> -j DNAT --to-destination <CONTAINERIP>:<PORT>\n```\n\n如果你是在 Virtualbox 中运行 Docker，那么你需要配置端口转发 (forward the port)。使用 [forwarded_port](https://docs.vagrantup.com/v2/networking/forwarded_ports.html) 在 Vagrantfile 上配置暴露的端口范围，这样你就可以动态地映射了：\n\n```\nVagrant.configure(VAGRANTFILE_API_VERSION) do |config|\n  ...\n\n  (49000..49900).each do |port|\n    config.vm.network :forwarded_port, :host => port, :guest => port\n  end\n\n  ...\nend\n```\n\n如果你忘记了将什么端口映射到宿主机上的话，可使用 `docker port` 查看：\n\n```\ndocker port CONTAINER $CONTAINERPORT\n```\n\n## 最佳实践\n\n这里有一些最佳实践，以及争论焦点：\n\n* [The Rabbit Hole of Using Docker in Automated Tests](http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/)\n* [Bridget Kromhout](https://twitter.com/bridgetkromhout) has a useful blog post on [running Docker in production](http://sysadvent.blogspot.co.uk/2014/12/day-1-docker-in-production-reality-not.html) at Dramafever.  \n* There's also a best practices [blog post](http://developers.lyst.com/devops/2014/12/08/docker/) from Lyst.\n* [A Docker Dev Environment in 24 Hours!](https://engineering.salesforceiq.com/2013/11/05/a-docker-dev-environment-in-24-hours-part-2-of-2.html)\n* [Building a Development Environment With Docker](https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/)\n* [Discourse in a Docker Container](https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container)\n\n## 安全(Security)\n\n这节准备讨论一些关于 Docker 安全性的问题。Docker 官方文档 [安全](https://docs.docker.com/articles/security/) 页面讲述了更多细节。\n\n首先第一件事：Docker 是有 root 权限的。如果你在 `docker` 组，那么你就有 [root 权限](https://web.archive.org/web/20161226211755/http://reventlov.com/advisories/using-the-docker-command-to-root-the-host)。如果你将 Docker 的 Unix Socket 暴露给容器，意味着你赋予了容器 [宿主机 root 权限](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/)。\n\nDocker 不应当作为唯一的防御措施。你应当使其更加安全可靠。\n\n为了更好地理解容器暴露了什么，可参阅由 [Aaron Grattafiori](https://twitter.com/dyn___) 编写的 [Understanding and Hardening Linux Containers](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/april/ncc_group_understanding_hardening_linux_containers-1-1.pdf)。这是一个完整全面且包含大量链接和脚注的容器问题指南，介绍了许多有用的内容。即使你已经加固过容器，以下的安全提示依然十分有帮助，但并不能代替理解的过程。\n\n### 安全提示\n\n为了最大的安全性，你应当考虑在虚拟机上运行 Docker。这是直接从 Docker 安全团队拿来的资料 -- [slides](http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security) / [notes](http://www.projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/)。之后，可使用 AppArmor、seccomp、SELinux、grsec 等来 [限制容器的权限](http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/)。更多细节，请查阅 [Docker 1.10 security features](https://blog.docker.com/2016/02/docker-engine-1-10-security/)。\n\nDocker 镜像 ID 属于 [敏感信息](https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4) 所以它不应该向外界公开。请将它们当作密码来对待。\n\n阅读由 [Thomas Sjögren](https://github.com/konstruktoid) 编写的 [Docker Security Cheat Sheet](https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc)：关于加固容器的不错的建议。\n\n查看 [Docker 安全测试脚本](https://github.com/docker/docker-bench-security)，下载 [最佳实践白皮书](https://blog.docker.com/2015/05/understanding-docker-security-and-best-practices/)。\n\n你应当远离使用非稳定版本 grsecurity / pax 的内核，比如 [Alpine Linux](https://en.wikipedia.org/wiki/Alpine_Linux)。如果在产品中用了 grsecurity，那么你应该考虑使用有 [商业支持](https://grsecurity.net/business_support.php) 的 [稳定版本](https://grsecurity.net/announce.php)，就像你对待 RedHat 那样。虽然要 $200 每月，但对于你的运维预算来说不值一提。\n\n从 Docker 1.11 开始，你可以轻松的限制在容器中可用的进程数，以防止 fork 炸弹。 这要求 Linux 内核 >= 4.3，并且要在内核配置中打开 CGROUP_PIDS=y。\n\n```\ndocker run --pids-limit=64\n```\n\n同时，你也可以限制进程再获取新权限。该功能是 Linux 内核从 3.5 版本开始就拥有的。你可以从 [这篇博客](http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/) 中阅读到更多关于这方面的内容。\n\n```\ndocker run --security-opt=no-new-privileges\n```\n\n以下内容摘选自 [Container Solutions](http://container-solutions.com/is-docker-safe-for-production/) 的 [Docker Security Cheat Sheet](http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf)（PDF 版本，难以使用，故复制至此）：\n\n关闭内部进程通讯：\n\n```\ndocker -d --icc=false --iptables\n```\n\n设置容器为只读：\n\n```\ndocker run --read-only\n```\n\n通过 hashsum 来验证卷标：\n\n```\ndocker pull debian@sha256:a25306f3850e1bd44541976aa7b5fd0a29be\n```\n\n设置卷标为只读：\n\n```\ndocker run -v $(pwd)/secrets:/secrets:ro debian\n```\n\n在 Dockerfile 中定义用户并以该用户运行，避免在容器中以 ROOT 身份操作：\n\n```\nRUN groupadd -r user && useradd -r -g user user\nUSER user\n```\n\n### 用户命名空间(User Namespaces)\n\n还可以通过使用 [用户命名空间](https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/) -- 自 1.10 版本起已内置，但默认并未启用。\n\n要在 Ubuntu 15.10 中启用用户命名空间 (remap the userns)，请 [跟着这篇博客的例子](https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/) 来做。\n\n### 安全相关视频\n\n* [Using Docker Safely](https://youtu.be/04LOuMgNj9U)\n* [Securing your applications using Docker](https://youtu.be/KmxOXmPhZbk)\n* [Container security: Do containers actually contain?](https://youtu.be/a9lE9Urr6AQ)\n* [Linux Containers: Future or Fantasy?](https://www.youtube.com/watch?v=iN6QbszB1R8)\n\n### 安全路线图\n\nDocker 的路线图提到关于 [seccomp 的支持](https://github.com/docker/docker/blob/master/ROADMAP.md#11-security)。\n一个名为 [bane](https://github.com/jfrazelle/bane) 的 AppArmor 策略生成器正在实现 [安全配置文件](https://github.com/docker/docker/issues/17142)。\n\n## 小贴士\n\n链接：\n\n* [15 Docker Tips in 5 minutes](http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes)\n* [CodeFresh Everyday Hacks Docker](https://codefresh.io/blog/everyday-hacks-docker/)\n\n### 清理\n\n最新的 [数据管理命令](https://github.com/docker/docker/pull/26108) 已在 Docker 1.13 实现：\n\n* `docker system prune`\n* `docker volume prune`\n* `docker network prune`\n* `docker container prune`\n* `docker image prune`\n\n### df 命令\n\n`docker system df` 将显示当前 Docker 各部分占用的磁盘空间。\n\n### Heredoc 声明 Docker 容器\n\n```\ndocker build -t htop - << EOF\nFROM alpine\nRUN apk --no-cache add htop\nEOF\n```\n\n### 最近一次的容器 ID\n\n```\nalias dl='docker ps -l -q'\ndocker run ubuntu echo hello world\ndocker commit $(dl) helloworld\n```\n\n### 带命令的提交（需要 Dockerfile）\n\n```\ndocker commit -run='{\"Cmd\":[\"postgres\", \"-too -many -opts\"]}' $(dl) postgres\n```\n\n### 获取 IP 地址\n\n```\ndocker inspect $(dl) | grep -wm1 IPAddress | cut -d '\"' -f 4\n```\n\n或使用 [jq](https://stedolan.github.io/jq/):\n\n```\ndocker inspect $(dl) | jq -r '.[0].NetworkSettings.IPAddress'\n```\n\n或使用 [go 模板](https://docs.docker.com/engine/reference/commandline/inspect)：\n\n```\ndocker inspect -f '{{ .NetworkSettings.IPAddress }}' <container_name>\n```\n\n或在通过 Dockerfile 构建镜像时，通过构建参数 (build argument) 传入：\n\n```\nDOCKER_HOST_IP=`ifconfig | grep -E \"([0-9]{1,3}\\.){3}[0-9]{1,3}\" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1`\necho DOCKER_HOST_IP = $DOCKER_HOST_IP\ndocker build \\\n  --build-arg ARTIFACTORY_ADDRESS=$DOCKER_HOST_IP \n  -t sometag \\\n  some-directory/\n```\n\n### 获取端口映射\n\n```\ndocker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <containername>\n```\n\n### 通过正则匹配容器\n\n```\nfor i in $(docker ps -a | grep \"REGEXP_PATTERN\" | cut -f1 -d\" \"); do echo $i; done`\n```\n\n### 获取环境变量配置\n\n```\ndocker run --rm ubuntu env\n```\n\n### 强行终止运行中的容器\n\n```\ndocker kill $(docker ps -q)\n```\n\n### 删除所有容器（强行删除！无论容器运行或停止）\n\n```\ndocker rm -f $(docker ps -qa)\n```\n\n### 删除旧容器\n\n```\ndocker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm\n```\n\n### 删除已停止的容器\n\n```\ndocker rm -v `docker ps -a -q -f status=exited`\n```\n\n### 停止并删除容器\n\n```\ndocker stop $(docker ps -aq) && docker rm -v $(docker ps -aq)\n```\n\n### 删除无用 (dangling) 的镜像\n\n```\ndocker rmi $(docker images -q -f dangling=true)\n```\n\n### 删除所有镜像\n\n```\ndocker rmi $(docker images -q)\n```\n\n### 删除无用 (dangling) 的卷标\n\nDocker 1.9 版本起：\n\n```\ndocker volume rm $(docker volume ls -q -f dangling=true)\n```\n\n1.9.0 中，参数 `dangling=false` 居然 _没_ 用 - 它会被忽略然后列出所有的卷标。\n\n### 查看镜像依赖\n\n```\ndocker images -viz | dot -Tpng -o docker.png\n```\n\n### Docker 容器瘦身\n\n- 在某层 (RUN layer) 清理 APT\n\n这应当和其他 apt 命令在同一层中完成。\n否则，前面的层将会保持原有信息，而你的镜像则依旧臃肿。\n\n```\nRUN {apt commands} \\\n  && apt-get clean \\  \n  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*\n```\n\n- 压缩镜像\n```\nID=$(docker run -d image-name /bin/bash)\ndocker export $ID | docker import – flat-image-name\n```\n\n- 备份\n```\nID=$(docker run -d image-name /bin/bash)\n(docker export $ID | gzip -c > image.tgz)\ngzip -dc image.tgz | docker import - flat-image-name\n```\n\n### 监视运行中容器的系统资源利用率\n\n检查某个容器的 CPU、内存以及网络 I/O 使用情况，你可以：\n```\ndocker stats <container>\n```\n\n按 ID 列出所有容器：\n```\ndocker stats $(docker ps -q)\n```\n\n按名称列出所有容器：\n```\ndocker stats $(docker ps --format '{{.Names}}')\n```\n\n按指定镜像名称列出所有容器：\n```\ndocker ps -a -f ancestor=ubuntu\n```\n\n删除所有未标签命名 (untagged) 的容器：\n```\ndocker rmi $(docker images | grep “^” | awk '{split($0,a,\" \"); print a[3]}')\n```\n\n通过正则匹配删除指定容器：\n```\ndocker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm -f\n```\n\n删除所有已退出 (exited) 的容器：\n```\ndocker rm -f $(docker ps -a | grep Exit | awk '{ print $1 }')\n```\n\n### 将文件挂载为卷标\n\n文件也可以被挂载为卷标。例如你可以仅仅注入单个配置文件：\n\n``` bash\n# 从容器复制文件\ndocker run --rm httpd cat /usr/local/apache2/conf/httpd.conf > httpd.conf\n\n# 编辑文件\nvim httpd.conf\n\n# 挂载修改后的配置启动容器\ndocker run --rm -ti -v \"$PWD/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro\" -p \"80:80\" httpd\n```\n\n## 贡献手册(Contributing)\n\n以下是如何贡献本速查表的说明。\n\n### 打开 README.md\n\n点击 [README.md](https://github.com/wsargent/docker-cheat-sheet/blob/master/README.md) <-- 这个链接\n\n![点击](../images/click.png)\n\n### 编辑页面\n\n![编辑](../images/edit.png)\n\n### 更新并提交\n\n![修改](../images/change.png)\n\n![提交](../images/commit.png)\n"
  }
]