【在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:)

ba 复制代码
mkdir docker
cd docker
mkdir proj_01
cd proj_01
mkdir api
cd api
mkdir db
mkdir src
cd ..
mkdir website
cd website
mkdir vendor
cd ..
code . 

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

转到: :proj_01/api/db/Dockerfile

ba 复制代码
FROM mysql
ENV MYSQL_ROOT_PASSWORD jaythree 

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

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

ba 复制代码
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

ba 复制代码
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

ba 复制代码
CREATE DATABASE IF NOT EXISTS outfit_db;
USE outfit_db;
CREATE TABLE IF NOT EXISTS products (
    id INT AUTO_INCREMENT,
    sales_code INT NOT NULL,
    date date NOT NULL,
    store_id VARCHAR(255),
    product VARCHAR(255),
    qty INT NOT NULL,
    unit_price DECIMAL(10, 2),
    PRIMARY KEY (id)
);
INSERT INTO products VALUE(0, 65014, '2019-01-12', 'Shopping Morumbi', 'Aster Pants', 5, 114);
INSERT INTO products VALUE(0, 65014, '2019-01-12', 'Shopping Morumbi', 'Trench Coat', 1, 269);
INSERT INTO products VALUE(0, 65016, '2019-01/-2', 'Iguatemi Campinas', 'Peter Pan Collar', 2, 363); 

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

ba 复制代码
docker exec -i mysql-container mysql -uroot -pjaythree < api/db/script.sql 

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

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

ba 复制代码
docker exec -it mysql-container /bin/bash 
ba 复制代码
bash-4.4# mysql -uroot -pjaythree

mysql> USE outfit_db;
mysql> SELECT * FROM products;
exit
exit 

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

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

ba 复制代码
$ docker exec -i mysql-container mysql -uroot -pjaythree < db/script.sql
mysql: [Warning] Using a password on the command line interface can be insecure.

$ docker exec -it mysql-container /bin/bash
bash-4.4# mysql -uroot -pjaythree
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 8.1.0 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> USE outfit<em>_db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> SELECT * FROM products;
+----+------------+------------+-------------------+------------------+-----+------------+
| id | sales_</em>code | date       | store<em>_id          | product          | qty | unit_</em>price |
+----+------------+------------+-------------------+------------------+-----+------------+
|  1 |      65014 | 2019-01-12 | Shopping Morumbi  | Aster Pants      |   5 |     114.00 |
|  2 |      65014 | 2019-01-12 | Shopping Morumbi  | Trench Coat      |   1 |     269.00 |
|  3 |      65016 | 2019-01-02 | Iguatemi Campinas | Peter Pan Collar |   2 |     363.00 |
+----+------------+------------+-------------------+------------------+-----+------------+
3 rows in set (0.00 sec)

mysql> exit
Bye
bash-4.4# exit
exit 

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

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

ba 复制代码
sudo apt install npm

node -v
v18.13.0 

10#Step--- GoTo & type:

proj_01/api/ :

ba 复制代码
npm init  

这是我们终端的输出:

ba 复制代码
~/docker/proj_01/api$ npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (api) 
version: (1.0.0) 
description: Docker intro
entry point: (index.js) 
test command: test
git repository: 
keywords: Docker
author: j3
license: (ISC) 
About to write to /home/j3/docker/proj_01/api/package.json:

{
  "name": "api",
  "version": "1.0.0",
  "description": "Docker intro",
  "main": "index.js",
  "scripts": {
    "test": "test"
  },
  "keywords": [
    "Docker"
  ],
  "author": "j3",
  "license": "ISC"
}


Is this OK? (yes)  

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

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

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

11#Step --- 让我们安装 。现在运行在 :nodemon``proj_01/api/

ba 复制代码
npm install --save-dev nodemon

or

npm install -D nodemon

npm fund 

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

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

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

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

这是我们的终端:

ba 复制代码
~/docker/proj_01/api$ npm install - save-dev nodemon

added 35 packages, and audited 36 packages in 5s

3 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

~/docker/proj_01/api$ npm fund
api@1.0.0
└─┬ https://opencollective.com/nodemon
  │ └── nodemon@3.0.1
  └─┬ https://paulmillr.com/funding/
    │ └── chokidar@3.5.3
    └── https://github.com/sponsors/jonschlinkert
        └── picomatch@2.3.1 

12#Step --- 让我们安装和驱动程序。转到 :express``MySQL``proj_01/api/

ba 复制代码
npm install --save express mysql 

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

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

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

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

ba 复制代码
, 
    "start": "nodemon ./src/index" 

整个文件的结果如下:

proj_01/api/package.json

ba 复制代码
{
  "name": "api",
  "version": "1.0.0",
  "description": "Docker intro",
  "main": "index.js",
  "scripts": {
    "test": "test", 
    "start": "nodemon ./src/index"
  },
  "keywords": [
    "Docker"
  ],
  "author": "j3",
  "license": "ISC",
  "dependencies": {
    "-": "^0.0.1",
    "express": "^4.18.2",
    "mysql": "^2.18.1",
    "nodemon": "^3.0.1",
    "save-dev": "^0.0.1-security"
  }
}

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

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

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

14#Step ---请建立一个目录并将文件放在其中:/api/src``index.js

proj_01/api/src/index.js

ba 复制代码
const express = require('express');
const mysql = require('mysql');

const app = express();

const connection = mysql.createConnection({
  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.'
  user: 'root',
  password: 'jaythree',
  database: 'outfit_db',
  insecureAuth: true // Add this line
});

connection.connect();

