How to install sudo and nano command in MySql docker image - mysql

I am trying to connect Django application with MySql docker container. I am using the latest version of MySql i.e MySql 8.0 to build a container. I was able to build the MySql container successfully but I am not able to connect it using Django's default MySql Connector. When I run the docker-compose up command I get the error mentioned below.
django.db.utils.OperationalError: (1045, 'Plugin caching_sha2_password could not be loaded: /usr/lib/x86_64-linux-gnu/mariadb19/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory')
I started looking for the solution and got to know that MySql has released a major change in its default authentication plugin which is not support by most of the MySql Connectors.
To fix this issue I will have to set the default-authentication-plugin to mysql_native_password in my.cnf file of MySql container.
I logged into container using command docker exec -it <conatiner id> /bin/bash and was also able to locate the my.cnf file inside the container.
To edit the my.cnf file I will have to use the nano command as stated below.
nano my.cnf
But unfortunately nano command is not installed in MySql Container. To install nano I will need sudo installed in container.
I tried installing sudo using below mentioned command but it did not work.
apt-get install sudo
error -
Reading package lists... Done
Building dependency tree
Reading state information... Done
What are the possible solutions to fix this issue.

In general you shouldn't try to directly edit files in containers. Those changes will get lost as soon as the container is stopped and deleted; this happens extremely routinely since many Docker options can only be set at startup time, and the standard way to update the software in a container is to recreate it with a newer image. In your case, you also can't live-edit a configuration file the main container process needs at startup time, because it will have already read the configuration file by the time you're able to edit it.
The right way to do this is to inject the modified configuration file at container startup time. If you haven't already, get the default configuration file out of the image
docker run --rm mysql:8 cat /etc/mysql/my.cnf > my.cnf
and edit it, directly, on your host, using your choice of text editor. When you launch the container, inject the modified file
docker run -v $PWD/my.cnf:/etc/mysql/my.cnf ... mysql:8
or, in Docker Compose,
volumes:
- ./my.cnf:/etc/mysql/my.cnf
The Docker Hub mysql image documentation has some more suggestions on ways to set this; see "Using a custom MySQL configuration file" there.
While docker exec is an extremely useful debugging tool, it shouldn't be part of your core workflow, and I'd recommend trying to avoid it in cases like this. (With the bind-mount approach, you can add the modified config file to your source control system and blindly docker-compose up like normal without knowing this detail; a docker exec approach you'd have to remember and repeat by hand every time you started the container stack.)
Also note that you don't need sudo in Docker at all. Every context where you can run something (Dockerfiles, docker run, docker exec) has some way to explicitly specify the user ID, so you can docker exec -u root .... sudo generally depends on things like users having passwords and interactive prompting, which works well for administering a real Linux host but doesn't match a typical Docker environment.

The issue is not with sudo because you've already permissions to install pacakegs.
You should instead update package manager before to install new packages in order to update package repositories:
RUN apt-get update
RUN apt-get install nano

Mysql build the image with oracle linux, run the commands to install nano:
microdnf update
microdnf install nano sudo -y
And edit the my.cnf with nano

Related

how to install mysql to existing docker file

I'm trying to add mysql to a dockerfile. I dont want to use a mysql source docker, I'm using something else as I need ffmpeg/nvidia/asp.net aswell. So I can't simple use a different base image to start from.
So how can I
Add mysql to my docker build file?
Configure it so the data for mysql is in a specific directory (so I can can map outside the docker file)
Have mysql start up but not be the entry point service
Everything I found so far basically say "use this base image". which doesn't help me. I dont want to have mysql separate, just self contained docker image with everything it needs.
TIA
Install mysql
Use apt-get to install packages on debian distro's. Add in your dockerfile the following line:
RUN apt-get update && apt-get install -y mysql-server
Start MySQL
Add to the Dockerfile CMD a prefix where you start mysql in detached mode. Like:
CMD mysql start & # [paste here your default command]`.
This will start mysql and start your app.
Mount directories
Mounting directories is done with the -v flag:
docker run -ti -v <host_dir>:<container_dir> my-image /bin/bash

Can i build a already local build mysql Database with the mysql Dockerfile?

i am completely new to Docker and everything that has to do with it. In my last semester i build a mysql Database locally with mysql Workbench and connected a java project to it. This year i need to make this run in a Docker Container. I have pulled the Dockerfile from GitHub and i am using Portainer to manage Docker.
My teacher wants the following:
He wants me to put my code in a repository which he created for me
Then he wants to pull my project, which should include a Dockerfile, so that he don't needs to manually rebuild my mysql Database.
So how can i do this? Do i need to change the mysql Dockerfile? Or should i use the default one and then initialize my Database in my javacode?
This i my first post here on stackoverflow and i am not that advanced in programming (only 2 years experience with java), so if i can give you any more information please let me know. I hope this is the right way to post questions here.
I am thankful to everyone helping me out!
Greets, Luciore
You need to place your sql file also on GitHub, and it should be accessible from your docker environment.
When a container is started for the first time, a new database with
the specified name will be created and initialized with the provided
configuration variables. Furthermore, it will execute files with
extensions .sh, .sql and .sql.gz that are found in
/docker-entrypoint-initdb.d. Files will be executed in alphabetical
order.
docker-hub-mysql
And yes, Also you need to modify your Dockerfile, Here is the example.
This will build mysql8 based docker image, will download sql file from GitHub and will initiate DB name classicmodels mean anything a valid SQL file will be executed on boot.
FROM mysql:8
RUN apt update && apt install curl -y
RUN curl -0 https://raw.githubusercontent.com/Adiii717/doctor-demo-app/master/sample_database.sql > /docker-entrypoint-initdb.d/sampledb.sql
Build the docker image
docker build -t mysql8 .
Run the docker container
docker run --rm --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -it mysql8

Docker container stops running only when volume is attached

I have written a dockerfile that runs mysql on an ubuntu image. The Dockerfile is:
FROM ubuntu
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server
RUN sed -i '43s/.*/bind-address = 0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf
EXPOSE 3306
ENTRYPOINT service mysql start && bash
If I run:
docker run -dit mysql-server
after building the container everything works fine and my Apache/PHP container can communicate with it. However, if I run it with a volume attached (docker run -dit -v ~/vol/:/var/lib/mysql/ mysql-server) the container will stop running after 30 seconds (I'm pretty sure it's the same amount of time every time).
Does anyone know a way I can keep the container up and mount a volume? I've never had this problem before and can't find anything else online (I've been looking a while). Thanks.
This is because you are masking the contents of /var/lib/mysql with the contents of ~/vol which I'm assuming is empty. As such the MySQL server can't start as it's missing database files. I would personally use the official image over your custom implementation as it will handle what your looking for here is the link to Dockerhub. It has options for mounting your custom my.cnf file if you need those changes. However by default the image does bind to 0.0.0.0. See the Dockerhub link for config options.
Hope this helps
Dylan

MySQL container crash after /etc/mysql/my.cnf change, how to edit back?

I changed some mysql config settings and set something wrong, now Docker container keeps restarting and I cannot find the my.cnf file to edit in host filesystem. I have tried aufs/diff folders but so far unable to find it. Also tried:
find / -name my.cnf -exec nano {} \;
But it does not bring up the file I changed. And I tried to change config.v2.json to start /bin/bash instead of mysqld and restarted docker, but yet it started mysqld (due supervisor or something?) using official mysql container image.
I am seeing two possible solutions for your problem:
Bypass the ENTRYPOINT for the MySQL image
Find your image name by running docker images then run:
docker run -it --entrypoint="/bin/sh" OPTIONS image
That should take you to the bash inside the container and from there you can execute all the commands you want to find your my.cnf file. Although I don't know if editing the file from there, save it and try to run it again will works. I didn't tried.
Delete the old image and use the proper way to edit the my.cnf file
Find your image name by running: docker images and then delete it by running docker rmi <image_name>
Check the docs for the default MySQL images at MySQL Dockerhub is pretty straight on this and I quote:
Using a custom MySQL configuration file The MySQL startup
configuration is specified in the file /etc/mysql/my.cnf, and that
file in turn includes any files found in the /etc/mysql/conf.d
directory that end with .cnf. Settings in files in this directory will
augment and/or override settings in /etc/mysql/my.cnf. If you want to
use a customized MySQL configuration, you can create your alternative
configuration file in a directory on the host machine and then mount
that directory location as /etc/mysql/conf.d inside the mysql
container.
If /my/custom/config-file.cnf is the path and name of your custom
configuration file, you can start your mysql container like this (note
that only the directory path of the custom config file is used in this
command):
$ docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e
MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
This will start a new
container some-mysql where the MySQL instance uses the combined
startup settings from /etc/mysql/my.cnf and
/etc/mysql/conf.d/config-file.cnf, with settings from the latter
taking precedence.
From that point and if you create the my.cnf file on your host then you'll never run into this problem again since you can edit the file as many times as you want.

If a service is started during docker build, should it be running at runtime?

I have been working on setting up a self contained rails app in a single container. This means getting both rails and a data persistence service running at the same time in one container. In our case, that means mysql.
However, I ran into multiple issues getting this working, because mysql wasn't running.
During the build step, if I had RUN mysqld and then a separate RUN rake db:create step, rake would crash, because mysql was down.
So I worked around this by wrapping the two commands into a script. However, at runtime, rails would fail to startup because mysql wasn't running.
My intuition says that if mysql is started during the build, it should be available at runtime, but I did not have that experience. Starting the rails server had to be wrapped in a script with another call to mysqld.
Here's the dockerfile:
FROM ruby:2.2
RUN mkdir -p $APPDIR
WORKDIR $APPDIR
ADD Gemfile* $APPDIR/
RUN bundle install
RUN apt-get update -qq
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -qq nodejs mysql-server --no-install-recommends
RUN rm -rf /var/lib/apt/lists/* # */ broken syntax highlighting
COPY . $APPDIR
RUN script/mysql-setup.sh # contents are: mysqld_safe; rake db:create; rake db:migrate
EXPOSE 3000
CMD ["script/rails-launcher.sh"] # contents are: mysqld_safe; rails s
Do I need to do something differently in the Dockerfile? Why isn't mysql up at runtime?
My intuition says that if mysql is started during the build, it should be available at runtime
This is incorrect. Docker will start the service for you and perform the subsequent steps you've defined in the same RUN command, but then it bundles everything up into an intermediate image for subsequent commands. The image doesn't have a known state of running processes, only whatever is required for startup such as init.d scripts.
Your solution would be to use a server startup script or continue to invoke mysqld_safe as you do in your CMD line.
A good idea is to use supervisord to maintain all of your services in a non-daemon mode. Phusion also provides a nice base image with a runit initializer script.
Eventually, you'll come to see how the power of Docker lies in how you can actually break MySQL out of your Rails app container and run it in an entirely different container linked together.
The RUN Command is used to configure your image, each time it is called, a new layer is created with the results of run command. So, if you need to configure your database on the image build step, you have 2 solutions: you can call a number of command in a single RUN call, like
RUN /bin/bash -c "mysqld_safe" && "rake db:create" && "rake db:migrate"
Or via call of single script, as you did.
In both cases, you have to inderstand, that the fact, you runned something during the image build, it'll not run automatcally on the container start up. So, you have to start your database server manually on container start up.