how to start docker container with detach for docker-java? - docker

I am trying to run a docker image using the following code. But the container is exiting immediately after starting. I don't find -d params at creating container. how to do?
HostConfig hostConfig = new HostConfig();
DefaultDockerClientConfig.Builder config = DefaultDockerClientConfig.createDefaultConfigBuilder();
DockerClient dockerClient = DockerClientBuilder.getInstance(config).build();
CreateContainerCmd createContainerCmd = dockerClient.createContainerCmd(image);
createContainerCmd.withTty(true)
.withAttachStdout(true)
.withStdinOpen(true)
.withAttachStdout(true)
.withAttachStderr(true)
.withAttachStdin(true)
.withName(containerName)
.withHostConfig(hostConfig);
String containerId = createContainerCmd.exec().getId();
dockerClient.startContainerCmd(containerId).exec();
Could anybody help me to understand the how to keep the container up and running?

Related

Docker (Spotify) API - cannot connect to Docker

In my Docker (Spring Boot) application I would like to execute Docker commands. I use the docker-spotify-api (client).
I get different connection errors. I start the application as part of a docker-compose.yml.
This is what I tried so far on an EC2 AWS VPS:
docker = DefaultDockerClient.builder()
.uri(URI.create("tcp://localhost:2376"))
.build();
=> TCP protocol not supported.
docker = DefaultDockerClient.builder()
.uri(URI.create("tcp://localhost:2375"))
.build();
=> TCP protocol not supported.
docker = new DefaultDockerClient("unix:///var/run/docker.sock");
==> No such file
docker = DefaultDockerClient.builder()
.uri("unix:///var/run/docker.sock")
.build();
==> No such file
docker = DefaultDockerClient.builder()
.uri(URI.create("http://localhost:2375")).build();
or
docker = DefaultDockerClient.builder()
.uri(URI.create("http://localhost:2376")).build();
or
docker = DefaultDockerClient.builder()
.uri(URI.create("https://localhost:2376"))
.build();
==> Connect to localhost:2376 [localhost/127.0.0.1] failed: Connection refused (Connection refused)
Wthat is my environment on EC2 VPS:
$ ls -l /var/run
lrwxrwxrwx 1 root root 6 Nov 14 07:23 /var/run -> ../run
$ groups ec2-user
ec2-user : ec2-user adm wheel systemd-journal docker
$ ls -l /run/docker.sock
srw-rw---- 1 root docker 0 Feb 14 17:16 /run/docker.sock
echo $DOCKER_HOST $DOCKER_CERT_PATH
(empty)
This situation is similar to https://github.com/spotify/docker-client/issues/838#issuecomment-318261710.
You use docker-compose on the host to start up your application; Within the container, the Spring Boot application is using docker-spotify-api.
What you can try is to mount /var/run/docker.sock:/var/run/docker.sock in you compose file.
As #Benjah1 indicated, /var/run/docker.sock had to be mounted first.
To do so in a docker-compose / Docker Swarm environment you can do:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Furthermore, the other options resulted in errors because the default setting of Docker is that it won't open up to tcp/http connections. You can change this, of course, taking a small risk.
What is your DOCKER_HOST and DOCKER_CERT_PATH env vars value.
Try below as docker-client communicates with your local Docker daemon using the HTTP Remote API
final DockerClient docker = DefaultDockerClient.builder()
.uri(URI.create("https://localhost:2376"))
.build();
please also verify the privileges of docker.sock is it visible to your app and check weather your docker service is running or not as from above screenshot your docker.sock looks empty but if service is running it should contain pid in it
It took me some time to figure out, but I was running https://hub.docker.com/r/alpine/socat/ locally, and also wanted to connect to my Docker daemon and couldn't (same errors). Then it struck me: the solution on that webpage uses 127.0.0.1 as the ip address to bind to. Instead, start that container with 0.0.0.0, and then inside your container, you can do this: DockerClient dockerClient = new DefaultDockerClient("http://192.168.1.215:2376"); (use your own ip-address of course).
This worked for me.

How do I get my IP address from inside an ECS container running with the awsvpc network mode?

