【在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 的更多见解。

相关推荐
CAFEBABE 3428 分钟前
linux离线安装docker并启动
linux·docker·eureka
yuguo.im3 小时前
Docker 两大基石:Namespace 和 Cgroups
运维·docker·容器
会飞的土拨鼠呀3 小时前
docker部署 outline(栗子云笔记)
笔记·docker·容器
Jelly-小丑鱼4 小时前
Linux搭建syslog日志服务器
linux·服务器·docker·日志服务器·syslog服务器
没有bug.的程序员4 小时前
高频IO服务优化实战指南
java·jvm·spring·容器
starvapour6 小时前
Ubuntu硬盘的创建分区、格式化与挂载
linux·ubuntu
lisanmengmeng6 小时前
docker 方式安装部署禅道zentao(五)
运维·docker·容器
程序员老赵6 小时前
AdguardHome Docker 容器化部署指南
docker·dns
露临霜7 小时前
Docker安装nginx
nginx·docker·容器
CAFEBABE 349 小时前
安装完docker之后怎么使用
运维·docker·容器