I am trying to insert an entrypoint script via volume bind.
My compose file looks like this:
version: '3.7'
services:
database:
container_name: database
image: microsoft/mssql-server-linux:latest
ports:
- "1435:1433"
volumes:
- ./db/init:/usr/src/app
command: sh -c 'ls -lah /usr/src/app/; chmod +x /usr/src/app/entrypoint.sh; ./usr/src/app/entrypoint.sh & /opt/mssql/bin/sqlservr;'
environment:
ACCEPT_EULA: Y
SA_PASSWORD: <password>
The two files I want to insert are in the specified init folder and seem to be added to the container since the output of a docker-compose up starts like this:
Creating network "docker_evaluation_deploy_default" with the default driver
Creating database ... done
Attaching to database
database | ls: cannot access '/usr/src/app/entrypoint.sh': No such file or directory
database | ls: cannot access '/usr/src/app/initdb.sql': No such file or directory
database | total 4.0K
database | drwxrwxrwx 1 root root 0 Mar 4 09:43 .
database | drwxr-xr-x 1 root root 4.0K Mar 4 11:58 ..
database | -????????? ? ? ? ? ? entrypoint.sh
database | -????????? ? ? ? ? ? initdb.sql
database | chmod: changing permissions of '/usr/src/app/entrypoint.sh': No such file or directory
database | sh: 1: /usr/src/app/entrypoint.sh: not found
database | 2020-03-04 11:58:37.03 Server Setup step is copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf'.
...
The files are added but are not accessible.
I am using a Windows10 Host with docker version 2.2.03 (42716) on stable channel installed. The docker-ompose version is 1.25.4.
Thank you for your help!
Related
I have tried many things and searched for this it, but nobody seems to have my exact problem.
I installed docker on my Ubuntu 20.04 LTS using these steps and the test run docker run hello-world works perfect.
My docker-compose.yml looks like this:
version: '3.7'
services:
db:
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: 42
volumes:
- type: bind
source: ./dbsetup
target: /docker-entrypoint-initdb.d
adminer:
image: adminer
ports:
- 8080:8080
depends_on:
- db
The docker service is running and mariadb/adminer images download without error.
When I try to use docker compose up (sudo or not) I get the following error:
Attaching to dbexercise3-adminer-1, dbexercise3-db-1
dbexercise3-db-1 | 2022-11-26 01:01:54+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.10.2+maria~ubu2204 started.
dbexercise3-db-1 | 2022-11-26 01:01:54+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
dbexercise3-db-1 | 2022-11-26 01:01:54+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.10.2+maria~ubu2204 started.
dbexercise3-db-1 | ls: cannot open directory '/docker-entrypoint-initdb.d/': Permission denied
dbexercise3-adminer-1 | [Sat Nov 26 01:01:54 2022] PHP 7.4.33 Development Server (http://[::]:8080) started
dbexercise3-db-1 exited with code 2
Adminer starts as it should, however I can't log in (because the mariadb container doesn't exist).
I also tried installing Docker Desktop.
After I start the GUI application docker compose up works and I can work with the DB.
Of course I could simply use Docker Desktop and start it on boot, but I don't need the GUI and the need to manually update via DEB-package is annoying.
The answer was surprisingly easy.
I simply hat to run chmod 777 dbsetup to clear the permission error.
I still have no idea how Docker Desktop managed to circumvent this issue, maybe because it runs a task which gives it higher priority?
Trying to mount a db into a mssql docker container
Dockerfile
FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Str0ngP#ssw0rd!
ENV MSSQL_TCP_PORT=1433
EXPOSE 1433
COPY mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf
ENTRYPOINT /opt/mssql/bin/sqlservr
EDIT
It seems that the only thing that prevents the image from running as a container is when I add those two COPY instructions within the Dockerfile. Everything works fine when I remove the two COPY.
In fact, it says that it can't copy c:\tempdata\master.mdf to /var/opt/mssql/data/master.mdf. But why is that?
Lately, when
Structure
All files are in the same folder on my local machine.
myfolder
/Dockerfile
/mydb.mdf
/mydb_log.ldf
Environment
Windows 10 for Workstation
Docker Desktop 4.5.1 (74721) (
Engine 20.10.12,
Compose 1.29.2,
Kubernetes 1.22.5,
Snyk 1.827.0,
Credential Helper 0.6.4)
Visual Studio Code 1.67.2
Error obtained
The image is built in a flawless fashion, letting believe everything's fine. But when I run it, I get an error:
ERROR: BootstrapSystemDataDirectories() failure (HRESULT 0x8007010b)
To run the image, I type the following command:
docker run -p 1433:1433 myimage
or even
docker run myimage
and both fashions creates the same error.
When I type in:
docker images
I can see:
REPOSITORY TAG IMAGE ID CREATED SIZE
myimage latest ffc13a86b57b 28 seconds ago 2.83GB
Which confirms that the image is correctly created.
FINAL EDIT
I thought I would share the resulting Dockerfile and final solution.
The Goal
The goal was to take a client's database MDF and LDF files in SQL Server and mount them in a Docker Container to avoid the process of installing a local SQL Server instance which I don't really need.
Lesson LEARNED
As #AlwaysLearning states, the COPY instructions are processed through the root user of the container, hence taking ownership over the /var/opt/mssql. Doing exactly as she/he said solved the problem. So folder's ownership needs to be given back to mssql user as described in #AlwaysLearning's answer. BIG THX!
Final Solution
The final solution is to be able to mount/attach the client's database files to the containerized instance of SQL Server. For that to work, I needed to write a shell script which does just that.
attach-db.sh
sleep 15s
/opt/mssql-tools/bin/sqlcmd -S . -U sa -P $tr0ngP#ssw0rd! -Q "CREATE DATABASE [mydb] ON (FILENAME = '/var/opt/mssql/data/mydb.mdf'),(FILENAME = '/var/opt/mssql/data/mydb_log.ldf') FOR ATTACH"
This comes from here: Attaching databases via a dockerfile
Dockerfile
FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=$tr0ngP#ssw0rd!
COPY mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf
COPY attach-db.sh /var/opt/mssql/data/attach-db.sh
ENTRYPOINT /var/opt/mssql/data/attach-db.sh & /opt/mssql/bin/sqlservr
Running the built image
docker run -p 1433:1433 --hostname mydb myimage
Connecting to database
Download and install Azure Data Studio is required to connect to a containerized SQL Server instance.
If you check the logs for the Docker container you'll see that the complete error message is:
2022-06-09 00:12:57.28 Server Setup step is copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf'.
2022-06-09 00:12:57.33 Server ERROR: Setup FAILED copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf': 5(Access is denied.)
ERROR: BootstrapSystemDataDirectories() failure (HRESULT 0x80070005)
This happens because the Dockerfile COPY actions are performed as the root user which leave the file system objects owned by the root user as seen with:
$ ls -la /var/opt/mssql/data
total 12
drwxr-xr-x 1 root root 4096 Jun 9 00:12 .
drwxrwx--- 1 root root 4096 Jun 9 00:12 ..
-rw-r--r-- 1 root root 0 Jun 9 00:06 mydb.mdf
-rw-r--r-- 1 root root 0 Jun 9 00:06 mydb_log.ldf
The SQL Server service itself is executed using the mssql user so now it doesn't have access to the /var/opt/mssql/data directory to add its own files. You can correct that situation by changing the ownership of the files and directories to the mssql user, i.e.:
FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Str0ngP#ssw0rd!
COPY mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf
USER root
RUN chown -R mssql:root /var/opt/mssql
USER mssql
Now the container will start successfully and you can see that the SQL Server service was able to copy its bootstrap files into the /var/opt/mssql/data directory:
$ ls -la /var/opt/mssql/data
total 81168
drwxr-xr-x 1 mssql root 4096 Jun 9 00:23 .
drwxrwx--- 1 mssql root 4096 Jun 9 00:23 ..
-rw-r----- 1 mssql root 256 Jun 9 00:23 Entropy.bin
-rw-r----- 1 mssql root 4653056 Jun 9 00:23 master.mdf
-rw-r----- 1 mssql root 2097152 Jun 9 00:23 mastlog.ldf
-rw-r----- 1 mssql root 8388608 Jun 9 00:23 model.mdf
-rw-r----- 1 mssql root 14090240 Jun 9 00:23 model_msdbdata.mdf
-rw-r----- 1 mssql root 524288 Jun 9 00:23 model_msdblog.ldf
-rw-r----- 1 mssql root 524288 Jun 9 00:23 model_replicatedmaster.ldf
-rw-r----- 1 mssql root 4653056 Jun 9 00:23 model_replicatedmaster.mdf
-rw-r----- 1 mssql root 8388608 Jun 9 00:23 modellog.ldf
-rw-r----- 1 mssql root 14090240 Jun 9 00:23 msdbdata.mdf
-rw-r----- 1 mssql root 524288 Jun 9 00:23 msdblog.ldf
-rw-r--r-- 1 mssql root 0 Jun 9 00:06 mydb.mdf
-rw-r--r-- 1 mssql root 0 Jun 9 00:06 mydb_log.ldf
-rw-r----- 1 mssql root 8388608 Jun 9 00:23 tempdb.mdf
-rw-r----- 1 mssql root 8388608 Jun 9 00:23 tempdb2.ndf
-rw-r----- 1 mssql root 8388608 Jun 9 00:23 templog.ldf
Edit:
It's worth pointing out that the Dockerfile COPY command can also set owner+group attributes on-the-fly whilst copying files into the image. This then alleviates the need to switch to USER root and back to USER mssql so as to apply chown manually, i.e.:
FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Str0ngP#ssw0rd!
COPY --chown=mssql:root mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY --chown=mssql:root mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf
I am trying to run a SQL Server container on my mac through Docker.
I ran the following command:
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=strongpassword" -p 1433:1433 --name sqlservercontainer -d mcr.microsoft.com/mssql/server:2019-latest
But the container is immediately exiting.
The docker logs for the container look like this:
SQL Server 2019 will run as non-root by default.
This container is running as user mssql.
To learn more visit https://go.microsoft.com/fwlink/?linkid=2099216.
SQL Server 2019 will run as non-root by default.
This container is running as user mssql.
To learn more visit https://go.microsoft.com/fwlink/?linkid=2099216.
/opt/mssql/bin/sqlservr: Error: The system directory [/.system] could not be created. File: LinuxDirectory.cpp:420 [Status: 0xC0000022 Access Denied errno = 0xD(13) Permission denied]
/opt/mssql/bin/sqlservr: Error: The system directory [/.system] could not be created. File: LinuxDirectory.cpp:420 [Status: 0xC0000022 Access Denied errno = 0xD(13) Permission denied]
Any idea what needs to be done to solve this?
If you use the sudo command to create a folder outside of your home directory structure for use by Docker then that folder is going to be owned by the root user, e.g.:
$ sudo mkdir /var/mssql-data
$ ls -la /var/mssql-data
total 0
drwxr-xr-x 2 root wheel 64B 26 May 11:31 ./
drwxr-xr-x 30 root wheel 960B 26 May 11:31 ../
When you try to launch an SQL Server container using a volume mapping with that folder the container will fail to start - because the Docker backend process doesn't have access - and you will see the "system directory could not be created" error message, e.g.:
$ docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=StrongPassw0rd" -p 1433:1433 -v /var/mssql-data:/var/opt/mssql --name sqlservercontainer -d mcr.microsoft.com/mssql/server:2019-latest
9d6bf76a91af08329ea07fafb67ae68410d5320d9af9db3b1bcc8387821916da
$ docker logs 9d6bf76a91af08329ea07fafb67ae68410d5320d9af9db3b1bcc8387821916da
SQL Server 2019 will run as non-root by default.
This container is running as user mssql.
To learn more visit https://go.microsoft.com/fwlink/?linkid=2099216.
/opt/mssql/bin/sqlservr: Error: The system directory [/.system] could not be created. File: LinuxDirectory.cpp:420 [Status: 0xC0000022 Access Denied errno = 0xD(13) Permission denied]
To correct the situation you need to give your own account access to the folder and then a container using that volume mapping will start successfully:
$ sudo chown $USER /var/mssql-data
$ docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=StrongPassw0rd" -p 1433:1433 -v /var/mssql-data:/var/opt/mssql --name sqlservercontainer -d mcr.microsoft.com/mssql/server:2019-latest
3b6634f234024e07af253e69f23971ab3303b3cb6b7bc286463e196dae4de82e
I create a new image base on the "mcr.microsoft.com/mssql/server" image.
Then I have a script to create a new database with some tables with seeded data within the Dockerfile.
FROM mcr.microsoft.com/mssql/server
USER root
# CreateDb
COPY ./CreateDatabaseSchema.sql ./opt/scripts/
ENV ACCEPT_EULA=true
ENV MSSQL_SA_PASSWORD=myP#ssword#1
# Create database
RUN /opt/mssql/bin/sqlservr & sleep 60; /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P ${MSSQL_SA_PASSWORD} -d master -i /opt/scripts/CreateDatabaseSchema.sql
I can see the database created by my script if I don't attach it to a persistent volume, and DO NOT see the new database if I attach it to a persistent volume. I check the log and don't see any error. Looks like the system skip to process that file. What is the problem that might cause the environment to skip processing the SQL script whci defined in Dockerfile?
thanks,
Austin
The problem with using persistent volume is all the data in that directory is replaced by the base image. I need to learn how to create the database after volume mounts
volumeMounts:
- mountPath: /var/opt/mssql
You can use docker-compose.yml and Dockerfile. Both can work together.
version: '3.9'
services:
mysqlserver:
build:
context: ..
dockerfile: Dockerfile
restart: always
volumes:
- make/my/db/persistent:/var/opt/mssql
Then you can run it with:
docker-compose -f docker-compose.yml up
Have fun
I have a problem with connection to MSSQL Docker database created from docker-compose.yml file and additional .sql file with ready-to-go empty database configuration. To connect to the MSSQL database i have used DBeaver. During the connection this error occured:
Login failed for user 'system'. ClientConnectionId:23649321-6526-4ec2-a6ed-9943e64ca019
Probably i have wrong docker-compose.yml file or wrong .sql configuration file (.sql file should work with MSSQL format). .sql file is mounted in scipts folder inside mssql folder with .yml file.
docker-compose.yml file:
version: "3.7"
services:
sql-server-db:
container_name: sql-server-db
image: mcr.microsoft.com/mssql/server:2019-latest
ports:
- "1433:1433"
environment:
SA_PASSWORD: "secret123new!"
ACCEPT_EULA: "Y"
TRUSTED_CONNECTION: "TRUE"
volumes:
- ./data/mssql:/scripts/
.sql file:
CREATE DATABASE probna
GO
USE probna
GO
CREATE LOGIN system WITH PASSWORD='system'
GO
CREATE USER system FOR LOGIN system
GO
ALTER ROLE [db_owner] ADD MEMBER system
GO
CREATE TABLE Products (ID int, ProductName nvarchar(max))
GO
If you have any ideas or fixes to existing code in .yml or .sql file please write a comment :)
Have a nice day !
PS. do you think this added to .yml file will work ?
mssql:
image: mcr.microsoft.com/mssql/server:2017-latest
environment:
- SA_PASSWORD=Admin123
- ACCEPT_EULA=Y
volumes:
- ./data/mssql:/scripts/
command:
- /bin/bash
- -c
- |
# Launch MSSQL and send to background
/opt/mssql/bin/sqlservr &
# Wait 30 seconds for it to be available
# (lame, I know, but there's no nc available to start prodding network ports)
sleep 30
# Run every script in /scripts
# TODO set a flag so that this is only done once on creation,
# and not every time the container runs
for foo in /scripts/*.sql
do /opt/mssql-tools/bin/sqlcmd -U sa -P $$SA_PASSWORD -l 30 -e -i $$foo
done
# So that the container doesn't shut down, sleep this thread
sleep infinity
if i have setup.sql file in scripts folder is this enough ? i had an error
sql-server-db | Sqlcmd: '/scripts/*.sql': Invalid filename.
what to change in that .yml file or should i add en extra file to scripts folder ?