自学 docker,自己写的 Dockerfile 语法编译通过不了,有哪些错误,请前辈指正

2022-12-06 14:01:54 +08:00
 slove
#基于 ubuntu 最新版镜像
FROM ubuntu:latest
#更新安装包列表
RUN apt update
#安装 apache2
RUN apt install apache2
#安装 mysql-server
RUN apt install mysql-server
#启动 mysql
RUN service mysql start
#登陆 mysql
RUN mysql
#修改 root 密码
RUN alter user “root”@“localhost” identified with mysql_native_password by “12345”;
#root 密码生效
RUN flush privileges ;
#新建数据库
RUN create database wordoress ;
#新建用户
RUN create user “solve”@“localhost” identufied by “888888”;
#配置数据库用户
RUN grant all on wordpress.* to “slove”@“localhost” with grant option ;
#配置生效
RUN flush privileges ;
#退出数据库
RUN exit
#下载 wordpress 最新版到指定 /var/www/html/
ADD https://cn.wordpress.org/latest-zh_CN.tar.gz /var/www/html
#开放端口号
EXPOSE 80
CMD
3098 次点击
所在节点    Docker
38 条回复
caocong
2022-12-06 14:03:14 +08:00
ubuntu:latest

ubuntu:latest
slove
2022-12-06 14:04:44 +08:00
@caocong 英文标点符号我知道,这份是我手机打的
lxzxl
2022-12-06 14:14:00 +08:00
RUN alter user “root”@“localhost” identified with mysql_native_password by “12345”;

你是想 shell 里面跑 sql?
slove
2022-12-06 14:24:07 +08:00
@lxzxl 是的,不可以使用 mysql 语句吗
lxzxl
2022-12-06 14:38:20 +08:00
@slove #4 换个问法,你是想 bash 里面执行 sql?
slove
2022-12-06 14:46:21 +08:00
@lxzxl 你的问法我理解,我在主机上敲 mysql ,直接进入 mysql ,所以可以执行 sql 语法,直到敲下 exit ,才算退出 mysql
Dockerfile RUN mysql ,我理解就是在主机中启动 mysql ,然后进入数据库,后面的 sql 语句应该也是在数据库中执行,如果不是这样的,那 sql 语法应该写在哪里
iyour
2022-12-06 14:46:25 +08:00
用 chatgpt 试了一下,仅供参考
[![ChatGPTaa6dca183f7b22f3.md.png]( https://img.picgo.net/2022/12/06/ChatGPTaa6dca183f7b22f3.md.png)]( https://www.picgo.net/image/Ul2mJ)
kaedeair
2022-12-06 14:51:55 +08:00
bash 里用 mysql 命令可以 RUN mysql < cmd1;cmd2;cmd3; 大概是这么做我没试过,也可能是 bash -c ""这种
OP 的这种情景一般有两种变通方法
1.用 docker-compose 拉别人的镜像组成服务群,加入环境变量来配置
2.写一个 EntryPoint 脚本去判断是不是第一次运行
Puteulanus
2022-12-06 14:54:32 +08:00
chloerei
2022-12-06 14:54:37 +08:00
@slove RUN 一条命令之后,相当于退出 shell ,下一条 RUN 是打开另一个 shell ,不会保留同一个会话。

要执行 mysql 命令可以这样:

```
RUN mysql -e "SQL"
```

但是不建议这样做,容器内容是固化的,持久化数据应该放在 volume 。对应数据库就是它的 data 目录要挂到 volume ,这样在 dockerfile 里面执行的 sql 语句会被清空。

而且不建议一个容器启动多个服务进程。

建议先学习 docker 的基本概念,它不是虚拟机。
slove
2022-12-06 14:55:25 +08:00
@iyour 我回头试下,感谢
Mindzy
2022-12-06 14:57:44 +08:00
建议所有 SQL 指令用 ENTRYPOINT 运行个 sh 执行
hefish
2022-12-06 14:58:52 +08:00
这个不应该从 ubuntu:latest 开始构建。
个人认为 docker 和微服务是相辅相成的。 相应的应用,也应该微服务化。OP 的这些应用至少可以分成三个服务。
一个 mysql 服务,一个 php-fpm+httpd 服务。分两个容器跑,相互调用。 而不是在一个容器里跑三个服务。

mysql 的服务,可以基于 mysql:8 来构建,具体可以参考 hub.docker.com 上的文档,用环境变量来指定默认的 root 密码。
php-fpm 和 httpd 服务,可以基于 ubuntu:latest ,但容器里不能把进程跑在后台,要跑在前台,否则容器会自动退出。所以一般我喜欢是用 nginx 作 httpd ,然后用 supervised 来管理 php-fpm 和 nginx 两个服务,具体可以查询 supervised 相应的用法,配置文件还是比较简单的。

做好容器之后,具体的应用数据,应该是在创建容器的时候,挂到容器里去,这样在容器销毁之后,数据可以保留下来。

大致先讲这么多。
starqoq
2022-12-06 15:01:56 +08:00
1. Always combine RUN apt-get update with apt-get install in the same RUN statement.
Best practices for writing Dockerfiles
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

For example:
RUN apt-get update && apt-get install -y \
package-bar \
package-baz \
package-foo \
&& rm -rf /var/lib/apt/lists/*
Using apt-get update alone in a RUN statement causes caching issues and subsequent apt-get install instructions fail.

2. 数据库应该和 docker layout 分开,新建用户之类的操作,应该在 enterpoint.sh 里面进行

3. 如果你真的特别想在 mysql 里面执行应该这样
RUN echo "CMD1 \n CMD2\n CMD3\n" | mysql
把 CMD1~3 发送到 mysql 的输入里执行

RUN 命令是执行 elf 而不是在终端里输入然后回车。你可以认为每句话都在一个新的终端里执行
slove
2022-12-06 15:03:32 +08:00
@kaedeair 感觉你说的应该可以执行,我回头测试下
slove
2022-12-06 15:08:26 +08:00
@Mindzy 自学的 docker ,对 Dockerfile 的语法理解还是不透彻,我看网上很多把 sql 语句单独写一个文件,回头参考下别人的 Dockerfile
javalaw2010
2022-12-06 15:10:10 +08:00
添加一个环境变量,ENV DEBIAN_FRONTEND=noninteractive 以避免软件安装过程中的交互出现,apt 安装的时候添加-y 参数,同样为了避免交互安装时出现交互。安装包控制镜像大小的一些小技巧前面的大佬们说过了,当然如果你不希望 DEBIAN_FRONTEND 在容器运行时也存在的话,可以 RUN DEBIAN_FRONTEND=noninteractive apt install -y XXX 。此外 ADD 命令并不会自动解压缩远程的压缩包,你得手动解压一下,至于 mysql 的问题,前面各位大佬也都说过了
slove
2022-12-06 15:11:03 +08:00
@hefish 讲的很细了,感谢
zhenrong
2022-12-06 15:11:55 +08:00
用这个校验: https://www.fromlatest.io
wunonglin
2022-12-06 15:12:11 +08:00
这是把 docker 当虚拟机用了呀

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/900487

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX