How to exit a postgres docker container from a bash script - bash

I have a docker-compose.yml configured to create and add data to a database. My compose file then loads in a bash script which will run a few short tests on the data and exit 1 upon a test failing. This is working as intended, however when I want my container to exit upon all tests passing but the docker-entrypoint.sh script seems to ignore my exit 0 command. I've attempted to write a different entrypoint script which will call on the docker-entrypoint.sh in hopes that I can then exit the container, but I'm not having any luck. Is there any easy way to implement this?
Output example:
postgres_1 | PostgreSQL init process complete; ready for start up.
postgres_1 |
postgres_1 | 2020-04-06 19:29:58.511 UTC [1] LOG: starting PostgreSQL 12.2 (Debian 12.2-2.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
postgres_1 | 2020-04-06 19:29:58.511 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres_1 | 2020-04-06 19:29:58.511 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres_1 | 2020-04-06 19:29:58.517 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_1 | 2020-04-06 19:29:58.534 UTC [102] LOG: database system was shut down at 2020-04-06 19:29:58 UTC
postgres_1 | 2020-04-06 19:29:58.540 UTC [1] LOG: database system is ready to accept connections

it's normal; entrypoint will ignore any command , to solve this you can use CDM parameter after entrypoint declaration in Dockerfile.
For example, the following snippet in Dockerfile
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
when container runs as
docker run -it <image>
will produce output:
Hello world
but when container runs as
docker run -it <image> John
will result in:
Hello John

Related

can't connect to docker container localhost connection refused

very new to docker. following this tutorial: https://medium.com/thecodefountain/develop-a-spring-boot-and-mysql-application-and-run-in-docker-end-to-end-15b7cdf3a2ba
I followed all the instructions (my application is called accessing-data-mysql) but I think I should have two containers running: one for mysql and one for the application. But when running docker container ls I only see the mysql container listed. Below I am creating a docker container for my application's image and linking it to the running instance of mysql container.
PS C:\projects\project1> docker run -d -p 8089:8089 --name accessing-data-mysql --link mysql-standalone:mysql accessing-data-mysql
82f499c6897d1f6bd2eeaabe4aa25ae786508146929a7039785e4ca37d691435
PS C:\projects\project1> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
62029a53b9d4 mysql "docker-entrypoint.s…" 16 minutes ago Up 16 minutes 3306/tcp, 33060/tcp mysql-standalone
PS C:\projects\project1> docker run -d -p 8089:8089 --name accessing-data-mysql --link mysql-standalone:mysql accessing-data-mysql
my docker file:
FROM openjdk:12
ADD target/user-mysql.jar user-mysql.jar
EXPOSE 8089
ENTRYPOINT ["java", "-jar", "user-mysql.jar"]
when connecting via browser to localhost:8089, I get connection refused error. Not even sure if the service is running.
below is the result of running docker logs:
PS C:\projects\project1> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
82f499c6897d accessing-data-mysql "java -jar accessing…" 50 minutes ago Exited (0) 50 minutes ago accessing-data-mysql
62029a53b9d4 mysql "docker-entrypoint.s…" About an hour ago Up About an hour 3306/tcp, 33060/tcp mysql-standalone
PS C:\projects\project1> docker logs accessing-data-mysql
Hibernate ORM core version 5.4.27.Final
PS C:\projects\project1>
EDIT:
When I run locally directly from Idea, I see the error: No such host is known (mysql-standalone), which is the mysql url I configured to connect to docker mysql. As soon as I change the mysql url to localhost:3306, it can connect. Does this mean that somehow the my-sql docker instance is not accepting connections?
Your container is not up and running. You need to see the container as up when you do docker ps. You should see something like this:
~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
62029a53b9d4 mysql "docker-entrypoint.s…" 16 minutes ago Up 16 minutes 3306/tcp, 33060/tcp mysql-standalone
XXXXXXXXXXXX openjdk "java" XX minutes ago Up xx minutes 8089/tcp accessing-data-mysql
If you are not able to see the second container, it means it's not running. You will need to find the reason for not running by getting the logs with docker logs accessing-data-mysql and see why the second container is not starting.
Also, consider creating a docker-compose for both containers and establish a separate network. This is not required, your example can work without this, but it makes the things much easier for management and also for troubleshooting.

how to run sqlplus from my laptop and connect to dockerized oracle launched with docker-compose?

I am trying to set up automated integration tests against an Oracle database and am
planning on using https://www.testcontainers.org/ to
launch the containers in my docker-compose.yml.
I have succeeded in getting Dockerized Oracle running on my laptop
using these instructions:
https://github.com/oracle/docker-images/tree/master/OracleWebLogic/samples/12212-oradb-wlsstore
The steps are:
# see https://docs.oracle.com/cd/E37670_01/E75728/html/oracle-registry-server.html
docker login container-registry.oracle.com # supply your oracle credentials as described above
docker network create -d bridge SampleNET
cat > env.txt <<EOF
DB_SID=InfraDB
DB_PDB=InfraPDB1
DB_DOMAIN=us.oracle.com
DB_BUNDLE=basic
EOF
docker run -d --name InfraDB --network=SampleNET -p 1521:1521 -p 5500:5500 --env-file env.txt -it --shm-size="8g" store/oracle/database-enterprise:12.2.0.1
After a minute when I issue the command "sudo docker ps -a" I see the DB is up and healthy.
CONTAINER ID IMAGE COMMAND
6a276a311b2e store/oracle/database-enterprise:12.2.0.1 "/bin/sh -c '/bin/ba…"
CREATED STATUS PORTS
2 minutes ago Up 2 minutes (healthy) 0.0.0.0:1521->1521/tcp, 0.0.0.0:5500->5500/tcp
NAMES
InfraDB
And I can now run sqlplus (from a shell prompt on my laptop, not a Docker container):
sqlplus sys/Oradoc_db1#localhost:1521/InfraDB.us.oracle.com AS SYSDBA
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
SQL>
My goal now is to create a Docker compose file that allows me to
the same thing as what was accomplished with the command line invocation of Dockerized
Oracle. Here is the docker-compose.yml file I tried:
version: '2'
services:
database:
image: store/oracle/database-enterprise:12.2.0.1
ports:
- 1521:1521
- 8080:8080
- 5500:5500
environment:
- DB_SID:InfraDB
- DB_PDB:InfraPDB1
- DB_DOMAIN:us.oracle.com
- DB_BUNDLE:basic
networks:
default:
external:
name: SampleNET
So, with this docker compose file I can launch a shell in the
container running my Oracle DB and run sqlplus:
container=`sudo docker ps -a | grep oracle | sed -e's/\s.*//'`
sudo docker exec -t -i $container bash
# SESSION INSIDE DOCKER CONTAINER:
[oracle#8f26f224db03 /]$ sqlplus sys/Oradoc_db1 AS SYSDBA
SQL*Plus: Release 12.2.0.1.0 Production on Tue Mar 3 02:44:03 2020
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Now, the million dollar question:
What is the syntax of the sqlplus command I would specify
to connect FROM MY LAPTOP (i.e., not launching a shell in the
container running the DB server)?
Here are some of the many variants I tried (note: I tried with localhost, 127.0.0.1, and
the actual IP of my laptop):
sqlplus sys/Oradoc_db1#'(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=InfraDB)))'
sqlplus sys/Oradoc_db1#'(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=InfraDB.us.oracle.com)))'
Diagnostic Note:
I am running Docker on Mac.
After I launch Docker-ized Oracle I do see listeners on the ports that the docker compose configuration is forwarding, as shown below:
sudo lsof -i -P | grep -i "listen" | egrep "1521|8080|5500"
com.docke 6295 christopher.bedford 33u IPv6 0xfffffffffffffff 0t0 TCP *:1521 (LISTEN)
com.docke 6295 christopher.bedford 34u IPv6 0xfffffffffffffff 0t0 TCP *:5500 (LISTEN)
com.docke 6295 christopher.bedford 38u IPv6 0xfffffffffffffff 0t0 TCP *:8080 (LISTEN)
Problem Solved
Here is a summary of what I did to solve the problem thanks to the suggestion of my friend Matt (Changos Muertos below).
1). creation of the bridge network 'SampleNET' is not required.
2). seems like specifying environment variables inline like this (below) does not work
environment:
- DB_SID:InfraDB
- DB_PDB:InfraPDB1
- DB_DOMAIN:us.oracle.com
- DB_BUNDLE:basic
3). Instead it is better to define those environment settings in a file that is referenced by the 'env_file' configuration option as shown below. This file resides on /tmp/docker-compose.yml
version: '2'
services:
database:
image: store/oracle/database-enterprise:12.2.0.1
ports:
- 1521:1521
- 8080:8080
- 5500:5500
env_file:
- e2.txt
And the env file contents live in the same directory ( /tmp/e2.txt ), and has the content below:
DB_SID=InfraDB
DB_PDB=InfraPDB1
DB_DOMAIN=us.oracle.com
DB_BUNDLE=basic
To run i do
docker-compose -f /tmp/docker-compose.yml up
and then i can connect (from my laptop as was the original goal) via:
sqlplus sys/Oradoc_db1#0.0.0.0:1521/InfraDB.us.oracle.com as SYSDBA
This depends on a few things, like network type, and if the port is forwarded properly. Then verify this on the host (in linux 'netstat -tlpn' ), this will show you if it is listening on the port, and if so what interface and protocol. The tool may differ depending on the host OS.
Once you see it listening via tcp (not tcp6 only), and the firewall is open on the host, you can combine that info to make your connection string.

