Docker从入门到动手实践

https://www.cnblogs.com/nsky/p/10853194.html

dockerfile的图很好呢.

但是自己没有做实验 , 其实知识都挺好.

docker 入门资料,参考:https://yeasy.gitbooks.io/docker_practice/content/

Dockerfile常用命令,图片来源于网络

Dockerfile 打包控制台应用程序

新建一个控制台程序,控制台程序添加一个文本文件,去掉.txt 扩展名,改成Dockerfile 输入以下代码

FROM microsoft/dotnet:sdk AS build
WORKDIR /code
COPY *.csproj /code
RUN dotnet restore

COPY . /code
RUN dotnet publish -c Release -o out

FROM microsoft/dotnet:runtime
WORKDIR /app
COPY --from=build /code/out /app
ENTRYPOINT ["dotnet","console.dll"]

Program.cs 中编写测试代码

一切准备完成。就是build把项目打包成镜像了

切换到当前项目路径下。输入: docker build -t cn/console:v1 .

docker build -t :是打包固有的命令

cn/console:v1 :

cn:是组织名称或者说是用户名,如果你想把自己的镜像push到hub.docker 上,cn必须是你自己的用户名

console:是镜像名称

v1:是tag。一个标签,可以用来区分同一个镜像,不同用途。,如果不指定。默认是latest

. :代表当前目录为上下文,dockerfile也必定是在当前目录下

回车后,会看到一系列的执行步骤,dockerfile中。一条命令就是一个步骤

通过 docker images 可以查看所有镜像

通过docker images cn/console 查看相关镜像

比如我本地有3个 cn/console镜像,但tag不同

既然镜像有了。那么就可以根据镜像生成容器了。容器是镜像的一个实例。镜像运行起来才会有容器,就跟类和对象一样,new一个类,是实例化的操作

输入命令:

docker run --name myfirst cn/console:v1

因为是占用前端线程运行容器,所有界面无法继续输入命令了。可以Ctrl+c 结束容器运行

从上面的dockerfile。你会发现,我们是把源码打包成镜像的。也就算执行了restore,到Release操作

其实如果你是已经Release后的文件了。dockerfile可以更简单

FROM microsoft/dotnet
WORKDIR /app
COPY . /app
CMD ["dotnet","run"]

以上就是一个基础的程序打包成镜像,我觉得这不是重点,常用的应该是应用程序,而不是控制台程序

后面打算把net core api打包成镜像。在讲这个之前,我们先来搭建好环境。

Docker mysql

因为我有个阿里云服务器(CentOS7),然后有2台笔记本,一个是Docker for Windows 环境,一个是CentOS7,所以经常会在这3个环境中来回折腾

两种系统还是有区别的,至少我弄的时候,遇到过不少问题

1:for Windows中默认拉起的镜像都在C盘。会导致C盘越来越大,建议迁移

如果迁移的盘。比如我这个E盘。路径中已经存在MobyLinuxVM.vhdx 。是迁移不过的。要删除,但之前的镜像都没有了

如果你想保存,先重命名MobyLinuxVM.vhdx,迁移后。删除之后的。之前的重命名回来即可

2:共享盘。为了数据卷挂载用

