testcontainers-python
testcontainers-python copied to clipboard
Containers fail to start: mssql/win11, mssql/m1, mssql with different port (not intended to work), postgres/win10, mariadb/win11, oracle
I'm unable to run the SqlServerContainer. After creating the MSSQL container, it gets stuck at the "waiting to be ready" state and does not proceed further.
To Reproduce
from sqlalchemy import create_engine, text
from testcontainers.mssql import SqlServerContainer
with SqlServerContainer() as mssql:
engine = create_engine(mssql.get_connection_url())
with engine.begin() as connection:
version = connection.execute(text("select @@VERSION"))
Runtime environment
Docker Desktop 4.19.0 (106363)
Windows 11
Python 3.9
testcontainers==3.7.1
it gets stuck at the "waiting to be ready" state and does not proceed further.
Does it finish execution at some point? Because your code does not actually print anything so you would see no output even if it works...
from sqlalchemy import create_engine, text
from testcontainers.mssql import SqlServerContainer
with SqlServerContainer() as mssql:
engine = create_engine(mssql.get_connection_url())
with engine.begin() as connection:
version = connection.execute(text("select @@VERSION"))
print(version.all())
This works fine for me (on linux though):
$ python baz.py
Pulling image mcr.microsoft.com/mssql/server:2019-latest
Container started: 813db1176b94
Waiting to be ready...
Waiting to be ready...
Waiting to be ready...
Waiting to be ready...
Waiting to be ready...
Waiting to be ready...
Waiting to be ready...
Waiting to be ready...
Waiting to be ready...
mssql+pymssql://SA:1Secure*Password1@localhost:49158/tempdb
[('Microsoft SQL Server 2019 (RTM-CU21) (KB5025808) - 15.0.4316.3 (X64) \n\tJun 1 2023 16:32:31 \n\tCopyright (C) 2019 Microsoft Corporation\n\tDeveloper Edition (64-bit) on Linux (Ubuntu 20.04.6 LTS) <X64>',)]
Any updates on this? I am facing the same issue on mac m1 machine.
Hello,
Any news ?
Same for me here !
EDIT :
It works if I do not change the default port for me
Same for me but for the PostgreSQL container:
Pulling image postgres:latest Container started: 502b64b3db55 Waiting to be ready... Waiting to be ready... Waiting to be ready...
Code is:
from testcontainers.postgres import PostgresContainer
postgres_container = PostgresContainer("postgres:latest", port=54321, dbname=database_name)
with postgres_container as postgres:
# Get the connection details for the container
connection_details = postgres.get_connection_url()
env:
Docker Desktop 4.21.1
Windows 10
Python 3.9
testcontainers==3.7.1
There is a temporary solution mentioned for this issue: https://github.com/testcontainers/testcontainers-python/issues/108#issuecomment-768367971
I've encountered this same issue with mariadb:11.1.2 on Windows 11, except in my case, I was using testcontainers.mysql.MySqlContainer. I got around this issue by just using the core API instead of relying on the addon package:
import subprocess
from testcontainers.core.container import DockerContainer
from testcontainers.core.waiting_utils import wait_for_logs
from time import sleep
from tqdm import tqdm
IMAGE="mariadb:11.1.2"
# Run the docker pull as a separate process since relying on testcontainers to
# pull through the API on windows gives me some issue.
if subprocess.run(["docker", "pull", IMAGE]).returncode == 1:
raise Exception(
f"Unable to pull image '{IMAGE}'. Make sure the Docker daemon is "
"running. If problems persist, you can pull the image manually."
)
container = DockerContainer(image=IMAGE)
container.env={
"MARIADB_ALLOW_EMPTY_ROOT_PASSWORD": "1",
"MARIADB_ALLOW_EMPTY_PASSWORD": "1",
}
container.start()
waiting = wait_for_logs(container, "ready for connections")
print(container.get_container_host_ip)
for i in tqdm(range(20)):
# Take this time to check docker that the container is running!
sleep(1)
container.stop()
I hope this helps someone!
Same for me for Oracle
from testcontainers.oracle import OracleDbContainer
with OracleDbContainer() as oracle:
engine = sqlalchemy.create_engine(oracle.get_connection_url())
with engine.begin() as connection:
result = connection.execute(sqlalchemy.text("select * from V$VERSION"))
env
Docker Desktop v4.26.1
Windows 10
Python 3.11
testcontainers==3.7.1
<Quoted Reply>
I've encountered this same issue with
mariadb:11.1.2on Windows 11, except in my case, I was usingtestcontainers.mysql.MySqlContainer. I got around this issue by just using the core API instead of relying on the addon package:import subprocess from testcontainers.core.container import DockerContainer from testcontainers.core.waiting_utils import wait_for_logs from time import sleep from tqdm import tqdm IMAGE="mariadb:11.1.2" # Run the docker pull as a separate process since relying on testcontainers to # pull through the API on windows gives me some issue. if subprocess.run(["docker", "pull", IMAGE]).returncode == 1: raise Exception( f"Unable to pull image '{IMAGE}'. Make sure the Docker daemon is " "running. If problems persist, you can pull the image manually." ) container = DockerContainer(image=IMAGE) container.env={ "MARIADB_ALLOW_EMPTY_ROOT_PASSWORD": "1", "MARIADB_ALLOW_EMPTY_PASSWORD": "1", } container.start() waiting = wait_for_logs(container, "ready for connections") print(container.get_container_host_ip) for i in tqdm(range(20)): # Take this time to check docker that the container is running! sleep(1) container.stop()I hope this helps someone!
Thanks to @nsaccente reply. I managed to make something that works for Oracle on Windows 10. I hope this helps someone.
oracle container sample code
import subprocess
import sqlalchemy
from sqlalchemy import create_engine
from testcontainers.core.container import DockerContainer
from testcontainers.core.waiting_utils import wait_for_logs
IMAGE="gvenzl/oracle-xe:21-slim-faststart"
# Run the docker pull as a separate process since relying on testcontainers to
# pull through the API on windows gives me some issue.
if subprocess.run(["docker", "pull", IMAGE]).returncode == 1:
raise Exception(
f"Unable to pull image '{IMAGE}'. Make sure the Docker daemon is "
"running. If problems persist, you can pull the image manually."
)
db_port = 1521
db_username = "system"
db_password = "oracle"
db_name = "xe"
os.environ['TC_HOST'] = 'localhost'
container = DockerContainer(image=IMAGE)
container.with_exposed_ports(db_port)
container.env={
"ORACLE_USERNAME": "system",
"ORACLE_PASSWORD": "oracle",
"DB_NAME": "xe",
"DB_HOST": "oracle",
}
container.start()
waiting = wait_for_logs(container, "DATABASE IS READY TO USE!")
engine = create_engine(f'oracle+oracledb://system:oracle@(DESCRIPTION=(CONNECT_TIMEOUT=30)(RETRY_COUNT=20)(RETRY_DELAY=3)(ADDRESS_LIST=(LOAD_BALANCE=ON)(ADDRESS=(PROTOCOL=TCP)(HOST={container.get_container_host_ip()})(PORT={container.get_exposed_port(db_port)})))(CONNECT_DATA=(SERVICE_NAME={db_name})))')
with engine.begin() as connection:
result = connection.execute(sqlalchemy.text("select * from V$VERSION"))
print(result)
container.stop()
@thuyng-ing i think this is the module we are looking to merge for oracle but i guess we will be looking at these suggestions as well when we are able to publish again - https://github.com/testcontainers/testcontainers-python/pull/363
<Quoted Reply>
I've encountered this same issue with
mariadb:11.1.2on Windows 11, except in my case, I was usingtestcontainers.mysql.MySqlContainer. I got around this issue by just using the core API instead of relying on the addon package:import subprocess from testcontainers.core.container import DockerContainer from testcontainers.core.waiting_utils import wait_for_logs from time import sleep from tqdm import tqdm IMAGE="mariadb:11.1.2" # Run the docker pull as a separate process since relying on testcontainers to # pull through the API on windows gives me some issue. if subprocess.run(["docker", "pull", IMAGE]).returncode == 1: raise Exception( f"Unable to pull image '{IMAGE}'. Make sure the Docker daemon is " "running. If problems persist, you can pull the image manually." ) container = DockerContainer(image=IMAGE) container.env={ "MARIADB_ALLOW_EMPTY_ROOT_PASSWORD": "1", "MARIADB_ALLOW_EMPTY_PASSWORD": "1", } container.start() waiting = wait_for_logs(container, "ready for connections") print(container.get_container_host_ip) for i in tqdm(range(20)): # Take this time to check docker that the container is running! sleep(1) container.stop()I hope this helps someone!
Thanks to @nsaccente reply. I managed to make something that works for Oracle on Windows 10. I hope this helps someone.
import subprocess import sqlalchemy from sqlalchemy import create_engine from testcontainers.core.container import DockerContainer from testcontainers.core.waiting_utils import wait_for_logs IMAGE="gvenzl/oracle-xe:21-slim-faststart" # Run the docker pull as a separate process since relying on testcontainers to # pull through the API on windows gives me some issue. if subprocess.run(["docker", "pull", IMAGE]).returncode == 1: raise Exception( f"Unable to pull image '{IMAGE}'. Make sure the Docker daemon is " "running. If problems persist, you can pull the image manually." ) db_port = 1521 db_username = "system" db_password = "oracle" db_name = "xe" os.environ['TC_HOST'] = 'localhost' container = DockerContainer(image=IMAGE) container.with_exposed_ports(db_port) container.env={ "ORACLE_USERNAME": "system", "ORACLE_PASSWORD": "oracle", "DB_NAME": "xe", "DB_HOST": "oracle", } container.start() waiting = wait_for_logs(container, "DATABASE IS READY TO USE!") engine = create_engine(f'oracle+oracledb://system:oracle@(DESCRIPTION=(CONNECT_TIMEOUT=30)(RETRY_COUNT=20)(RETRY_DELAY=3)(ADDRESS_LIST=(LOAD_BALANCE=ON)(ADDRESS=(PROTOCOL=TCP)(HOST={container.get_container_host_ip()})(PORT={container.get_exposed_port(db_port)})))(CONNECT_DATA=(SERVICE_NAME={db_name})))') with engine.begin() as connection: result = connection.execute(sqlalchemy.text("select * from V$VERSION")) print(result) container.stop()
@pytest.fixture(scope="session", autouse=True)
def setup_testdb():
image = "mcr.microsoft.com/mssql/server:2022-latest"
container = DockerContainer(image=image)
container.env = {
"ACCEPT_EULA": "Y",
"MSSQL_SA_PASSWORD":"1TestTest!"
}
container.with_bind_ports(1433, host=1433)
with container as mssql:
wait_for_logs(container, "SQL Server is now ready for client connections")
print(mssql.get_container_host_ip())
yield mssql
The above listing adapted for usage within a pytest.fixture and mssql. Thank you very much for your help!
I have the same problem
Just wanted to add a clue to the problem solving (I know below isn't really practical as a solution)...
If I debug into the SqlServerContainer and further into the _connect method of the underlying DbContainer base class and simply step through the lines the container class successfully instantiates and connects to the docker container. This led me to believe that the time delay introduced by manually stepping through the code in debug made the testcontainer successfully capture the log message it was listening for.
In fact, adding a sleep to the start method of the DbContainer makes it run successfully on my end (I know this is hacky and is likely hiding another problem - but wanted to mention it as a clue)
The SQL Server images take a looong time to start in most cases. To try pinpointing the errors here further, you could try the following:
- Try using a specific SQL Server container image tag, like
mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 - Try using a lighter SQL Server compatible image like
mcr.microsoft.com/azure-sql-edge:1.0.7
Also note that the default SqlServerContainer expects sqlalchemy to use the pymssql driver, where the package pymssql needs to be installed. If you want to use another driver (which also needs to be installed), try using pyodbc:
with SqlServerContainer("mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04", dialect="mssql+pyodbc",) as mssql:
engine = sqlalchemy.create_engine(mssql.get_connection_url())
with engine.begin() as connection:
result = connection.execute(sqlalchemy.text("select @@VERSION"))
Lastly, to check that you are able to start the image at all, try starting it manually with docker and observe the log output:
docker run -e ACCEPT_EULA=y -e SQLSERVER_USER=SA -e SA_PASSWORD="1Secure*Password1" mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04
On another note: If https://github.com/testcontainers/testcontainers-python/pull/525 lands, the wait strategy will change and testing will be more robust for more image versions which might fix your problems.