Cannot connect from MySQL Workbench to dockerized MySQL server - java

I'm trying to connect from the MySQL Workbench to my dockerized mysql server. I'm using Windows 10. Here is my Dockerfile:
FROM ubuntu:latest
# package updates & install mysql
RUN apt-get update && apt-get install -y mysql-server
RUN apt-get -y install supervisor
ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# bind sql script
ADD musicdb.sql /tmp/musicdb.sql
RUN sed -i -e"s/^bind-address\s*=\s*127.0.0.1/bind-address = 0.0.0.0/" /etc/mysql/my.cnf
EXPOSE 3306
RUN /bin/bash -c "/usr/bin/mysqld_safe &" && \
sleep 5 && \
mysql -u root -e "CREATE DATABASE musicdb" && \
mysql -u root musicdb < /tmp/musicdb.sql
CMD ["/usr/bin/supervisord", "-n"]
I'm using this library to create, run, etc. the container from Java:
https://github.com/spotify/docker-client
My actual method to do this in Java is:
public static void createContainerWithPorts(){
DockerClient docker;
try {
docker = DefaultDockerClient.fromEnv().build();
//PortBindings
Map<String, List<PortBinding>> portBindings = new HashMap<>();
List<PortBinding> hostPorts = new ArrayList<>();
hostPorts.add(PortBinding.of("0.0.0.0", "3306"));
portBindings.put("3306", hostPorts);
HostConfig hostConfig = HostConfig.builder().portBindings(portBindings).build();
ContainerConfig containerConfig = ContainerConfig.builder().hostConfig(hostConfig).image("mysql-container").exposedPorts("3306").build();
//create container
ContainerCreation contaierCreation = docker.createContainer(containerConfig);
String id = contaierCreation.id();
//start container
docker.startContainer(id);
ContainerInfo containerInfo = docker.inspectContainer(id);
System.out.println(containerInfo.toString());
Scanner scanner = new Scanner(System.in);
scanner.next();
docker.killContainer(id);
docker.removeContainer(id);
docker.close();
} catch (DockerCertificateException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (DockerException e) {
e.printStackTrace();
}
}
Java builds the Container fine from the before created Docker Image. When I'm looking on actual running Docker Container it looks that the port binding works. When I access my container with docker exec -it SQLContainer bash it works fine and I can access my SQL server.
When i try to connect with MySQL Workbench, I got the error message shown in the picture below:
MySQL Workbench Error Message
Does someone know what I'm doing wrong?
Thanks,

I think you need to create a new user for your mysql server and specify from where the user can be used. This is because root access is only available through localhost I believe.
So to create a new user, you need to add a little something to the RUN command where you start your server:
RUN /bin/bash -c "/usr/bin/mysqld_safe &" && \
sleep 5 && \
mysql -u root -e "CREATE DATABASE musicdb" && \
mysql -u root musicdb < /tmp/musicdb.sql && \
mysql -u root -e "CREATE USER 'newUser'#'%' IDENTIFIED BY 'somePassword'" && \
mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'newUser'#'%' WITH GRANT OPTION"
That way you create a new user with the name newUser that can access from anywhere.

Related

How to: Docker container running java jar connecting to host mysql server?

I wrote a simple java program that should connect to the host machine running a MYSQL server and insert a record. The java progam is running inside a docker container with an ubuntu base image. At this point I have the jar working but can't connect to the host machine MYSQL server yet.
I've tried different mysql server installs and coppied from other dockerfiles in the hope to copy/past something together that works but it's getting messy and I don't know what parts are necessary anymore.
Java code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
class ConnectionTest {
private Connection conn;
ConnectionTest() throws IOException, ClassNotFoundException {
try {
test();
} catch (SQLException e) {
logError(e);
}
}
private void logError(SQLException e) throws IOException {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String sStackTrace = sw.toString();
File fout = new File("logs.txt");
FileOutputStream fos = new FileOutputStream(fout);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
bw.write(sStackTrace);
bw.close();
}
private void test() throws SQLException, ClassNotFoundException { ;
String hostname = "localhost";
String dbName = "test";
String userName = "root";
String password = "";
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://" + hostname + ":3306/" + dbName + "?useLegacyDatetimeCode=false&serverTimezone=Europe/Paris", userName, password);
PreparedStatement prep = conn.prepareStatement("INSERT INTO test(Login, Password) values('test', 'test')");
prep.execute();
}
}
Dockerfile:
RUN mkdir -p /root/java
COPY jdk-8u221-linux-x64.tar.gz /
RUN tar -zxf jdk-8u221-linux-x64.tar.gz -C /root/java
RUN apt-get update
RUN update-alternatives --install /usr/bin/java java /root/java/jdk1.8.0_221/bin/java 100
ENV JAVA_HOME /root/java/jdk1.8.0_221/bin
RUN export JAVA_HOME
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server \
&& sed -i "s/127.0.0.1/0.0.0.0/g" /etc/mysql/mysql.conf.d/mysqld.cnf \
&& mkdir /var/run/mysqld \
&& chown -R mysql:mysql /var/run/mysqld
VOLUME ["/var/lib/mysql"]
CMD ["mysqld_safe"]
EXPOSE 3306
COPY lib /root/test/lib
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
Entrypoint.sh:
chmod -R 777 /root/test
cd /root/test
java -cp "lib/*" -jar lib/DockerTest.jar
tail -f /dev/null
/root/test/lib contains both the mysql-connector-java.jar and the DockerTest.jar. If I run mysqld before the jar the server starts but the jar won't launch.
MYSQL status when the server is running:
$ winpty docker exec -it mysql_container service mysql status
* /usr/bin/mysqladmin Ver 8.42 Distrib 5.7.27, for Linux on x86_64
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Server version 5.7.27-0ubuntu0.16.04.1
Protocol version 10
Connection Localhost via UNIX socket
UNIX socket /var/run/mysqld/mysqld.sock
Uptime: 3 sec
Threads: 1 Questions: 4 Slow queries: 0 Opens: 105 Flush tables: 1 Open tables: 98 Queries per second avg: 1.333
Error when running just the jar:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:832)
at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:207)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at ConnectionTest.test(ConnectionTest.java:42)
at ConnectionTest.<init>(ConnectionTest.java:13)
at Main.main(Main.java:5)
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
If you are using Spring Framework you can set the spring.datasource.url in application.properties to use host.docker.internal:3306 if the MySQL is running on your local / host machine.
spring.datasource.url=jdbc:mysql://host.docker.internal:3306/<yourdatabase>