3:配置镜像加速(https://hlef8lmt.mirror.aliyuncs.com)

然后可以去hub.docker上寻找需要的镜像,官方的mysql有2个镜像

当然你通过命令也可以收索到: docker search mysql

首先来看docker mysql

准备需要挂载的目录和文件,上面我设置的共享盘是D盘,所以挂载的在D盘

my.cnf配置文件,主要是设置mysql的参数

[mysqld]
user=mysql
character-set-server=utf8
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

data是空的。当run的时候,mysql会写入文件

sql是需要在运行myslq后执行的初始化文件,比如我这里是给刚创建的用户名分配权限

这里为了说明sql是执行成功的。我在加条。创建数据库的sql,创建数据库 docker和user表,并插入一条数据

GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' WITH GRANT OPTION;Create DATABASE docker;USE docker;CREATE TABLE user (ID int auto_increment primary key,name nvarchar(20),address nvarchar(50));insert into user(name,address)values('刘德华','香港');

初始化后就执行的好处是。不用在run后,去手动执行,关于run后手动执行,

可以查看我之前的docker安装mysql https://www.cnblogs.com/nsky/p/10413136.html

全部配置完成后,开始敲命令,以下命令需要去掉注释

docker run -d -p 3306:3306
--restart always #总是自动重启。比如系统重启,该容器会自动启动
-e MYSQL_USER=test #创建用户名test
-e MYSQL_PASSWORD=123456 #test密码
-e MYSQL_PASSWORD_HOST=% #test 开启外部登陆
-e MYSQL_ROOT_PASSWORD=123456  #root密码
-e MYSQL_ROOT_HOST=% #root开启外部登陆
-v /d/docker/mysql/my.cnf:/etc/my.cnf #配置文件
-v /d/docker/mysql/sql:/docker-entrypoint-initdb.d #初始化的sql
-v /d/docker/mysql/data:/var/lib/mysql  #data文件
--name mysql #镜像名称
mysql #基于那个镜像创建容器

执行成功没有异常后。通过  docker ps 可以查看运行的容器,如果没有, 那就通过 docker ps -a 一定会有的

现在可以通过Navicat连接试试

创建了docker库。user表也有数据,能看到mysql库,说明test用户是有权限的

当我使用mysql-server 镜像时,创建容器会无法启动

可以看到。启动失败后。又继续重启,因为参数指定了restart always

输入命令  docker logs mysql  查看启动日志

最后在my.cnf中加这个,经测试,启动成功,就不一一放图了

数据库准备好了,那么就快速的构建一个net core api 接口

1:引入NugGet包,MySql.Data.EntityFrameworkCore

2:创建DbContext

using Docker.Api.Model;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Docker.Api.Data
{
    public class DbUserInfoContext : DbContext
    {
        public DbUserInfoContext(DbContextOptions<DbUserInfoContext> options) : base(options) { }

        public DbSet<UseInfo> userInfos { get; set; }

        /// <summary>
        /// 模型创建时触发
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            /*
             修改表名和主键,user对应数据库的表,mysql默认是区分大小写的
             查看:show variables like '%lower%';
            lower_case_table_names 为 0 区分,1 不区分
             */
            modelBuilder.Entity<UseInfo>(b => b.ToTable("user").HasKey(u => u.id));

            //or
            //modelBuilder.Entity<user>()
            //    .ToTable("user")
            //    .HasKey(u => u.id);

            base.OnModelCreating(modelBuilder);
        }
    }
}

3:添加UserInfo控制器

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Threading.Tasks;
 5 using Docker.Api.Data;
 6 using Microsoft.AspNetCore.Http;
 7 using Microsoft.AspNetCore.Mvc;
 8 using Microsoft.EntityFrameworkCore;
 9
10 namespace Docker.Api.Controllers
11 {
12     [Route("api/[controller]")]
13     [ApiController]
14     public class UserInfoController : ControllerBase
15     {
16         private DbUserInfoContext _DbUserInfoContext;
17         public UserInfoController(DbUserInfoContext context)
18         {
19             _DbUserInfoContext = context;
20         }
21         [HttpGet]
22         public async Task<IActionResult> Get()
23         {
24             return new JsonResult(await _DbUserInfoContext.userInfos.FirstOrDefaultAsync());
25         }
26     }
27 }

4:配置sql连接字符串: server=localhost;port=3306;userid=test;password=123456;database=docker

run项目。访问能成功获取信息

容器互连,Docker Network

接下来我们把这个api也打包成镜像,然后连接mysql镜像。这称之为容器互连

容器互连有3种方式

