I have a Job that connects to a running MySQL database and executes some commands:
apiVersion: batch/v1
kind: Job
metadata:
name: do-db-stuff
spec:
template:
spec:
containers:
- name: do-db-stuff
image: mysql:5
command: ["/bin/sh"]
args: ["-c", "mysql -h db -uroot -pmypassword mydb -Bse 'show tables;'"]
restartPolicy: Never
backoffLimit: 10
This job spins on a crash loop, with each pod reporting: ERROR 2005 (HY000): Unknown MySQL server host 'db' (11). If I change the command to ["/bin/sh", "-c", "sleep 3600"] and log in, I can connect from the Job's pod to the database with the command mysql -h db -uroot -pmypassword mydb -Bse 'show tables;' just fine. Based on this, I changed the command in the job to
args: ["-c", "sleep 3 && mysql -h db -uroot -pmypassword mydb -Bse 'show tables;'"]`
and now it works (i.e. correctly prints out the db tables instead of the unknown host error above). My question is why does the sleep 3 do anything? The service and database are not changing in the background at all, so why does waiting in the Job's pod make it connect?
Related
I'm currently building application and want to test on GitHub actions.
I'm using mysql for database and need to insert test data(csv format) into GitHub action's container, but it's not working well.
Here is the steps.
Create mysql container. → OK
Run script to create table. → NG.
Insert test data into table created on step2. → NG.
In every step, there are no errors, but it seems I can't run scripts in step2 and step3.
Please tell me which part of my code is wrong.
Codes here.
ci.yml
name: sample-ci
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
job-with-mysql-8_0:
runs-on: ubuntu-latest
services:
db:
image: mysql:8
ports:
- 3306:3306
env:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: sampleDB
options: >-
--health-cmd "mysqladmin ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: setup-go
uses: actions/setup-go#v3
with:
go-version: 1.16
- name: checkout
uses: actions/checkout#v3
- name: Show Docker containers
run: docker ps -a
- name: Show databases for root user
run: mysql --protocol=tcp -h localhost -P 3306 -u root -ppassword -e "SHOW DATABASES"
- name: Set up MySQL
run: sudo /lib/systemd/systemd-sysv-install enable mysql
sudo systemctl enable mysql.service
sudo systemctl start mysql.service
- name: Run sample.sql
run: |
mysql --protocol=tcp -h localhost -P 3306 -u root -ppassword -e "$(cat $(find ./ -name sample.sql))"
- name: Show created tables
run: mysql --protocol=tcp -h localhost -P 3306 -u root -ppassword -e "USE sampleDB"
mysql --protocol=tcp -h localhost -P 3306 -u root -ppassword -e "SHOW TABLES"
- name: Insert data into user table
run: sudo /lib/systemd/systemd-sysv-install enable mysql
sudo systemctl enable mysql.service
sudo systemctl start mysql.service
sh ./.github/scripts/sample.sh
- name: Check inserted data
run: mysql --protocol=tcp -h localhost -P 3306 -u root -ppassword -e "USE sampleDB"
mysql --protocol=tcp -h localhost -P 3306 -u root -ppassword -e "SELECT * FROM user"
sample.sql
USE sampleDB;
CREATE TABLE user(
id INT,
name VARCHAR(100) NOT NULL,
PRIMARY KEY(id),
UNIQUE(name)
);
sample.sh
mysql -uroot -ppassword --local-infile=1 sampleDB -e "LOAD DATA LOCAL INFILE '/docker-entrypoint-initdb.d/user.csv' INTO TABLE user FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 LINES"
user.csv
id,name
1,aaa
2,bbb
3,ccc
I have see that are other post about these issue, but nothing for the specific case described below.
In my gitlab-ci test pipeline configuration I want to run a mysql docker, and connect to it directly from my runner. But I have difficult to connect to the database.
This is my gitlab-cy-yml test step:
services:
- docker:dind
- mysql:5.7
script:
- apt-get update && apt-get install -y git curl libmcrypt-dev default-mysql-client
- mysql --version
- sleep 20
- docker login -u XXXXXXXX -p XXXXXXXXX
- docker pull mysql:5.7
- docker run --name ticketsDB -d -p 3304:3306 -it -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7
- mysql --protocol=tcp -u root -P 3304
- create database ticketOnline;
- use ticketOnline;
The error is during mysql --protocol=tcp -u root -P 3304 connections:
ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (111)
Where am I doing wrong?
There is no need for docker:dind service in you setup.
job:
variables:
MYSQL_ALLOW_EMPTY_PASSWORD: "true"
MYSQL_DATABASE: ticketsDB
services:
- mysql:5.7
script:
- apt-get update && apt-get install -y git curl libmcrypt-dev default-mysql-client
- mysql --version
- sleep 20
- mysql --protocol=tcp -u root -P 3304 -h mysql -e "create database ticketOnline; use ticketOnline;"
# -h to specify the host and -e to run a SQL query
Edit:
ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (111)
The error occurs because you are trying to connect to localhost instead of the mysql service. By default services have aliases that are created by GitLab by default. Learn More in the docs.
If you need multiple mysql instance you can use multiple aliases like so:
services:
- name: mysql:5.7
alias: mysql-1
- name: mysql:5.7
alias: mysql-2
script:
- mysql mysql --protocol=tcp -u root -P 3304 -h mysql-1 # to connect to the first
- mysql --protocol=tcp -u root -P 3304 -h mysql-2 # to connect to the second.
I created mysql docker container
docker run -p 13306:3306 -d -e MYSQL_ROOT_PASSWORD="pass" -e MYSQL_DATABASE="db" --name mysql mysql:5.6.46
and I tried to connect to mysql
mysql -u root -p -h localhost -P 13306
but I can't connect to mysql.
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
I must connect like this for some reason. not use docker exec -i -t mysql bash
you should try and expand your question a bit and add some more information about the errors you receive.
In my local development environment in order to connect to my MySQL database I give it a static ip address. I tend to use docker-compose and not run it from the docker command directly for simplicity. This is what my docker-compose.yaml file looks like for a mariaDB container :
version: '3.7'
services:
maria:
container_name: maria
image: mariadb:10.4
restart: always
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_USER=user
- MYSQL_PASSWORD=user_password
volumes:
- ./maria:/var/lib/mysql
networks:
static:
ipv4_address: 172.30.0.10
networks:
static:
ipam:
driver: default
config:
- subnet: 172.30.0.0/16
After running the docker-compose up command I can now connect to the mysql shell with the command
mysql -uuser -puser_password -h 172.30.0.10
if you are running linux you can also add a line to your /etc/hosts file like :
172.30.0.10 mysql
you can then connect with the command
mysql -uuser -puser_password -h mysql
I'm pretty confident you can get the same results with a pure docker command but it just seems easier with docker-compose. Anyway I hope ths helps
I already executed mentioned here: Unable to connect to MYSQL from Docker Instance, but this time I'm running docker on windows machine.
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ docker pull mysql/mysql-server
Using default tag: latest
latest: Pulling from mysql/mysql-server
e64f6e679e1a: Pull complete
799d60100a25: Pull complete
85ce9d0534d0: Pull complete
d3565df0a804: Pull complete
Digest: sha256:59a5854dca16488305aee60c8dea4d88b68d816aee627de022b19d9bead48d04
Status: Downloaded newer image for mysql/mysql-server:latest
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql/mysql-server:latest
79ff1c03452ab2eac0d798b576ffeabde24d4c5aa6954d3d5c5bef99dcc40ce8
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ mysql -uroot -ppassword
bash: mysql: command not found
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ docker exec -it mysql bash
bash-4.2# mysql -uroot -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
bash-4.2# mysql -uroot -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
bash-4.2#
You should try to connect through the loopback interface, as you don't have access to the socket.
mysql -h 127.0.0.1 -uroot -p
In this case, it's like if your server is running on another machine, this only thing share with your host machine is the exposed port.
If you download the MySQL client from https://dev.mysql.com/downloads/windows/ then you'll be able to access the Docker-hosted MySQL in the same way you'd access any other MySQL database (of note without needing to get a root shell in the database container). Since you're using Docker Toolbox you'd probably use 192.168.99.100 as the IP address of the database server.
Try adding below in docker-compose.y\ml
services:
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: 'Dbname'
# So you don't have to use root, but you can if you like
MYSQL_USER: 'username'
# You can use whatever password you like
MYSQL_PASSWORD: 'Password'
# Password for root access
MYSQL_ROOT_PASSWORD: 'RootPassword'
ports:
# <Port exposed> : < MySQL Port running inside container>
- '3307:3306'
expose:
# Opens port 3306 on the container
- '3306'
# Where our data will be persisted
volumes:
- my-db:/var/lib/mysql
volumes:
my-db:
I want to run a creation of a new database using mysql
this is the snippet I have in my docker-compose.yml file
mysql:
image: mysql
container_name: mysql-machine
ports:
- 3306:3306
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: true
MYSQL_DATABASE: mxdb
MYSQL_USER: mxdb
MYSQL_PASSWORD: mxdb
command: mysqladmin create testing_db
Now when i run docker-compose up
I watch the console, and it says
mysql_1 | mysqladmin: connect to server at 'localhost' failed
mysql_1 | error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'
mysql_1 | Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!
So how do I re-write the command piece, so i get the service working properly?
I want to create more than one database. So manually using commands is the easiest way.
I think you should run the mysql container and then have another container do the data import. Example:
.credentials
MYSQL_ALLOW_EMPTY_PASSWORD=true
MYSQL_USER=mxdb
MYSQL_PASSWORD=mxdb
MYSQL_DATABASE=mxdb
Run the container:
docker run --name mydb -d --env-file .credentials mysql
If you want to import data from file, create a new container, link to the one that is already running and do the import:
docker run --rm -t --link mydb:DB -v /path/to/dump.sql:/dump.sql mysql bash -c "mysql -h DB -u mxdb -pmxdb mxdb < /dump.sql"
If you just want to run a command, use:
docker run --rm -t --link mydb:DB mysql mysql -h DB -u mxdb -pmxdb -e "CREATE DATABASE bar"
or
docker exec -t mydb mysql -u mxdb -pmxdb -e "CREATE DATABASE bar"
I don't think you should override the command to create the database.
In docker-compose, the command should be the command to start the given service in the docker image. In your case, the service is a MySQL server. If you gives a command for the mysql service in your docker_compose.yml, the MySQL server will never start.
What you should do is start the mysql service, and then run commands in it.
mysql:
image: mysql
container_name: mysql-machine
ports:
- 3306:3306
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: true
MYSQL_DATABASE: mxdb
MYSQL_USER: mxdb
MYSQL_PASSWORD: mxdb
Start the service:
docker-compose up
Connect to it:
mysql -umxdb -pmxdb
Then create the database:
create database testing_db;
If you need to automatize this database creation, you could put these SQL commands in a file, and do when needed:
cat init_db.sql | mysql -umxdb -pmxdb
If you use this image of mysql: tutum/mysql
You can add the name of the database you want to create at startup as an environment variable:
environment:
-ON_CREATE_DB="newdatabase"
Another solution is to put a shell script on the command part. In the script you start mysql and then create databases and add users:
command : run.sh
And on you script:
/usr/bin/mysqld_safe &
mysqladmin create testing_db