Mark Tyers
Mark Tyers

Reputation: 3269

Temporary Server issue: Docker MySQL Failed Connection unless also connection from mySQL Workbench

Bit of an odd one here. I have a simple docker file that builds a mysql database container and a simple Deno API container.

After the containers have finished building, the API can't connect.

[uncaught application error]: Error - Access denied for user 'websiteuser'@'172.18.0.3' (using password: YES)

Examining the mysql logs, after connecting using MySQL Workbench, I found that I am starting a temporary server which probably explains the issue but not sure why this is happening.

[Note] [Entrypoint]: Temporary server started.
2024-09-06 20:40:32 '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
[Note] [Entrypoint]: Creating database website
[Note] [Entrypoint]: Creating user websiteuser
[Note] [Entrypoint]: Giving user websiteuser access to schema website
[Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/setup.sql
[Note] [Entrypoint]: Stopping temporary server
[Note] [Entrypoint]: Temporary server stopped
[Note] [Entrypoint]: MySQL init process done. Ready for start up.

Does anyone know why the database is starting a temporary server? I have not modified any config files. There appears to be no documentation on temporary servers.

# compose.yaml

volumes:
  mysqldata:

services:
  api:
    image: api
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - 1993:1993
    environment:
      MYSQL_USER: websiteuser
      MYSQL_PASSWORD: Tg9rJv4bDf
      MYSQL_DATABASE: website
      DB_HOST: mysqldb
      DB_PORT: '3306'
    depends_on:
      mysqldb:
        condition: service_started
    restart: always
    develop:
      watch:
        - path: .
          target: /app
          action: sync+restart
      
  mysqldb:
    image: mysql:8.4.2
    environment:
      MYSQL_ROOT_PASSWORD: c7RxJU95aS
      MYSQL_USER: websiteuser
      MYSQL_PASSWORD: Tg9rJv4bDf
      MYSQL_DATABASE: website
    ports:
      - '3306:3306'
    volumes:
      - mysqldata:/var/lib/mysql
      - ./setup.sql:/docker-entrypoint-initdb.d/setup.sql
      - ./my.cnf:/etc/mysql/my.cnf
    restart: always
# Dockerfile

FROM denoland/deno:2.0.0-rc.0

EXPOSE 1993
WORKDIR /app
USER deno

COPY . .

CMD ["run", "--allow-net", "--allow-env", "main.ts"]
// main.ts


/* post.js */

import { Application, Router, Status, type Context, type Request, type Body } from 'https://deno.land/x/oak/mod.ts'
import { oakCors } from 'https://deno.land/x/cors/mod.ts'
import { Client, type ClientConfig, type ExecuteResult } from 'https://deno.land/x/mysql/mod.ts'

type Quote = {
    author: string
    quote: string
}

const config: ClientConfig = {
    hostname: 'mysqldb',
    port: 3306,
    username: 'websiteuser',
    password: 'Tg9rJv4bDf',
    poolSize: 3,
    db: 'website'
}


const client: Client = await new Client().connect(config)

const port = 1993

const app = new Application()
const router = new Router()

async function createTables() {
    await client.execute(`CREATE TABLE IF NOT EXISTS quotes (
        id MEDIUMINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        author VARCHAR(50) NOT NULL,
        quote VARCHAR(200) NOT NULL
    )`) 
}

router.get('/quotes', async (context: Context) => {
    console.log('GET /quotes')
    await createTables()
    const sql = 'SELECT author, quote FROM quotes'
    try {
        const result:ExecuteResult = await client.execute(sql)
        const rows: Quote[] = result.rows || []
        context.response.status = 200
        context.response.body = JSON.stringify(rows, null, 2)
    } catch(error) {
        console.log(error)
        context.response.status = 400
        context.response.body = JSON.stringify({error: 'database error'}, null, 2)
    }
})

router.post('/quotes', async (context: Context) => {
    console.log('POST /quotes')
    await createTables()
    const data: Quote  = await context.request.body.json()
    const sql = `INSERT INTO quotes(author, quote) VALUES("${data.author}", "${data.quote}")`
    // console.log(sql)
    try {
        const result:ExecuteResult = await client.execute(sql)
        console.log('RESULT', result)
        const response = {
            status: 'success',
            msg: 'quote added',
            data: data
        }
        context.response.status = 201
        context.response.body = JSON.stringify(response, null, 2)
    } catch(error) {
        console.log('ERROR')
        console.log(error)
        context.response.status = 400
        context.response.body = JSON.stringify({error: 'database error'}, null, 2)
    }
})

app.use(oakCors())
app.use(router.routes())
app.use(router.allowedMethods())

app.addEventListener('listen', ({ port }) => {
    console.log(`listening on port: ${port}`)
})

await app.listen({ port })
-- setup.sql

CREATE TABLE quotes (
    id MEDIUMINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    author VARCHAR(50) NOT NULL,
    quote VARCHAR(200) NOT NULL
);

INSERT INTO quotes(author, quote) VALUES(
    "Albert Einstein",
    "Two things are infinite, the Universe and human stupidity"
);

Upvotes: 0

Views: 53

Answers (0)

Related Questions