From a regular ECS container running with the bridge mode, or from a standard EC2 instance, I usually run
curl http://169.254.169.254/latest/meta-data/local-ipv4
to retrieve my IP.
In an ECS container running with the awsvpc network mode, I get the IP of the underlying EC2 instance which is not what I want. I want the address of the ENI attached to my container. How do I do that?
A new convenience environment variable is injected by the AWS container agent into every container in AWS ECS: ${ECS_CONTAINER_METADATA_URI}
This contains the URL to the metadata endpoint, so now you can do
curl ${ECS_CONTAINER_METADATA_URI}
The output looks something like
{
"DockerId":"redact",
"Name":"redact",
"DockerName":"ecs-redact",
"Image":"redact",
"ImageID":"redact",
"Labels":{ },
"DesiredStatus":"RUNNING",
"KnownStatus":"RUNNING",
"Limits":{ },
"CreatedAt":"2019-04-16T22:39:57.040286277Z",
"StartedAt":"2019-04-16T22:39:57.29386087Z",
"Type":"NORMAL",
"Networks":[
{
"NetworkMode":"awsvpc",
"IPv4Addresses":[
"172.30.1.115"
]
}
]
}
Under the key Networks you'll find IPv4Address
You application code can then look something like this (python)
METADATA_URI = os.environ['ECS_CONTAINER_METADATA_URI']
container_metadata = requests.get(METADATA_URI).json()
ALLOWED_HOSTS.append(container_metadata['Networks'][0]['IPv4Addresses'][0])
import * as publicIp from 'public-ip';
const publicIpAddress = await publicIp.v4(); // your container's public IP

gitlab runner - network_mode = "host"

I want to setup CI/CD in GitLab.
So i installed docker and the gitlab-runner on linux, created a config for a runner and started everything. So far so good.
The runner works, and docker works.
But i am using the linux subsystem from windows, so i need to run the docker container with parameter "--network host" otherwise they not gonna work.
So right now i try to configure the gitlab-runner to use the host network via the "network_mode" parameter. But it does not work. I get the same error as if i would run a docker container directly and without the "--network host".
The error:
WARNING: Preparation failed: Error response from daemon: oci runtime error: container_linux.go:265: starting container process caused "process_linux.go:368: container init caused \"process_linux.go:351: running prestart hook 0 caused \\"error running hook: exit status 1, stdout: , stderr: time=\\\\"2019-04-12T18:42:33+02:00\\\\" level=fatal msg=\\\\"failed to add interface vethfc7c8d1 to sandbox: failed to get link by name \\\\\\\\"vethfc7c8d1\\\\\\\\": Link not found\\\\" \\n\\"\"" (executor_docker.go:423:16s) job=123project=123 runner=123
This is my config:
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "MyHostName"
url = "https://my.gitlab.url/"
token = "SoMeFaNcYcOdE-e"
executor = "docker"
[runners.docker]
tls_verify = false
image = "beevelop/ionic:latest"
privileged = true
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0
network_mode = "host"
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
My question is how do i force the gitlab runner to create the containers to use the host network like with the docker parameter: "--network host"
I was unable to solve the problem directly, but i found an alternative way which is a lot better.
I configured the GitLab Container Registry
of the repository to upload and white list a custom docker image and then enabled the Shared Runners of my company. The custom image i uploaded was created via a Dockerfile using docker for windows, avoiding the struggle of the buggy docker in the linux subsystem of windows. Now i can execute my CI pipeline flawlessly and have full control over the used image and do not have to keep my local machine running.

Docker Container from Terraform will not start