Migrate from MySQL to Postgresql

I Installed Postgresql-9.5 and PgAdmin III in my CentOS 6.6, i use these commands,
1) service postgresql-9.5 status
2) service postgresql-9.5 start
3) su postgres
4) psql
5) password
6) mysqldump --compatible=postgresql --default-character-set=utf8 -r databasename.mysql -u root -p databasename
7) mysqldump -u root -p --compatible=postgres databasename < /home/databasename.mysql
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=#OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=#OLD_SQL_MODE /;
/!40014 SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS /;
/!40014 SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS /;
/!40111 SET SQL_NOTES=#OLD_SQL_NOTES */;
-- Dump completed on 2017-08-28 11:42:14
Once it completed i open my PgAdmin III and check there is nothing... No data present inside my Database. What mistake I done.
mysqldump can't be used for executing SQL commands from file - you need to use something like psql: psql -h hostname -d databasename -U username -f file.sql.
You need to create database before using this command (so remove create database from file).
UNLOCK TABLES; That will throw error in PostgreSQL, you need to remove that line.
An insanely easy approach will be to use NMIG an amazing script with near 0 config needed.
Clone the repo
npm i, npm run build
Set your MySQL and Postgres servers connections in the ./config/config.json
npm start
Enjoy your migrated db

com.google.cloud.storage.StorageException: 401 Unauthorized