1:Link方式。已经被docker淘汰,docker官方不推荐使用该方式

2:Bridger,桥接的方式,单台机器用

3:Overlay 适用于集群时候用

Overlay 就我目前环境不适合测试,集群也不懂。就不搞了

说说LInk和Bridger方式,具体理论知识请看docker官方文档。我这里只实践

现在一切来回忆下

刚上面打包控制台应用程序用的是:microsoft/dotnet 镜像

然后后面带上tag

比如:

Micirosoft/dotnet:sdk

包含了运行时和sdk命令,打包后会很大,因为包含sdk,一般用于测试环境

Microsoft/dotnet:<version>-runtime

包含运行时,不包含sdk,打包后就很小了,一般用于正式环境

Microsoft/dotnet:<version>-runtime-deps

打包的时候,会自包含runtime,也就是部署的机器有没有runtime是没有关系

上面2种,必须机器要包含core环境

修改程序port运行在80上

编写api的Dockerfile

我这里用的sdk,因为要用到sdk命令比如dotnet restore,dotnet publish

如果已经publish的文件,直接用runtime会方便很多。上面也有提及

 1 #FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
 2 FROM microsoft/dotnet:2.2-sdk AS build
 3 WORKDIR /src
 4 WORKDIR /source
 5 #这里的后面的 . 就是/source 路径
 6 #或者 COPY *.csproj /source
 7 COPY *.csproj .
 8 RUN dotnet restore
 9 COPY . .
10 # 发布到 /source/out 下
11 RUN dotnet publish -c Release -o out
12
13 #FROM mcr.microsoft.com/dotnet/core/runtime:2.2
14 FROM microsoft/dotnet:2.2-aspnetcore-runtime
15 WORKDIR /app
16 COPY --from=build /source/out .
17 EXPOSE 80
18 ENTRYPOINT ["dotnet","Docker.Api.dll"]

开始build项目 docker build -t cn/myapi .

可以看到。这里没有指定tag。所以默认是latest,size也不大

成功后开始run一个容器,不过这之前要先:

准备挂载目录。因为配置文件 appsettings 会需要动态配置,所以挂载出来

还有,比如一个网站都有log日志,这些也需要挂载出来。便于管理。

我这里就只挂载appsettings.json

执行命令:

docker run -d -p 80:80 --restart always --link mysql:mysqldb -v /d/docker/myapi/appsettings.json:/app/appsettings.json --name api cn/myapi

分析:

--restart always :总是重启

-d:是在后台执行

-p 80:80 :第一个80是暴露给外部的。第二个80是程序的。

--link mysql:mysqldb : mysql是容器名称,mysqldb是自定义名称,可以理解为服务器

-v /d/docker/myapi/appsettings.json:/app/appsettings.json:这里就是挂载外部的数据卷了

也许你会问。我怎么知道这个路径的:/app/appsettings.json。从编写的dockerfile能分析出来,待会也可以进入容器看看

最有的工作目录是 根路径下: /app

然后通过页面访问试试

发现依然无法访问,因为修改appsettings.json的连接方式

记住这里是修改D:\docker\myapi\appsettings.json ,因为已经挂载出来

把server改成mysqldb,然后重启容器: docker restart api

再次刷新页面

我们 进入容器看看: docker exec -it api bash 可以看到根目录下存在app目录

进入app目录

个人认为link方式是最简单的。在这3种中,接下来看看Bridge方式

1:首先创建一个网络 network,名称叫api2bridge

docker network create -d bridge api2bridge

通过: docker network ls 可以查看到已经创建成功

2:实例化容器

为了区别于上面的80端口,这里新增一个8081

docker run -d -p 8081:80 --restart always  -v /d/docker/myapi/appsettings.json:/app/appsettings.json --net api2bridge --name api2 cn/myapi

创建容器的时候,自定network 这里的--net api2bridge 就是上面的bridge

3:连接2个容器,通过: docker network connect api2bridge mysql  把api2和mysql连接起来

