MYSQL connection error using service name as user host - mysql

I have a couple of containers which need to connect to a mysql container. For this example I will use my webapi container. Currently I am able to do this if my "test" user host is set to the IP (172.18.0.4) of the container in the mysql user table.
My understanding is that I can use the service name from the docker-compose file since they will be on the same network, thus not relying on an IP. Although when I change the host of my "test" user to the service name of the container e.g. webapi. I get thrown a mysql error.
SQLSTATE[HY000] [1045] Access denied for user 'test'#'172.18.0.4' (using password: YES)
My docker-compose file is as
version: '2.3'
services:
webapp:
image: webapp:0.3
networks:
- frontend
depends_on:
- database
webapi:
image: webapi:0.2
networks:
- frontend
depends_on:
- database
database:
image: database:0.1
networks:
- frontend
- backend
volumes:
- mysql-data:/var/lib/mysql
networks:
frontend:
external: true
backend:
external: true
volumes:
mysql-data:
external:
name: mysql-data
Is there something I am doing wrong or is my understanding of being able to use the service name as the MYSQL user host incorrect?
The database image is built from the official MariaDB dockerfile.

I found this but forgot to reply back. Interestingly the dockerfile sets the skip-name-resolve which disables DNS host name lookup.
I found this a bit odd as docker pushes the developer into using the container names as the DNS records...
So if you come across this issue, remove the line where it echo's it into the .cnf file near the bottom of the Dockerfile.

Related

Why won't TeamCity connect to MySQL when using docker-compose?

I'm trying to get TeamCity server running using docker-compose. Here's my compose file:
version: '3'
services:
db:
image: mysql
container_name: teamcity-db
restart: unless-stopped
env_file: .env
environment:
- MYSQL_DATABASE=teamcity
volumes:
- mysql:/var/lib/mysql
command: '--default-authentication-plugin=mysql_native_password'
teamcity:
depends_on:
- db
image: jetbrains/teamcity-server
container_name: teamcity
restart: unless-stopped
volumes:
- datadir:/data/teamcity_server/datadir
- logs:/opt/teamcity/logs
ports:
- "8111:8111"
volumes:
mysql:
datadir:
logs:
I've been successful getting wordpress set up using a very similar technique, and I can run phpMyAdmin and link it to the MySQL container and see the database, so its there.
When I browse to the teamcity web address, it shows me the initial setup screen as expected. I tell it to use MySQL and I put in 'root' as teh username and my MySQL root password. Teamcity then shows this:
I'm sure it's something simple but I just can't see what's wrong. Any ideas?
Solved! Here is my solution and some other learnings.
The problem was that I was telling TeamCity to use 'localhost' as the database server URL. This seems intuitive because all the services are on the same machine, but is incorrect. It is as if each container is its own host and so 'localhost' is specific to each container. 'localhost' inside a container refers to the container itself, not the host machine or any other container. So 'localhost' on the teamcity service refers to the teamcity server, not the database server, and that's why it couldn't connect.
The correct address for the database server based on my docker-compose.yml file is db (the service name of the database container). The service name becomes the host name for that container and docker resolves these as DNS names correctly within the composed group.
Also note: the default virtual network is created implicitly by docker-compose and allows all of the containers in the composed group to communicate with each other. The name of this network derives from the folder where the docker-compose.yml file is located (in my case ~/projects/teamcity) so I get a network called teamcity_default. All servers on this private vitual network are visible to each other with no further configuration needed.
The teamcity server container explicitly exposes port 8111 on the host's network interface, so it is the only container visible to the outside world. You do not need to (and probably should not) expose ports if you only need the servers to talk to each other. For example, the database server does not need to have a ports entry because it is automatically exposed on the private inter-container network. This is great for security because all the back-end services are hidden from the physical LAN and therefore the Internet.

Can't migrate existing MySQL Wordpress database to Docker with docker-compose

