diff --git a/06-building-container-images/Makefile b/06-building-container-images/Makefile index e0a9135..6286c83 100644 --- a/06-building-container-images/Makefile +++ b/06-building-container-images/Makefile @@ -1,19 +1,3 @@ -.PHONY: compose-build -compose-build: - docker compose build - -.PHONY: compose-up -compose-up: - docker compose up - -.PHONY: compose-up-build -compose-up-build: - docker compose up --build - -.PHONY: compose-down -compose-down: - docker compose down - .PHONY: build-sample build-sample: DOCKER_BUILDKIT=1 docker build \ @@ -35,24 +19,6 @@ build-multiarch: --push \ . -define ENTRYPOINT_CMD_DESCRIPTION -############################## - -See Dockerfile.sample for image definition. - -This series of docker run commands is meant -to help you understand the interaction between -CMD and ENTRYPOINT. - -The image has the following: - - ENTRYPOINT [ "echo", "Hey Team πŸ‘‹ (entrypoint)" ] - CMD [ "+ (cmd)" ] - -############################## -endef -export ENTRYPOINT_CMD_DESCRIPTION - .PHONY: run-sample-entrypoint-cmd run-sample-entrypoint-cmd: build-sample @echo "$$ENTRYPOINT_CMD_DESCRIPTION" @@ -70,4 +36,24 @@ run-sample-entrypoint-cmd: build-sample @echo "##############################" @echo "Overriden entrypoint with arguments (CMD is ignored):" - docker run --entrypoint echo sample "Hey Team πŸ‘‹ (Overriden entrypoint + arguments)" \ No newline at end of file + docker run --entrypoint echo sample "Hey Team πŸ‘‹ (Overriden entrypoint + arguments)" + +define ENTRYPOINT_CMD_DESCRIPTION + +βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ… + +See Dockerfile.sample for image definition. + +This series of docker run commands is meant +to help you understand the interaction between +CMD and ENTRYPOINT. + +The image has the following: + + ENTRYPOINT [ "echo", "Hey Team πŸ‘‹ (entrypoint)" ] + CMD [ "+ (cmd)" ] + +βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ…βœ… + +endef +export ENTRYPOINT_CMD_DESCRIPTION \ No newline at end of file diff --git a/06-building-container-images/client-react/Dockerfile.5 b/06-building-container-images/client-react/Dockerfile.5 index 2c94674..6be8c04 100644 --- a/06-building-container-images/client-react/Dockerfile.5 +++ b/06-building-container-images/client-react/Dockerfile.5 @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1.5 + FROM node:19.4-bullseye AS build # Specify working directory other than / diff --git a/07-container-registries/README.md b/07-container-registries/README.md new file mode 100644 index 0000000..1b9eb9c --- /dev/null +++ b/07-container-registries/README.md @@ -0,0 +1,28 @@ +# Container Registries + +A container registry is a repository, or collection of repositories, used to store and access container images. They serve as a place to store and share container images between developer systems, continuous integration servers, and deployment environments. + +![](./images/container-registry.jpg) + +Examples of popular container registries include: + +- [Dockerhub](https://hub.docker.com) +- [Github Container Registry (ghcr.io.)](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) +- [Gitlab Container Registry](https://docs.gitlab.com/ee/user/packages/container_registry/) +- [Google Container Registry (gcr.io)](https://cloud.google.com/container-registry) +- [Amazon Elastic Container Registry (ECR)](https://aws.amazon.com/ecr/) +- [Azure Container Registry (ACR)](https://azure.microsoft.com/en-us/products/container-registry) +- [jFrog Container Registry](https://jfrog.com/container-registry/) +- [Nexus](https://blog.sonatype.com/nexus-as-a-container-registry) +- [Harbor](https://goharbor.io/) + +## Authenticating to Container Registries + +While you can pull many public images from registries without authenticating, in order to push images to a registry, or pull a private image, you will need to authentic + +Docker can login directly to some registries with basic authentication (username/password) or call out to separate programs known as credential helpers. For example, to authenticate to the Google Container Registry, docker uses the `gcloud` command line utility from GCP (https://cloud.google.com/container-registry/docs/advanced-authentication#gcloud-helper). + +If available, Docker can also store the credentials in a secure store (`macOS keychain`, `Windows Credential Manager`) to help protect those credentials. + +![](./images/credential-helper.jpg) + diff --git a/07-container-registries/images/container-registry.jpg b/07-container-registries/images/container-registry.jpg new file mode 100644 index 0000000..6c5304c Binary files /dev/null and b/07-container-registries/images/container-registry.jpg differ diff --git a/07-container-registries/images/credential-helper.jpg b/07-container-registries/images/credential-helper.jpg new file mode 100644 index 0000000..26f9be5 Binary files /dev/null and b/07-container-registries/images/credential-helper.jpg differ diff --git a/08-running-containers/Makefile b/08-running-containers/Makefile new file mode 100644 index 0000000..eab4a7d --- /dev/null +++ b/08-running-containers/Makefile @@ -0,0 +1,112 @@ +### DOCKER COMPOSE COMMANDS + +.PHONY: compose-build +compose-build: + docker compose build + +.PHONY: compose-up +compose-up: + docker compose up + +.PHONY: compose-up-build +compose-up-build: + docker compose up --build + +.PHONY: compose-down +compose-down: + docker compose down + +### DOCKER CLI COMMANDS + +DOCKERCONTEXT_DIR:=../05-example-web-application/ +DOCKERFILE_DIR:=../06-building-container-images/ + +.PHONY: docker-build-all +docker-build-all: + docker build -t client-react-vite -f ${DOCKERFILE_DIR}/client-react/Dockerfile.3 ${DOCKERCONTEXT_DIR}/client-react/ + + docker build -t client-react-ngnix -f ${DOCKERFILE_DIR}/client-react/Dockerfile.5 ${DOCKERCONTEXT_DIR}/client-react/ + + docker build -t api-node -f ${DOCKERFILE_DIR}/api-node/Dockerfile.7 ${DOCKERCONTEXT_DIR}/api-node/ + + docker build -t api-golang -f ${DOCKERFILE_DIR}/api-golang/Dockerfile.6 ${DOCKERCONTEXT_DIR}/api-golang/ + +.PHONY: docker-run-all +docker-run-all: + echo "$$DOCKER_COMPOSE_NOTE" + + # Stop and remove all running containers to avoid name conflicts + $(MAKE) docker-stop + + $(MAKE) docker-remove + + docker run -d \ + --name db \ + -e POSTGRES_PASSWORD=foobarbaz \ + -p 5432:5432 \ + --restart unless-stopped \ + postgres:15.1-alpine + + docker run -d \ + --name api-node \ + -e DATABASE_URL=postgres://postgres:foobarbaz@db:5432/postgres \ + -p 3000:3000 \ + --restart unless-stopped \ + --link=db \ + api-node + + docker run -d \ + --name api-golang \ + -e DATABASE_URL=postgres://postgres:foobarbaz@db:5432/postgres \ + -p 8080:8080 \ + --restart unless-stopped \ + --link=db \ + api-golang + + docker run -d \ + --name client-react-vite \ + -v ${PWD}/client-react/vite.config.js:/usr/src/app/vite.config.js \ + -p 5173:5173 \ + --restart unless-stopped \ + --link=api-node \ + --link=api-golang \ + client-react-vite + + docker run -d \ + --name client-react-nginx \ + -p 5174:80 \ + --restart unless-stopped \ + --link=api-node \ + --link=api-golang \ + client-react-ngnix + +docker-stop: + -docker stop db + -docker stop api-node + -docker stop api-golang + -docker stop client-react-vite + -docker stop client-react-nginx + +docker-remove: + -docker container rm db + -docker container rm api-node + -docker container rm api-golang + -docker container rm client-react-vite + -docker container rm client-react-nginx + +define DOCKER_COMPOSE_NOTE + +🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 + +❯ NOTE: + +This command runs the example app with a bunch +of individual docker run commands. This is much +easier to manage with docker-compose (see +docker-compose.yml and compose make targets above) + +🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 + + +endef +export DOCKER_COMPOSE_NOTE \ No newline at end of file diff --git a/08-running-containers/README.md b/08-running-containers/README.md new file mode 100644 index 0000000..f7f3b9f --- /dev/null +++ b/08-running-containers/README.md @@ -0,0 +1,65 @@ +# Running Containers (with Docker) + +Documentation: https://docs.docker.com/engine/reference/run/ + +Options everyone should know: +``` +-d +--entrypoint +--env, -e, --env-file +--init +--interactive, -i +--mount, --volume, -v +--name +--network, --net +--platform +--publish, -p +--restart +--rm +--tty, -t +``` + +Less commonly used by worth knowing: + +```bash +--cap-add, --cap-drop +--cgroup-parent +--cpu-shares +--cpuset-cpus (pin execution to specific CPU cores) +--device-cgroup-rule, +--device-read-bps, --device-read-iops, --device-write-bps, --device-write-iops +--gpus (NVIDIA Only) +--health-cmd, --health-interval, --health-retries, --health-start-period, --health-timeout +--memoryΒ ,Β -m +--pid, --pids-limit +--privileged +--read-only +--security-opt +--userns +``` + +## Example web app + +### individual docker run commands + +See Makefile: +```bash +make docker-build-all +make docker-run-all +``` + +- Uses the default docker bridge network +- Uses `--link` to enable easy host name for network connections +- Publishing ports useful to connect to each service individually from host, but only necessary to connect to the frontend +- Named containers make it easier to reference (e.g. with link), but does require removing them to avoid naming conflict +- Restart policy allows docker to restart the container (for example if database weren't up yet causing one of the api servers to crash) + +### docker compose + +See Makefile: +```bash +make compose-build +make compose-up +``` + +Using docker compose allows encoding all of the logic from the `docker build` and `docker run` commands into a single file. Docker compose also manages naming of the container images and containers, attaching to logs from all the containers at runtime, etc... diff --git a/06-building-container-images/client-react/vite.config.js b/08-running-containers/client-react/vite.config.js similarity index 100% rename from 06-building-container-images/client-react/vite.config.js rename to 08-running-containers/client-react/vite.config.js diff --git a/06-building-container-images/docker-compose.yml b/08-running-containers/docker-compose.yml similarity index 97% rename from 06-building-container-images/docker-compose.yml rename to 08-running-containers/docker-compose.yml index 32f6433..0db8a14 100644 --- a/06-building-container-images/docker-compose.yml +++ b/08-running-containers/docker-compose.yml @@ -1,5 +1,5 @@ services: - client-react: + client-react-vite: build: context: ../05-example-web-application/client-react/ dockerfile: ../../06-building-container-images/client-react/Dockerfile.3 @@ -11,7 +11,7 @@ services: client-react-nginx: build: context: ../05-example-web-application/client-react/ - dockerfile: ../../06-building-container-images/client-react/Dockerfile.4 + dockerfile: ../../06-building-container-images/client-react/Dockerfile.5 init: true ports: - 5174:80