1
caocong 2022-12-06 14:03:14 +08:00
ubuntu:latest
ubuntu:latest |
3
lxzxl 2022-12-06 14:14:00 +08:00
RUN alter user “root”@“localhost” identified with mysql_native_password by “12345”;
你是想 shell 里面跑 sql? |
6
slove OP @lxzxl 你的问法我理解,我在主机上敲 mysql ,直接进入 mysql ,所以可以执行 sql 语法,直到敲下 exit ,才算退出 mysql
Dockerfile RUN mysql ,我理解就是在主机中启动 mysql ,然后进入数据库,后面的 sql 语句应该也是在数据库中执行,如果不是这样的,那 sql 语法应该写在哪里 |
7
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) |
8
kaedeair 2022-12-06 14:51:55 +08:00
bash 里用 mysql 命令可以 RUN mysql < cmd1;cmd2;cmd3; 大概是这么做我没试过,也可能是 bash -c ""这种
OP 的这种情景一般有两种变通方法 1.用 docker-compose 拉别人的镜像组成服务群,加入环境变量来配置 2.写一个 EntryPoint 脚本去判断是不是第一次运行 |
9
Puteulanus 2022-12-06 14:54:32 +08:00
|
10
chloerei 2022-12-06 14:54:37 +08:00 1
@slove RUN 一条命令之后,相当于退出 shell ,下一条 RUN 是打开另一个 shell ,不会保留同一个会话。
要执行 mysql 命令可以这样: ``` RUN mysql -e "SQL" ``` 但是不建议这样做,容器内容是固化的,持久化数据应该放在 volume 。对应数据库就是它的 data 目录要挂到 volume ,这样在 dockerfile 里面执行的 sql 语句会被清空。 而且不建议一个容器启动多个服务进程。 建议先学习 docker 的基本概念,它不是虚拟机。 |
12
Mindzy 2022-12-06 14:57:44 +08:00
建议所有 SQL 指令用 ENTRYPOINT 运行个 sh 执行
|
13
hefish 2022-12-06 14:58:52 +08:00 3
这个不应该从 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 相应的用法,配置文件还是比较简单的。 做好容器之后,具体的应用数据,应该是在创建容器的时候,挂到容器里去,这样在容器销毁之后,数据可以保留下来。 大致先讲这么多。 |
14
starqoq 2022-12-06 15:01:56 +08:00 1
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 而不是在终端里输入然后回车。你可以认为每句话都在一个新的终端里执行 |
16
slove OP @Mindzy 自学的 docker ,对 Dockerfile 的语法理解还是不透彻,我看网上很多把 sql 语句单独写一个文件,回头参考下别人的 Dockerfile
|
17
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 的问题,前面各位大佬也都说过了
|
19
zhenrong 2022-12-06 15:11:55 +08:00
用这个校验: https://www.fromlatest.io
|
20
wunonglin 2022-12-06 15:12:11 +08:00
这是把 docker 当虚拟机用了呀
|
21
lxzxl 2022-12-06 15:13:44 +08:00
|
22
slove OP @Puteulanus
a | b ,a 执行完结果扔给 b 执行,不知道我理解的对不对 |
23
deplivesb 2022-12-06 15:31:48 +08:00
你这个真把 docker 当成虚拟机用了,启动一个 ubuntu 系统,安装一个 Apache 再安装一个 MySQL ,你这个干啥呢?
|
24
slove OP |
26
dier 2022-12-06 16:35:03 +08:00 3
你这个误区有点多,我一时不知道从哪讲起。既然你说想练习 Dockerfile 语法,那我先从 Docker 的理解说起
Docker 推荐一个容器只运行一个服务,例如你这个环境的最优做法是 MySQL 服务构建一个镜像,Apache 服务再构建一个镜像。 原因就是容器在运行时必须要有一个主服务进程在前台持续运行,一般建议这个进程就是容器要运行的服务进程。当这个服务的进程停止时,容器会以为这个服务运行结束,容器则结束运行退出。 如果你在一个容器里运行了多个服务,比如 MySQL 和 Apache ,你以其中一个服务为主服务使其在前台运行,如果另外一个服务意外终止了,你排查时会发现这个容器的状态还是运行状态。就没办法从容器的状态直接判断出来服务是否正常(简单的比喻就是你明明结束了 MySQL 的进程,但用其它命令查看 MySQL 端口发现它还在监听,你觉得是还在运行还是已经结束了?)。因为容器在运行时,你从外部是不容易观察到容器内的运行情况。 再说 Dockerfile; 用再说 Dockerfile 构建镜像时,Dockerfile 中的每个以大写开头的 FROM\RUN\ADD\COPY\CMD 都会像是一层饼,如果你要通过 RUN 做一些操作,就尽量写在这一个 RUN 下,以减少镜像的层数,同时也能防止一个镜像最后体积变得很大。 例如: ```shell RUN apt update && \ apt install aptech curl bash && \ rm /tmp/*.gz ``` 另外,练习 Dockerfile 可以到 hub.docker.com 上去看看一些服务官方的镜像。基本上都有附 Dockerfile 的 github 的地址。建议先基于官方的 Dockerfile 来改着试试理解怎么写 Dockerfile 最后,Dockerfile 排错。在使用 docker build 构建时,你每写的一个大写开头的命令都是一层,会从上到下依次执行,如果哪一层有问题,会提示准确的行级信息来供你排查是哪些命令编写有问题。 |
27
hsfzxjy 2022-12-06 16:46:06 +08:00 via Android
建议先学 shell/bash 语法和相关知识,还是基础知识不够
如果你写成 shell 脚本能跑通,那改成 Dockerfile 基本也可以 |
29
dev436 2022-12-06 18:17:49 +08:00
您好,您给出的 Dockerfile 中存在一些语法错误和书写不规范的问题。我尝试纠正这些问题,并给出修改后的 Dockerfile 内容:
|
30
dev436 2022-12-06 18:18:04 +08:00
# 基于 ubuntu 最新版镜像
FROM ubuntu:latest # 更新安装包列表 RUN apt update # 安装 apache2 RUN apt install -y apache2 # 安装 mysql-server RUN apt install -y mysql-server # 启动 mysql RUN service mysql start # 登录 mysql RUN mysql -u root # 修改 root 密码 RUN alter user "root"@"localhost" identified with mysql_native_password by "12345"; # root 密码生效 RUN flush privileges; # 新建数据库 RUN create database wordpress; # 新建用户 RUN create user "solve"@"localhost" identified by "888888"; # 配置数据库用户 RUN grant all on wordpress.* to "solve"@"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 ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"] |
31
slove OP @dev436 这个语句到# 修改 root 密码 RUN alter user "root"@"localhost" identified with mysql_native_password by "12345";就不行了。二楼说的对,RUN 命令执行完就结束了,sql 命令没在 mysql 里执行,网上搜了下,基本是单独做个 shell 脚本,引入 sql 语句,再执行数据库操作。
有没有大佬知道单独语句怎么写,这样写不知对不对:RUN /bin/sh -c mysql -uroot <"alter user "root"@"localhost" identified with mysql_native_password by "12345""; |
32
g001 2022-12-06 20:41:47 +08:00
FROM ubuntu:latest:您在使用 : 分隔镜像名称和标签时,应该使用英文的冒号而不是中文的冒号。正确的语法应该是 FROM ubuntu:latest 。
alter user “root”@“localhost”:您在使用字符串时,应该使用英文的双引号而不是中文的双引号。正确的语法应该是 alter user "root"@"localhost"。 mysql_native_password by “12345”;:您在定义密码时,应该使用英文的双引号而不是中文的双引号。正确的语法应该是 mysql_native_password by "12345" |
33
slove OP @g001 中英文是我在车上手机编辑的,主要问题不在这里,我的意思还是在 Dockerfile 里使用 sql 命令创建和修改用户权限
|
34
slove OP |
35
slove OP |
36
slove OP |
37
slove OP 不会贴图
---------Dockerfile-------------- FROM ubuntu:latest COPY run.sh /root/test/run.sh COPY my.sql /root/test/my.sql RUN apt update RUN apt install mysql-server -y EXPOSE 3306 CMD ["sh", "/root/test/run.sh"] ---------run.sh-------------- #!bin/bash #查看 mysql 运行状态 echo '1.查看 mysql 服务状态...' service mysql status echo '2.启动 mysql 服务...' service mysql start echo '3.导入 sql 命令...' mysql < /root/test/my.sql echo '4.执行完毕...' ---------my.sql-------------- use mysql; #修改 root 密码 alter user 'root'@'localhost' identified with mysql_native_password by '123456'; #创建数据库 wordpress create database Wordpress; #创建用户 slove create user 'slove'@'localhost' identified by '888888'; #设置 wordpress 数据库用户 grant all on wordpress.* to 'slove'@'localhost' with grant option; #配置生效 flush privileges; |
38
qq296015668 2023-03-02 15:49:45 +08:00
简单的看了下,按照 op 给出的部分代码,简单的给出大致样本,但是有几个问题需要解决
1. `service mysql start` 这条命令无法在构建是启动 2. 缺少 `php` 依赖,就算构建成功也无法访问 wordpress 3. 就算补全了 `php` 相关依赖,apache2 也缺少配置 总之,只能给出一个大致的样本供参考。另外 `wordpress` 有 [官方镜像]( https://hub.docker.com/_/wordpress) ```Dockerfile FROM ubuntu:22.04 ARG MYSQL_ROOT_PASSWORD 12345 ARG DB_PASSWORD 888888 ARG DEPENDENCIES=" \ apache2 \ mysql-server \ wget" RUN apt-get update && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ apt-get install -y --no-install-recommends ${DEPENDENCIES} && \ rm -rf /var/lib/apt/lists/* RUN service mysql start # 无法执行成功 RUN mysql -uroot -e "\ create database wordoress; \ create user 'solve'@'localhost' identufied by '${DB_PASSWORD}'; \ grant all on wordoress.* to 'solve'@'localhost'; \ alter user 'root'@'localhost' identified with mysql_native_password by '${MYSQL_ROOT_PASSWORD}'; \ flush privileges;" WORKDIR /var/www/html RUN wget https://cn.wordpress.org/latest-zh_CN.tar.gz && \ tar -xf latest-zh_CN.tar.gz \ rm -f latest-zh_CN.tar.gz EXPOSE 80 CMD ["/bin/bash"] ``` |