docker/getting-started: the official Docker tutorial you run as a container
Getting started with Docker
At a glance
- What is it?
- The docker/getting-started repository is Docker's beginner tutorial, shipped as a runnable container image and a mkdocs site. It is a teaching artifact, not a toolkit, and the repo's own contribution rules say so.
- Who is it for?
- Adopt docker/getting-started if you are onboarding engineers who have never built an image, or if you want a self-hosted teaching page on an internal host. Do not adopt it as a reference architecture: the Dockerfile exists to publish a tutorial, not to model a production build, and the pinned mkdocs stack is from an older generation.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 109 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What docker/getting-started actually is, and who it is for
This repository is the source of Docker's introductory tutorial. The README states the intent plainly: it was written to help people get up and running with containers, and it is designed to work with Docker Desktop. The scope list is a beginner's path through container concepts: running a first container, building containers, learning what containers are, running and removing them, volumes for persistence, bind mounts for development, networking for multi-container applications, Compose for defining and sharing applications, image layer caching, and multi-stage builds.
The audience is narrow on purpose. The Contributing section says the maintainers want to keep the tutorial scoped to newcomers, and that they may reject ideas for more advanced requests. That is an unusual thing to publish, and it is worth taking at face value. If you already know why a bind mount differs from a named volume, this repository has little to teach you. It is a first-week document, not a migration guide and not a production pattern library.
How the tutorial is built and served: mkdocs, nginx and a zip
The repository layout shows two separate concerns. The docs/ directory plus mkdocs.yml and requirements.txt produce the written tutorial. The app/ directory holds a JavaScript project with its own package.json, yarn.lock, spec and src, and the Dockerfile treats it as the interactive part of the tutorial.
The Dockerfile is a multi-stage build, and reading it is the fastest way to understand the delivery. A python:alpine stage installs requirements.txt. A node:18-alpine stage copies app/package.json, app/yarn.lock, app/spec and app/src, then a test stage runs yarn install --immutable followed by yarn test. A separate stage copies the tested app back out and zips it into /app.zip. A build stage runs mkdocs build, and the final nginx:alpine stage copies the built site into /usr/share/nginx/html and the zip into /usr/share/nginx/html/assets/app.zip.
That is the whole data flow: Markdown becomes static HTML through mkdocs, the tested JavaScript bundle becomes a downloadable zip, and nginx serves both. The dev target skips all of it and runs mkdocs serve on 0.0.0.0:8000 with the working directory mounted.
One detail stands out. The Dockerfile pins node:18-alpine while the final image is nginx:alpine, and the base stages use --platform=$BUILDPLATFORM while the nginx stage uses --platform=$TARGETPLATFORM. That split is deliberate for multi-architecture publishing, and it is the most advanced thing in the file. The tutorial itself does not explain it.
Running the tutorial in one command
The README gives a single command, and it assumes Docker Desktop is already installed. The container runs detached, publishes port 80 on the host, and serves the tutorial. After it starts, the README says to open a browser at http://localhost.
docker run -d -p 80:80 docker/getting-startedIf something else already listens on port 80, the run fails. Map a different host port instead, for example -p 8080:80, and open http://localhost:8080. The README does not document that variation, but the published port is the only thing that changes.
The repository also carries a docker-compose.yml for editing the tutorial itself. It builds the dev target of the local Dockerfile, publishes 8000:8000, and bind-mounts the repository root into /app, so edits to docs/ appear without a rebuild.
docker compose upThe dev container's command is mkdocs serve -a 0.0.0.0:8000, so the browser target is http://localhost:8000. This is the path for anyone fixing a typo or adding a page. Note that the compose file sets version: "3.7", and the docs service builds from the Dockerfile's dev stage rather than pulling an image.
The pinned mkdocs stack is the real constraint
requirements.txt pins five packages: mkdocs==1.3.0, mkdocs-material==4.6.3, mkdocs-minify-plugin==0.2.3, pygments==2.7.4 and pymdown-extensions==7.0. Every one of them is an exact pin with no range.
Exact pins make the build reproducible, which is why the tutorial site looks the same today as when it was published. They also freeze the toolchain. mkdocs-material 4.6.3 is several major versions behind what the theme ships now, and a contributor who wants a modern Markdown extension has to change requirements.txt and rebuild the whole image to find out whether it still works. The repository does not document a dependency upgrade process, and there are no retrieved releases, so there is no changelog to consult about when or why these pins move.
The Dockerfile makes this worse in a small way: the base stage copies only requirements.txt before running pip install, so the layer caches well and stays cached. A version bump invalidates that layer and reinstalls everything. For a tutorial that changes rarely, that is an acceptable trade. For anyone treating this repository as a template for their own documentation site, it is a maintenance liability they should decide about deliberately.
Why this is the wrong tool for a production reference
The most common misreading of docker/getting-started is treating its Dockerfile as an example to copy. It is not. The file's job is to publish a website and a downloadable zip, and every stage serves that goal. The final image is nginx:alpine serving static HTML plus an assets/app.zip file. There is no application server, no configuration management, no health check, and no signal handling beyond what nginx provides.
The app-zip-creator stage is a good illustration. It copies package.json, yarn.lock, spec and src into a fresh stage, installs zip with apk, and zips /app. That is a packaging step for a download link, not a deployment artifact. Copying it into a service repository would give you a zip file and nothing to run it with.
There is a second mismatch. The tutorial is designed to work with Docker Desktop, per the README. Teams running Docker Engine on Linux servers, or Podman, or a rootless setup, will find the environment differs from what the screenshots and instructions assume. The repository does not document those environments, and the README does not claim to.
Finally, the contribution policy is a real gate. The README asks contributors to open an issue before working on an idea, and states that advanced requests may be rejected. If your goal is to extend this tutorial with your organization's internal container standards, you are working against the project's stated scope, and you should fork rather than send a pull request.
Alternatives, and where the difference actually lies
The obvious alternative is Docker's own documentation site, which is not this repository. It is maintained separately, covers topics beyond the beginner path, and is not something you run locally. The difference in approach is delivery, not content: docker/getting-started gives you a container you can start on your own machine and a repository you can edit, while the documentation site gives you current material that you read in a browser and cannot version alongside your own notes.
A second alternative is writing your own onboarding page in whatever static site generator your team already uses. That trades the maintained beginner curriculum for full control over scope. The cost is that you now own the explanation of volumes, bind mounts, networking and multi-stage builds, and you will be updating it as Docker changes. This repository hands you that curriculum already written, at the price of a pinned toolchain and a scope the maintainers deliberately keep narrow.
A third option is to skip the tutorial and have new engineers work through a real internal service's Dockerfile. That is faster for people who learn by reading code, and it fails for people who have never run a container. The order matters more than the choice: run the tutorial first, then read a real Dockerfile.
Licence and the cost of keeping it current
The repository is licensed Apache-2.0, which permits commercial use, modification and redistribution provided the licence and notices are preserved. If you fork the tutorial and republish it internally, keep the LICENSE file and note what you changed. This is a description of the licence text, not legal advice; route anything unusual through your own counsel.
The upgrade cost is concentrated in requirements.txt. Because every dependency is an exact pin, there is no automatic drift and no dependabot-style churn visible in the repository layout. The cost appears when you want a change: bumping mkdocs-material means checking the mkdocs.yml configuration against the new theme's options, and bumping pymdown-extensions means checking the Markdown extensions the docs rely on. The repository does not document which of those are load-bearing.
For the JavaScript side, the Dockerfile runs yarn install --immutable against a committed yarn.lock, which means the build fails rather than silently resolving a new version. That is the right default for a published tutorial and it means app dependency updates are explicit commits, not surprises. The last push to the repository was on 2026-06-12, so the project has been touched within the last few months.
Editorial conclusion
Adopt docker/getting-started if you are onboarding engineers who have never built an image, or if you want a self-hosted teaching page on an internal host. Do not adopt it as a reference architecture: the Dockerfile exists to publish a tutorial, not to model a production build, and the pinned mkdocs stack is from an older generation. Verify first that port 80 is free on the host you intend to use, and read the Contributing section before you plan any content changes, because the maintainers ask for an issue before work begins and say they may reject advanced material.
Frequently asked questions
What is docker/getting-started?
It is Docker's beginner tutorial, stored as a repository and published as a container image. The README says it is designed to work with Docker Desktop and covers running, building and removing containers, volumes, bind mounts, networking, Compose, layer caching and multi-stage builds.
How do I run the docker/getting-started tutorial?
Install Docker Desktop, then run docker run -d -p 80:80 docker/getting-started and open http://localhost in a browser. If port 80 is taken, publish a different host port and change the URL to match.
How do I edit the docker/getting-started tutorial locally?
Use the repository's docker-compose.yml, which builds the Dockerfile's dev stage, publishes 8000:8000 and bind-mounts the repository root into /app. Running docker compose up starts mkdocs serve on 0.0.0.0:8000, so edits under docs/ appear without a rebuild.
Can I contribute new content to docker/getting-started?
The README asks you to open an issue before working on an idea, and states that the tutorial is deliberately scoped to newcomers. It also says ideas for more advanced requests may be rejected, so confirm the direction before writing.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/docker-getting-started)