"Base table or view not found" error in docker container - mysql

I have Laravel app with mysql db. I'm trying to run it in docker using this docker-compose.yml:
load_balancer:
image: tutum/haproxy
links:
- web
ports:
- "80:80"
cache:
image: redis
web:
image: andrewmclagan/nginx-hhvm
links:
- db
- cache
volumes:
- ./:/var/www
environment:
- APP_ENV=local
- DB_DATABASE=regappbase
- DB_PASSWORD=Q1w2e3r4t5
- DB_HOST=db
- VIRTUAL_HOST=laravel.local
db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: Q1w2e3r4t5
MYSQL_DATABASE: regappbase
On my host database has three tables:
migrations
password_resets
users
When I run the app and try refer to database, I have an error like this:
QueryException in Connection.php line 715: SQLSTATE[42S02]: Base table or view not found: Table 'regappbase.users' doesn't exist (SQL: select * from users where email=(e-mail#ghhjghj77))
How can I create database regappbase? I don't need to store data, only schema

Check the documentation for the mysql image (hub.docker.com). There is a directory which you can mount your .SQL scripts into, on container start mysql will loop through and execute each file in this dir. Use this to build up your DB schema
"Initializing a fresh instance
When a container is started for the first time, a new database mysql will be initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh and .sql that are found in /docker-entrypoint-initdb.d. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data"

Well, I spend two days trying to change variables, or use data-only-container, or mount sql-scritps.
But the decision was to make from running web-container:
php artisan migrate

Related

Dockerfile - Run a init sql file for setting up tables

I am able to run a SQL file as follows:
Setup Dockerfile as:
FROM mysql
ENV MYSQL_DATABASE stock_app
COPY ./sql-scripts/ /docker-entrypoint-initdb.d/
Building the image:
docker build -t db.
Run the following command:
docker run -d -p 3306:3306 --name db -e MYSQL_ROOT_PASSWORD=password db
This is working and able to verify that SQL commands inside the script are executed and the table is created.
What changes should I make so that all three steps are done when I do the following command to bring up all my images?
docker-compose up -d
Instead of manually building the image for db and running the command to execute the SQL file, is there an option to place the run SQL file within Dockerfile? That is to include step 3 mentioned above within Dockerfile.
You probably don't even need the Dockerfile unless you are doing something else that isn't listed above. You should be able to do what you want with a simple docker-compose like this:
version: '3.3'
services:
database:
image: mysql
volumes:
- "./sql-scripts:/docker-entrypoint-initdb.d"
environment:
MYSQL_DATABASE: stock_app
MYSQL_ROOT_PASSWORD: password
ports:
- '3306:3306'
Whenever you update your sql script you would need to recreate the containers with docker-compose up -d --force-recreate. By design the mysql image will run any sql files found in the "/docker-entrypoint-initdb.d" folder so you should not have to manually run those every time you recreate the containers.
The mysql image has the a volume mounted that stores the database. If the folder does not exists, it is created and your scripts are applied.
Instead of trying to write a script that destroys the way the base image is built, just change your base image and make it run scripts every times as it is suggested in this question : docker-compose: reinitializing MySQL db every time

Error while running docker compose up while connecting to sql database

I have setup docker environment in my local machine to run our development code by pointing to dev mysql database url. Done all configurations and was able to build the docker using docker-compose build command. Even though i was able to build it successfully , on running the command docker-compose up , i am getting numerous errors.
Few of the errors are :
ERROR - TransactionManager Failed to start new registry transaction.
ERROR- AsyncIndexer. Error while indexing
I saw another answers in stackoverflow and updated my code accordingly like limiting max active connections to field to 50 in master-datasources.xml file and changing the configuration url to the below format.
jdbc:mysql://${db_url}:${db_port}/${carbon_db}?autoReconnect=true&relaxAutoCommit=true
Docker version : 19.03.5
Docker compose version : 1.24.1
My docker-compose.yml file:
services:
wso2am:
build: ./apim
image: wso2am:2.1.0
env_file:
- sample.env
ports:
- "9444:9444"
- "8281:8281"
- "8244:8244"
depends_on:
- wso2is-km
wso2is-km:
build: ./is-as-km
image: wso2is-km:5.3.0
env_file:
- sample.env
ports:
- "9443:9443"
My sample.env file:
HOST_NAME=<hostname>
DB_URL=<db_connection_url>
DB_USER=admin
DB_PASS=adminpassword
DB_PORT=3306
CARBON_DB=carbondb
APIM_DB=apimdb
ADMIN_PASS=<wso2_password>
Can anyone provide a solution for this issue.

How to access redmine log folder inside a docker after a docker-compose?

