Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions content/get-started/workshop/02_our_app.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ Before you can run the application, you need to get the application source code
│ ├── README.md
│ ├── spec/
│ ├── src/
│ └── yarn.lock
```

## Build the app's image
Expand All @@ -58,18 +57,21 @@ To build the image, you'll need to use a Dockerfile. A Dockerfile is simply a te
```dockerfile
# syntax=docker/dockerfile:1

FROM node:lts-alpine
FROM node:24-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
RUN npm install --omit=dev
CMD ["node", "src/index.js"]
EXPOSE 3000
```
This Dockerfile does the following:

This Dockerfile starts off with a `node:lts-alpine` base image, a
light-weight Linux image that comes with Node.js and the Yarn package
manager pre-installed. It copies all of the source code into the image,
installs the necessary dependencies, and starts the application.
- Uses `node:24-alpine` as the base image, a lightweight Linux image with Node.js pre-installed
- Sets `/app` as the working directory
- Copies source code into the image
- Installs the necessary dependencies
- Specifies the command to start the application
- Documents that the app listens on port 3000

2. Build the image using the following commands:

Expand All @@ -85,9 +87,9 @@ To build the image, you'll need to use a Dockerfile. A Dockerfile is simply a te
$ docker build -t getting-started .
```

The `docker build` command uses the Dockerfile to build a new image. You might have noticed that Docker downloaded a lot of "layers". This is because you instructed the builder that you wanted to start from the `node:lts-alpine` image. But, since you didn't have that on your machine, Docker needed to download the image.
The `docker build` command uses the Dockerfile to build a new image. You might have noticed that Docker downloaded a lot of "layers". This is because you instructed the builder that you wanted to start from the `node:24-alpine` image. But, since you didn't have that on your machine, Docker needed to download the image.

After Docker downloaded the image, the instructions from the Dockerfile copied in your application and used `yarn` to install your application's dependencies. The `CMD` directive specifies the default command to run when starting a container from this image.
After Docker downloaded the image, the instructions from the Dockerfile copied in your application and used `npm` to install your application's dependencies.

Finally, the `-t` flag tags your image. Think of this as a human-readable name for the final image. Since you named the image `getting-started`, you can refer to that image when you run a container.

Expand Down
50 changes: 1 addition & 49 deletions content/get-started/workshop/04_sharing_app.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,55 +81,7 @@ Let's try to push the image to Docker Hub.

## Run the image on a new instance

Now that your image has been built and pushed into a registry, try running your app on a brand
new instance that has never seen this container image. To do this, you will use Play with Docker.

> [!NOTE]
>
> Play with Docker uses the amd64 platform. If you are using an ARM based Mac with Apple silicon, you will need to rebuild the image to be compatible with Play with Docker and push the new image to your repository.
>
> To build an image for the amd64 platform, use the `--platform` flag.
> ```console
> $ docker build --platform linux/amd64 -t YOUR-USER-NAME/getting-started .
> ```
>
> Docker buildx also supports building multi-platform images. To learn more, see [Multi-platform images](/manuals/build/building/multi-platform.md).