4:修改appsettings.json  server=mysql

5 : restart 容器,如果是在创建容器前修改的配置文件。是不需要重启的,测试通过

看看这两个容器是怎么连接的。通过命令: docker inspect api2bridge 可以查看对象的元数据(容器或者网络)

分别看看;

docker inspect api2

docker inspect mysql

你会发现mysql有个"IPAddress":地址,

上面我们在api2中的appsettings.json的server是直接些的容器名称:mysql。也可以直接些这个ip地址。比如: server=172.20.0.3 同样是可以的。

Overlay方式就不讲了。因为我也不知道。哈哈

docker-compose 容器编排

通过这几个例子你会发现。2个容器要部署2个,如果项目依赖mysql,redis,MQ等等。那得部署多次,如此重复性的工作会影响效率

所以有了docker-compose,compose

参考:https://yeasy.gitbooks.io/docker_practice/content/compose/install.html

安装:

sudo curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

安装完成后,可以通过: docker-compose --version 查看版本

通过: docker-compose --help 查看基本的命令

不过我英文不好,就通过百度翻译了,翻译得有点生硬。仅供参考

Commands:
  build              建立或重建服务
  bundle             从撰写文件生成Docker捆绑包
  config             验证并查看撰写文件
  create             创建服务
  down               停止并删除容器、网络、图像和卷
  events             从容器接收实时事件
  exec               在正在运行的容器中执行命令
  help               获取有关命令的帮助
  images             列表图像
  kill               杀死容器
  logs               查看容器的输出
  pause              暂停服务
  port               打印端口绑定的公共端口
  ps                 列表容器
  pull               拉取服务图像
  push               推送服务图像
  restart            重新启动服务
  rm                 移除停止的容器
  run                运行一次性命令
  scale              设置服务的容器数
  start              启动服务
  stop               停止服务
  top                显示正在运行的进程
  unpause            取消暂停服务
  up                 创建和启动容器
  version            显示Docker撰写版本信息

目前为止已经有3个容器了,

为了区别于之前的mysql和api和api2,这里命名要修改,编写在程序根目录下添加docker-compose.yml文件

compose用的是yml语法。可以参考阮一峰些的文章

http://www.ruanyifeng.com/blog/2016/07/yaml.html

项目准备。依然在上面的api项目中添砖加瓦

还记得上面初始化的创建docker库,user表吗。这里我们通过在代码中来实现,

场景:创建myslq的时候,判断数据库是否有数据,否则新增一条数据

技术栈:项目依赖mysql,redis,其实我工作中用的都是mssql,所以待会也会介绍

1:init.sql 只保留一条sql语句

2:新增UserInit类。用于初始化数据

using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Docker.Api.Data
{
    public class UserInit
    {
        private ILogger<UserInit> _logger;

        public UserInit(ILogger<UserInit> logger)
        {
            _logger = logger;
        }

        public static async Task InitData(IApplicationBuilder app, ILoggerFactory loggerFactory)
        {

            using (var scope = app.ApplicationServices.CreateScope())
            {
                var context = scope.ServiceProvider.GetService<DbUserInfoContext>();
                var logger = scope.ServiceProvider.GetService<ILogger<UserInit>>();
                logger.LogDebug("begin mysql init");
                context.Database.Migrate();
                if (context.userInfos.Count() <= 0)
                {
                    context.userInfos.Add(new Model.UseInfo
                    {
                        name = "admin",
                        address = "博客园"
                    });
                    context.SaveChanges();
                }
            }
            await Task.CompletedTask;
        }
    }
}

程序启动调用:

3:实体类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Docker.Api.Model
{
    public class UseInfo
    {
        public int id { get; set; }
        public string name { get; set; }
        public string address { get; set; }
    }
}

4:DbContext 上面也列出,这里就不展示了

5:RedisHelper网络有。这里也不提了

