How to launch a service like mysql in a docker container? - mysql

So I've tried to create a docker-compose.yml file to create one container for my web app with laravel and an other container for my database with mariadb. I've tried to link those two container together so that laravel could fetch data from mariadb. The problem is that my laravel container does not have a mysql socket file, so it can't use mysql. I'm pretty sure that I've missed something, or that I don't understood something because nothing works. So my question is how do we propely connect a archlinux container with laravel to a mysql container? Here's my docker-compose file
version: '3'
services:
database:
build: ./database
container_name: database.dev
command: mysqld --user=root --verbose
ports:
- "3307:3306"
restart: always
web:
build: .
volumes:
- "/app"
ports:
- "8000:8000"
links:
- database
depends_on:
- database
When I'm trying to install mysql in my archlinux container, mysql won't create a service at /etc/init.d/mysql or event a socket file at /run/mysqld/mysqld.sock. I get this output when I try to use mysql in my container terminal.
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (2 "No such file or directory")
Here are my docker files:
database/Dockerfile
FROM mysql:latest
RUN mkdir -p /db
WORKDIR /db
COPY . /db
RUN cd /db
RUN /etc/init.d/mysql start
Dockerfile
FROM base/archlinux
RUN mkdir -p /app
WORKDIR /app
COPY . /app
RUN pacman -Syu --noconfirm
RUN pacman -S openssh composer php mariadb --noconfirm
RUN groupadd -g 89 mysql &>/dev/null
RUN useradd -u 89 -g mysql -d /var/lib/mysql -s /bin/false mysql &>/dev/null
#RUN chown -R mysql:mysql var/lib/mysql &>/dev/null
RUN mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
RUN COMPOSER_ALLOW_SUPERUSER=1
RUN cd /app
RUN /usr/bin/composer install
RUN echo APP_KEY= > .env
RUN echo DB_USERNAME=root >> .env
RUN echo DB_PASSWORD= >> .env
RUN cat php.ini > /etc/php/php.ini #my custom configuration for the project
RUN php artisan key:generate
RUN ln -srf storage/app/public public/storage
RUN php artisan storage:link
VOLUME ["/app"]
EXPOSE 8000
CMD php /app/artisan serve --host=0.0.0.0 --port=8000
I don't feel like I'm doing the proper thing, anyone can help me or show me the right way?

This repository on GitHub is an ArchLinux based image for docker, it includes PHP, PHP-composer, MySQL, PostgreSQL, and MariaDB. I just had to tweak it a bit to make it work and suits my needs!

Related

Docker compose and mysql issues connecting to local db

Even though I googled as much as I could there's not really anything that worked out for me.
Hence my question:
I am learning docker and docker compose.
I made a dockerfile:
# base image
FROM mysql:8.0-debian
# creating user to access db
RUN groupadd -r group-mysql && useradd -r -g user-mysql group-mysql
# required env variable
ENV MYSQL_ROOT_PASSWORD ale123
ENV MYSQL_USER user-mysql
ENV MYSQL_PASSWORD pass123
# expose the default port
EXPOSE 3306
When I docker run the equivalent container and execute a command from the inside of the container the mysql part works perfectly and it allows me to create tables, users dbs and such. There is no connection error.
Now the issue, I created an (in my opinion) equivalent docker compose file
services:
mysql:
image: mysql:8.0-debian
command: sh -c "groupadd -r group-mysql &&
useradd -r -g user-mysql group-mysql &&
tail -f /dev/null"
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_USER: user-mysql
MYSQL_PASSWORD: pass123
ports:
- 3306:3306
When I run the docker compose up of the aforementioned .yml file and I try to run docker exec -it containername bash and then mysql -u root -p I get this connection error: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
What am I doing wrong? Could someone point me in the right direction?
Thank you very much
Delete the command: line.
If you provide a Compose command: override, that runs instead of the normal main container command. In your case the command: override runs a couple of commands, then does tail -f /dev/null; that "keep the container running" command is running instead of the actual database server.
You don't actually need the additional user inside the container. Nothing in this setup makes use of that user. The default mysql image setup will run the MySQL server as a foreground process, and that's the behavior you need.

How to install nc in mysql container

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.

Database connection error while using .net core and mysql in docker

I have a simple web API application in .net core with MySQL database and It works locally as well without docker. I have windows 10 Home edition and can't use docker directly and I have to use VirtualBox to using docker.
Appsettings
"DatabaseConfig": {
"Server": "db",
"Port": "3306",
"Database": "CoreApiDatabase",
"User": "root",
"Password": "27101376"
}
ConfigureServices
var server = Configuration["DatabaseConfig:Server"];
var port = Configuration["DatabaseConfig:Port"];
var database = Configuration["DatabaseConfig:Database"];
var user = Configuration["DatabaseConfig:User"];
var password = Configuration["DatabaseConfig:Password"];
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql($"server={server}; userid={user}; pwd={password}; port={port}; database={database}"));
migration and seed the database in Configure method in startup.cs
Dockerfile
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
EXPOSE 80
COPY --from=build-env app/out .
ENTRYPOINT [ "dotnet","CoreApiDatabase.dll" ]
Docker-compose.yml
version: "3"
services:
db:
image: mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 27101376
networks:
- default
coreapidatabase:
image: saeedgz98/coreapidatabase
build:
context: .
dockerfile: Dockerfile
links:
- db:db
ports:
- 8001:80
restart: always
and finally, when running command docker-compose up I get this error while executing and doing migrations.
I've had a terrible luck running setting up mysql with root user and running it on some remote machine. MySQL has some strict permission requirements root#localhost is different that root#127.0.0.1 for example. Or that's what I have undrestood. If you find out otherwise please share.
Just trying to help here. Switch to another connection string form
appsettings.json
"server=<database name from docker-compose >;port=3306;userid=<database owner>;password=<owner password>;database=<database name>;"
The docker-compose might look like the below:
docker-compose.yaml
version: '3.3'
services:
moviedb:
image: mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: <root password>
MYSQL_DATABASE: <database name>
MYSQL_USER: <database owner>
MYSQL_PASSWORD: <owner password>
dockerfile
Avoid writing custom dockerfile. use the one that visual studio creates and make amends to that file.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY ["<project relative path>", "<project name>/"]
RUN dotnet restore "<project relative path>"
COPY . .
WORKDIR "/src/<project name>"
RUN dotnet build "<csproj name>" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "<csproj name>" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "<project dll name>"]
You can also run below docker commands and try to log in to the database server
Debugging tips:
docker-compose up
docker ps
docker exec -it <sql container id> bash
Once inside the container. Run below mysql commands:
mysql -u <owner name> -p
<owner password>
SHOW DATABASES;
USE <database name>;
SHOW TABLES;

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.

mkdir error: Cannot create directory '' - when trying to start mysql container with docker-compose up

I'm having a baffling time with docker-compose and mysql. When I try to start my mysql container with docker-compose, I get an uninformative mkdir error. My Dockerfile and docker-compose.yml don't even seem to contain a mkdir command for mysql.
Here is configuration:
docker-compose.yml
db:
build: docker/mysql
volumes:
- ./database:/var/lib/mysql
environment:
- MYSQL_DATABASE=xxxx
- MYSQL_USER=xxxx
- MYSQL_PASSWORD=xxxx
- MYSQL_ROOT_PASSWORD=xxxx
privileged: true
hostname: "docker.mysql"
Dockerfile
FROM mysql:5.6
MAINTAINER "ABC" <developers#abc.com>
ADD my.cnf /etc/mysql/my.cnf
RUN usermod -u 1000 mysql
RUN usermod -G staff mysql
RUN chown mysql /var/run/mysqld
EXPOSE 3306
my.cnf pastebin
http://pastebin.com/iVSGxhGV
sudo docker --version
Docker version 1.10.0, build 590d5108
This is a docker setup built by my team mates, so I am not sure what the priviledged:true line is doing, but when I remove it, everything appears to work.
with privileged:true
sudo docker-compose up db
Creating appname_db_1
Attaching to appname_db_1
db_1 | mkdir: cannot create directory '': No such file or directory
appname_db_1 exited with code 1
Once privileged: true is removed, it seems to work.
Does anyone know why this might be?