假设我们有一个服务器 ip xxx.xxx.xxx.xxx 密码 xxxxx 用户 root
并且有一个项目hello-world,现在需要使用ssh+docker把它搬到服务器上。
远程连接服务器
ssh root@xxx.xxx.xxx.xxx !ssh #非第一次连接可用,会自动使用上次ssh的用户名和ip
然后按照提示输入密码xxxxx,就可以通过终端操作服务器了。
本机和服务器之间的数据传输
语法和栗子:
scp 本机源路经 用户名@ip:目标路径#本机传给服务器scp 用户名@ip:源路径 本机目标路径#从服务器上下载scp hello-world.zip root@xxx.xxx.xxx.xxx:/
另外需要使用cd,ls,rm等命令
解决依赖问题
以上操作后代码肯定是跑不起来的,这时候就需要依赖的安装。推荐使用docker来获得所需的环境。
docker可理解为一个轻量级的虚拟机,在/可以找你需要的基础款,然后以此为基础配置环境跑代码。
比如我需要跑机器学习,拉一个pytorch/pytorch的docker我就不用再配一遍pytorch了!
docker有两个概念要提前了解,一个是镜像,是虚拟机的定义(类),一个是容器,是虚拟机的实体(对象)
docker的安装
参考/docker/docker-tutorial.html中的步骤
注意,是安装在服务器上,本机docker是后面镜像制作时才需要安装的。以下操作若无说明都是在ssh连接的服务器终端上进行的。
初学版:拉个docker然后在里面装依赖(非练习者须先看下一部分)
首先拉一个合适的镜像:
docker pull 你需要的镜像名字
具体要哪个镜像可以去/查, 也可以使用
docker search 查找关键词
来进行查找
理论上应该也可以查到版本…但我没找到在哪看可用版本。
另外可能需要换源操作,网上资料很多可以自行搜索解决。随便帖个链接在这:/docker/458929.html
拉下来后,查看所有镜像:
docker images
然后就可以创建容器,举个栗子:
docker run -p 8000:80 -it 你拉的镜像名字 /bin/bash
其中p是端口映射,将容器的80端口映射到服务器的8000端口上。其它参数表达操作模式,这里是终端shell交互。
-it默认会直接进入docker中。说明一下现在的结构,你有一个本地电脑,本机通过ssh连了一个服务器,服务器里面有一个docker(约等于虚拟机)。你目前在docker中,输入exit可以回到服务器中,再输入exit可以回到本机中。
一般来讲,现在需要退出docker,把你的项目从服务器拉进docker中。
回到服务器后,我们有命令查看所有容器:
docker ps -a
记下你的容器id,使用以下命令进行文件传输:
docker cp 本地文件的路径 容器id:容器内的路径#将服务器内文件传入容器docker cp /hello-world.zip 123456789:/hello-world.zipdocker cp 容器id:容器内的路径 本地文件的路径#同理反过来就是传出来
然后可以通过以下命令进入容器
docker start 容器iddocker attach 容器id
最后就可以pip requirements.txt什么的了。记得换apt和pip的源。
还有一个常见需求是,如何使容器内的进程一直运行。如果程序设置为自动启动那很简单,直接start就可以了,但如果需要进容器打开,attach就不行了,会在退出的时候关掉容器。这时候须使用:
docker exec -it 容器id /bin/bash
来代替attach来进行容器操作。
python如何后台运行:
nohup python py 文件> log文件 &nohup python hello-world.py > hello-world-log &
如果需要标准操作流程或在多个服务器安装…
整体流程:使用dockerfile在本地电脑将所有环境和文件打包成一个镜像,通过某种方法传到服务器上,在服务器上通过镜像启动容器即可。
首先在合适的路径下创建一个名字叫Dockerfile的文件。在文件中定义镜像构建的规则,以下是一个简单的示例:
#声明构建起始的基础款镜像,#对应上述过程中“docker pull 你需要的镜像名字”FROM nvcr.io/nvidia/pytorch:21.10-py3#将本机中和Dockerfile同级目录下的requirements.txt复制到镜像中的.目录下COPY requirements.txt .#RUN命令可以理解为在镜像中执行终端命令,此处为安装依赖RUN pip install -r requirements.txt -i /pypi/simple/ --trusted-host #创建一个工作目录(非必须)RUN mkdir -p /usr/src/app#修改默认工作路径WORKDIR /usr/src/app#将本机中的文件(比如脚本,图片,模型)拷贝进镜像#对应上述过程中“docker cp 本地文件的路径 容器id:容器内的路径”COPY . /usr/src/app#CMD指的是运行容器而非构建镜像时使用的命令CMD python hello-world.py#或者仍需要重定向,可使用:#CMD ["/bin/bash","-c","nohup python hello-world.py > hello-world-log"]#注意,不可用&,必须是前台进程,否则容器会认为没有任务直接关掉自己#更优秀的写法是写个启动脚本:
#容器秒退可能是因为权限不够,不清楚是否必要RUN chmod 777 start_py.sh#运行脚本CMD ["/bin/bash", "-c", "./start_py.sh"]
shell脚本中就和终端命令一样:
nohup python hello-world.py > hello-world-log &nohup python hello-china.py > hello-china-log &#不能多个前台,但也不能全是后台nohup python hello-zhejiang.py > hello-zhejiang-log
更多功能可参考/docker/docker-dockerfile.html
创建好Dockerfile后,终端进入Dockerfile存放的目录,运行
#最后的.指的是上下文路径docker build -t 你期望的镜像名字:版本号 .
如果Dockerfile写错了可以修改完毕后再次运行build,并且镜像名字保持一致,只修改版本号,docker会自动复用已经构建好的层。
然后就有一个镜像了!接下来有两个选择:
将镜像打包成tar压缩文件,传输到服务器上,再通过压缩文件读取镜像
打包命令:
docker save -o 压缩包名称.tar 你的镜像名字:版本号
从压缩包中读取镜像的命令:
docker load -i 压缩包名称.tar
若加载镜像后不显示名字和版本号,可使用命令:
docker tag 镜像id 你的镜像名字:版本号
镜像id可以通过docker images
查看
创建一个docker hub账号,上传到自己的账号上,在另一边再下载下来。
创建账号过程略,创建好后先在终端进行登陆:
docker login
输入用户名(不是邮箱!)和密码。
如果遇到报错:Error response from daemon: Get “https://registry-1.docker.io/v2/”: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers),解决方案为:/weixin_30794851/article/details/94918517,如果遇到权限问题可使用chmod 777 /etc/docker/daemon.json
修改权限。
上传命令:
docker push 你的镜像名字:版本号
如果遇到报错:denied: requested access to the resource is denied,解决方案为:/Florine113/article/details/121748462
这样操作后最后上传的命令其实是:
docker push 你的用户名/你的镜像名字:版本号
服务器端登陆后,参考初学版的步骤获取镜像。
其实可以不用docker pull,直接进行docker run,如果没有本地镜像docker会自动从网上下载的。
最后就到了创建容器并运行的部分了。注意,如果Dockerfile中有CMD命令,再使用/bin/bash会覆盖掉CMD命令,此处常见的命令应该是:
#-d指的是后台运行docker run -p 8000:80 -itd --name 容器名字 镜像名字:版本号
如果需要使用gpu(且装好了显卡驱动),可添加参数–gpus all/个数/编号
另外,如果只是想查看程序输出而不想进入容器,可使用命令:
docker logs -f 容器id
查看python进程:
ps -ef | grep .py
如果觉得《阿里云服务器部署+docker学习》对你有帮助,请点赞、收藏,并留下你的观点哦!