只准备2个接口。用于测试redis。一个读,一个写

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Docker.Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class RedisController : ControllerBase
    {
        [HttpPost]
        public void Post()
        {
            RedisCommon.GetRedis().StringSet("docker", "hello", TimeSpan.FromMinutes(1));
        }
        [HttpGet]
        public string Get()
        {
            var docker = RedisCommon.GetRedis().GetStringKey("docker");
            if (docker.HasValue) return docker.ToString();
            return "empty";
        }
    }
}

6:根据Model生成Migration,这里简单过一下,具体参考我之前的:https://www.cnblogs.com/nsky/p/10323415.html

调出程序包管理控制台

输入: Add-Migration init

如果成功了就会这样:

编写docker-compose.yml 文件,我这里的注释是便于理解。尽量不要写

注:我是直接在项目中创建的文本文件,然后修改后缀名

在网络上看到说。如果是在外部创建的记事本。要修改编码为:ASCII编码格式,我未测试

version: '3'

services:
  db:
    image: mysql
    container_name: 'mysql01'
    command: --character-set-server=utf8 --collation-server=utf8_general_ci
    restart: always
    ports:
      - '3307:3306'
    environment:
      MYSQL_USER: test
      MYSQL_PASSWORD: 123456
      MYSQL_PASSWORD_HOST: '%'
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_ROOT_HOST: '%'
    volumes:
      - /d/docker/mysql02/my.cnf:/etc/my.cnf
      - /d/docker/mysql02/data:/var/lib/mysql
      - /d/docker/mysql02/SqlInit:/docker-entrypoint-initdb.d
  redis:
    image: redis
    container_name: 'redis'
    command: redis-server /usr/local/etc/redis/redis.conf
    restart: always
    ports:
      - '6379:6379'
    environment:
      requirepass: 123456 #redis密码
      appendonly: 'yes' #redis是否持久化
    volumes:
      - /d/docker/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf
      - /d/docker/redis/data:/data #这里会保存持久化数据
  web:
    build: . #会执行当前目录下面的dockerfile文件
    container_name: 'api3' #容器名称
    restart: always # web依赖于db,如果web比db启动快。就连接不上db导致web异常,web容器启动失败,restart可以不断重试,直到连接为止
    volumes:
      - /d/docker/myapi/appsettings.json:/app/appsettings.json
    ports:
      - '8082:80'
    depends_on: #依赖db容器,并不代表执行顺序
      - db
      - redis

如果想看编写的yml文件是否正确,可以去在线的网站,验证是否正确,比如:http://nodeca.github.io/js-yaml/

切换到当前目录输入: docker-compose build 会开始build项目成镜像

查看镜像:名字叫dockerapi_web

输入命令: docker-compose up 会开始创建容器并启动

输出的日志太多。这里只点几个有用的看

EFcore插入Migration历史记录

创建表:

直到最后,程序阻塞。显示成功,因为这里没用用 -d 会阻塞,调试的时候不建议 -d

然后新打开一个PowerShell,输入docker ps 查看运行的容器

分别测试是否成功

同样验证redis,用RedisDesktopManager连接

从容器可以看出api3端口是8082,尝试访问下

测试写redis,打开Postman写入Redis

写人成功

那么读取就不是什么大问题了

问题汇总:

如果你修改了代码,需要重新build。那么先删除容器: docker-compose down 会停止容器并删除

docker-compose ps 查看容器列表

docker-compose up -d  后端运行,不阻塞前端

docker-compose restart  重启所有容器。

自此所有容器成功运行,但我感觉还不够,因为一直都是在windos上玩。而没有上CentOS7,可我又不缺CentOS环境。所以要玩一把

net core Api 跨平台部署

技术栈:Jexus,mysql,mssql,redis

关于jexus部署net core 可以参考我前面写的文章:https://www.cnblogs.com/nsky/p/10386460.html

