Docker.控制台程序.发布

简介

缘起想试一下Docker的挂载,
根据我对挂载的理解就是容器中的一个文件,
对应宿主机中的一个文件.

我就想一下什么场景中会使用到这种,
后来想到可以写入日志,
就想着搞一个程序,就是专门用于新建日志.然后挂载测试.

第一想法其实是想搞一个Web应用,
容器运行起来之后,我们直接访问Web的api,
然后api可以将请求路径和参数,写入日志文件中.

但是,以前在Docker中发布过Web应用,
所以这次想试一试在Docker中部署一个控制台程序.

控制台程序,发布,Dockerfile

准备一个简单的控制台程序,

while
Console.ReadLine()

while在工作中已经很少用到了,"Console.ReadLine()"更是认识了之后一直没用过...
当然程序中最重要的是要写日志.
程序部分好说,然后发布.

我意外的是Dockerfile这次竟然也是一次成功了.
(现在编写Dockerfile还是磕磕绊绊的...主要是复制粘贴)

将发布文件上传到Linux服务器

记得上次上传文件还是在用{Xshell}+一个插件,
来完成文件上传的.
这次是用 {MobaXterm},功能更强大(使用更"傻瓜").

MobaXterm(按钮栏)=>会话=>会话设置=>SFTP
然后就是文件互相拖动即可.

//Linux上经常会忘了目录,比如我这次发布控制台程序,就忘了上次将Web程序发布到哪里去了...

//扩展.SFTP和FTP的区别.

镜像生成.Docker build又忘了...

距离上次生成镜像,已经过去了2个月左右了,只记得一个build,具体参数全忘...

#先确认下是否文件已经就位,别build了一个寂寞...
[root@VM_0_12_centos ~]# cd /usr/dockerPubTest/ConsolePro/
[root@VM_0_12_centos ConsolePro]# ls
dockerConsoleDemo.deps.json  dockerConsoleDemo.dll  dockerConsoleDemo.exe  dockerConsoleDemo.pdb  dockerConsoleDemo.runtimeconfig.json  Dockerfile

#确认发布文件都在,开始生成镜像.
[root@VM_0_12_centos ConsolePro]# docker build -t dc01 .
Sending build context to Docker daemon  189.4kB
Step 1/4 : FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base
3.1-buster-slim: Pulling from dotnet/core/runtime
...
Step 2/4 : WORKDIR /app
 ---> Running in bad776943dae
Removing intermediate container bad776943dae
 ---> da7d0f6af7e8
Step 3/4 : COPY . /app
 ---> 8f79950e496a
Step 4/4 : ENTRYPOINT ["dotnet", "dockerConsoleDemo.dll"]
 ---> Running in 4b94880913ad
Removing intermediate container 4b94880913ad
 ---> 6141b3f2bf13
Successfully built 6141b3f2bf13
Successfully tagged dc01:latest

看到生成镜像过程其实就是执行{Dockerfile}中的一行行命令.

#查看镜像,确实已经成功生成了.
[root@VM_0_12_centos ConsolePro]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dc01 latest 6141b3f2bf13 3 minutes ago 190MB

容器启动.Docker run

#启动镜像
[root@VM_0_12_centos ConsolePro]# docker run --name dci01 -ti dc01
Hello World!
********************************************
请输入第一数字
2
...

其中尴尬的程序第一次写的时候,
没有写退出输入,并且也忘了如何快捷键退出容器,
所以被自己写的程序困在里面了....
这时候想起命令行,经常会出现的"Y/N?"重要性...

容器.退出.快捷键=>{Ctrl + P + Q}

容器.进入.查看日志

#容器.进入
[root@VM_0_12_centos ConsolePro]# docker exec -it dci01 /bin/bash
#容器.列表.查看
root@35995f2eea16:/app# ls
Dockerfile  Log  dockerConsoleDemo.deps.json  dockerConsoleDemo.dll  dockerConsoleDemo.exe  dockerConsoleDemo.pdb  dockerConsoleDemo.runtimeconfig.json
#容器.列表.查看.Log
root@35995f2eea16:/app# cd Log/
root@35995f2eea16:/app/Log# ls
2020-09-22.txt

#容器.txt文件查看
root@35995f2eea16:/app/Log# vim 2020-09-22.txt
bash: vim: command not found
root@35995f2eea16:/app/Log# vi 2020-09-22.txt
bash: vi: command not found
root@35995f2eea16:/app/Log# cat 2020-09-22.txt
09/22/2020 13:22:28     ********************************************
09/22/2020 13:22:28     请输入第一数字
09/22/2020 13:22:33     输入正确=>2
09/22/2020 13:22:33     请输入第2数字
09/22/2020 13:22:34     输入正确=>3
09/22/2020 13:22:34     请输入算法["+","-","*","/"]!
09/22/2020 13:22:36     输入正确=>+
09/22/2020 13:22:36     结果:5
09/22/2020 13:22:36     ********************************************
...