I'm trying to migrate a pre-existing Wordpress install from an exported SQL file to a local Docker development environment. I'm somewhat new to Docker, but I have gone through some tutorials and documentation. The problem appears to be that the "wordpress" and "phpmyadmin" services cannot access the database.
I did a search & replace in Vim on the SQL file to replace instances of the original URL with "http://localhost:8000". Then I used docker-compose.
# docker-compose.yml
version: "3.7"
services:
db:
image: mysql:5.7.29
volumes:
- ./dbdata-import/:/docker-entrypoint-initdb.d/ # Where my exported SQL file is stored
# I also tried -./dbdata-import/thedata.sql:/docker-entrypoint-initdb.d/thedata.sql
- ./dbdata:/var/lib/mysql # So local database changes persist
ports:
- "3306:3306"
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wp_database
MYSQL_USER: wp_username
MYSQL_PASSWORD: wp_password
wordpress:
depends_on:
- db
image: wordpress:php7.3-apache
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wp_username
WORDPRESS_DB_PASSWORD: wp_password
WORDPRESS_DB_NAME: wp_database
WORDPRESS_TABLE_PREFIX: wp_ #Tried without and without this
WORDPRESS_DEBUG: 1
volumes:
- ./wp-vol:/var/www/html
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin:4.9.4
container_name: phpmyadmin
environment:
PMA_HOST: db
PMA_USER: admin
PMA_PASSWORD: phpmyadmin_password
restart: always
ports:
- "8080:80"
It might be worth noting that I use this fix so I can still use OpenVPN. Basically, I created a subnet by running docker network create localdev --subnet 10.0.1.0/24. I also added this file next to my docker-compose.yml:
# docker-compose.override.yml
version: '3.7'
networks:
default:
external:
name: localdev
When I access http://localhost:8000, I don't get anything and the browser times out. When I access http://localhost:8080 for PHPMyAdmin, I get the error:
MySQL said: Documentation
Cannot connect: invalid settings.
mysqli_real_connect(): (HY000/1045): Access denied for user 'admin'#'10.0.1.3' (using password: YES)
phpMyAdmin tried to connect to the MySQL server, and the server rejected the connection. You should check the host, username and password in your configuration and make sure that they correspond to the information given by the administrator of the MySQL server.
It seems odd this would be a credential issue. I pulled the Wordpress database information straight from wp-config.php on the host server. I also tested the database, username and password by signing into the MySQL CLI on the host server.
I used docker-compose down -v to delete volumes after I finished and docker volumes ls appears to be empty. So I don't think this is an issue with /docker-entrypoint-initdb.d/ not running because MySQL already initalized. However, I'm not sure.
I've been troubleshooting this for awhile now. I've done an almost identical Docker setup without /docker-entrypoint-initdb.d to create fresh Wordpress installs. That works fine. I could really use some help. I'm currently running Debian 10. Thanks.
UPDATE: I'm still having issues. I verified that I still have the same issues when I shutdown OpenVPN, remove docker-compose.override.yml and remove the localdev network. I get all the same problems. The only difference is that PHPMyAdmin gives me a different IP address after "admin#", which is expected.
I logged into my MySQL container using docker exec -it. Running MySQL CLI with my username and password worked. The tables looked like all the data was imported by docker-entrypoint-initdb.d. So the issue doesn't appear to be with docker-entrypoint-initdb.d, but rather the wordpress and phpmyadmin services can't access the database.
UPDATE 2: I fixed MyPHPAdmin. I didn't realize that PMA_USER and PMA_PASSWORD need to match the Wordpress database. I also needed PMA_HOST to include the port number:
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin:4.9.4
environment:
PMA_HOST: db:3306
PMA_USER: wp_username
PMA_PASSWORD: wp_password
restart: always
ports:
- "8080:80"
I still need help with Wordpress.

Unable to connect to mysql container defined in docker-compose using service name

I have the following docker-compose.yml
version: '3'
services:
app:
build: .
network_mode: host
volumes:
- .:/usr/usr/src/app
db:
image: mysql/mysql-server:5.7
environment:
MYSQL_DATABASE: config_dev
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
volumes:
- ./docker/images/config-dev-image/sql-scripts:/docker-entrypoint-initdb.d
restart: always
ports:
- "1200:3306"
My app service needs to connect to the db and using the documentation I tried to connect to using the service-name 'db' like so (from the app container)
mysql --hostname=db --port=3306 --user=root However, I get the error ERROR 2005 (HY000): Unknown MySQL server host 'db'
What am I doing wrong?
Your app container is running with network_mode: host. If it's using the host network then it can't use any of the Docker-specific network features; for example, it can't reach other containers by host name and it can't be reached by host name. For Docker networking purposes it's indistinguishable from a process running on the host.
Host networking isn't actually necessary for most of the cases I see suggested on SO, and you should see if your application works if you just remove that line. You might need to add ports: to make it accessible from outside.
If you really can't disable host networking, then you need to connect to the database the same way other processes running outside Docker network space would, via the other container's published ports. A host name of localhost should work (because you're in the context of the host) but you need the mapped port number --port=1200.
Add links configuration in app section
version: '3'
services:
app:
build: .
network_mode: host
volumes:
- .:/usr/usr/src/app
links:
- db
db:
image: mysql/mysql-server:5.7
environment:
MYSQL_DATABASE: config_dev
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
volumes:
- ./docker/images/config-dev-image/sql-scripts:/docker-entrypoint-initdb.d
restart: always
ports:
- "1200:3306"
Because of network_mode: host your app container is effectively on a docker's private network like 192.168.65.1/24 while you db container is on a different private network created by docker-compose like 172.20.0.2/16. You can see this network being deleted when you run docker-compose down:
Removing network XXXX_default
where XXXX is your directory name.
If you were to remove network_mode: host from service app, both containers would be on the same private network and reachable by their service name.
$ docker inspect XXXX_default
"Containers": {
...
"Name": "app",
"IPv4Address": "172.21.0.3/16",
...
},
...
"Name": "db",
"IPv4Address": "172.21.0.2/16",
...
}
},
app container can access db on port 3306. No need to expose the port as 1200. As per docs:
Containers connected to the same user-defined bridge network
automatically expose all ports to each other, and no ports to the
outside world. This allows containerized applications to communicate
with each other easily, without accidentally opening access to the
outside world.

