diff --git a/build-a-simple-containerized-application/build-a-simple-containerized-application.md b/build-a-simple-containerized-application/build-a-simple-containerized-application.md index 2c86b1a..9e9d12f 100644 --- a/build-a-simple-containerized-application/build-a-simple-containerized-application.md +++ b/build-a-simple-containerized-application/build-a-simple-containerized-application.md @@ -1,102 +1,106 @@ +# Prerequisites -# Prereqs +Ensure you have cloned or downloaded the course GitHub repository to your local machine. -Make sure you have the course github repo cloned/downloaded to your local machine. - -Locate the `build-a-simple-containerized-application` folder in the course repo. +Locate the `build-a-simple-containerized-application` folder in the course repository. # Application 1 - 2048 ![2048-diagram](files/2048-game.png) -*Diagram shows the flow - from the Dockerfile to the fun playing game!* +*Diagram shows the flow - from the Dockerfile to the fun playing game!* + ## Creating a 2048 Docker Image -Move into the `app1-2048` folder. -open the `Dockerfile` in a text editor of choice. -Notice how there are `5` lines .. FROM, LABEL, COPY, EXPOSE and CMD. When you build the docker image in the next step, pay attention to how many layers are created in the image. +- Move into the `app1-2048` folder. +- Open the `Dockerfile` in a text editor of your choice. +- Notice how it contains `5` lines: `FROM`, `LABEL`, `COPY`, `EXPOSE`, and `CMD`. When you build the Docker image in the next step, pay attention to how many layers are created. -This Dockerfile uses the latest version of the `nginx` image (which includes a configured installation of NGINX). +This Dockerfile uses the latest version of the `nginx` image (which includes a pre-configured installation of NGINX). -https://hub.docker.com/_/nginx +[https://hub.docker.com/_/nginx](https://hub.docker.com/_/nginx) -It sets metadata `maintainer`. It then copies all of the `2048/` folder from the localdocker host/client machine into the `/usr/share/nginx/html` folder within the image. +It sets the metadata `maintainer`. It then copies all of the `2048/` folder from the local Docker host/client machine into the `/usr/share/nginx/html` folder within the image. -Finally we use the `EXPOSE` directive to inform uses of this image that the appplication is running on `tcp/80` and use the `CMD` statement to set the initial process for containers running from this image. +Finally, we use the `EXPOSE` directive to inform users of this image that the application is running on `tcp/80` and use the `CMD` statement to set the initial process for containers running from this image. -To build the image, from the `app1-2048` folder we run the docker build command. We use `-t` to tag the image with `2048` and use `.` to set the working directory for the command. ANy paths specified in the dockerfile will use `.` as the starting point ..the working directory. +To build the image, from the `app1-2048` folder, we run the Docker build command. We use `-t` to tag the image with `dockerized-2048` and use `.` to set the working directory for the command. Any paths specified in the Dockerfile will use `.` as the starting point, which is the working directory. -```docker build -t dockerized-2048 .``` +```sh +docker build -t dockerized-2048 . +``` -Notice how 2 layers are created in the docker image. +Notice how 2 layers are created in the Docker image: -- The first layer is the base image `nginx:latest`. -- The last layer is created based on the `COPY` statement to copy in the application files from `./2048`. +- The first layer is the base image `nginx:latest`. +- The last layer is created based on the `COPY` statement to copy in the application files from `./2048`. ## Running a 2048 Docker Container -Run a `docker images` to show all images on the Docker Host. -Locate the `dockerized-2048` image which you just created. -This image, is running an application using `tcp/80` so we need to use the `-p` CLI option to run this on an alternative docker host post (this will be discussed in detail later in the course). +Run `docker images` to show all images on the Docker Host. Locate the `dockerized-2048` image you just created. This image is running an application using `tcp/80`, so we need to use the `-p` CLI option to run this on an alternative Docker host port (this will be discussed in detail later in the course). -Run a docker container of 2048 using +Run a Docker container of 2048 using: -`docker run -d -p 8081:80 dockerized-2048` +```sh +docker run -d -p 8081:80 dockerized-2048 +``` -this will run in detached mode, so your terminal should return to the prompt immediately. +This will run in detached mode, so your terminal should return to the prompt immediately. -Verify the container is running with `docker ps`. Confirm the port mapping with `docker port `. +Verify the container is running with `docker ps`. Confirm the port mapping with `docker port `. -Browse to `http://localhost:8081` +Browse to `http://localhost:8081`. Play the game :) ## Cleanup -Run a `docker stop ` to stop the 2048 container app. -Run a `docker rm ` to remove the 2048 container. +Run `docker stop ` to stop the 2048 container app. Run `docker rm ` to remove the 2048 container. # Application 2 - Container of Cats -This dockefile is intentionally less efficient than app1 above. I want you to understand WHY it's less efficient. +This Dockerfile is intentionally less efficient than app1 above. I want you to understand WHY it's less efficient. ## Creating a Container of Cats Docker Image -Move into the `app2-containerofcats` folder. -open the `Dockerfile` in a text editor of choice. +- Move into the `app2-containerofcats` folder. +- Open the `Dockerfile` in a text editor of your choice. + +Let's review this `Dockerfile` and specifically identify how it's different from the previous `app1`. -Let's review this `Dockerfile` and specifically identify how it's different from the previous `app1`. +- First, it uses a different base image. Instead of `nginx:latest`, which is specifically designed for simple `nginx` web use-cases, this uses `ubi8`, which is a universal Red Hat 8 image (general purpose). +- This image is also larger than other lean images such as `alpine` and `nginx`. +- Because this is a general-purpose image, we have to install a web server (apache2) in this case via the `RUN` statement. This creates a layer. +- Next, there are 2 `COPY` statements which copy in `index.html` and `containerandcat*.jpg` media files into the image. These two statements create _2_ additional layers. -- First, it uses a different base image. Instead of `nginx:latest` which is specifically designed for simple `ngnix` web use-cases, this uses `ubi8` which is a universal redhat 8 image (general purpose) -- This image is also larger than other lean image such as `alpine` and `nginx`. -- Because this is a general purpose image, we have to install a web server (apache2) in this case via the `RUN` statement. This creates a layer. -- Next, there are 2 x `COPY` statements which copy in `index.html` and `contaierandcat*.jpg` media files into the image. These two statements create _2_ additional layers. +This Dockerfile and resultant image are more generalized. This results in a larger image and containers which consume more resources. -This dockerfile and resultant image are more generalised. This results in a larger image, and containers which consume more resources. +To create a Docker image for the `containerofcats` application, we run this command: -To create a docker image for the `containerofcats` dockerized application we run this command. +```sh +docker build -t containerofcats . +``` -```docker build -t containerofcats .``` +*Notice how much longer it takes to create, compared to the 2048 image, even though it's a similar architecture: a web server & some files.* -*notice how much longer it takes to create, vs the 2048 image, even though it's a similar architecture .. web server & some files* +## Running a Containerofcats Docker Container -## Running a containerofcats Docker Container +Run `docker images` to show all images on the Docker Host. Locate the `containerofcats` image you just created. This image is running an application using `tcp/ -Run a `docker images` to show all images on the Docker Host. -Locate the `containerofcats` image which you just created. -This image, is running an application using `tcp/80` so we need to use the `-p` CLI option to run this on an alternative docker host post (this will be discussed in detail later in the course). +80`, so we need to use the `-p` CLI option to run this on an alternative Docker host port (this will be discussed in detail later in the course). -Run a docker container of containerofcats using +Run a Docker container of containerofcats using: -`docker run -d -p 8081:80 containerofcats` +```sh +docker run -d -p 8081:80 containerofcats +``` -this will run in detached mode, so your terminal should return to the prompt immediately. +This will run in detached mode, so your terminal should return to the prompt immediately. -Verify the container is running with `docker ps`. Confirm the port mapping with `docker port `. +Verify the container is running with `docker ps`. Confirm the port mapping with `docker port `. -Browse to `http://localhost:8081` +Browse to `http://localhost:8081`. ## Cleanup -Run a `docker stop ` to stop the containerofcats container app. -Run a `docker rm ` to remove the containerofcats container. +Run `docker stop ` to stop the containerofcats container app. Run `docker rm ` to remove the containerofcats container. diff --git a/docker-compose/instructions.md b/docker-compose/instructions.md index 8ca6d46..dc9c3f5 100644 --- a/docker-compose/instructions.md +++ b/docker-compose/instructions.md @@ -1,18 +1,17 @@ - # Docker Compose -Docker compose is a way to create and manage multi-container applications. It works using a YAML configuration file called `compose.yaml` or `docker-compose.yml`. +Docker Compose is a way to create and manage multi-container applications. It works using a YAML configuration file called `compose.yaml` or `docker-compose.yaml`. -Generally using docker compose is a multi-step process: +Generally, using Docker Compose is a multi-step process: -- Define each of your containers using a `Dockerfile` -- Push those containers to a repository -- Define a docker compose file -- use the file via the `docker compose` command. +- Define each of your containers using a `Dockerfile`. +- Push those containers to a repository. +- Define a Docker Compose file. +- Use the file via the `docker compose` command. -This is an example `compose.yaml` file. +This is an example `compose.yaml` / `docker-compose.yaml` file. -``` +```yaml services: db: image: mariadb:10.6.4-focal @@ -45,26 +44,22 @@ volumes: wordpress_data: ``` -It defines two containers `db` and `wordpress` both defined under `services:`. It also defines two named volumes `mariadb_data` and `wordpress_data`, which are created outside of the lifecycle of any one container and can be referenced by the containers defined within the compose file, in this example `db`. +It defines two containers, `db` and `wordpress`, both defined under `services:`. It also defines two named volumes, `mariadb_data` and `wordpress_data`, which are created outside of the lifecycle of any one container and can be referenced by the containers defined within the compose file, in this example, `db`. -Go ahead and create a file in your current working folder called `compose.yaml` and paste in the above contents. Then to use this file run a `docker compose up -d`. `up` is how we tell docker compose to bring up the things defined in the file, and `-d` directs compose to run in detached mode (which works in the same way as it does it containers). +Go ahead and create a file in your current working folder called `compose.yaml` and paste in the above contents. Then to use this file, run a `docker compose up -d`. `up` is how we tell Docker Compose to bring up the things defined in the file, and `-d` directs compose to run in detached mode (which works in the same way as it does in containers). -browse to ```http://localhost:8081``` and complete the installation process of wordpress. You will need to select a language, click next, set a site title `All the cats`, set an admin user `admin`, note down the auto generated password (you will need this a few times), enter your email and click `Install Wordpress`. +Browse to `http://localhost:8081` and complete the installation process of WordPress. You will need to select a language, click next, set a site title `All the cats`, set an admin user `admin`, note down the auto-generated password (you will need this a few times), enter your email, and click `Install WordPress`. -Then ..Login, Click `posts` then `Add new` and create a new post with some images, use the `+` to add a gallery, then add some test images, the details don't matter. Click `publish` and then `publish` again. Then click `view post` & make sure you can see the site ok... +Then...Login, Click `posts` then `Add new` and create a new post with some images, use the `+` to add a gallery, then add some test images, the details don't matter. Click `publish` and then `publish` again. Then click `view post` & make sure you can see the site ok... -Run a ```docker compose down``` to stop all the containers and then do a, ```docker ps -a```, notice the containers are fully removed? -run a ```docker volume ls``` and note how the named volumes still exist? - -The containers just created by docker compose are now gone. -Run a ```docker compose up -d``` .. and watch what compose does, it only recreates what's missing. Docker compose is smart enough to always create what's required to make what is container in the docker compose file `true` whether that means creating everything in it, or just a small section. -browse to ```http://localhost:8081``` and notice how the install is finished ? no configuration is needed ? and you see your blog post? that's because the named volumes are used, which contain the database and the image data from wordpress. Even though the containers were deleted and recreated the data persisted because it's stored in volumes which exist outside of the lifecycle of the container. +Run a `docker compose down` to stop all the containers and then do a, `docker ps -a`, notice the containers are fully removed? +Run a `docker volume ls` and note how the named volumes still exist? +The containers just created by Docker Compose are now gone. +Run a `docker compose up -d`... and watch what compose does, it only recreates what's missing. Docker Compose is smart enough to always create what's required to make what is contained in the Docker Compose file `true`, whether that means creating everything in it, or just a small section. +Browse to `http://localhost:8081` and notice how the install is finished? No configuration is needed? And you see your blog post? That's because the named volumes are used, which contain the database and the image data from WordPress. Even though the containers were deleted and recreated, the data persisted because it's stored in volumes that exist outside of the lifecycle of the container. # Cleanup -Run a `docker compose down` to stop and delete any containers. -Run a `docker volume ls` to list all volumes and delete the named ones created by compose using `docker volume rm ` - - - +Run a `docker compose down` to stop and delete any containers. +Run a `docker volume ls` to list all volumes and delete the named ones created by compose using `docker volume rm ` diff --git a/docker-container-environment-variables/instructions.md b/docker-container-environment-variables/instructions.md index ad8ece3..9057546 100644 --- a/docker-container-environment-variables/instructions.md +++ b/docker-container-environment-variables/instructions.md @@ -1,82 +1,91 @@ +# Setup phpMyAdmin +This is a simple MySQL or MariaDB management app. We map the container port 80 to the Docker host port 8081 and call it phpMyAdmin. +The `-e PMA_ARBITRARY=1` option allows us to specify the server to use each time via the UI, versus statically setting this. -# Setup phpmyadmin -this is a simple mySQL or mariaDB management app, we map container port 80 to docker host port 8081, we call it phpmyadmin. -the -e `PMA_ARBITRARY=1` lets us specify the server to use each time via the UI, vs statically setting this. +## Run -Run -```docker run --name phpmyadmin -d -p 8081:80 -e PMA_ARBITRARY=1 phpmyadmin/phpmyadmin``` +```sh +docker run --name phpmyadmin -d -p 8081:80 -e PMA_ARBITRARY=1 phpmyadmin/phpmyadmin +``` -This will create a container running the `phpmyadmin` DB management application. +This command creates a container running the `phpMyAdmin` DB management application. -# Create a mariaDB container using ONLY environment variables +# Create a MariaDB Container Using ONLY Environment Variables -first we need to pull down the mariaDB image. -```docker pull mariadb:10.6.4-focal``` -lets inspect it and review all metadata. -```docker inspect mariadb:10.6.4-focal``` +First, we need to pull down the MariaDB image. +```sh +docker pull mariadb:10.6.4-focal +``` +Let's inspect it and review all metadata. +```sh +docker inspect mariadb:10.6.4-focal +``` -Now let's run a container and note how we use environment variables. +Now, let's run a container and note how we use environment variables: -- using `-e` we specify a key=value pair -- it's convention for NAMES to be in caps -- in this case we create `MYSQL_ROOT_PASSWORD`, `MYSQL_PASSWORD`, `MYSQL_DATABASE` and `MYSQL_USER` -- The container is configured to accept these variables and take action on them -- `MYSQL_ROOT_PASSWORD` sets the mariaDB root password -- `MYSQL_DATABASE` creates a database with the name of the env variable value `wordpress` in this example -- `MYSQL_USER` creates a mariaDB user -- `MYSQL_PASSWORD` creates a password for that user -- `--default-authentication-plugin=mysql_native_password` is an argument for the process running in the docker container, extra options. - -```docker run --name db -e MYSQL_ROOT_PASSWORD=somewordpress -e MYSQL_PASSWORD=wordpress -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -d mariadb:10.6.4-focal --default-authentication-plugin=mysql_native_password``` +- Using `-e`, we specify a key=value pair. +- It's convention for names to be in uppercase. +- In this case, we create `MYSQL_ROOT_PASSWORD`, `MYSQL_PASSWORD`, `MYSQL_DATABASE`, and `MYSQL_USER`. +- The container is configured to accept these variables and take action on them. +- `MYSQL_ROOT_PASSWORD` sets the MariaDB root password. +- `MYSQL_DATABASE` creates a database with the name of the environment variable value `wordpress` in this example. +- `MYSQL_USER` creates a MariaDB user. +- `MYSQL_PASSWORD` creates a password for that user. +- `--default-authentication-plugin=mysql_native_password` is an argument for the process running in the Docker container, adding extra options. -confirm the docker container is running with a -```docker ps -a``` +```sh +docker run --name db -e MYSQL_ROOT_PASSWORD=somewordpress -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wordpress -d mariadb:10.6.4-focal --default-authentication-plugin=mysql_native_password +``` -and get the container ID... note this down as `MARIADB_ID` -run the command below to show the metadata for the running container for mariaDB. -```docker inspect MARIADB_ID ``` +Confirm the Docker container is running with: +```sh +docker ps -a +``` +Run the command below to show the metadata for the running container for MariaDB. +```sh +MARIA_DB_CONTAINER_ID=$(docker ps | grep mariadb | awk '{print $1}') +docker inspect ${MARIA_DB_CONTAINER_ID} +``` -look for "IPAddress": "XXXXXXXXXX", this is the internal docker network IP that the DB container is running on. note this down as `DB_IP` +Look for `"IPAddress": "XXXXXXXXXX"`, this is the internal Docker network IP that the DB container is running on. Note this down as `DB_IP`. -open http://localhost:8081 to access phpmyadmin -enter `DB_IP` for server -enter `root` for username -enter `somewordpress` for password +Open `http://localhost:8081` to access phpMyAdmin. +Enter `DB_IP` for the server. +Enter `root` for the username. +Enter `somewordpress` for the password. -You are now accessing the db container, from the phpmyadmin container +You are now accessing the DB container from the phpMyAdmin container. -- Go to `User Accounts` and confirm a wordpress user has been created. -- Look on the menubar on the left and confirm there is a `wordpress` database +- Go to `User Accounts` and confirm a WordPress user has been created. +- Look on the menu bar on the left and confirm there is a `wordpress` database. -Now we're going to explore the container. +Now we're going to explore the container. -run a ```docker exec -it db bash``` to go into the container via a bash shell. -run a ```df -k``` and note how there are no externally mapped drives/mounts. All storage that this container uses, is within this container. -This means the storage is linked to the lifecycle of this container, if the container is deleted, so is the storage. +Run a `docker exec -it db bash` to go into the container via a bash shell. +Run a `df -k` and note how there are no externally mapped drives/mounts. All storage that this container uses is within this container. +This means the storage is linked to the lifecycle of this container; if the container is deleted, so is the storage. -The mariaDB service stores its data in `/var/lib/mysql` so let's check that out. -run a ```cd /var/lib/mysql``` and then ```ls -la``` -this is the `data` for the database service ... inside the container. +The MariaDB service stores its data in `/var/lib/mysql`, so let's check that out. +Run a `cd /var/lib/mysql` and then `ls -la`. +This directory contains the `data` for the database service inside the container. -This is a limitation we're going to fix in the next demo, where we will look at configuring separate storage for our container. +This is a limitation we're going to fix in the next demo, where we will look at configuring separate storage for our container. -That's it for this lesson +That's it for this lesson. # Cleanup -run the following two comments to stop and delete the mariaDB container.. +Run the following two commands to stop and delete the MariaDB container: -``` +```sh docker stop db docker rm db ``` -lets also for now delete the phpmyadmin container (we can easily launch this again in the next demo) +Let's also, for now, delete the phpMyAdmin container (we can easily launch this again in the next demo): -``` +```sh docker stop phpmyadmin docker rm phpmyadmin ``` - - diff --git a/docker-container-volumes/instructions.md b/docker-container-volumes/instructions.md index 5aa79ea..de2576c 100644 --- a/docker-container-volumes/instructions.md +++ b/docker-container-volumes/instructions.md @@ -1,55 +1,60 @@ -# Prep +# Preparation -Make sure you have done the previous demo lesson on environment variables and understand all parts of that demo. -Recreate the `phpmyadmin` container via the command below +Ensure you have completed the previous demonstration lesson on environment variables and understand all aspects of that demonstration. Recreate the `phpmyadmin` container with the following command: -```docker run --name phpmyadmin -d -p 8081:80 -e PMA_ARBITRARY=1 phpmyadmin/phpmyadmin``` +```sh +docker run --name phpmyadmin -d -p 8081:80 -e PMA_ARBITRARY=1 phpmyadmin/phpmyadmin +``` # Bind Mounts -Bind mounts allow us to mount a file or directory on the host machine into a container. This has pros and cons but it can be useful if you need to see this files on the container host, or access a shared collection of files between container, or between containers and other compute services. +Bind mounts allow us to mount a file or directory from the host machine into a container. This approach has both advantages and disadvantages, but it can be particularly useful if you need to access files on the container host, share files between containers, or between containers and other compute services. -In this example, we're going to create a bind mount for the mariaDB data folder in the container, and map it to a folder on the docker host. +In this example, we will create a bind mount for the MariaDB data directory within the container and map it to a directory on the Docker host. -we can do this is two ways, using the `-v` option or the `--mount` option. They both do the same thing, but they look different. +There are two ways to achieve this: using the `-v` option or the `--mount` option. Both options accomplish the same task but are formatted differently. -As a reminder, in the environment variables demo lesson, we created a mariaDB container using this command:- +As a reminder, in the environment variables demonstration lesson, we created a MariaDB container using the following command: -```docker run --name db -e MYSQL_ROOT_PASSWORD=somewordpress -e MYSQL_PASSWORD=wordpress -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -d mariadb:10.6.4-focal --default-authentication-plugin=mysql_native_password``` +```sh +docker run --name db -e MYSQL_ROOT_PASSWORD=somewordpress -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wordpress -d mariadb:10.6.4-focal --default-authentication-plugin=mysql_native_password +``` -and the mariaDB data was stored in the container in the `/var/lib/mysql` folder. +The MariaDB data was stored within the container in the `/var/lib/mysql` directory. -first, on your local machine/docker host we will create a folder for the mariaDB data, and we will call it `mariadb_data`. +First, on your local machine/Docker host, create a directory for the MariaDB data, and name it `mariadb_data`. -- move into a folder where you are ok creating files and folders, either your home folder or a tmp folder. -- I'll assume your home folder -- windows `cd %HOMEDRIVE%` macos/Linux `cd ~` -- create a folder called `mariadb_data` -- `mkdir mariadb_data` +- Navigate to a directory where you are comfortable creating files and directories, such as your home directory or a temporary directory. +- For simplicity, let's assume you're using your home directory. +- On Windows, navigate with `cd %HOMEDRIVE%`. On macOS/Linux, use `cd ~`. +- Create a directory called `mariadb_data` with `mkdir mariadb_data`. ### macOS / Linux -*both of these do the same thing, pick one* -``` +*Choose one of the following commands, as both perform the same action:* + +```sh docker run \ --name db \ -e MYSQL_ROOT_PASSWORD=somewordpress \ - -e MYSQL_PASSWORD=wordpress \ -e MYSQL_DATABASE=wordpress \ -e MYSQL_USER=wordpress \ + -e MYSQL_PASSWORD=wordpress \ --mount type=bind,source="$(pwd)"/mariadb_data,target=/var/lib/mysql \ -d \ mariadb:10.6.4-focal \ --default-authentication-plugin=mysql_native_password ``` -*both of these do the same thing, pick one* -``` + +*Or:* + +```sh docker run \ --name db \ -e MYSQL_ROOT_PASSWORD=somewordpress \ - -e MYSQL_PASSWORD=wordpress \ -e MYSQL_DATABASE=wordpress \ -e MYSQL_USER=wordpress \ + -e MYSQL_PASSWORD=wordpress \ -v "$(pwd)"/mariadb_data:/var/lib/mysql \ -d \ mariadb:10.6.4-focal \ @@ -57,85 +62,74 @@ docker run \ ``` ### Windows -*both of these do the same thing, pick one* -*bind mounts often requires specific configuration on windows docker hosts* -*it's often tricky to get it working* -```docker run --name db -e MYSQL_ROOT_PASSWORD=somewordpress -e MYSQL_PASSWORD=wordpress -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress --mount type=bind,source=%cd%/mariadb_data,target=/var/lib/mysql -d mariadb:10.6.4-focal --default-authentication-plugin=mysql_native_password``` +*Choose one of the following commands, noting that bind mounts often require specific configuration on Windows Docker hosts and can be challenging to set up:* -```docker run --name db -e MYSQL_ROOT_PASSWORD=somewordpress -e MYSQL_PASSWORD=wordpress -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -v %cd%/mariadb_data:/var/lib/mysql -d mariadb:10.6.4-focal --default-authentication-plugin=mysql_native_password``` +```sh +docker run --name db -e MYSQL_ROOT_PASSWORD=somewordpress -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wordpress --mount type=bind,source=%cd%/mariadb_data,target=/var/lib/mysql -d mariadb:10.6.4-focal --default-authentication-plugin=mysql_native_password +``` + +*Or:* +```sh +docker run --name db -e MYSQL_ROOT_PASSWORD=somewordpress -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wordpress -v %cd%/mariadb_data:/var/lib/mysql -d mariadb:10.6.4-focal --default-authentication-plugin=mysql_native_password +``` ### macOS / Linux & Windows -In all of the above cases, move into the `mariadb_data` folder and do a listing.. -You should be able to see all the files and folders created by the bind mount into the container. Any data stored in the `/var/lib/mysql` folder in the folder, is stored in this folder on the host. Any changes made to the `/var/lib/mysql` in the container will be reflected in this folder. Any changes made to this folder, will be reflected in the `/var/lib/mysql` folder in the container. +In all the above cases, navigate into the `mariadb_data` directory and list its contents. You should see all files and directories created by the bind mount. Any data stored in `/var/lib/mysql` within the container is also stored in this directory on the host. Changes made in one location are reflected in the other. # Volumes -Volumes are the prefered way to adding storage to docker containers outside of the lifecycle of a container. They are managed entirely by docker and work flawlessly on windows container hosts. +Volumes are the preferred method of adding storage to Docker containers outside of a container's lifecycle. Managed entirely by Docker, volumes work seamlessly on Windows container hosts. -to create a volume run +To create a volume, run: -```docker volume create mariadb_data``` -you can list any volumes via the ```docker volume ls``` command. -you can review full metadata for a volume via the ```docker volume inspect mariadb_data``` command. -you can delete a volume via the ```docker volume rm mariadb_data``` command. -and verify it's been removed via the ```docker volume ls``` command. +```sh +docker volume create mariadb_data +``` -if you run a container and specify a volume which doesn't already exist, it will create this volume for you. +List volumes with `docker volume ls`, inspect a volume with `docker volume inspect mariadb_data`, and delete a volume with `docker volume rm mariadb_data`. Verify removal with `docker volume ls`. -*both of these do the same thing, pick one* +If you start a container and specify a non-existing volume, Docker will automatically create it for you. -``` -docker run \ - --name db \ - -e MYSQL_ROOT_PASSWORD=somewordpress \ - -e MYSQL_PASSWORD=wordpress \ - -e MYSQL_DATABASE=wordpress \ - -e MYSQL_USER=wordpress \ - --mount source=mariadb_data,target=/var/lib/mysql \ - -d \ - mariadb:10.6.4-focal \ - --default-authentication-plugin=mysql_native_password -``` +*Choose one of the following commands, as both achieve the same result:* -``` +```sh docker run \ --name db \ -e MYSQL_ROOT_PASSWORD=somewordpress \ - -e MYSQL_PASSWORD=wordpress \ -e MYSQL_DATABASE=wordpress \ -e MYSQL_USER=wordpress \ - -v mariadb_data:/var/lib/mysql \ + -e MYSQL_PASSWORD=wordpress \ + --mount source=mariadb_data,target=/var/lib/mysql \ -d \ mariadb:10.6.4-focal \ --default-authentication-plugin=mysql_native_password ``` -notice via ```docker volume ls``` how this has automatically created a volume. if we stop the container with ```docker stop db``` and then delete it with ```docker rm db``` notice how the volume still exists ```docker volume ls``` ? - -if we start up the container again, we can use the same volume and any data stored within it persists, so data can live on beyond the lifecycle of the container. +*Or:* -``` +```sh docker run \ --name db \ -e MYSQL_ROOT_PASSWORD=somewordpress \ - -e MYSQL_PASSWORD=wordpress \ -e MYSQL_DATABASE=wordpress \ -e MYSQL_USER=wordpress \ + -e MYSQL_PASSWORD=wordpress \ -v mariadb_data:/var/lib/mysql \ -d \ mariadb:10.6.4-focal \ --default-authentication-plugin=mysql_native_password ``` -get the internal container ip via ```docker inspect db``` and then browse to https://localhost:8081 and login with that ip, `root` and `somewordpress`, notice how it works fine ? - +Note how `docker volume ls` shows the newly created volume. Stopping the container with `docker stop db` and deleting it with `docker rm db` leaves the volume intact. Data within the volume persists beyond the container's lifecycle, allowing reuse in new containers. # Cleanup -``` +To clean up, run the following commands: + +```sh docker stop db docker rm db docker stop phpmyadmin @@ -143,5 +137,4 @@ docker rm phpmyadmin docker volume rm mariadb_data ``` - - +This ensures all containers and the volume are properly removed. \ No newline at end of file diff --git a/docker-registry/instructions.md b/docker-registry/instructions.md index 067f733..9a2d42c 100644 --- a/docker-registry/instructions.md +++ b/docker-registry/instructions.md @@ -1,33 +1,46 @@ +First, we pull an image from Docker Hub to our local Docker host. This involves pulling the `latest` image from the `containerofcats` repository in the `acantril` account on Docker Hub. -First we pull an image from Docker Hub to our local docker host. This is pulling the `latest` image, from the `containerofcats` respsitory in the `acantril` account on Docker Hub. +```sh +docker pull acantril/containerofcats:latest +``` -```docker pull acantril/containerofcats:latest``` +Now, we will create an image and upload it to Docker Hub. +First, go to [https://hub.docker.com](https://hub.docker.com) and create an account. You will need to note down your account name. -Now we will create an image and upload it to Docker Hub. -First, go to https://hub.docker.com and create an account. You will need to note down your account name. +Create a repo on Docker Hub called `newcontainerofcats`. -Create a repo on dockerhub called `newcontainerofcats` . +Then, you will need to log in to Docker Hub. If you use `username` and `password` to log in, you can enter your password when prompted in the step below. If you use `username`, `password`, and `MFA`, you will need to go to [https://hub.docker.com/settings/security](https://hub.docker.com/settings/security) and generate a token to input **instead** of your password below. -Then, you will need to login to Docker Hub. if you use use `username` and `password` to login, then you can enter your password when prompted in the step below. if you use `username`, `password` and `MFA` you will need to go to https://hub.docker.com/settings/security and generate a token and input that **instead** of your password below. +Log in to Docker Hub using the command below: -Login to Docker Hub using the command below -```docker login --username=YOUR_USER``` -**you will either enter your password when prompted or your token (see above)** +```sh +docker login --username=YOUR_USER +``` -Move into the repo/docker-registry folder and build the `newcontainerofcats` image using the command below +**You will either enter your password when prompted or your token (see above).** -```docker build -t newcontainerofcats .``` +Move into the repo/docker-registry folder and build the `newcontainerofcats` image using the command below: -Verify the image is created using the command below, and note down the image ID +```sh +docker build -t newcontainerofcats . +``` -```docker images``` +Verify the image is created using the command below, and note down the image ID: -To push this image to Docker Hub we need to tag it with our hub username and repo name. +```sh +docker images +``` -```docker tag IMAGEID YOUR_USER/newcontainerofcats:latest``` +To push this image to Docker Hub, we need to tag it with our hub username and repo name. -Then we can push this image to dockerhub +```sh +docker tag IMAGEID YOUR_USER/newcontainerofcats:latest +``` -```docker push YOUR_USER/newcontainerofcats:latest``` +Then, we can push this image to Docker Hub: -Then browse to docker hub and verify that it's visible. +```sh +docker push YOUR_USER/newcontainerofcats:latest +``` + +Then, browse to Docker Hub and verify that it's visible.