我是Docker的新手.我已使用以下Dockerfile成功创建了Docker镜像:
From alpine:3.4
MAINTAINER SomeName - domain.tld
# Timezone
ENV TIMEZONE Asia/Kolkata
# RUN sed -i 's#dl-cdn\.alpinelinux\.org#mirrors\.aliyun\.com#' /etc/apk/repositories
# install MysqL,apache and PHP and PHP extensions,tzdata,wget
RUN echo "@community http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && \
apk add --update \
MysqL MysqL-client \
apache2 \
curl wget \
tzdata \
PHP5-apache2 \
PHP5-cli \
PHP5-phar \
PHP5-zlib \
PHP5-zip \
PHP5-bz2 \
PHP5-ctype \
PHP5-MysqLi \
PHP5-MysqL \
PHP5-pdo_MysqL \
PHP5-opcache \
PHP5-pdo \
PHP5-json \
PHP5-curl \
PHP5-gd \
PHP5-gmp \
PHP5-mcrypt \
PHP5-openssl \
PHP5-dom \
PHP5-xml \
PHP5-iconv \
PHP5-xdebug@community
RUN curl -sS https://getcomposer.org/installer | \
PHP -- --install-dir=/usr/bin --filename=composer
# configure timezone,MysqL,apache
RUN cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && \
echo "${TIMEZONE}" > /etc/timezone && \
mkdir -p /run/MysqLd && chown -R MysqL:MysqL /run/MysqLd /var/lib/MysqL && \
MysqL_install_db --user=MysqL --verbose=1 --basedir=/usr --datadir=/var/lib/MysqL --rpm > /dev/null && \
mkdir -p /run/apache2 && chown -R apache:apache /run/apache2 && chown -R apache:apache /var/www/localhost/htdocs/ && \
sed -i 's#AllowOverride none#AllowOverride All#' /etc/apache2/httpd.conf && \
sed -i 's#ServerName www.example.com:80#\nServerName localhost:80#' /etc/apache2/httpd.conf && \
sed -i '/skip-external-locking/a log_error = \/var\/lib\/MysqL\/error.log' /etc/MysqL/my.cnf && \
sed -i '/skip-external-locking/a general_log = ON' /etc/MysqL/my.cnf && \
sed -i '/skip-external-locking/a general_log_file = \/var\/lib\/MysqL\/query.log' /etc/MysqL/my.cnf
# Configure xdebug
RUN echo "zend_extension=xdebug.so" > /etc/PHP5/conf.d/xdebug.ini && \
echo -e "\n[XDEBUG]" >> /etc/PHP5/conf.d/xdebug.ini && \
echo "xdebug.remote_enable=1" >> /etc/PHP5/conf.d/xdebug.ini && \
echo "xdebug.remote_connect_back=1" >> /etc/PHP5/conf.d/xdebug.ini && \
echo "xdebug.idekey=PHPSTORM" >> /etc/PHP5/conf.d/xdebug.ini && \
echo "xdebug.remote_log=\"/tmp/xdebug.log\"" >> /etc/PHP5/conf.d/xdebug.ini
#start apache
RUN echo "#!/bin/sh" > /start.sh && \
echo "httpd" >> /start.sh && \
echo "nohup MysqLd --skip-grant-tables --bind-address 0.0.0.0 --user MysqL > /dev/null 2>&1 &" >> /start.sh && \
echo "sleep 3 && MysqL -uroot -e \"create database db;\"" >> /start.sh && \
echo "tail -f /var/log/apache2/access.log" >> /start.sh && \
chmod u+x /start.sh
WORKDIR /var/www/localhost/htdocs/
EXPOSE 80
EXPOSE 3306
#VOLUME ["/var/www/localhost/htdocs","/var/lib/MysqL","/etc/MysqL/"]
ENTRYPOINT ["/start.sh"]
理想情况下,我希望docker镜像包含Apache,PHP和MysqL – 所有这些都在一个图像中.我希望图像尽可能便携.因此,每次我需要启动一个新项目时,我都可以创建一个新容器并安装卷并继续编写代码.
当我开始一个新容器时,我按预期得到了所有东西.但无法装入MysqL数据.我认为这是因为挂载是单向的(或者是它?)如果我在启动新容器时添加-v / project_dir / data:/ var / lib / MysqL,则MysqL无法启动,因为project_dir / data是空的.我的问题是:
>如何将数据从我的project_dir挂载到容器内的/ var / lib / MysqL?
>如何将不同的MysqL密码设置为不同的容器?
编辑:如果我没有挂载我的本地卷(即project_dir / data)并启动容器,得到一个shell tty,我看到/ var / lib / MysqL有几个文件,我认为需要运行MysqL及其初始数据库.但是如果我将本地卷和ls挂载到/ var / lib / MysqL(在容器内),它就是空的.这就是MysqL没有启动的原因,我无法从容器外部保留数据.我的问题是:我如何让它运行并持久保存本地目录中的数据.
这里发生的是你在构建Docker镜像时创建一个空数据库:
MysqL_install_db --user=MysqL --verbose=1 --basedir=/usr --datadir=/var/lib/MysqL --rpm > /dev/null && \
但是,当您从此映像创建容器时,您将在/ var / lib / MysqL文件夹上装入卷.这会隐藏容器数据,以显示主机的文件夹.因此,您看到一个空文件夹.
解决方案:
如果您查看https://hub.docker.com/_/mysql/,您将看到通过在容器实际启动时创建数据库而不是在创建映像时解决此问题.这回答了你的问题:
>如果您使用已安装的卷启动容器,则之后将执行数据库init,并且您的数据将实际写入主机的FS中
>您必须将这些信息作为env变量传递
换句话说,使用ENTRYPOINT中的脚本初始化数据库,而不是直接在映像中.
警告:
但是有些警告.你不是真正推荐你的形象,因为Docker的理念是“每个容器一个进程”.你在这里遇到的困难是你必须在同一个容器(apache,MysqL等)上启动多个服务,所以你可能不得不在你的入口点做两件事,这是令人困惑的.此外,一个服务失败,您的容器仍然会启动,但不能按预期工作.
然后我会建议将你在每个进程中分成1个图像分开,然后用原始Docker或者像docker-compose这样的用户启动它们.
此外,这将使您从Docker Hub:https://hub.docker.com中使用现有且高度可配置的图像的方式受益.为您减少工作量,减少错误.