Bases de datos con Docker

En tiempo de desarrollo

Un post sencillo con un par de recetas para levantar en local un contenedor de MS SQL Server y/o de PostgreSQL, con volúmenes para no perder los datos.

Para MS SQL Server, bastaría con crear un fichero docker-compose.yml con el siguiente contenido:

restart podría ser always (si quieres que se levante cada vez que el daemon de Docker arranque) o incluso unless-stopped (que funciona igual pero si lo paramos nosotros no se arrancará automáticamente la proxima vez que arranque Docker)

services:

  db:
    image: mcr.microsoft.com/mssql/server
    restart: unless-stopped
    volumes:
        - /C/Temp/mssql/data:/var/opt/mssql/data
        - /C/Temp/mssql/log:/var/opt/mssql/log
        - /C/Temp/mssql/secrets:/var/opt/mssql/secrets
    environment:
        ACCEPT_EULA: Y
        SA_PASSWORD: P@ssw0rd
    ports:
        - "6969:1433"

Si lo has guardado con el nombre docker-compose.yml, ejecutando docker-compose up en el mismo directorio sería suficiente. Si por el contrario lo has llamado con algún otro nombre, por ejemplo mssql.yml, docker-compose up -f .\mssql.yml up es tu amigo.

Si no quieres crear el fichero docker-compose.yml, el comando equivalente sería docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=P@ssw0rd" -v /C/Temp/mssql/data:/var/opt/mssql/data -v /C/Temp/mssql/log:/var/opt/mssql/log -v /C/Temp/mssql/secrets:/var/opt/mssql/secrets -p 6969:1433 --name mssql -d mcr.microsoft.com/mssql/server

Para confirmar que está funcionando docker exec -it mssql bash (si usaste el comando) o docker exec -it mssql-db-1 bash (si usaste docker-compose) y luego

/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P P@ssw0rd
SELECT @@VERSION
GO
exit
exit

Para PostgreSQL, la misma jugada:

services:

  db:
    image: postgres
    restart: unless-stopped
    volumes:
        - /C/Temp/postgresql/data:/var/lib/postgresql/data
    environment:
        POSTGRES_PASSWORD: P@ssw0rd
    ports:
        - "5432:5432"

Y si eres más de comando docker run -e "POSTGRES_PASSWORD=P@ssw0rd" -v /C/Temp/postgresql/data:/var/lib/postgresql/data -p 5432:5432 --name postgres -d postgres

Para probar el contenedor docker exec -it postgres bash y psql -U postgres -d postgres -c 'SELECT version()'

En ambos casos, para la version de docker-compose, yo estoy usando la última disponible pero no es necesario.

En el caso de PostgreSQL, pgAdmin sería el equivalente al SQL Server Management Studio (SSMS) y si quieres, también puedes levantarlo en un contenedor.

docker run -p 8080:80 -e 'PGADMIN_DEFAULT_EMAIL=panicoenlaxbox@gmail.com' -e 'PGADMIN_DEFAULT_PASSWORD=P@ssw0rd' -d dpage/pgadmin4.

Y ya que estamos usando docker-compose, todo a la vez es mejor:

services:

  db:
    image: postgres
    restart: unless-stopped
    volumes:
        - /C/Temp/postgresql:/var/lib/postgresql
    environment:
        POSTGRES_PASSWORD: P@ssw0rd
    ports:
        - "5432:5432"
  admin:
    image: dpage/pgadmin4
    restart: unless-stopped
    environment:
        PGADMIN_DEFAULT_EMAIL: panicoenlaxbox@gmail.com
        PGADMIN_DEFAULT_PASSWORD: P@ssw0rd
    ports:
        - "8080:80"
    depends_on:
      - db

Si vamos por la versión full-equipe, desde pgAdmin4 nos conectaremos a db. Si levantamos por separado los contenedores, el nombre del host será la dirección IP de nuestro equipo (no se creó una red interna entre servicios como sí ocurrió con docker-compose).

Para mejorar la experiencia y no tener que registrar el servidor local cada vez que accedamos, podemos hacer lo siguiente:

Crear un fichero servers.json en el mismo directorio donde esté el fichero docker-compose.yml con el siguiente contenido:

{
  "Servers": {
    "1": {
      "Name": "Local",
      "Group": "Servers",
      "Host": "db",
      "Port": 5432,
      "MaintenanceDB": "postgres",
      "Username": "postgres",
      "SSLMode": "prefer",
      "SavePassword": true
    }
  }
}

Actualizar docker-compose.yml:

services:

  db:
    image: postgres
    restart: unless-stopped
    volumes:
        - /C/Temp/postgresql:/var/lib/postgresql
    environment:
        POSTGRES_PASSWORD: P@ssw0rd
    ports:
        - "5432:5432"
  admin:
    image: dpage/pgadmin4
    restart: unless-stopped
    environment:
        PGADMIN_DEFAULT_EMAIL: panicoenlaxbox@gmail.com
        PGADMIN_DEFAULT_PASSWORD: P@ssw0rd
        PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: "False"
    volumes:
        - ./servers.json:/pgadmin4/servers.json
        - pgadmin-storage:/var/lib/pgadmin
    ports:
        - "8080:80"
    depends_on:
      - db

volumes:
  pgadmin-storage: {}

Un saludo!