How to install nc in mysql container - mysql

I am getting this message
nc command is missing and by doing some R&D, I got to know that in order to resolve this, (I think) I need to run below command in MySQL container in docker-compose
RUN apt-get -q update && apt-get -qy install netcat
But the issue is I don't have it's docker file else I could have written this command in docker file and might have called docker file from docker-compose
Does anyone have any idea how can I run this command from docker-compose?
Edit 1:
I have made separate the DockerFile for mysql which consists of
FROM mysql:8
RUN apt-get -q update && apt-get -qy install netcat
COPY wait-for.sh .
and then called this docker file from docker-compose which goes like this...
version: "3"
services:
mysql-standalone:
image: mysql:8.0.25
environment:
- MYSQL_ROOT_PASSWORD=********
- MYSQL_DATABASE=usermanagementappdp
ports:
- 3306:3306
depends_on: ['eureka-server']
build:
context: "./mysqlDockerFile2"
dockerfile: "Dockerfile"
volumes:
- ./wait-for:/docker-entrypoint-initdb.d
entrypoint: ["/docker-entrypoint-initdb.d/wait-for.sh", "eureka-server:8761", "--", "docker-entrypoint.sh"]
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
restart: always
environment:
PMA_HOST: mysql-standalone
PMA_USER: root
PMA_PASSWORD: root123M.
ports:
- 8085:80
eureka-server:
image: eureka-server
ports:
- 8761:8761
build:
context: "../Eureka-Server-For-User-Management-App"
dockerfile: "Dockerfile"
usermanagementapp-docker:
image: usermanagementapp-docker:latest
ports:
- 8089:8089
links:
- eureka-server
environment:
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-standalone:3306/usermanagementappdp?allowPublicKeyRetrieval=true&autoReconnect=true&useSSL=false
build:
context: "./"
dockerfile: "Dockerfile"
restart: on-failure
entrypoint: ["/wait-for.sh", "mysql-standalone:3306", "--", "['java','-jar','/app.jar']"]
depends_on: ['mysql-standalone','eureka-server']
Docker file for User management app is:
FROM openjdk:8
Add target/User-Management-App-0.0.1-SNAPSHOT.jar app.jar
VOLUME /tmp
EXPOSE 8089
RUN apt-get -q update && apt-get -qy install netcat
COPY wait-for.sh .
COPY target/User-Management-App-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Docker file for Eureka- server
FROM openjdk:8
EXPOSE 8761
ADD /target/Eureka-Server-For-User-Management-App-0.0.1-SNAPSHOT.jar netflix-eureka-server-1.0.jar
COPY wait-for.sh .
netflix-eureka-server-1.0.jar
ENTRYPOINT ["java","-jar","netflix-eureka-server-1.0.jar"]
Edit 2
I just edited mysql docker file to check if it is even getting executed or not
RUN echo "'Entered in docker file of mysql'"
FROM mysql:8
RUN apt-get -q update && apt-get -qy install netcat
COPY wait-for.sh .
RUN echo "'Exiting docker file of mysql'"
and found that on doing docker-compose up it is not echoing the text

