• 【在Ubuntu部署Docker项目】— PROJECT#1


    一、说明

            让我们深入了解 Docker。用docker构建web服务器。我们正在计划开发JavaScript API,建立MySQL数据库,并创建一个 PHP 网站使用 API 服务。Php + Node.js + Mysql — DockerSeries — Episode#1

    二、系统架构概述

            我们要构建的容器,是三个独立的容器组成,它们三者构成一个网络。

            以下是目录结构和相应的步骤:

    四、通过实践来学习 Docker

            这是最终结果:http://localhost:8888/

            准备好练习了吗?

    1#Step — 在 Ubuntu 上安装并运行 Docker Desktop。如果需要,您可以参考这篇文章;

    2#Step — 使目录结构(复制/粘贴并按回车键,您就可以进入VScode:)

    1. mkdir docker
    2. cd docker
    3. mkdir proj_01
    4. cd proj_01
    5. mkdir api
    6. cd api
    7. mkdir db
    8. mkdir src
    9. cd ..
    10. mkdir website
    11. cd website
    12. mkdir vendor
    13. cd ..
    14. code .

    3#Step — 进入 VScode 后,让我们创建一个 Dockerfile:

    转到: :proj_01/api/db/Dockerfile

    1. FROM mysql
    2. ENV MYSQL_ROOT_PASSWORD jaythree

    4#Step — 让我们构建映像。

    返回到根目录并在终端中键入:proj_01/

    docker build -t mysql-image -f api/db/Dockerfile . 

    你会得到这个:/ERROR

    无法在 unix:///home/j3/.docker/desktop/docker.sock 连接到 Docker 守护程序。docker 守护程序是否正在运行?

    哎呀!运行 Docker 桌面,您就可以开始了!

    请立即运行 Docker 桌面!

    返回根目录 ~/docker/proj_01$ 并尝试再次构建 MySQL 镜像...巨大的成功!

    5#Step — 使用我们最近生成的映像运行 MySQL 容器。转到 &类型:proj_01/

    容器 # 1

    docker run -d -v $(pwd)/api/db/data:/var/lib/mysql --rm --name mysql-container mysql-image 

    在 Docker 桌面中,您将看到 MySQL 容器运行良好!

    6#Step — 现在我们已经启动并运行了一个 MySQL 容器,让我们创建一个数据库 (outfit_db),定义一个表(产品),并插入一些值。

    对于此测试,我们将使用我们在服装商店的在线数据库:

    DB来自这篇文章。我们现在只使用三行...

    创建此文件:

    proj_01/db/script.sql

    1. CREATE DATABASE IF NOT EXISTS outfit_db;
    2. USE outfit_db;
    3. CREATE TABLE IF NOT EXISTS products (
    4. id INT AUTO_INCREMENT,
    5. sales_code INT NOT NULL,
    6. date date NOT NULL,
    7. store_id VARCHAR(255),
    8. product VARCHAR(255),
    9. qty INT NOT NULL,
    10. unit_price DECIMAL(10, 2),
    11. PRIMARY KEY (id)
    12. );
    13. INSERT INTO products VALUE(0, 65014, '2019-01-12', 'Shopping Morumbi', 'Aster Pants', 5, 114);
    14. INSERT INTO products VALUE(0, 65014, '2019-01-12', 'Shopping Morumbi', 'Trench Coat', 1, 269);
    15. INSERT INTO products VALUE(0, 65016, '2019-01/-2', 'Iguatemi Campinas', 'Peter Pan Collar', 2, 363);

    7#Step —让我们执行数据库和表,并使用前面的脚本用值填充它。转到 :proj_01/

    docker exec -i mysql-container mysql -uroot -pjaythree < api/db/script.sql 

    8#Step — 现在,让我们访问容器以执行 SQL 选择。

    若要查看容器中的表并使用命令行与数据库交互,需要通过调用方法访问它:outfit_dbexec

    docker exec -it mysql-container /bin/bash 
    1. bash-4.4# mysql -uroot -pjaythree
    2. mysql> USE outfit_db;
    3. mysql> SELECT * FROM products;
    4. exit
    5. exit

    具体来说,它使用该命令与名为 的 Docker 容器进行交互。命令末尾的 指示它正在指定容器内启动交互式 b灰壳 (CLI) 会话。这允许您访问容器的文件系统并在其中工作,并像在容器本身中一样运行命令。这是在 Docker 容器中执行任务或维护操作的常用方法。docker execmysql-container/bin/bash

    为方便起见,以下是我们在终端中执行的上述两项操作:

    1. $ docker exec -i mysql-container mysql -uroot -pjaythree < db/script.sql
    2. mysql: [Warning] Using a password on the command line interface can be insecure.
    3. $ docker exec -it mysql-container /bin/bash
    4. bash-4.4# mysql -uroot -pjaythree
    5. mysql: [Warning] Using a password on the command line interface can be insecure.
    6. Welcome to the MySQL monitor. Commands end with ; or \g.
    7. Your MySQL connection id is 13
    8. Server version: 8.1.0 MySQL Community Server - GPL
    9. Copyright (c) 2000, 2023, Oracle and/or its affiliates.
    10. Oracle is a registered trademark of Oracle Corporation and/or its
    11. affiliates. Other names may be trademarks of their respective
    12. owners.
    13. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    14. mysql> USE outfit_db;
    15. Reading table information for completion of table and column names
    16. You can turn off this feature to get a quicker startup with -A
    17. Database changed
    18. mysql> SELECT * FROM products;
    19. +----+------------+------------+-------------------+------------------+-----+------------+
    20. | id | sales_code | date | store_id | product | qty | unit_price |
    21. +----+------------+------------+-------------------+------------------+-----+------------+
    22. | 1 | 65014 | 2019-01-12 | Shopping Morumbi | Aster Pants | 5 | 114.00 |
    23. | 2 | 65014 | 2019-01-12 | Shopping Morumbi | Trench Coat | 1 | 269.00 |
    24. | 3 | 65016 | 2019-01-02 | Iguatemi Campinas | Peter Pan Collar | 2 | 363.00 |
    25. +----+------------+------------+-------------------+------------------+-----+------------+
    26. 3 rows in set (0.00 sec)
    27. mysql> exit
    28. Bye
    29. bash-4.4# exit
    30. exit

    注意:如果需要删除,请使用:mysql> DROP DATABASEoutlet_db;

    9#Step — 继续通过终端安装Node(NodeJs官网),因此输入以下命令:

    1. sudo apt install npm
    2. node -v
    3. v18.13.0

    10#Step — GoTo & type:

    proj_01/api/ :

    npm init  

    这是我们终端的输出:

    1. ~/docker/proj_01/api$ npm init
    2. This utility will walk you through creating a package.json file.
    3. It only covers the most common items, and tries to guess sensible defaults.
    4. See `npm help init` for definitive documentation on these fields
    5. and exactly what they do.
    6. Use `npm install ` afterwards to install a package and
    7. save it as a dependency in the package.json file.
    8. Press ^C at any time to quit.
    9. package name: (api)
    10. version: (1.0.0)
    11. description: Docker intro
    12. entry point: (index.js)
    13. test command: test
    14. git repository:
    15. keywords: Docker
    16. author: j3
    17. license: (ISC)
    18. About to write to /home/j3/docker/proj_01/api/package.json:
    19. {
    20. "name": "api",
    21. "version": "1.0.0",
    22. "description": "Docker intro",
    23. "main": "index.js",
    24. "scripts": {
    25. "test": "test"
    26. },
    27. "keywords": [
    28. "Docker"
    29. ],
    30. "author": "j3",
    31. "license": "ISC"
    32. }
    33. Is this OK? (yes)

    该命令用于初始化新的 Node.js 项目。当您在终端中运行此命令时,它会提示您一系列问题,并询问各种配置选项来设置您的项目。这些问题通常包括项目名称、版本、说明、入口点文件、测试命令等内容。npm init

    回答这些问题或接受默认值后,npm 将在项目目录中生成一个文件。此文件对于管理 Node.js 应用程序的依赖项、脚本和其他与项目相关的元数据至关重要。它会跟踪项目的依赖项及其版本,从而更轻松地在不同系统上共享和重现项目。package.jsonpackage.json

    总之,是一个命令,可帮助您为 Node.js 项目创建和配置文件,从而更轻松地管理依赖项和项目设置。npm initpackage.json

    11#Step — 让我们安装 。现在运行在 :nodemonproj_01/api/

    1. npm install --save-dev nodemon
    2. or
    3. npm install -D nodemon
    4. npm fund

    我们提到的两个命令执行以下操作:

    1. npm install --save-dev nodemon:此命令将包安装为 Node.js 项目的开发依赖项。 是一个实用程序,用于监视 Node.js 应用程序文件中的更改,并在检测到更改时自动重新启动服务器。该标志指定应添加到文件部分的标志。这通常用于仅在开发和测试期间(而不是在生产中)需要的工具和依赖项。nodemonnodemon--save-devnodemondevDependenciespackage.json
    2. npm fund:此命令用于显示有关项目中使用的文件包的资金选项的信息。它显示了有关如何在经济上支持您所依赖的软件包的维护者的信息。这是一种鼓励用户为开源项目做出贡献的方式,如果维护者已经设置了资金选项或捐赠平台的链接。
    3. 您还可以选择使用速记:-D
    npm install -D nodemon 

    这两个命令(或)都将正确地将nodemon安装为开发依赖项,并相应地更新您的package.json文件。--save-dev-D

    总之,第一个命令作为开发依赖项安装,这对于开发目的很有用,第二个命令用于检查与项目中使用的包相关的资金信息。nodemon

    这是我们的终端:

    1. ~/docker/proj_01/api$ npm install - save-dev nodemon
    2. added 35 packages, and audited 36 packages in 5s
    3. 3 packages are looking for funding
    4. run `npm fund` for details
    5. found 0 vulnerabilities
    6. ~/docker/proj_01/api$ npm fund
    7. api@1.0.0
    8. └─┬ https://opencollective.com/nodemon
    9. │ └── nodemon@3.0.1
    10. └─┬ https://paulmillr.com/funding/
    11. │ └── chokidar@3.5.3
    12. └── https://github.com/sponsors/jonschlinkert
    13. └── picomatch@2.3.1

    12#Step — 让我们安装和驱动程序。转到 :expressMySQLproj_01/api/

    npm install --save express mysql 

    该命令用于安装两个 Node.js 包和 ,并将它们另存为项目中的依赖项。npm install --save express mysqlexpressmysql

    • express:这个流行的 Node.js Web 应用程序框架简化了 Web 应用程序和 API 的构建。它提供了用于路由、处理 HTTP 请求和响应、中间件支持等的工具和功能。通过安装它并将其另存为依赖项(标志现已弃用,因此对于现代 npm 版本不是必需的),您可以包含在项目中,使其可用于代码。请参阅官方 NPM 文档--saveexpress
    • mysql:这是 MySQL 数据库的 Node.js 驱动程序。它允许您的 Node.js 应用程序与 MySQL 数据库交互,使您能够执行数据库操作,例如查询、插入、更新和删除数据。通过安装并另存为依赖项,您可以在项目中使用它来连接和使用 MySQL 数据库。mysql

    因此,该命令会安装这两个包并将它们添加到文件中的项目部分,从而允许您在 Node.js 应用程序中使用它们。npm install --save express mysqldependenciespackage.json

    13#Step —转到该文件并将以下代码添加到脚本部分中:proj_01/api/package.json

    1. ,
    2. "start": "nodemon ./src/index"

    整个文件的结果如下:

    proj_01/api/package.json

    1. {
    2. "name": "api",
    3. "version": "1.0.0",
    4. "description": "Docker intro",
    5. "main": "index.js",
    6. "scripts": {
    7. "test": "test",
    8. "start": "nodemon ./src/index"
    9. },
    10. "keywords": [
    11. "Docker"
    12. ],
    13. "author": "j3",
    14. "license": "ISC",
    15. "dependencies": {
    16. "-": "^0.0.1",
    17. "express": "^4.18.2",
    18. "mysql": "^2.18.1",
    19. "nodemon": "^3.0.1",
    20. "save-dev": "^0.0.1-security"
    21. }
    22. }

    在文件中,该部分用于定义可以使用 npm 执行的各种脚本或命令。此代码块定义了两个脚本:package.json"scripts"

    1. "test": "test":此脚本名为“test”,它与命令“test”相关联。此脚本的实际功能取决于它在项目中的实现方式。在许多 Node.js 项目中,“test”脚本用于运行自动化测试,例如使用 Mocha、Jest 等测试框架编写的测试。“test”脚本的特定行为应记录在项目的自述文件或单独的测试配置文件中。
    2. "start": "nodemon ./src/index":此脚本名为 ,它与命令 相关联。当您在终端中运行时,它将执行此处指定的命令,即 。此命令使用该工具通过运行位于 的文件来启动 Node.js 应用程序。 是一个实用程序,每当在指定文件中检测到更改时,它都会自动重新启动 Node.js 应用程序,这在开发过程中非常有用,可以在您进行代码更改时自动刷新服务器。startnodemon ./src/indexnpm startnodemon ./src/indexnodemon./src/indexnodemon

    因此,总而言之,这些脚本定义了可以使用 npm 执行的命令。 通常用于运行测试,通常用于启动 Node.js 应用程序,通常在开发期间通过 自动重新加载。"test""start"nodemon

    14#Step —请建立一个目录并将文件放在其中:/api/srcindex.js

    proj_01/api/src/index.js

    1. const express = require('express');
    2. const mysql = require('mysql');
    3. const app = express();
    4. const connection = mysql.createConnection({
    5. host: 'mysql-container', //'172.17.0.2', You can streamline this operation by employing the alias 'mysql-container' when executing the Docker run command with the addition of '--link mysql-container.'
    6. user: 'root',
    7. password: 'jaythree',
    8. database: 'outfit_db',
    9. insecureAuth: true // Add this line
    10. });
    11. connection.connect();
    12. app.get('/products', function(req, res) {
    13. connection.query('SELECT * FROM products', function (error, results) {
    14. if (error) {
    15. throw error
    16. };
    17. res.send(results.map(item => ({ name: item.product, price: item.unit_price })));
    18. });
    19. });
    20. app.listen(9001, '0.0.0.0', function() {
    21. console.log('Listening on port 9001');
    22. })

    注意:要获取 IP 地址:docker inspect mysql-container

    此指令将生成一组与指定容器相关的大量 JSON 格式的详细信息。我们的目标是使用以下格式查找网络 IP “IPAddress”: “172.17.0.2”

    15#Step —生成一个 Dockerfile 来设置 Node.js 应用程序:

    proj_01/api/Dockerfile

    1. FROM node:18-slim
    2. WORKDIR /home/node/app
    3. CMD npm start

    此 Dockerfile 定义了为 Node.js 应用程序创建 Docker 容器的指令:

    1. 它指定要用作起点的基本映像,即 。此映像包含 Node.js 版本 18,并且是 Node.js 映像的轻量级(苗条)版本。node:18-slim
    2. 它将容器内的工作目录设置为 。这是应用程序的文件和代码将放置在容器中的位置。/home/node/app
    3. CMD 指令指定容器启动时要运行的命令,即 。此命令通常用于启动项目文件中定义的 Node.js 应用程序。npm startpackage.json

    总体而言,此 Dockerfile 设置了一个运行 Node.js 应用程序的环境,将应用程序文件放在指定的目录中,并在启动容器时使用“npm start”启动应用程序。

    16#Step — 让我们为 Node.js 应用程序构建一个映像。

    转到:proj_01/

    docker build -t node-image -f api/Dockerfile .

    这是我的终端:

    1. j3@JAYTHREE:~/docker/proj_01$ docker build -t node-image -f api/Dockerfile .
    2. [+] Building 2.5s (6/6) FINISHED docker:desktop-linux
    3. => [internal] load build definition from Dockerfile 0.0s
    4. => => transferring dockerfile: 91B 0.0s
    5. => [internal] load .dockerignore 0.0s
    6. => => transferring context: 2B 0.0s
    7. => [internal] load metadata for docker.io/library/node:18-slim 2.4s
    8. => [1/2] FROM docker.io/library/node:18-slim@sha256:e5c8c319295f6cbc288e19506a9ac37afa3b330f4e38afb01d1269b579cf6a5b 0.0s
    9. => CACHED [2/2] WORKDIR /home/node/app 0.0s
    10. => exporting to image 0.0s
    11. => => exporting layers 0.0s
    12. => => writing image sha256:9edd82ba69b8e912e3f0e3ef876a14bb4f5a82f8b19b8bbeaa612cb1e642ae0e 0.0s
    13. => => naming to docker.io/library/node-image 0.0s
    14. What's Next?
    15. View summary of image vulnerabilities and recommendations → docker scout quickview

    17#Step — 现在在以下位置运行节点容器proj_01/

    容器 # 2

    docker run -d -v $(pwd)/api:/home/node/app -p 9001:9001 --link mysql-container --rm --name node-container node-image

    该标志用于指定端口映射。-p

    以下是在此上下文中执行的操作:-p

    1. -p 9001:9001:此标志将主机上的端口映射到 Docker 容器内的端口。在本例中,它将主机上的端口 9001 映射到容器内的端口 9001。定向到主机上端口 9001 的任何流量都将转发到容器的端口 9001。
    2. 使用该标志链接两个容器。这允许Web应用程序容器轻松地与MySQL容器进行通信。--link

    当您在侦听特定端口的 Docker 容器中运行服务,并且您希望从主机访问该服务时,通常会使用此方法。通过指定此端口映射,可以与容器中运行的服务进行交互,就像它直接在主机上运行一样。

    因此,在此特定示例中,对主机上的端口 9001 发出的任何请求都将转发到在名为 的 Docker 容器内运行的 Node.js 应用程序。node-container

    18#step — 如果您打开 Web 浏览器并导航到 ,它将断言:http://localhost:9001/

    不:/

    转到您的 Docker 桌面终端 在选项卡中,您将看到以下内容:/Logs

    错误:ER_NOT_SUPPORTED_AUTH_MODE:客户端不支持服务器请求的身份验证协议;考虑升级 MySQL 客户端

    此问题已在 StackOverflow 上的线程中得到解决。

    解决方案:请重复步骤#8,一旦进入MySQL容器的终端,输入以下命令:

    1. ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'jaythree';
    2. or
    3. ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
    4. flush privileges;
    5. exit

    在 Docker 桌面选项卡内,请运行这些脚本 👆️ 终端

    19#step — 在 Docker Desktop 中停止并重新初始化此容器。

    按以下顺序刷新两个容器,方法是单击按钮:Restart

    重新启动 mysql 容器并...

    重新启动节点容器。

    20#step — 现在导航到:

    http://localhost:9001/products

    瞧!您的 API 已启动并平稳运行,并按预期响应!

    21#step — 让我们继续创建一个 PHP 应用程序,该应用程序将与该 API 交互并使用该 API。

    转到:

    proj_01/website/index.php

    1. Docker Intro | Jungletronics
    2. $result = file_get_contents("http://node-container:9001/products");
    3. $products = json_decode($result);
    4. ?>
    5. Inspirational Clothing and Fashion Catalogue:

    6. ProductPrice
      product; ?>unit_price; ?>
  • Please visit this post on our Outfit App:
  • 22#step — 为您的 PHP 应用程序创建另一个 docker 文件:

    proj_01/website/Dockerfile

    1. FROM php:7.2-apache
    2. WORKDIR /var/www/html

    23#step — 在其上构建映像app_01/:

    docker build -t php-image -f website/Dockerfile .

    24#step — 运行 php 容器

    容器 # 3

    docker run -d -v $(pwd)/website:/var/www/html -p 8888:80 --link node-container --rm --name php-container php-image

    25#step —浏览至:

    http://localhost:8888/

    26#step - 启用引导程序以增强网页的外观。

    下载适用于 Bootstrap v5.0.2 的即用型编译代码,轻松放入您的项目中。

    请点击提供的链接下载ZIP文件。下载后,提取其内容,然后将解压缩的文件夹重命名为 .bootstrap

    将文件保存在目录中。proj_01/website/vendor

    27#step — 转到并在 app_01/website/index.php

     

    28#step — 在 Docker Desktop 中访问 MySQL 容器的终端并引入新产品。观察此添加是否同时反映在 API 和网站中。

    29#step — 创建一个 Docker 组合:

    proj_01/docker-compose.yml

    1. version: "3.7"
    2. services:
    3. db:
    4. image: mysql-image
    5. container_name: mysql-container
    6. command: --default-authentication-plugin=mysql_native_password
    7. environment:
    8. MYSQL_ROOT_PASSWORD: jaythree
    9. volumes:
    10. - ./api/db/data:/var/lib/mysql
    11. restart: always
    12. api:
    13. build: ./api
    14. container_name: node-container
    15. restart: always
    16. volumes:
    17. - ./api:/home/node/app
    18. ports:
    19. - "9001:9001"
    20. depends_on:
    21. - db
    22. web:
    23. image: php-image
    24. container_name: php-container
    25. restart: always
    26. volumes:
    27. - ./website:/var/www/html
    28. ports:
    29. - "8888:80"
    30. depends_on:
    31. - db
    32. - api

    要达到预期的结果,只需执行:,就像魔术一样,一切都将被配置!docker-compose up -d

    给你!

    如果你也有兴趣学习Python,请考虑查看这篇文章。非常感谢您的关注!

    我相信这篇文章为您提供了有关 Docker 的更多见解。

  • 相关阅读:
    激活函数总结(三十九):激活函数补充(NFN、Hermite)
    【微信小程序】微信小程序自定义标题跟随滚动
    python实现将图片数据以LMDB方式存储
    AWS账号注册以及Claude 3 模型使用教程!
    论文字数和检测字数有什么区别?
    【Go语言刷题篇】Go完结篇|函数、结构体、接口、错误入门学习
    基于helm的方式在k8s集群中部署gitlab - 备份恢复(二)
    陇萃堂:CRM系统赋能业务人员以及渠道商,线上线下快速突破和拓展
    接口测试和性能测试的区别
    Vue3 - Pinia 状态管理,解构 store(Pinia storeToRefs API 详细使用教程)
  • 原文地址:https://blog.csdn.net/gongdiwudu/article/details/133146598