I am trying to get this sample working without success
I installed and initialized the client:
export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)"
echo "deb https://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-get update \
&& sudo apt-get -y install google-cloud-sdk \
&& sudo apt-get -y install google-cloud-sdk-app-engine-java \
&& sudo apt-get -y install google-cloud-sdk-app-engine-python \
gcloud init
Then I authenticated successfully:
gcloud auth activate-service-account 13672300789-compute#developer.gserviceaccount.com --key-file=DockerStorage-e7def0adcafb.json
Then I tried the quick start sample:
Storage storage = StorageOptions.getDefaultInstance().getService();
String bucketName = "my-first-bucket"; // "my-new-bucket";
Bucket bucket = storage.create(BucketInfo.of(bucketName));
System.out.printf("Bucket %s created.%n", bucket.getName());
BOOM unauthorized
Exception in thread "main" com.google.cloud.storage.StorageException: 401 Unauthorized
What did I miss?
At first, You have to a generate a Service account credential.
Generating a service account credential
To generate a private key in JSON or PKCS12 format:
Open the list of credentials in the Google Cloud Platform Console.
Google Cloud Platform Console
Click Create credentials.
Select Service account key.
A Create service account key window opens.
Click the drop-down box below Service account, then click New service account.
Enter a name for the service account in Name.
Use the default Service account ID or generate a different one.
Select the Key type: JSON or P12.
Click Create.
Then simply use the credential json file in you code.
StorageOptions storageOptions = StorageOptions.newBuilder()
.setProjectId("YOUR_PROJECT_ID")
.setCredentials(GoogleCredentials.fromStream(new
FileInputStream("path/YOUR_SERVICE_ACCOUNT_CRENDENTIAL.json"))).build();
Storage storage = storageOptions.getService();
Hrm...good question. Theoretically this should work If you don't otherwise specify auth, that library will first attempt to use the credentials file specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable, and if that's not set, it should go looking for your gcloud credentials.
I'm guessing that it can't find your gcloud credentials for some reason. By default, they'll be in the ".config/gcloud" directory under your home directory, but that can be overridden. Maybe check to see if there're some files there?
One thing worth trying is simply copying a service account's JSON file to that machine and specifying the path to it with the GOOGLE_APPLICATION_CREDENTIALS environment variable. That shouldn't be necessary, but if that fails as well, something more interesting is going on.

Need to combine "Sudo" and "ScpTo" examples of JSch

I'm unsuccessful with combining "Sudo" and "ScpTo" cases.
I noticed, that both work through "exec" channel.
Clean "ScpTo" case finishes with "Permission denied" message.
"Sudo" case
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand("sudo -S -u <supervisor> whoami");
works fine.
When I connect to my server through FarManager I write server option:
sudo su -l <supervisor> -c /usr/libexec/openssh/sftp-server
Also, I can run usual SFTP client like this:
sftp -s 'sudo su -l <supervisor> -c /usr/libexec/openssh/sftp-server' "usual user"#"host"
and give put command.
But such option (-s) is not implemented in JSch.
How can I configure my case (Sudo & ScpTo) with JSch?
In ScpTo.java example, there's this code:
String command="scp " + (ptimestamp ? "-p" :"") +" -t "+rfile;
Change that to:
String command="sudo su -l <supervisor> -c scp " + (ptimestamp ? "-p" :"") +" -t "+rfile;

Grails: Connecting jconsole to local process on specified port

I am trying to connect jconsole to a specified port for a local process. I can connect to the local process using the PID but not using the remote option.
I am using ubuntu 14.04 and JDK 1.7
This is what I am doing to run my app.
grails \
-Dcom.sun.management.jmxremote=true \
-Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=xxx.xxx.xxx.xxx \
-Dserver.port=8090 \
run-app
hostname -i also gives me xxx.xxx.xxx.xxx
Grails 2.3 and later uses "forked mode" by default, where the JVM running run-app spawns a separate process to run the target application. Therefore, rather than passing the -D options to grails you should configure them in BuildConfig.groovy. Find the grails.project.fork option and add jvmArgs:
grails.project.fork = [
run:[...., jvmArgs:['-Dcom.sun.management.jmxremote=true',
'-Dcom.sun.management.jmxremote.port=9999',
// etc.
]]
]
Using the -D options on the command line as you are currently doing will set up the JMX connector in the grails process, not in your application.
Adding the below code to resources.groovy resolved the issue for me.
String serverURL = grailsApplication.config.grails.serverURL
URL url = new URL(serverURL)
System.setProperty("java.rmi.server.hostname", "${url.host}")
rmiRegistry(org.springframework.remoting.rmi.RmiRegistryFactoryBean) {
port = 9999
alwaysCreate: true
}
serverConnector(org.springframework.jmx.support.ConnectorServerFactoryBean) { bean ->
bean.dependsOn = ['rmiRegistry']
objectName = "connector:name=rmi"
serviceUrl = "service:jmx:rmi://${url.host}/jndi/rmi://${url.host}:9999/jmxrmi"
environment = ['java.rmi.server.hostname' : "${url.host}",
'jmx.remote.x.password.file' : "${grailsApplication.parentContext.getResource('/WEB-INF/jmx/jmxremote.password').file.absolutePath}",
'jmx.remote.x.access.file' : "${grailsApplication.parentContext.getResource('/WEB-INF/jmx/jmxremote.access').file.absolutePath}",
'com.sun.management.jmxremote.authenticate': true,
'com.sun.management.jmxremote.local.only' : false,
'com.sun.management.jmxremote' : true]
}

Categories

Resources