既然要加入新的成员。jexus 和 mssql,那么就得修改docker-compose文件

在通过docker-compose统一打包前,我们先来单独玩玩mssql

准备数据卷挂载目录

data:保存数据库文件

sql:执行的脚本。mssql没有mysql的docker-entrypoint-initdb.d 挂载,启动mysql就执行sql。这里sql文件夹

虽然保存的是.sql文件。但要手动执行,不知道是不是我没有找到具体的方案

sql里面放一个init.sql文件。编写sql脚本如下

这里要注意一点,一条语句完成必须要带一个Go语句

参考官方文档:

https://docs.microsoft.com/zh-cn/sql/linux/quickstart-install-connect-docker?view=sql-server-2017&pivots=cs1-bash

https://docs.microsoft.com/zh-cn/sql/linux/tutorial-restore-backup-in-sql-server-container?view=sql-server-2017

镜像文档:https://hub.docker.com/_/microsoft-mssql-server

//注释部分
docker run -d -p 1433:1433 \
-e ACCEPT_EULA=Y \ #确认您接受最终用户许可协议。
-e SA_PASSWORD=DockerPwd123 \ #强大的系统管理员(SA)密码:至少8个字符,包括大写,小写字母,基数为10的数字和/或非字母数字符号。
-e MSSQL_PID=Express \ #版本(Developer,Express,Enterprise,EnterpriseCore)默认值:Developer
-v /docker/mssql:/var/opt/mssql \  # 映射数据库
v /d/docker/mssql/sql:/script #把需要执行的脚本放这里,script路径随便改,不是初始化执行,是手到执行
--name mssql #容器名称
mcr.microsoft.com/mssql/server #镜像

执行成功后。数据卷挂载目录。生成了文件

此时data也有默认的数据库了

通过 MSSMS(  Microsoft SQL Server Management Studio )连接试试

刚上面说了sql中文件是没有被执行的。必须手动执行。

手动执行前,先来看看其他一些相关命令

进入容器后: docker exec -it mssql bash

登陆数据库:localhost也可以用指定的ip代替,如果有端口。则带端口号即可

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P DockerPwd123

-S 是服务器,不管端口是多少,都不用写
-U 是用户名
-P 是密码

如果出现 1> 说明的登陆成功了

可以输入语句:select getdate() 试试,回车后,需要加Go语句,不过日期怎么不对?好像是相差8个时区

执行sql中的文件

登陆容器后执行操作: /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P DockerPwd123 -i /script/init.sql

挂载目录也有,这样就算容器无法进入。数据库也存在

由于时间问题,docker-compose 就不加入mssql,只加jexus,修改docker-compose如下

阿里云安装docker-compose 特别慢,今天就不写。后期在加上

关键时刻掉链子,写了这么多。其实也就一点皮毛而已,docker强大之处远远不止这些

未完待续

Portainer管理镜像

上传镜像到hub.docker

源码:https://github.com/byniqing/docker-compose