Can't connect to database: Access denied for user

I am setting up a CakePHP 3.7 application and using docker compose. I have a mysql service as well that I'm trying to connect to, but I am getting this error: Access denied for user 'ws_user'#'172.20.0.3' (using password: YES)
I am granting permissions to the user like so: GRANT ALL PRIVILEGES ON mydb.* TO 'ws_user'#'%' IDENTIFIED BY '<superSecretPasswordHere>'.
If I use the root credentials, cakephp is able to make the connection just fine.
I also expose the mysql service on port 3030 to my local machine and I am able to connect with the ws_user credentials just fine.
I also setup mysql running on my local machine with the same credentials and cake is able to connect to host 172.17.0.1 just fine as well.
I'm perplexed as what could be the problem. It sure seems like it's a permissions problem (because of the error message), but I'm able to connect via the exposed port via the command line. My next thought was that it might be because of special characters in the password, but again, if I connect to mysql running on my host machine, it works fine with the same password.
Here is my docker-compose file:
version: '2'
# define all services
services:
# our service is called CakePHP ;-)
cakephp:
# we want to use the image which is build from our Dockerfile
build:
context: .
dockerfile: Dockerfile
# apache is running on port 80 but we want to expose this to port 4000 on our local machine
ports:
- "80:80"
# we are depending on the mysql backend
depends_on:
- mysql
# we mount the working dir into the container, handy for development
volumes:
- .:/var/www/html/
environment:
- SECURITY_SALT
- MYSQL_HOST
- MYSQL_USERNAME
- MYSQL_PASSWORD
mysql:
# we use the mysql base image, version 5.6.36
#image: mysql:5.6.39
build:
context: .
dockerfile: Dockerfile.mysql
ports:
- "3030:3006"
# we mount a datavolume to make sure we don't lose data
volumes:
- mysql_data:/var/lib/mysql
# setting some envvars to create the DB
environment:
- MYSQL_ROOT_PASSWORD
- MYSQL_DATABASE
volumes:
mysql_data:
From "cakephp" you connect to "mysql:3306". This should be in your connection string.
From your host you can connect to "127.0.0.1:3030" to verify that your database accepts remote login.
Then you should check the credentials that they are the same. I suggest you put them in a .env file and then test the connection by "copy-paste" of the values.
you can check the values that are actually passed to the containers by running:
docker-compose config
This shows you the exact version of the docker-compose file that will be sent to the docker engine.
Hope this works, otherwise drop me a comment.

Docker django mysql.sock in different location

I'm trying to containerize my django file, and I keep running into the issue:(2006, ’Can\‘t connect to local MySQL server through socket \‘/var/run/mysqld/mysqld.sock\’ (2 “No such file or directory”)
I found out later mysql.sock is in this location:/tmp/mysql.sock instead of /var/run/mysqld/mysqld.sock, how do I change the location for docker to see /tmp/mysql.sock
Here is my docker-composr.yml:
version: '3'
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: somepassword
adminer:
image: adminer
restart: always
ports:
- 8080:8080
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
I have followed the instructions on the mysql docker website to link mysql instance to a container
EDIT: I read another stack overflow similar to this, I changed my django code to 'HOST': '127.0.0.1' in DATABASES now I get : (2006, 'Can\'t connect to MySQL server on \'127.0.0.1\' (111 "Connection refused")')
Your host should be db. When using docker-compose, you address different servers by their service name.
So, in settings.py, you should have:
DATABASES = {
'default': {
'HOST': 'db',
...
}
}
If you want to connect to your containerized MySQL server both inside and outside of the container, you'll first need to make sure the port is mapped on the host machine:
services:
db:
image: mysql
ports:
- "3306:3306"
...
That will allow you to access MySQL using localhost or 127.0.0.1 directly on your host machine.
If you want to be able to run Django in both the web container and also on the host, you'll need to override the DATABASES setting depending upon the scenario. The web container will need to use a HOST value of db, whereas your local machine will need a value of localhost.