I launched a Docker container with Terraform, simple code.
> cat main.tf
provider "docker"{
}
resource "docker_image" "ubuntu"{
name = "ubuntu:latest"
}
resource "docker_container" "webserver" {
image = "${docker_image.ubuntu.latest}"
name = "dev-web-p01"
#start = true
must_run = true
publish_all_ports = true
}
I can see the container spun up but not running.
> docker container -ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63c770e28ad2 47b19964fb50 "/bin/bash" 10 minutes ago Exited (0) 3 minutes ago dev-web-p01
My attempt to start and connect to the container fails and I am not sure why?
> docker container start 63c
63c
> docker container exec -it 63c /bin/bash
Error response from daemon: Container 63c770e28ad256e77442cb2fb8b9b8bbc14b8f37b99296bc63f2d249209e0399 is not running
I have tried this for a couple of times but it doesn't work. Sorry bit of a noob here.
Exited (0) means program successfully completed. With docker you need to execute some long running commands to ensure it doesn't finish immediately.
Best way to test some changes with docker, is waiting for nothing. Try this:
resource "docker_image" "ubuntu" {
name = "ubuntu:latest"
}
resource "docker_container" "webserver" {
image = "${docker_image.ubuntu.latest}"
name = "terraform-docker-test"
must_run = true
publish_all_ports = true
command = [
"tail",
"-f",
"/dev/null"
]
}

Couldn't connect to Docker Aerospike from host

I'm running aerospike server in docker.
$ docker run -d --name aerospike aerospike/aerospike-server
0ad3b2df67bd17f896e87ed119758d9af7fcdd9b82a8632828e01072e2c5673f
It is started successfully.
$docker ps
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS NAMES
0ad3b2df67bd aerospike/aerospike-server "/entrypoint.sh asd"
4 seconds ago Up 2 seconds 3000-3003/tcp aerospike
I found the ip address of docker using below command.
$ docker inspect -f '{{.NetworkSettings.IPAddress }}' aerospike
172.17.0.2
When I trying to connect to aql using the below command, it is successful as well.
$ docker run -it aerospike/aerospike-tools aql -h $(docker inspect -f
'{{.NetworkSettings.IPAddress }}' aerospike)
Aerospike Query Client
Version 3.15.0.3
C Client Version 4.2.0
Copyright 2012-2017 Aerospike. All rights reserved.
aql> select * from test.person
0 rows in set (0.002 secs)
Now I am trying to connect to the aerospike server in docker using java client in host machine.
public class AerospikeDemo {
public static void main(String []args) {
AerospikeClient client = new AerospikeClient("172.17.0.2", 3000);
Key key = new Key("test", "demo", "putgetkey");
//Key key2 = new Key("1", "2", "3");
Bin bin1 = new Bin("bin1", "value1");
Bin bin2 = new Bin("bin2", "value2");
Bin bin3 = new Bin("bin2", "value3");
// Write a record
client.put(null, key, bin1, bin2, bin3);
// Read a record
Record record = client.get(null, key);
System.out.println("record is "+ record);
System.out.println("record bins is " + record.bins);
client.close();
}
}
When I run the above program, I'm getting below error -
objc[3446]: Class JavaLaunchHelper is implemented in both
/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java (0x10f7b14c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10f8794e0). One of the two will be used. Which one is undefined.
Exception in thread "main" com.aerospike.client.AerospikeException$Connection:
Error Code 11: Failed to connect to host(s): 172.17.0.2 3000 Error Code 11: java.net.SocketTimeoutException: connect timed out
at com.aerospike.client.cluster.Cluster.seedNodes(Cluster.java:413)
at com.aerospike.client.cluster.Cluster.tend(Cluster.java:306)
at com.aerospike.client.cluster.Cluster.waitTillStabilized(Cluster.java:271)
at com.aerospike.client.cluster.Cluster.initTendThread(Cluster.java:181)
at com.aerospike.client.AerospikeClient.<init>(AerospikeClient.java:210)
at com.aerospike.client.AerospikeClient.<init>(AerospikeClient.java:151)
at com.demo.aerospike.AerospikeDemo.main(AerospikeDemo.java:12)
I've tried both AerospikeClient("172.17.0.2", 3000) and AerospikeClient("localhost", 3000)
I see in the Dockerfile the port 3000 is exposed to the host but I'm not sure why I'm not able to use the aerospike server in the docker.
The IP 172.17.0.2 is only accessible within Docker (therefore you can use another container to connect). In case you want to connect from your host you need to map the respective port.
docker run -d --name aerospike -p 3000:3000 aerospike/aerospike-server
Afterwards you can use:
AerospikeClient client = new AerospikeClient("localhost", 3000);

Resources