[转帖]Docker从入门到动手实践的更多相关文章

  1. Docker从入门到动手实践

    一些理论知识,我这里就不累赘了 docker 入门资料,参考:https://yeasy.gitbooks.io/docker_practice/content/ Dockerfile常用命令,图片来 ...

  2. Docker 从入门到实践(一)Docker 简介

    读前须知:本教程大部分都是[Docker 从入门到实践 ]一书的知识,有兴趣可以直接观看书籍.同时,借鉴书籍的知识,如有侵权,请告知我,我会删除处理.谢谢. 一.什么是 Docker? Docker ...

  3. 微服务 + Docker + Kubernetes 入门实践 目录

    微服务 + Docker + Kubernetes 入门实践: 微服务概念 微服务的一些基本概念 环境准备 Ubuntu & Docker 本文主要讲解在 Ubuntu 上安装和配置 Dock ...

  4. Docker 入门教程与实践

    title: Docker 入门教程与实践 tags: Docker ---- 在Windows上安装Docker客户端 1.下载Docker TollBox: https://docs.docker ...

  5. Docker从入门到实践

    一般说来 SPA 的项目我们只要启一个静态文件 Server 就可以了,但是针对传统项目就不一样了,一个项目会依赖很多服务端程序.之前我们的开发模式是在一台开发机上部署开发环境,所有人都在这台开发机上 ...

  6. 学习资源 Docker从入门到实践 pdf ,docker基础总结导图

    学习资源 Docker从入门到实践 pdf ,docker基础总结导图 Docker从入门到实践 pdf 云盘地址:https://pan.baidu.com/s/1vYyxlW8SSFSsMuKaI ...

  7. 小白学 Python 爬虫(4):前置准备(三)Docker基础入门

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  8. Docker快速入门

    Docker已经火了很长一段时间,最近打算在阿里云上好好熟悉一下Docker的相关应用,为今后的工作做准备. 基本概念 Docker是基于Go语言实现的云开源项目,诞生于2013年初,最初发起者是do ...

  9. Docker新手入门:基本用法

    Docker新手入门:基本用法 1.Docker简介 1.1 第一本Docker书 工作中不断碰到Docker,今天终于算是正式开始学习了.在挑选系统学习Docker以及虚拟化技术的书籍时还碰到了不少 ...

随机推荐

  1. SpringBoot框架(3)--条件装配

    场景:需要根据系统的编码格式有选择装配类. 分析:最直接的实现方式,定义各种编码格式对应的处理类,可以通过System.getProperty("file.encoding")获得 ...

  2. 使用linq将2个Datatable合并

    DataTable dtStepX = new DataTable("dtStepX"); DataTable dtStepS = new DataTable("dtSt ...

  3. cpu、gpu 安装框架pytorch,cntk,theano及测试

    一,cpu 下安装 tensorflow conda env list source activate tensorflow 直接安装相应版本 python import tensorflow as ...

  4. node.js入门学习(四)--Demo图书的增删改查

    需求:图书的增删改查,图书数据保存在data.json文件中. 1.Demo结构: 2.首先下载安装node.js,配置环境变量:参考博客 3.项目初始化 1)创建项目根目录node-hello,进入 ...

  5. eclipse设置酷炫的代码颜色风格

    eclipse安装默认的代码颜色风格是“白色背景”,颜色有些刺眼,于是想到手动去改eclipse的代码颜色,但改来改去还是很难达到我们的要求,甚至有时候将背景和某些代码的颜色改成相同,导致代码看不见. ...

  6. 关于项目中的一些经验:封装activity、service的基类,封装数据对象

    经验一,将几个页面公用的数据,和方法进行封装,形成一个baseActivity的类: package com.ctbri.weather.control; import java.util.Array ...

  7. 【Python】学习笔记二:基本数据类型

    变量 python的变量不需要提前声明,可以直接输入: >>> str = 'oliver' 此时,str已经被赋值字符串oliver,在赋值之前并没有提前定义与事先声明 打印值 & ...

  8. pwd命令学习

    pwd命令学习 1.学习pwd命令 pwd命令功能为输出当前所在工作目录的绝对路径名称. 绝对路径和相对路径: 绝对路径:从根目录开始直到文件位置 相对路径:相对于程序当前所在目录到文件位置 例:程序 ...

  9. vue中下载excel的使用,后端链接两种情况,一个是链接,一个是文件流

    vue中下载excel使用 一.这是第一种情况,后台链接地址返回的是一个url,这个时候我只要在导出按钮上绑定exportData()这个事件方法就好了 exportData() {     this ...

  10. SQL Server新老版本CE区别

    对比CE7和2014 CE12的区别: 1.表连接中连接列估算方式 老CE对所有参与连接列的统计信息step进行逐个估算.新CE只对于最大和最小step统计信息进行收集估算,在连接列的值分布不均匀的时 ...