Why SSH connection to docker container is not working? - mysql

So i have this Dockerfile:
FROM debian:squeeze
MAINTAINER Name < email : >
# Update the repository sources list
RUN apt-get update
# Install apache, PHP, and supplimentary programs. curl and lynx-cur are for debugging the container.
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install apache2 build-essential php5 mysql-server openssh-server libapache2-mod-php5 php5-mysql php5-gd php-pear php-apc php5-curl curl lynx-cur
# Enable apache mods.
RUN a2enmod php5
RUN a2enmod rewrite
# Manually set up the apache environment variables
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid
EXPOSE 80
# Copy site into place.
ADD www /var/www/site
# Update the default apache site with the config we created.
ADD apache-config.conf /etc/apache2/sites-enabled/000-default.conf
# start mysqld and apache
EXPOSE 3306
RUN mkdir /var/run/sshd
RUN echo 'root:123' | chpasswd
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
EXPOSE 22
CMD bash -c ' (mysqld &); /usr/sbin/apache2ctl -D FOREGROUND;/usr/sbin/sshd -D'
it builds up, no problem,MySQL and Apache start and work fine but the ssh won't work and i don't know why. openssh-server is installed.
i tried starting it up like this:
#startup.sh file
#/bin/bash
sshd
+
ADD ./startup.sh /opt/startup.sh
ENTRYPOINT ["/opt/startup.sh"]
and many other,i'm stuck.
What am i doing wrong?

you are starting apache in the foreground, hence the apachectl process will never give back the hand to the shell that started it and thus the /usr/sbin/sshd -D will never be called (unless you kill apache).
The following instruction will start both mysql and apache in the background and then sshd in the foreground:
CMD bash -c ' (mysqld &); /usr/sbin/apache2ctl start;/usr/sbin/sshd -D'
While such a CMD statement is ok for tests I would advise using a different approach for running multiple processes in a single docker container:
supervisor
phusion/baseimage

Replace below lines of code in the docker file,
RUN mkdir /var/run/sshd
RUN echo 'root:123' | chpasswd
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
Using these codes
RUN apt-get install -y openssh-server
RUN echo 'root:password' |chpasswd
RUN mkdir -p /var/run/sshd
this works for me.
Note: Use ssh only for debugging purpose, it is not a good practice at all.

Related

Create a Dockerfile with ubuntu image and run mysql in it

I am trying to set up a Dockerfile with an ubuntu image that runs a mysql server (I know I should use the mysql image instead, but I need to do it this way for an assignment). I am having a lot of trouble designing the Dockerfile. My Dockerfile looks like this right now:
FROM ubuntu:latest
EXPOSE 3306
VOLUME [ "/var/lib/mysql" ]
RUN apt update && \
apt install -y mysql-server && \
apt-get install -y gosu
ENV MYSQL_ROOT_PASSWORD=secret
COPY ./wordpress.sql /docker-entrypoint-initdb.d/
COPY ./docker-entrypoint.sh /usr/local/bin/
COPY ./entrypoint.sh /
RUN chmod +x entrypoint.sh && \
chmod +x /docker-entrypoint-initdb.d/wordpress.sql && \
chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
CMD [ "mysqld" ]
(I am running docker build -t sql . to build the image, and docker run --name sql_cont -v sql_vol:/var/lib/mysql sql_img to run the container)
I have a folder where I have the docker-entrypoint.sh file and the entrypoint.sh file, because when I install mysql-server, these files are not created by default as If I was just using the mysql docker image.
I just need a Dockerfile from an ubuntu image that runs mysql and just stays waiting ready for connections, so, If anybody know how to refactor this Dockerfile or just give me the answer I'd much appreciate it.
If I got What is the difference between CMD and ENTRYPOINT in a Dockerfile? right, the argument in CMD will be passed to the ENTRYPOINT. Don’t know about your ENTRYPOINT script, but I expect it to just ignore parameters.
I would suggest to:
not replace the default ENTRYPOINT (defaults to /bin/sh -c)
start the docker-entrypoint.sh from CMD
Append mysqld to docker-ENTRYPOINT.sh

Connecting to mysql in docker fails