I am a noob with docker, and I try to implement a redmine+mysql container in Windows environment and add production mysql dump in it after that.
I have an issue when trying to access to redmine after my execution of sql script production dump, after sql launch I only have Internal error when browsing redmine with docker.
I don't know how to change the database name in the data-compose file , if I replace 'redmine' with anything else my script is broken.
Also I don't know how I can access to redmine error logs folder in my docker to fix the issue.
Here is my docker-compose file :
version: '3.7'
services:
db:
image: mysql:5.5.47
restart: always
ports:
- 3306:3306
volumes:
- .\mysql_files\data-mysql:/var/lib/mysql
- .\mysql_files\backup-mysql:/var/lib/mysql/backup
- .\mysql_files\dump-mysql:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: monmdp
MYSQL_DATABASE: redmine
redmine:
image: redmine:4.0.3
restart: always
ports:
- 8080:3000
depends_on:
- db
volumes:
- .\redmine_files\files:/usr/local/redmine/files
- .\redmine_files\logs:/var/log/redmine
environment:
REDMINE_DB_MYSQL: db
REDMINE_DB_PASSWORD: monmdp
as you can see I tried to access to redmine log folder in this line :
- .\redmine_files\logs:/var/log/redmine
but the folder is still empty :(
expected result : can browse redmine with production data dump
current result : Can't browse redmine and can't access log folder to check what's wrong.
Thanks for your help
From what I understand, you are trying to access the logs of redmine container but you found the .\redmine_files\logs directory empty. First, you need to check whether there are logs in the docker /var/log/redmine directory or not. You can do so by running commands in redmine shell itself. Use the command docker exec -it redmine /bin/bash to move to redmine shell and cd to /var/log/redmine to check if the logs are present there or not. If you don't find the logs there then that means that there was not logs to be replicated to ./redmine_files/logs.
If you find the logs in /var/log/redmine then there must be some issue with your docker-compose file, but it seems fine to me. Also, as #Mihai has suggested you can check the logs of redmine using the command sudo docker-compose logs redmine to see if it is running properly or not.
this docked image host redmine under /usr/src/redmine/ so you should use
- .\redmine_files\logs:/usr/src/redmine/log

How to create database in database docker container?

I'm new in docker, so cant understand - if I want to build container of mysql/postgresql/clickhouse etc - how to create database and schema of database/table? Maybe in Dockerfile or i can do it from docker-compose.yml?
I mean, that I dont know when and where to use CREATE DATABASE; CREATE TABLE ...; queries if I use docker containers of popular databases
You can use both docker and docker-compose. For example with docker compose.
Create a file called docker-compose.yml like:
version: '3'
services:
db:
image: percona:5.7
container_name: whatever_you_want
environment:
- MYSQL_DATABASE=${DATABASE}
- MYSQL_ROOT_PASSWORD=${ROOT_PASSWORD}
- MYSQL_USER=${USER}
- MYSQL_PASSWORD=${PASSWORD}
volumes:
- ./data:/docker-entrypoint-initdb.d
ports:
- "3306:3306"
Additionally you need a file under ./data with whatever SQL commands you want to run and and .env file where you define the environmental variables I used in the docker-compose.yml file above like: ${DATABASE}
Your .env file:
# MySQL
DATABASE=db_name_here
ROOT_USER=root
ROOT_PASSWORD=root
USER=dev
PASSWORD=dev
Your file with SQL commands to execute ./data/init.sql (you can name the file whatever you want)
CREATE DATABASE 'whatever';
DROP DATABASE 'whatever';
-- you can do whatever you want here
This file will be executed each time you do:
docker-compose up -d db
At first you need to create docker a image for your db server, or use an already existing image.
Bellow is an example of mysql docker image.
version: "3"
services:
****************
mysql:
container_name: mysql
image: mysql:5.7
restart: on-failure
environment:
- MYSQL_DATABASE=YOUR_DB_NAME
- MYSQL_ROOT_PASSWORD=YOUR_ROOT_USER_PASSWORD
- MYSQL_USER=YOUR_USER
- MYSQL_PASSWORD=YOUR_USER_PASSWORD
ports:
- "33060:3306"
volumes:
- "./data/db/mysql:/var/lib/mysql"
Let's describe some sections:
volumes:
- "./data/db/mysql:/var/lib/mysql"
This is like "mounting" container's /var/lib/mysql to system's ./data/db/mysql. So your data will be on your system drive, because in debian the default path to MySQL data is /var/lib/mysql.
ports:
- "33060:3306"
This will map port 3306 from container to system's 33060 port, to avoid conflicts if you have installed MySQL server on system as well.
environment:
- MYSQL_DATABASE=YOUR_DB_NAME
- MYSQL_ROOT_PASSWORD=YOUR_ROOT_USER_PASSWORD
- MYSQL_USER=YOUR_USER
- MYSQL_PASSWORD=YOUR_USER_PASSWORD
This will create a database with the defined parameters: name, root password, ..., or if a database already exists it will try to access with the defined credentials. Functionality to check/create database is already defined in the image.
If you want to define your own functionality you can define your image (e.g. dockerfile: ./Dockerfile instead of image: mysql:5.7). Dockerfile can be something like this:
FROM mysql:5.7
ARG MYSQL_DATABASE
ARG MYSQL_USER
ARG MYSQL_PASSWORD
ARG MYSQL_ROOT_PASSWORD
ENV MYSQL_DATABASE=${MYSQL_DATABASE}
ENV MYSQL_USER=${MYSQL_USER}
ENV MYSQL_PASSWORD=${MYSQL_PASSWORD}
ENV MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
# copy predefined config file
COPY configs/default.cnf /etc/mysql/conf.d/
# To be sure that MySQL will not ignore configs
RUN chmod og-w /etc/mysql/conf.d/default.cnf
# DO SOMETHING ELSE YOU WANT
EXPOSE 3306
CMD ["mysqld"]
So you can build and up your container with command docker-compose up -d --build
Here is an example I used to initialise SQL Server 2017 database using container.
https://www.handsonarchitect.com/2018/01/build-custom-sql-server-2017-linux.html
The trick is to use a shell script to run which will invoke the database initialisation script. You might have to wait for few seconds for the database engine service to start before executing the initialisation script.

Using docker-compose in order to create a MySQL schema/database

I am trying to create a mysql database/schema if it doesn't already exist.
Here is what I have tried:
docker-compose.yml
mysql:
image: mysql:5.6.26
environment:
- MYSQL_ROOT_PASSWORD=root
command: "mysql -uroot -proot < createDB.sql"
ports:
- "3306:3306"
createDB.sql
CREATE DATABASE IF NOT EXISTS bignibou;
It does not work. What would be the best way to use docker/docker-compose in order to create a schema if it does not exist?
I finally found the beginning of a solution.
The MySQL image takes an environment variable i.e. MYSQL_DATABASE that initialize the container with the name of the database on image startup See here for full documentation.
Or read the excerpt below:
MYSQL_DATABASE
This variable is optional and allows you to specify the name of a
database to be created on image startup. If a user/password was
supplied (see below) then that user will be granted superuser access
(corresponding to GRANT ALL) to this database.
Here is what I came up with:
mysql:
image: mysql:5.6.26
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=bignibou
ports:
- "3306:3306"
I now need a way to specify the default collation but that is another story...
edit: For those interested in specifying a different collation from the default, here are the instructions to use another config file that will override the default one. See below:
Using a custom MySQL configuration file The MySQL startup
configuration is specified in the file /etc/mysql/my.cnf, and that
file in turn includes any files found in the /etc/mysql/conf.d
directory that end with .cnf. Settings in files in this directory will
augment and/or override settings in /etc/mysql/my.cnf. If you want to
use a customized MySQL configuration, you can create your alternative
configuration file in a directory on the host machine and then mount
that directory location as /etc/mysql/conf.d inside the mysql
container.
If /my/custom/config-file.cnf is the path and name of your custom
configuration file, you can start your mysql container like this (note
that only the directory path of the custom config file is used in this
command):
$ docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e
MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag This will start a new
container some-mysql where the MySQL instance uses the combined
startup settings from /etc/mysql/my.cnf and
/etc/mysql/conf.d/config-file.cnf, with settings from the latter
taking precedence.
To not lost your data better use volumes as well:
version: '3'
services:
db:
image: mysql:5.7
volumes:
- mysql-db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: my_db_name
ports:
- "3307:3306"
volumes:
mysql-db:
probably what you are trying to do needs an additional script. So if building an image instead of directly using a prebuilt image is an option for you, you need to use a Dockerfile and use a script file which first imports the script in MySql and then runs the service itself.
take a look at this answer: Docker - Initialize mysql database with schema
From the docker-compose documentation - see Define Services - you can tell which Dockerfile it will use to build the image. Therefore you can create a Dockerfile based on the mysql image and create the database inside it using standard Dockerfile commands.
This might be useful in case someone lands here in future. The real issue appears to be the "command" statement in the docker-compose file. Once the command finishes successfully the container will get destroyed. This sql script must be run only after docker-compose has run and containers have been created. docker-compose "command" is really to start a service in the container. In this case you overrode the mysql service with your command.