How to reach a linked service in docker-compose?

According to https://docs.docker.com/compose/compose-file/#links, if I specify the name of another service under links in docker-compose, I should be able to reach that service at a hostname identical to the service name.
To test this, I tried the following docker-compose.yml:
version: '3'
services:
tor:
build: ./tor
use_tor:
build: ./use_tor
links:
- tor
where the tor and use_tor directories contain Dockerfiles:
.
├── docker-compose.yml
├── tor
│   └── Dockerfile
└── use_tor
└── Dockerfile
which are, for tor:
FROM alpine:latest
EXPOSE 9050
RUN apk --update add tor
CMD ["tor"]
and for use_tor:
FROM alpine:latest
CMD ["nc", "-z", "tor", "9050"]
However, if I do docker-compose build followed by docker-compose up, I see from the logs that the use_tor service exits with status code 1:
Starting scrapercompose_tor_1
Recreating scrapercompose_use_tor_1
Attaching to scrapercompose_tor_1, scrapercompose_use_tor_1
tor_1 | May 02 15:36:34.123 [notice] Tor v0.2.8.12 running on Linux with Libevent 2.0.22-stable, OpenSSL LibreSSL 2.4.4 and Zlib 1.2.8.
tor_1 | May 02 15:36:34.123 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning
tor_1 | May 02 15:36:34.123 [notice] Configuration file "/etc/tor/torrc" not present, using reasonable defaults.
tor_1 | May 02 15:36:34.129 [notice] Opening Socks listener on 127.0.0.1:9050
tor_1 | May 02 15:36:34.000 [notice] Parsing GEOIP IPv4 file /usr/share/tor/geoip.
tor_1 | May 02 15:36:34.000 [notice] Parsing GEOIP IPv6 file /usr/share/tor/geoip6.
tor_1 | May 02 15:36:34.000 [warn] You are running Tor as root. You don't need to, and you probably shouldn't.
tor_1 | May 02 15:36:34.000 [notice] We were built to run on a 64-bit CPU, with OpenSSL 1.0.1 or later, but with a version of OpenSSL that apparently lacks accelerated support for the NIST P-224 and P-256 groups. Building openssl with such support (using the enable-ec_nistp_64_gcc_128 option when configuring it) would make ECDH much faster.
tor_1 | May 02 15:36:34.000 [notice] Bootstrapped 0%: Starting
scrapercompose_use_tor_1 exited with code 1
tor_1 | May 02 15:36:35.000 [notice] Bootstrapped 80%: Connecting to the Tor network
tor_1 | May 02 15:36:36.000 [notice] Bootstrapped 85%: Finishing handshake with first hop
tor_1 | May 02 15:36:36.000 [notice] Bootstrapped 90%: Establishing a Tor circuit
tor_1 | May 02 15:36:36.000 [notice] Tor has successfully opened a circuit. Looks like client functionality is working.
tor_1 | May 02 15:36:36.000 [notice] Bootstrapped 100%: Done
Apparently the command nc -z tor 9050 doesn't return the expected status code 0 on the use_tor container. However, it would seem to me that this should work. For example, if I modify the tor service to map port 9050 on the container to the host as follows,
services:
tor:
build: ./tor
ports:
- "9050:9050"
Then in my ordinary terminal, I do see that nc -z localhost 9050 yields an exit code of 0:
kurt#kurt-ThinkPad:~$ nc -z localhost 9050
kurt#kurt-ThinkPad:~$ echo $?
0
In short, I would expect the hostname tor to behave like localhost on my the host after the port mapping, but this appears not to be the case. Why is this not working?
This question made me gawk at it for once. Although I cloned this example but was not able to get the solution. According to docker docs
The EXPOSE instruction informs Docker that the container listens on
the specified network ports at runtime. EXPOSE does not make the ports
of the container accessible to the host. To do that, you must use
either the -p flag to publish a range of ports or the -P flag to
publish all of the exposed ports. You can expose one port number and
publish it externally under another number.
So I think that may be because the tor service is running on 127.0.0.1 instead of 0.0.0.0 (for difference between them you can look here)
tor_1 | May 02 15:36:34.129 [notice] Opening Socks listener on
127.0.0.1:9050
It is accessible through terminal is because of the ports argument in docker-compose.yml which does the same as -p argument.
All in all if the tor service listens on 0.0.0.0 then it should work as expected.