app.get('/products', function(req, res) {
  connection.query('SELECT * FROM products', function (error, results) {

    if (error) { 
      throw error
    };

    res.send(results.map(item => ({ name: item.product, price: item.unit_price })));
  });
});


app.listen(9001, '0.0.0.0', function() {
  console.log('Listening on port 9001');
})

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

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

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

proj_01/api/Dockerfile

ba 复制代码
FROM node:18-slim
WORKDIR /home/node/app
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 start``package.json

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

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

转到:proj_01/

ba 复制代码
docker build -t node-image -f api/Dockerfile .

这是我的终端:

ba 复制代码
j3@JAYTHREE:~/docker/proj_01$ docker build -t node-image -f api/Dockerfile .
[+] Building 2.5s (6/6) FINISHED                                                                                                                                              docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                                                                          0.0s
 => => transferring dockerfile: 91B                                                                                                                                                           0.0s
 => [internal] load .dockerignore                                                                                                                                                             0.0s
 => => transferring context: 2B                                                                                                                                                               0.0s
 => [internal] load metadata for docker.io/library/node:18-slim                                                                                                                               2.4s
 => [1/2] FROM docker.io/library/node:18-slim@sha256:e5c8c319295f6cbc288e19506a9ac37afa3b330f4e38afb01d1269b579cf6a5b                                                                         0.0s
 => CACHED [2/2] WORKDIR /home/node/app                                                                                                                                                       0.0s
 => exporting to image                                                                                                                                                                        0.0s
 => => exporting layers                                                                                                                                                                       0.0s
 => => writing image sha256:9edd82ba69b8e912e3f0e3ef876a14bb4f5a82f8b19b8bbeaa612cb1e642ae0e                                                                                                  0.0s
 => => naming to docker.io/library/node-image                                                                                                                                                 0.0s

What's Next?
  View summary of image vulnerabilities and recommendations → docker scout quickview

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

容器 # 2

ba 复制代码
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容器的终端,输入以下命令:

ba 复制代码
ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'jaythree';

or 

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';


flush privileges;

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

ba 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Docker Intro | Jungletronics</title>
  <link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.min.css" />
</head>
<body>
  <?php
    $result = file_get_contents("http://node-container:9001/products");
    $products = json_decode($result);
  ?>
  <h1 style="text-align: center;">Inspirational Clothing and Fashion Catalogue:</h1>  
  <div class="container d-flex justify-content-center">  
    <table class="table">      
      <thead>
        <tr>
          <th>Product</th>
          <th>Price</th>
        </tr>
      </thead>
      <tbody>
        <?php foreach($products as $product): ?>
          <tr>
            <td><?php echo $product->product; ?></td>
            <td><?php echo $product->unit_price; ?></td>
          </tr>
        <?php endforeach; ?>
      </tbody>
    </table>
  </div>
  <footer style="text-align: center;">
    Please visit this post on our Outfit App:
    <a href="https://medium.com/jungletronics/simple-ecommerce-api-using-flask-b192e2079791">Simple eCommerce API using Flask - How to Get Started on Flask --- #flaskSeries #Episode00</a>
</footer>
</body>
</html>

22#step--- 为您的 PHP 应用程序创建另一个 docker 文件:

proj_01/website/Dockerfile

ba 复制代码
FROM php:7.2-apache
WORKDIR /var/www/html

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

ba 复制代码
docker build -t php-image -f website/Dockerfile .

24#step --- 运行 php 容器

容器 # 3

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

25#step ---浏览至:

ba 复制代码
http://localhost:8888/

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

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

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

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

27#step --- 转到并在 </head 上方添加此行>app_01/website/index.php

ba 复制代码
 <link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.min.css" />

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

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

proj_01/docker-compose.yml

ba 复制代码
version: "3.7"
services:
  db:
    image: mysql-image
    container_name: mysql-container
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_ROOT_PASSWORD: jaythree
    volumes:
      - ./api/db/data:/var/lib/mysql
    restart: always

  api:
    build: ./api
    container_name: node-container
    restart: always
    volumes:
      - ./api:/home/node/app
    ports:
      - "9001:9001"
    depends_on:
      - db

  web:
    image: php-image
    container_name: php-container
    restart: always
    volumes:
      - ./website:/var/www/html
    ports:
      - "8888:80"
    depends_on:
      - db
      - api

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

给你!

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

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

相关推荐
mit6.8241 小时前
[Docker#9] 存储卷 | Volume、Bind、Tmpfs | -v/mount | MySQL 灾难恢复 | 问题
linux·运维·docker·容器·架构
qq_167401511 小时前
Docker 组添加用户,设置允许普通用户操作 docker
docker·容器
Z1eaf_complete1 小时前
Docker的基础使用
运维·docker·容器·云计算
YRr YRr2 小时前
ubuntu ros 解决建完图后 保存的地图非常小的问题
linux·运维·ubuntu
李少兄2 小时前
Docker 命令总结:从入门到入土
docker·容器·eureka
想学习java初学者4 小时前
Docker compose部署elasticsearch(单机版)
运维·docker·容器
WEIII4 小时前
MySQL 主从复制原理与搭建实践
后端·mysql·docker
微刻时光5 小时前
Docker部署Nginx
运维·nginx·docker·容器·经验
小安运维日记6 小时前
CKA认证 | Day3 K8s管理应用生命周期(上)
运维·云原生·容器·kubernetes·云计算·k8s
陈小肚6 小时前
k8s 1.28.2 集群部署 docker registry 接入 MinIO 存储
docker·容器·kubernetes