I have a container group which consists of database(MySQL), client app(SSR, SvelteKit with node-adapter) and reverse proxy(Caddy, for enabling automatic HTTPS)
Dockerfile for database:
FROM mysql:8.2.0
COPY init-prod.sql /docker-entrypoint-initdb.d/init.sql
EXPOSE 3306
init-prod.sql mentioned in the database Dockerfile:
GRANT ALL PRIVILEGES ON <database_name>.* TO '<database_user>'@'%';
-- Required for Prisma Migrate
GRANT CREATE, ALTER, DROP, REFERENCES ON *.* TO '<database_user>'@'%';
-- Flush privileges to apply changes
FLUSH PRIVILEGES;
Dockerfile for SvelteKit application. The container from which I'm trying to execute npx prisma migrate deploy is created from this image.
FROM node:18.19.0 as build
WORKDIR /app
COPY . .
RUN npm ci --omit dev
RUN npm run build
FROM node:18.19.0
COPY --from=build /app/package.json .
COPY --from=build /app/.env.production .env
COPY --from=build /app/node_modules node_modules
COPY --from=build /app/prisma prisma
COPY --from=build /app/build .
CMD ["npm", "run", "prod"]
After successful deployment to Container Instances I'm trying to run migrations with following Azure CLI command:
az container exec --resource-group <resource_group> --name <container_group> --container-name app --exec-command "npx --yes prisma migrate deploy"
The command output:
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": MySQL database "txtsummprod" at "db:3306"
Error: P1001: Can't reach database server at `db`:`3306`
Please make sure your database server is running at `db`:`3306`.
Prisma DATABASE_URL env variable is formed like this:
mysql://<database_user>:<database_password>@db:3306/<database_name>?connect_timeout=300
I've tried:
- adding
?connect_timeout=300toDATABASE_URLper this answer - changing node image versions per this answer
But still, no luck. Locally migrations are applied just fine, the problem appears only when I'm attempting to execute npx prisma migrate deploy in a container deployed to Container Instances
According to db container logs from Azure Container Instances everything seem to be ok and database is ready to accept connections:
2024-01-03 22:34:00+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.2.0-1.el8 started.
2024-01-03 22:34:01+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2024-01-03 22:34:01+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.2.0-1.el8 started.
ln: failed to create symbolic link '/var/lib/mysql/mysql.sock': Operation not supported
2024-01-03T22:34:03.057381Z 0 [System] [MY-015015] [Server] MySQL Server - start.
2024-01-03T22:34:03.348494Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
2024-01-03T22:34:03.377157Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.2.0) starting as process 150
2024-01-03T22:34:03.526733Z 0 [Warning] [MY-000054] [Server] World-writable config file '/var/lib/mysql/auto.cnf' is ignored.
2024-01-03T22:34:03.537967Z 0 [Warning] [MY-010107] [Server] World-writable config file '/var/lib/mysql/auto.cnf' has been removed.
2024-01-03T22:34:03.543031Z 0 [Warning] [MY-010075] [Server] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 328cd822-aa88-11ee-8f84-00155d592a61.
2024-01-03T22:34:03.623222Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2024-01-03T22:34:10.269749Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2024-01-03T22:34:11.972853Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2024-01-03T22:34:11.977611Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2024-01-03T22:34:12.071977Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2024-01-03T22:34:12.168356Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
2024-01-03T22:34:12.168448Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.2.0' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
YAML for deployment to Azure Container Instances looks like this:
apiVersion: 2021-10-01
location: eastus
name: txt-summ
properties:
containers:
- name: reverse-proxy
properties:
image: summacr.azurecr.io/reverse-proxy:latest
ports:
- port: 80
protocol: TCP
- port: 443
protocol: TCP
resources:
requests:
memoryInGB: 1.0
cpu: 1.0
limits:
memoryInGB: 1.0
cpu: 1.0
volumeMounts:
- name: proxy-data
mountPath: /data
- name: proxy-config
mountPath: /config
- name: app
properties:
image: summacr.azurecr.io/app:latest
resources:
requests:
cpu: 1.5
memoryInGB: 1.5
ports:
- port: 3000
protocol: TCP
- name: db
properties:
image: summacr.azurecr.io/db:latest
resources:
requests:
cpu: 1.0
memoryInGB: 1.0
volumeMounts:
- name: db-data
mountPath: /var/lib/mysql
environmentVariables:
- name: MYSQL_USER
value: $DB_USER
- name: MYSQL_PASSWORD
value: $DB_PASSWORD
- name: MYSQL_ROOT_PASSWORD
value: $DB_ROOT_PASSWORD
- name: MYSQL_DATABASE
value: $DB_NAME
ports:
- port: 3306
protocol: TCP
ipAddress:
dnsNameLabel: txt-summ
ports:
- port: 80
protocol: TCP
- port: 443
protocol: TCP
type: Public
imageRegistryCredentials:
- server: $ACR_LOGIN_SERVER
username: $ACR_USERNAME
password: $ACR_PASSWORD
volumes:
- name: proxy-data
azureFile:
shareName: $PROXY_DATA_FILE_SHARE_NAME
storageAccountName: $STORAGE_ACCOUNT_NAME
storageAccountKey: $STORAGE_ACCOUNT_KEY
- name: proxy-config
azureFile:
shareName: $PROXY_CONFIG_FILE_SHARE_NAME
storageAccountName: $STORAGE_ACCOUNT_NAME
storageAccountKey: $STORAGE_ACCOUNT_KEY
- name: db-data
azureFile:
shareName: $DB_DATA_FILE_SHARE_NAME
storageAccountName: $STORAGE_ACCOUNT_NAME
storageAccountKey: $STORAGE_ACCOUNT_KEY
osType: Linux
type: Microsoft.ContainerInstance/containerGroups
So it looks like it wasn't a timing issue but database url issue. While database url
mysql://<user>:<password>@db:3306/<database>works fine locally(given that your database service in docker compose named as
db) it won't let you to establish database connection in ACI.Changing
DATABASE_URLenv variable in ACI tomysql://<user>:<password>@localhost:3306/<database>did the trick.