How to connect to SSHD inside a Docker container from Windows?

I have a Ruby on Rails environment, and I'm converting it to run in Docker. This is largely because the development machine is a Windows laptop and the server is not. I have the Docker container mainly up and running, and now I want to connect the RubyMine debugger. To accomplish this the recommendation is to setup an SSH server in the container.
https://intellij-support.jetbrains.com/hc/en-us/community/posts/207649545-Use-RubyMine-and-Docker-for-development-run-and-debug-before-deployment-for-testing-
I successfully added SSHD to the container using the dockerfile lines from https://docs.docker.com/engine/examples/running_ssh_service/#build-an-egsshd-image minus the EXPOSE 22 (because it wasn't working with the port mapping in the docker-compose.yml). But the port is not accessible on the local machine
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6652389d248c civilservice_web "bundle exec rails..." 16 minutes ago Up 16 minutes 0.0.0.0:3000->3000/tcp, 0.0.0.0:3022->22/tcp civilservice_web_1
When I try to point PUTTY at localhost and 3022, it says that the server unexpectedly closed the connection.
What am I missing here?
This is my dockerfile
FROM ruby:2.2
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's#session\s*required\s*pam_loginuid.so#session optional pam_loginuid.so#g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
CMD ["/usr/sbin/sshd", "-D"]
RUN mkdir /MyApp
WORKDIR /MyApp
ADD Gemfile /MyApp/Gemfile
ADD Gemfile.lock /MyApp/Gemfile.lock
RUN bundle install
ADD . /MyApp
and this is my docker-compose.yml
version: '2'
services:
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/CivilService
ports:
- "3000:3000"
- "3022:22"
DOCKER_HOST doesn't appear to be an environment variable
docker version outputs the following
Client:
Version: 17.03.0-ce
API version: 1.26
Go version: go1.7.5
Git commit: 60ccb22
Built: Thu Feb 23 10:40:59 2017
OS/Arch: windows/amd64
Server:
Version: 17.03.0-ce
API version: 1.26 (minimum version 1.12)
Go version: go1.7.5
Git commit: 3a232c8
Built: Tue Feb 28 07:52:04 2017
OS/Arch: linux/amd64
Experimental: true
docker run -it --rm --net container:civilservice_web_1 busybox netstat -lnt outputs
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.11:35455 0.0.0.0:* LISTEN
SSHD is now running along side the Rails app, but the recipe that I was working from for setting up the service is not correct for the flavor of Linux that came with my base image https://docs.docker.com/engine/examples/running_ssh_service/#build-an-egsshd-image
The image I'm using is based on Debian 8. Could someone point me at where the example breaks down?
Your sshd process isn't running. That's visible in the netstat output:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.11:35455 0.0.0.0:* LISTEN
But as user2105103 points out, I should have realized that if I compared your docker-compose.yml with the Dockerfile. You define the sshd command in the image with a Dockerfile line:
CMD ["/usr/sbin/sshd", "-D"]
But then you override your image setting when running the container with the docker-compose command:
command: bundle exec rails s -p 3000 -b '0.0.0.0'
So, the only thing run, as you can see in the netstat, is the rails app listening on 3000. If you need multiple commands to run, then you can docker exec to kick off the second command (not recommended for a second service like this), use a command that launches sshd in the background and rails in the foreground (fairly ugly), or you can consider something like supervisord.
Personally, I'd skip sshd and just use docker exec -it civilservice_web_1 /bin/bash to get a prompt inside the container when you need it.

Can't connect to Neo

I've installed Docker on OSX and downloaded the neo image. when I run it (using the args in the home page of the image), everything seems to work, but the last lines of the log indicate something like:
00:20:39.662 [main] INFO org.eclipse.jetty.server.Server - Started
#4761ms 2015-10-05 00:20:39.663+0000 INFO [API] Server started on:
http://022b5f3a38fc:7474/ 2015-10-05 00:20:39.663+0000 INFO [API]
Remote interface ready and available at [http://022b5f3a38fc:7474/]
which seem odd and attempting to connect my browser to either http://localhost:7474/ or the indicated http://022b5f3a38fc:7474/ results in an error
what am I missing here?
You'll want to use the IP address of the docker VM, which you can determine with this command:
docker-machine inspect default | grep IPAddress
The default IP address is 192.168.99.100
So depending on which port you exposed when running the Neo4j docker container you can access the Neo4j browser at:
http://192.168.99.100:7474
or
http://192.168.99.100:8474
Port 8474 is the the binding specified by this command:
docker run -i -t --rm --name neo4j -v $HOME/neo4j-data:/data -p 8474:7474 neo4j/neo4j
which is the example given in the documentation here

Resources