1. Open your browser to [Play with Docker](https://labs.play-with-docker.com/).

2. Select **Login** and then select **docker** from the drop-down list.

3. Sign in with your Docker Hub account and then select **Start**.

4. Select the **ADD NEW INSTANCE** option on the left side bar. If you don't see it, make your browser a little wider. After a few seconds, a terminal window opens in your browser.

![Play with Docker add new instance](images/pwd-add-new-instance.webp)

5. In the terminal, start your freshly pushed app.

```console
$ docker run -dp 0.0.0.0:3000:3000 YOUR-USER-NAME/getting-started
```

You should see the image get pulled down and eventually start up.

> [!TIP]
>
> You may have noticed that this command binds the port mapping to a
> different IP address. Previous `docker run` commands published ports to
> `127.0.0.1:3000` on the host. This time, you're using `0.0.0.0`.
>
> Binding to `127.0.0.1` only exposes a container's ports to the loopback
> interface. Binding to `0.0.0.0`, however, exposes the container's port
> on all interfaces of the host, making it available to the outside world.
>
> For more information about how port mapping works, see
> [Networking](/manuals/engine/network/_index.md#published-ports).

6. Select the 3000 badge when it appears.

If the 3000 badge doesn't appear, you can select **Open Port** and specify `3000`.
Now that your image has been built and pushed into a registry, you can run your app on any machine that has Docker installed. Try pulling and running your image on another computer or a cloud instance.

## Summary

Expand Down
58 changes: 29 additions & 29 deletions content/get-started/workshop/06_bind_mounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@ filesystem you can share with containers. For details about accessing the settin
```console
root@ac1237fad8db:/# cd src
root@ac1237fad8db:/src# ls
Dockerfile node_modules package.json spec src yarn.lock
Dockerfile node_modules package.json package-lock.json spec src
```

6. Create a new file named `myfile.txt`.

```console
root@ac1237fad8db:/src# touch myfile.txt
root@ac1237fad8db:/src# ls
Dockerfile myfile.txt node_modules package.json spec src yarn.lock
Dockerfile myfile.txt node_modules package.json package-lock.json spec src
```

7. Open the `getting-started-app` directory on the host and observe that the
Expand All @@ -136,17 +136,17 @@ filesystem you can share with containers. For details about accessing the settin
│ ├── myfile.txt
│ ├── node_modules/
│ ├── package.json
│ ├── package-lock.json
│ ├── spec/
│ ├── src/
│ └── yarn.lock
│ └── src/
```

8. From the host, delete the `myfile.txt` file.
9. In the container, list the contents of the `app` directory once more. Observe that the file is now gone.

```console
root@ac1237fad8db:/src# ls
Dockerfile node_modules package.json spec src yarn.lock
Dockerfile node_modules package.json package-lock.json spec src
```

10. Stop the interactive container session with `Ctrl` + `D`.
Expand Down Expand Up @@ -181,8 +181,8 @@ You can use the CLI or Docker Desktop to run your container with a bind mount.
```console
$ docker run -dp 127.0.0.1:3000:3000 \
-w /app --mount type=bind,src="$(pwd)",target=/app \
node:lts-alpine \
sh -c "yarn install && yarn run dev"
node:24-alpine \
sh -c "npm install && npm run dev"
```

The following is a breakdown of the command:
Expand All @@ -192,11 +192,11 @@ You can use the CLI or Docker Desktop to run your container with a bind mount.
command will run from
- `--mount type=bind,src="$(pwd)",target=/app` - bind mount the current
directory from the host into the `/app` directory in the container
- `node:lts-alpine` - the image to use. Note that this is the base image for
- `node:24-alpine` - the image to use. Note that this is the base image for
your app from the Dockerfile
- `sh -c "yarn install && yarn run dev"` - the command. You're starting a
shell using `sh` (alpine doesn't have `bash`) and running `yarn install` to
install packages and then running `yarn run dev` to start the development
- `sh -c "npm install && npm run dev"` - the command. You're starting a
shell using `sh` (alpine doesn't have `bash`) and running `npm install` to
install packages and then running `npm run dev` to start the development
server. If you look in the `package.json`, you'll see that the `dev` script
starts `nodemon`.

Expand Down Expand Up @@ -227,8 +227,8 @@ You can use the CLI or Docker Desktop to run your container with a bind mount.
```powershell
$ docker run -dp 127.0.0.1:3000:3000 `
-w /app --mount "type=bind,src=$pwd,target=/app" `
node:lts-alpine `
sh -c "yarn install && yarn run dev"
node:24-alpine `
sh -c "npm install && npm run dev"
```

The following is a breakdown of the command:
Expand All @@ -238,11 +238,11 @@ You can use the CLI or Docker Desktop to run your container with a bind mount.
command will run from
- `--mount "type=bind,src=$pwd,target=/app"` - bind mount the current
directory from the host into the `/app` directory in the container
- `node:lts-alpine` - the image to use. Note that this is the base image for
- `node:24-alpine` - the image to use. Note that this is the base image for
your app from the Dockerfile
- `sh -c "yarn install && yarn run dev"` - the command. You're starting a
shell using `sh` (alpine doesn't have `bash`) and running `yarn install` to
install packages and then running `yarn run dev` to start the development
- `sh -c "npm install && npm run dev"` - the command. You're starting a
shell using `sh` (alpine doesn't have `bash`) and running `npm install` to
install packages and then running `npm run dev` to start the development
server. If you look in the `package.json`, you'll see that the `dev` script
starts `nodemon`.

Expand Down Expand Up @@ -273,8 +273,8 @@ You can use the CLI or Docker Desktop to run your container with a bind mount.
```console
$ docker run -dp 127.0.0.1:3000:3000 ^
-w /app --mount "type=bind,src=%cd%,target=/app" ^
node:lts-alpine ^
sh -c "yarn install && yarn run dev"
node:24-alpine ^
sh -c "npm install && npm run dev"
```

The following is a breakdown of the command:
Expand All @@ -284,11 +284,11 @@ You can use the CLI or Docker Desktop to run your container with a bind mount.
command will run from
- `--mount "type=bind,src=%cd%,target=/app"` - bind mount the current
directory from the host into the `/app` directory in the container
- `node:lts-alpine` - the image to use. Note that this is the base image for
- `node:24-alpine` - the image to use. Note that this is the base image for
your app from the Dockerfile
- `sh -c "yarn install && yarn run dev"` - the command. You're starting a
shell using `sh` (alpine doesn't have `bash`) and running `yarn install` to
install packages and then running `yarn run dev` to start the development
- `sh -c "npm install && npm run dev"` - the command. You're starting a
shell using `sh` (alpine doesn't have `bash`) and running `npm install` to
install packages and then running `npm run dev` to start the development
server. If you look in the `package.json`, you'll see that the `dev` script
starts `nodemon`.

Expand Down Expand Up @@ -319,8 +319,8 @@ You can use the CLI or Docker Desktop to run your container with a bind mount.
```console
$ docker run -dp 127.0.0.1:3000:3000 \
-w //app --mount type=bind,src="/$(pwd)",target=/app \
node:lts-alpine \
sh -c "yarn install && yarn run dev"
node:24-alpine \
sh -c "npm install && npm run dev"
```

The following is a breakdown of the command:
Expand All @@ -330,11 +330,11 @@ You can use the CLI or Docker Desktop to run your container with a bind mount.
command will run from
- `--mount type=bind,src="/$(pwd)",target=/app` - bind mount the current
directory from the host into the `/app` directory in the container
- `node:lts-alpine` - the image to use. Note that this is the base image for
- `node:24-alpine` - the image to use. Note that this is the base image for
your app from the Dockerfile
- `sh -c "yarn install && yarn run dev"` - the command. You're starting a
shell using `sh` (alpine doesn't have `bash`) and running `yarn install` to
install packages and then running `yarn run dev` to start the development
- `sh -c "npm install && npm run dev"` - the command. You're starting a
shell using `sh` (alpine doesn't have `bash`) and running `npm install` to
install packages and then running `npm run dev` to start the development
server. If you look in the `package.json`, you'll see that the `dev` script
starts `nodemon`.

Expand Down
24 changes: 13 additions & 11 deletions content/get-started/workshop/07_multi_container.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ You can now start your dev-ready container.
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:lts-alpine \
sh -c "yarn install && yarn run dev"
node:24-alpine \
sh -c "npm install && npm run dev"
```

{{< /tab >}}
Expand All @@ -234,8 +234,8 @@ You can now start your dev-ready container.
-e MYSQL_USER=root `
-e MYSQL_PASSWORD=secret `
-e MYSQL_DB=todos `
node:lts-alpine `
sh -c "yarn install && yarn run dev"
node:24-alpine `
sh -c "npm install && npm run dev"
```

{{< /tab >}}
Expand All @@ -250,8 +250,8 @@ You can now start your dev-ready container.
-e MYSQL_USER=root ^
-e MYSQL_PASSWORD=secret ^
-e MYSQL_DB=todos ^
node:lts-alpine ^
sh -c "yarn install && yarn run dev"
node:24-alpine ^
sh -c "npm install && npm run dev"
```

{{< /tab >}}
Expand All @@ -265,8 +265,8 @@ You can now start your dev-ready container.
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:lts-alpine \
sh -c "yarn install && yarn run dev"
node:24-alpine \
sh -c "npm install && npm run dev"
```

{{< /tab >}}
Expand All @@ -276,11 +276,13 @@ You can now start your dev-ready container.
using the mysql database.

```console
$ nodemon src/index.js
[nodemon] 2.0.20
[nodemon] 3.1.11
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,cjs,json
[nodemon] starting `node src/index.js`
Waiting for mysql:3306.
Connected!
Connected to mysql db at host mysql
Listening on port 3000
```
Expand Down
30 changes: 15 additions & 15 deletions content/get-started/workshop/08_using_compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ In the `getting-started-app` directory, create a file named `compose.yaml`.
│ ├── compose.yaml
│ ├── node_modules/
│ ├── package.json
│ ├── package-lock.json
│ ├── spec/
│ ├── src/
│ └── yarn.lock
│ └── src/
```

## Define the app service
Expand All @@ -46,8 +46,8 @@ $ docker run -dp 127.0.0.1:3000:3000 \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:lts-alpine \
sh -c "yarn install && yarn run dev"
node:24-alpine \
sh -c "npm install && npm run dev"
```

You'll now define this service in the `compose.yaml` file.
Expand All @@ -58,25 +58,25 @@ You'll now define this service in the `compose.yaml` file.
```yaml
services:
app:
image: node:lts-alpine
image: node:24-alpine
```

2. Typically, you will see `command` close to the `image` definition, although there is no requirement on ordering. Add the `command` to your `compose.yaml` file.

```yaml
services:
app:
image: node:lts-alpine
command: sh -c "yarn install && yarn run dev"
image: node:24-alpine
command: sh -c "npm install && npm run dev"
```

3. Now migrate the `-p 127.0.0.1:3000:3000` part of the command by defining the `ports` for the service.

```yaml
services:
app:
image: node:lts-alpine
command: sh -c "yarn install && yarn run dev"
image: node:24-alpine
command: sh -c "npm install && npm run dev"
ports:
- 127.0.0.1:3000:3000
```
Expand All @@ -89,8 +89,8 @@ You'll now define this service in the `compose.yaml` file.
```yaml
services:
app:
image: node:lts-alpine
command: sh -c "yarn install && yarn run dev"
image: node:24-alpine
command: sh -c "npm install && npm run dev"
ports:
- 127.0.0.1:3000:3000
working_dir: /app
Expand All @@ -103,8 +103,8 @@ You'll now define this service in the `compose.yaml` file.
```yaml
services:
app:
image: node:lts-alpine
command: sh -c "yarn install && yarn run dev"
image: node:24-alpine
command: sh -c "npm install && npm run dev"
ports:
- 127.0.0.1:3000:3000
working_dir: /app
Expand Down Expand Up @@ -185,8 +185,8 @@ At this point, your complete `compose.yaml` should look like this:
```yaml
services:
app:
image: node:lts-alpine
command: sh -c "yarn install && yarn run dev"
image: node:24-alpine
command: sh -c "npm install && npm run dev"
ports:
- 127.0.0.1:3000:3000
working_dir: /app
Expand Down
Loading