经验+1...
记得以前查看文件都是用vim...
这次发现不好使了,只能再去搜了一下,
使用"cat"...
//cat,原来不是"猫"的意思,是"concatenate"缩写...
//扩展,vim和cat的区别.什么时候用vim,什么时候用cat?
//为什么不能用vim查看txt ...

容器.进入.执行我的程序,

[root@VM_0_12_centos ConsolePro]# docker ps -a
CONTAINER ID        IMAGE               COMMAND NAMES
35995f2eea16        dc01                "dotnet dockerConsol…"    dci01

#注意上面的那一列:COMMAND NAMES,进入控制台程序,
[root@VM_0_12_centos ConsolePro]# docker exec -ti dci01 dotnet dockerConsoleDemo.dll
Hello World!
********************************************
请输入第一数字
1
输入正确=>1
请输入第2数字
1
输入正确=>1
请输入算法["+","-","*","/"]!
+
输入正确=>+
结果:2
********************************************
...

附录_1_控制台程序代码

程序主体

class Program
{
	/// <summary>
	/// Game.1+1.
	/// </summary>
	/// <param name="args"></param>
	static void Main(string[] args)
	{
		Console.WriteLine("Hello!开始游戏?Y/N?");
		string tempLog = string.Empty;
		try
		{
			while (Console.ReadLine().ToLower().Equals("y"))
			{
				ConsoleAndLog("********************************************");
				ConsoleAndLog("请输入第一数字");
				var tempInput = Console.ReadLine();
				int firstNum = 0;
				while (!int.TryParse(tempInput, out firstNum))
				{
					ConsoleAndLog("请输入数字!");
					tempInput = Console.ReadLine();
					ConsoleAndLog("输入错误+1=>" + tempInput);
				}
				ConsoleAndLog("输入正确=>" + tempInput);

				ConsoleAndLog("请输入第2数字");
				int secondNum = 0;
				tempInput = Console.ReadLine();
				while (!int.TryParse(tempInput, out secondNum))
				{
					ConsoleAndLog("请输入数字!");
					tempInput = Console.ReadLine();
				}
				ConsoleAndLog("输入正确=>" + tempInput);
				ConsoleAndLog("请输入算法["+","-","*","/"]!");

				List<string> list = new List<string>() { "+", "-", "*", "/" };
				tempInput = Console.ReadLine();
				while (!list.Any(s => s.Equals(tempInput)))
				{
					ConsoleAndLog("警告:请手不要抖...然后输入+-*/!!!");
					tempInput = Console.ReadLine();
				}
				ConsoleAndLog("输入正确=>" + tempInput);
				switch (tempInput)
				{
					case "+":
						var logStr = string.Format("结果:{0}", firstNum + secondNum);
						ConsoleAndLog(logStr);
						break;
					case "-":
						Console.WriteLine(string.Format("结果:{0}", firstNum - secondNum));
						break;
					default:
						break;
				}
				ConsoleAndLog("下一局?Y/N?");
			}
		}
		catch (Exception ex)
		{
			ConsoleAndLog(ex.Message);
		}
	}

	/// <summary>
	/// 输出&记录日志
	/// </summary>
	/// <param name="str"></param>
	public static void ConsoleAndLog(string str)
	{
		Console.WriteLine(str);
		LogCommon.WriteLog(str);
	}
}

日志记录代码↓

/// <summary>
/// 日志
/// </summary>
public class LogCommon
{
	/// <summary>
	/// 记录日志
	/// </summary>
	/// <param name="debugstr"></param>
	public static void WriteLog(string debugstr)
	{
		FileStream fs = null;
		StreamWriter sw = null;
		try
		{
			string filename = DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
			//日志目录
			string folder = string.Concat(AppDomain.CurrentDomain.BaseDirectory, "/Log");
			if (!Directory.Exists(folder))
				Directory.CreateDirectory(folder);
			fs = new FileStream(folder + "/" + filename, System.IO.FileMode.Append, System.IO.FileAccess.Write);
			sw = new StreamWriter(fs, Encoding.UTF8);
			sw.WriteLine(DateTime.Now.ToString() + "     " + debugstr + "
");
		}
		catch (Exception ex)
		{
			throw ex;
		}
		finally
		{
			if (sw != null)
			{
				sw.Flush();
				sw.Dispose();
				sw = null;
			}
			if (fs != null)
			{
				//     fs.Flush();
				fs.Dispose();
				fs = null;
			}
		}

	}
}

附录_2_Dockerfile

#Dockerfile中的内容
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base
WORKDIR /app

COPY . /app
#"dockerConsoleDemo.dll"根据自己项目的名称修改
ENTRYPOINT ["dotnet", "dockerConsoleDemo.dll"]

结尾.

程序已经搞起,
现在要去搞挂载了....

原文地址:https://www.cnblogs.com/love-zf/p/13735656.html