You don't need to install netcat in the database server container. There are a couple of other things you can clean up to simplify this setup.
Let's start by thinking through what needs to happen when you run docker-compose up. The application container can't function until the database is up and running; for that, the application container is using the wait-for script, which in turn uses nc. The database itself doesn't need to make any outbound connections, though; it needs to start up and accept inbound connections so the rest of the system can proceed. So you don't need nc in the database server container, and you can just use the standard unmodified mysql image.
(In your Dockerfile you show the database depending on the Eureka service registry; but the database itself won't do anything to connect to it, and you're using a direct connection to the database from your application. It doesn't need to be part of this stack.)
Your Compose setup also overrides the image's entrypoint:. This shouldn't usually be necessary. I'd suggest a pattern where the image's ENTRYPOINT is a self-contained script that ends with a shell exec "$#" command, which will let it run the CMD passed to it as arguments. So that script could look something like
#!/bin/sh
# ./entrypoint.sh
# Set defaults for common environment variables
: ${MYSQL_PORT:=3306}
: ${MYSQL_DATABASE:=usermanagementappdp}
# Wait for the database to be ready
./wait-for.sh "$MYSQL_HOST:$MYSQL_PORT"
# Dynamically set the Spring database URL
export SPRING_DATASOURCE_URL="jdbc:mysql://$MYSQL_HOST:$MYSQL_PORT/$MYSQL_DATABASE?allowPublicKeyRetrieval=true&autoReconnect=true&useSSL=false"
# Run the main container command
exec "$#"
Then in your application's Dockerfile -- again, you don't need to change anything in the database's Dockerfile -- set this script as the ENTRYPOINT, and make your java -jar command the CMD.
FROM openjdk:8
# Install OS-level dependencies before COPYing anything in
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install --no-install-recommends --assume-yes \
netcat
# COPY in the actual application (don't usually ADD things)
WORKDIR /app
COPY target/User-Management-App-0.0.1-SNAPSHOT.jar app.jar
COPY wait-for.sh entrypoint.sh .
# Set metadata for how to run the application
EXPOSE 8089
ENTRYPOINT ["./entrypoint.sh"] # must be JSON-array syntax
CMD ["java", "-jar", "app.jar"]
Now in your docker-compose.yml setup you can get rid of most of the overrides. Run an unmodified mysql image and don't override the command: or entrypoint: of anything.
version: "3.8"
services:
mysql-standalone:
image: mysql:8.0.25
environment:
- MYSQL_ROOT_PASSWORD=********
- MYSQL_DATABASE=usermanagementappdp
ports:
- 3306:3306
phpmyadmin: { image: phpmyadmin/phpmyadmin, ... }
eureka-server:
build: ../Eureka-Server-For-User-Management-App
usermanagementapp-docker:
ports:
- 8089:8089
environment:
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka
MYSQL_HOST: mysql-standalone
build: .
restart: on-failure
depends_on: [mysql-standalone, eureka-server]
The setup you show above will contaminate your local copy of the MySQL image, so before you start, you should clean it up
docker pull mysql:8.0.25
If you need to do some sort of registration in the MySQL image at startup time, then you can follow this same basic approach. It is helpful to look up the Docker Hub mysql image page and from there its Dockerfile because you will need to know the original ENTRYPOINT and CMD.
In the ENTRYPOINT wrapper script, at the end, run the original entrypoint:
#!/bin/sh
# my-entrypoint.sh
...
exec docker-entrypoint.sh "$#" # running the original entrypoint
In your derived Dockerfile, you'll need to repeat the original CMD
FROM mysql:8.0.27
...
COPY wait-for.sh my-entrypoint.sh /usr/local/bin
ENTRYPOINT ["my-entrypoint.sh"]
CMD ["mysqld"]
In your Compose file, do not specify both image: mysql and a build: block. This will overwrite your local copy of the Docker Hub image with your custom build. For most purposes you can only specify build: and ignore image:. You do not need to use volumes: to inject code, that's contained within the custom Dockerfile.
services:
mysql-standalone:
build: ./mysql
# no image:

You could build and publish your own container image if you wanted with a dockerfile like this
FROM mysql:8
RUN apt-get -q update && apt-get -qy install netcat
and build it like docker build . -t user123/mysql:8
and push it like docker push user123/mysql:8
then switch your docker compose to use your custom container.
if you just need to pop in temporarily to install netcat, you can do that by doing
docker exec -it --user=root ContainerHashOrName /bin/bash where ContainerHashOrName can be retrieved from docker ps then just run your commands like you would on any other distro. Just be aware that you are only making changes to the specific instance of a container and that any rescheduling will bring up a different instance of the container.

You can use "build" option of compose file, https://docs.docker.com/compose/compose-file/compose-file-v3/#build and use your own Dockerfile starts with FROM mysql:8 and then install all additional stuff you need.

Related

Building a docker-compose.yaml to get mysql to autostart on a custom-built image

I took a repository tomcat8 image (entry point runs tomcat there) and added mysql to it (i.e. now i have an image with tomcat8/mysql).
Having a problem to create docker-compose.yaml which shall do the following:
get mysql to start along with tomcat8 on my new tomcat8/mysql image (i.e., instead of manually executing /etc/init.d/mysql start)
get the container to run other command-line switches i use with 'docker run':
docker run --rm -d --restart unless-stopped -p 80:8080 -p 443:8443 -v /DB:/DB tomcat8-mysql
get docker compose to run this docker-compose.yaml at server restart
Docker version 20.10.23, build 7155243
Ubuntu 22.04.1 LTS
I tried a few variations from documentation i am going through however still cannot find a way to succeed with all of the above. Any help will do.
Is it possible to combine [A] and [B] below?
[A] docker compose up -d
[B] docker exec -it [container_id] /etc/init.d/mysql start
My docker-compose.yaml
version: '3'
services:
tomcatmysql:
container_name: tomcatmysql
image: tomcat8https-mysql
ports:
- "80:8080" # tomcat http
- "443:8443" # tomcat https
- "13306:3306" # mysql
volumes:
- "/DB:/DB"
restart: unless-stopped

docker-entrypoint-initdb.d is empty when container is started from within another container

I have a directory structure like -
- Dockerfile
- docker-compose.yml
- db
- schema.sql
and contents of each file is -
Dockerfile -
FROM alpine:3.7
RUN apk update && \
apk add --no-cache docker python3 && \
apk add --no-cache --virtual .docker-compose-deps python3-dev libffi-dev openssl-dev gcc libc-dev make && \
pip3 install docker-compose && \
apk del .docker-compose-deps
ADD . .
docker-compose.yml -
version: "2"
services:
test_mysql:
image: "mysql:5.7"
container_name: test_mysql_v1
volumes:
- ./db:/docker-entrypoint-initdb.d/
environment:
- MYSQL_ROOT_PASSWORD=root
ports:
- "3310:3306"
schema.sql -
create database if not exists db2;
When I do -
docker-compose up --build --remove-orphans
it behaves expectedly and I get a db called db2 inside test_mysql_v1 container.
However, when I do -
1. docker build -t dfd_1 .
2. docker run -v /var/run/docker.sock:/var/run/docker.sock -it dfd_1 sh
from inside -
3. docker-compose up --build --remove-orphans
Then in newly created test_mysql_v1 container, docker-entrypoint-initdb.d directory is empty (no db created).
Can someone please help how to make this work?
End result should be - when I run docker-compose up from inside dfd_1 container, it should create a mysql container with db already created.
Additional notes -
To bring down mysql container, I use - docker-compose down
My guess is when I do docker run -v /var/run/docker.sock:/var/run/docker.sock ..., then I require another volume mount so that docker-compose.yml (inside dfd_1) can copy db to docker-entrypoint-initdb.d correctly.
Got nothing from docker logs.
Any help is appreciated. Thanks.
Achieved it by passing path on host directory to the container within.
Changed docker run command as -
docker run -v /var/run/docker.sock:/var/run/docker.sock -e HOST_DIR=$PWD -it dfd_1 sh
And docker-compose.yml (used HOST_DIR env variable while mapping volume) as -
version: "2"
services:
test_mysql:
image: "mysql:5.7"
container_name: test_mysql_v1
volumes:
- ${HOST_DIR}/db:/docker-entrypoint-initdb.d/
environment:
- MYSQL_ROOT_PASSWORD=root
ports:
- "3310:3306"

Dockerfile - deploy mysql dump in entrypoint

Is it possible to connect to external container in entrypoint and upload DB dump to it?
I always get web_1 exited with code 0 on this line execution: mysql -h$MYSQL_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE < magento-sample-data-1.9.1.0/magento_sample_data_for_1.9.1.0.sql in install-sampledata from Dockerfile
However, I can do docker exec -it <> bash after containers creation, execute install-sampledata there and it works
I have such docker-compose
version: '2.1'
services:
db:
image: mysql:5.6.23
volumes:
- db-data:/var/lib/mysql/data
env_file:
- env
web:
build: .
ports:
- "8089:80"
links:
- db
env_file:
- env
tty: true
volumes:
db-data:
Dockerfile
FROM alexcheng/magento
ENTRYPOINT install-sampledata
and install-sampledata file
#!/usr/bin/env bash
cd /tmp
cp /opt/magento-sample-data-1.9.1.0.tgz .
tar xvf magento-sample-data-1.9.1.0.tgz
cp -R magento-sample-data-1.9.1.0/media/* /var/www/htdocs/media/
cp -R magento-sample-data-1.9.1.0/skin/* /var/www/htdocs/skin/
chown -R www-data:www-data /var/www/htdocs/media
mysql -h$MYSQL_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE < magento-sample-data-1.9.1.0/magento_sample_data_for_1.9.1.0.sql
The problem is: your ENTRYPOINT is install-sampledata: a script which will run one mysql command and... exit!
At this point the container will stop.
If possible, it is best to call that script, and then call mysql as in the mysql Dockerfile, in order to leave a foreground process running.
Or you can have a look at multi-stage build, in order to build an image with your pre-requisite files already baked in.
You have an entry point in mysql containers that allows you to have the container use your mysql dump upon startup. Make a volume to here /docker-entrypoint-initdb.d and you're container will populate your database.
Add
sh -c /bin/bash
at last to your install-sampledata script. It will start a new process bash with a new pid. So your container will not die.

Connecting webserver container to a MySQL container

I am learning docker and I created a MySQL container with a persistent database using volumes and I want to connect to the MySQL container from the web container during the docker-compose up --build procedure.
The problem is that the connection always fail during that time. I can only access the MySQL container after everything is finished.
The line RUN mysql -uroot -pmy-root-password -hdatabase in the build/web-server/docker-compose.ymlfile below, always fail.
How can I accomplish this?
docker-compose.yml
version: '3'
services:
database:
container_name: kadu-database
build:
context: build/database
dockerfile: Dockerfile
web-server:
container_name: kadu-web-server
links:
- database
depends_on:
- database
build:
context: build/web-server
dockerfile: Dockerfile
build/database/docker-compose.yml
FROM mariadb:5.5
ARG MYSQL_DATABASE
ARG MYSQL_ROOT_PASSWORD
RUN apt-get update
RUN apt-get install patch --assume-yes
build/web-server/docker-compose.yml
FROM ubuntu:16.04
ARG WEB_USERNAME
ARG MYSQL_DATABASE
ARG MYSQL_ROOT_PASSWORD
RUN apt-get update --quiet=2 && apt-get install mariadb-client --quiet=2
RUN mysql -uroot -pmy-root-password -hdatabase
Working with docker includes 2 steps:
building a image
creating container based on image and running this container
The point is you mysql client can connect to server only on second step.
Dockerfile "executes" while you build image. In this time you don't have any containers, therefore you can't connect to them.
You need move command RUN mysql -uroot -pmy-root-password -hdatabase
from Dockerfile to entrypoint.sh

Running docker-compose with mysql and own docker container

I am trying to start my own container and link it with the official mysql container. I am using docker-compose to start both containers and link them together. My own container is supposed to be a regular LAMP-stack which runs a simple PHP application.
When I run docker-compose up, they both build properly, but when docker tries to run them, they just stop with the error code mytestservice_web_1 exited with code 0. I can not see any errors in the build log.
Here is my docker-compose.yml
web:
build: .
links:
- mysql
ports:
- "80:80"
mysql:
image: mysql:5.6
environment:
- MYSQL_ROOT_PASSWORD=verysecret
Here is my Dockerfile for my own container.
FROM linode/lamp
WORKDIR /var/www
RUN a2enmod rewrite
ADD . /var/www/mytestservice
ADD mytestservice.conf /etc/apache2/sites-enabled/
CMD service apache2 start
If I start them manually with docker run there are no problems.
How can I keep the containers running?
As mentioned in my comment above:
CMD exec /usr/sbin/apachectl -D FOREGROUND