I'm setting up a Dockerfile where I can run my automated tests, and I'm having troubles with connecting to mysql database.
The Dockerfile depends on a prevoously built image and looks like this:
# Stage 0, assign argument as multistage image alias
ARG PHP_IMAGE
FROM ${PHP_IMAGE} as image
# Stage 1, start tests
FROM php:7.2-fpm
RUN curl -sS https://getcomposer.org/installer | php \
&& chmod +x composer.phar && mv composer.phar /usr/local/bin/composer
RUN apt-get update && apt-get install -y gnupg
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && \
apt-get install -yq nodejs build-essential \
git unzip \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
subversion \
&& curl -sL https://deb.nodesource.com/setup_8.x | bash - \
&& pecl install mcrypt-1.0.1 \
&& docker-php-ext-enable mcrypt \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-install -j$(nproc) mysqli
RUN apt-get install -y mysql-server
RUN /etc/init.d/mysql start
RUN mysqladmin -u root -p status
RUN yes | pecl install xdebug \
&& echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini
RUN npm install -g npm
COPY --from=image /var/www/html/ /var/www/html/
WORKDIR /var/www/html/
COPY scripts/develop.sh develop.sh
COPY scripts/docker-test.sh docker-test.sh
RUN ["/bin/bash", "-c", "bash develop.sh && bash docker-test.sh"]
I've added RUN mysqladmin -u root -p status to try to debug why connecting to mysql failed and I got
Enter password: mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory")'
Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!
To run this I am running
docker build -t $TEST_DOCKER_NAME --build-arg PHP_IMAGE=$DOCKER_IMAGE_NAME_PHP -f Dockerfile.test .
The TEST_DOCKER_NAME and DOCKER_IMAGE_NAME_PHP are stored in an env file and read from there. The PHP image was built successfuly and I'm using it to copy the files from there to here so that I can run PHPUnit.
When I remove that RUN line my build fails when I'm trying to run a script that creates the database
mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to MySQL server on 'localhost' (99 "Cannot assign requested address")'
Check that mysqld is running on localhost and that the port is 3306.
You can check this by doing 'telnet localhost 3306'
What do I need to do in my Dockerfile to make it work?
Answer to your specific problem
This is a common mistake people make when using docker. When you use the RUN directive in docker you are running a command through to completion, capturing the filesystem changes and then exiting.
So when you have the lines
RUN /etc/init.d/mysql start
RUN mysqladmin -u root -p status
The first one is starting mysql. But then the changes are captured, the container is exited and then a new one is started to run the mysqladmin command. Therefore the mysql process is no longer running.
To avoid this you could combine them into a single line like
RUN /etc/init.d/mysql start && mysqladmin -u root -p status
However you will need to do this every time you want to use mysql. Such as in your develop.sh.
Wider answer
It is not recommended to run multiple processes within your container and it is also not recommended to use init.d or other system startup frameworks within your container.
You seem to be treating your container like a virtual machine and are having issues because containers are not VMs.
I recommend you explore running mysql in a separate container and then using a tool like docker-compose to start and and stop your containers.

How to install mysql-server in a Dockerfile?

I have a complex Dockerfile which install much more than just mysql-server so I cannot start from an existing mysql container.
When removing all the extra-stuff I get this Dockerfile
FROM ubuntu:latest
ENV MYSQL_ROOT_PASSWORD=root
ENV MYSQL_ROOT_USER=root
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y apt-utils
RUN apt-get install -y mysql-server
RUN usermod -d /var/lib/mysql/ mysql
RUN service mysql start
Unfortunately, mysql does not want to start:
---> 57a66bd64c2c
Step 8/9 : RUN usermod -d /var/lib/mysql/ mysql
---> Running in 596df248c2e4
---> ee78442bcc56
Step 9/9 : RUN service mysql start
---> Running in 0d9e5803cf33
* Starting MySQL database server mysqld
...fail!
The command '/bin/sh -c service mysql start' returned a non-zero code: 1
What is my mistake?
Looks like you've removed the most important parts of your docker file. Here is the Official MySQL repo Docker file.
FROM oraclelinux:7-slim
ENV PACKAGE_URL https://repo.mysql.com/yum/mysql-8.0-community/docker/x86_64/mysql-community-server-minimal-8.0.2-0.1.dmr.el7.x86_64.rpm
# Install server
RUN rpmkeys --import http://repo.mysql.com/RPM-GPG-KEY-mysql \
&& yum install -y $PACKAGE_URL \
&& yum install -y libpwquality \
&& rm -rf /var/cache/yum/*
RUN mkdir /docker-entrypoint-initdb.d
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 3306 33060
CMD ["mysqld"]
You need to include a proper source with correct version to pull the image from.
and expose right ports, separate out volumes for MySQL to run. your container maybe failing due to any of this. I'd say remove the MySQL part out of your dockerfile and run the rest of the container.
Use the official mySQL image and install it in separate container. and then you can connect the Database with other apps.

OpenShift3 Pro doesn't run a simple Centos image which runs locally on minishift

I have a simple Centos6 docker image:
FROM centos:6
MAINTAINER Simon 1905 <simbo#x.com>
RUN yum -y update && yum -y install httpd && yum clean all
RUN sed -i "s/Listen 80/Listen 8080/" /etc/httpd/conf/httpd.conf && \
chown apache:apache /var/log/httpd && \
chmod ug+w,a+rx /var/log/httpd && \
chown apache:apache /var/run/httpd
RUN mkdir -p /var/www/html && echo "hello world!" >> /var/www/html/index.html
EXPOSE 8080
USER apache
CMD /usr/sbin/httpd -D FOREGROUND
I can run this locally and push it up to hub.docker.com. If I then go into the web console of the Redhat OpenShift Container Developer Kit (CDK) running locally and deploy the image from dockerhub it works fine. If I go into the OpenShift3 Pro web console the pod goes into a crash loop. There are no logs on the console or the command line to diagnose the problem. Any help much appreciated.
To try to see if it was a problem only with Centos7 I changed the first line to be centos:7 and once again it works on minishift CDK but doesn't work on OpenShift3 Pro. It does show something on the logs tab of the pod:
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.128.2.55. Set the 'ServerName' directive globally to suppress this message
(13)Permission denied: AH00058: Error retrieving pid file /run/httpd/httpd.pid
AH00059: Remove it before continuing if it is corrupted.
It is failing because your image expects to run as a specific user.
In Minishift this is allowed, as is being able to run images as root.
On OpenShift Online your images will run as an arbitrary assigned UID and can never run as a selected UID and never as root.
If you are only after a way of hosting static files, see:
https://github.com/sclorg/httpd-container
This is a S2I builder for taking static files for Apache and running them up in a container.
You could use it as a S2I builder by running:
oc new-app centos/httpd-24-centos7~<repository-url> --name httpd
oc expose svc/httpd
Or you could create a derived image if you wanted to try and customise it.
Either way, look at how it is implemented if wanting to build your own.
From the redhat enterprise docs at https://docs.openshift.com/container-platform/3.5/creating_images/guidelines.html#openshift-container-platform-specific-guidelines:
By default, OpenShift Container Platform runs containers using an
arbitrarily assigned user ID. This provides additional security
against processes escaping the container due to a container engine
vulnerability and thereby achieving escalated permissions on the host
node. For an image to support running as an arbitrary user, directories
and files that may be written to by processes in the image should be
owned by the root group and be read/writable by that group. Files to
be executed should also have group execute permissions.
RUN chgrp -R 0 /some/directory \
&& chmod -R g+rwX /some/directory
So in this case the modified Docker file which runs on OpenShift 3 Online Pro is:
FROM centos:6
MAINTAINER Simon 1905 <simbo#x.com>
RUN yum -y install httpd && yum clean all
RUN sed -i "s/Listen 80/Listen 8080/" /etc/httpd/conf/httpd.conf && \
chown apache:0 /etc/httpd/conf/httpd.conf && \
chmod g+r /etc/httpd/conf/httpd.conf && \
chown apache:0 /var/log/httpd && \
chmod g+rwX /var/log/httpd && \
chown apache:0 /var/run/httpd && \
chmod g+rwX /var/run/httpd
RUN mkdir -p /var/www/html && echo "hello world!" >> /var/www/html/index.html && \
chown -R apache:0 /var/www/html && \
chmod -R g+rwX /var/www/html
EXPOSE 8080
USER apache
CMD /usr/sbin/httpd -D FOREGROUND

Docker: MySQL refuses host IP unless I restart it manually

Here is my Dockerfile:
FROM debian:jessie-backports
RUN apt-get update --yes && apt-get upgrade --yes
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
git \
curl \
build-essential\
libssl-dev\
ca-certificates\
mysql-server\
redis-server\
elasticsearch
USER root
ENV HOME /root
# MYSQL SETUP
RUN sed -i -e"s/^bind-address\s*=\s*127.0.0.1/#bind-address = 0.0.0.0/" /etc/mysql/my.cnf
RUN sed -i -e"s/^#max_connections\s*=\s*100/max_connections = 200/" /etc/mysql/my.cnf
RUN echo "\n[mysqld]\nskip-grant-tables\n" >> /etc/mysql/my.cnf
VOLUME ["/var/lib/mysql", "/var/log/mysql"]
EXPOSE 3306
# REDIS SETUP
RUN echo "daemonize yes\nbind 0.0.0.0" >> /etc/redis/redis-serve.conf
RUN sed 's/^daemonize no/daemonize yes/' -i /etc/redis/redis.conf \
&& sed 's/^bind 127.0.0.1/bind 0.0.0.0/' -i /etc/redis/redis.conf \
&& sed 's/^# unixsocket /unixsocket /' -i /etc/redis/redis.conf \
&& sed 's/^# unixsocketperm 755/unixsocketperm 777/' -i /etc/redis/redis.conf \
&& sed '/^logfile/d' -i /etc/redis/redis.conf
VOLUME ["/var/lib/redis", "/var/log/redis"]
EXPOSE 6379 6380
# ELASTICSEARCH SETUP
RUN sed 's/^#START_DAEMON=true/START_DAEMON=true/' -i /etc/default/elasticsearch
VOLUME ["/opt/elasticsearch/data", "/opt/elasticsearch/logs"]
EXPOSE 9200 9300
ADD docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod 777 /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
The entrypoint:
#!/bin/bash
/etc/init.d/mysql start
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
And the command I'm running to start the container:
docker run -i -t -p 3306:3306 -p 6379:6379 -p 9200:9200 -p 9300:9300 assethost
I want to connect to the MySQL server running in the container from the host, but this is what happens when I try to connect:
ERROR 1130 (HY000): Host '192.168.99.1' is not allowed to connect to this MySQL server
Both Redis and Elasticsearch expose themselves just fine. MySQL will only begin accepting external hosts if I restart it manually from the Bash shell that comes up from the entrypoint when I run the container. I have to run /etc/init.d/mysql restart. Only then, can I successfully connect from the host using the MySQL client.
Note that I am using docker-machine, so I have to give the MySQL client the host IP in order to connect.
How can I be able to connect from the host to the MySQL instance running in the container without having to manually restart MySQL?
Docker version 1.12.1, build 23cf638
I figured out a way to get the skip-grant-tables option to be applied on start.
Workaround
In docker-entrypoint.sh, I changed
/etc/init.d/mysql start to
HOME=/etc/mysql /usr/bin/mysqld_safe > /dev/null 2>&1 &
Other changes
Since there was already a [mysqld] section in my.cnf, I changed the following line in Dockerfile
RUN echo "\n[mysqld]\nskip-grant-tables\n" >> /etc/mysql/my.cnf
to
RUN sed -i '/\[mysqld\]/ a skip-grant-tables\nskip-name-resolve' /etc/mysql/my.cnf
I added skip-name-resolve so mysql doesn't attempt to resolve names for local ip addresses.
Caveats
The workaround no longer works when /etc/init.d/mysql restart is executed, but /etc/init.d/mysql stop; /etc/init.d/mysql start preserved the 'skip-grant-tables' option.
I'm guessing MySQL has already started after your installation and running sed to change configuration won't take effect. Entry point you have has mysql start but it is probably seeing that MySQL is already running and not doing anything. Try changing that command to mysql restart, so your entry point bash script becomes:
#!/bin/bash
/etc/init.d/mysql restart
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
You're using skip-grant-tables flag to login without password. I think due to some reasons of /etc/init.d/mysql script, the flag is ignored on the first start, making the connection from the root#192.168.99.1 rejected. I believe Docker has nothing to do with this issue.
To answer your question, you don't have to restart by hand, you can change your entrypoint to either:
#!/bin/bash
/etc/init.d/mysql start
# Wait for mysql to be fully up, then restart (e.g., 5 seconds)
sleep 5
/etc/init.d/mysql restart
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
Or, don't use /etc/init.d/mysql start, instead invoke mysqld directly
#!/bin/bash
mysqld &
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
In addition, although creating one more [mysqld] group in my.cnf is not an issue, you should append new configuration to the existing group:
RUN sed -i '/\[mysqld\]/a skip-grant-tables' /etc/mysql/my.cnf
Refer the doc for several ways to start/stop Mysql server