Nuestros desarrolladores estrellas han agotado sus reservas de café, investigando día y noche por la respuesta, hasta que Mateo halló el resultado en Gitea así que hoy la comparte contigo.
Solución:
Después de buscar y probar muchos escenarios diferentes, pude agregar la espera usando el siguiente archivo de composición. Esto es para asp.net
solución central. El key es que tienes que sobrescribir entrypoint
si se especifica en dockerfile
. Además, debe asegurarse de guardar “wait-for-it.sh” LF como final de línea en lugar de CRLF; de lo contrario, obtendrá el error de file not found
.
El dockerfile
debe tener lo siguiente (descárguelo desde aquí: https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh, asegúrese de guardar el archivo):
COPY ./wait-for-it.sh /wait-for-it.sh
RUN chmod +x wait-for-it.sh
docker-compose.yml
version: '3.7'
services:
vc-db:
image: mcr.microsoft.com/mssql/server:latest
ports:
- "$DOCKER_SQL_PORT:-1433:1433"
expose:
- 1433
environment:
- ACCEPT_EULA=Y
- MSSQL_PID=Express
- SA_PASSWORD=v!rto_Labs!
networks:
- virto
vc-platform-web:
image: virtocommerce/platform:$DOCKER_TAG:-latest
ports:
- "$DOCKER_PLATFORM_PORT:-8090:80"
environment:
- ASPNETCORE_URLS=http://+
depends_on:
- vc-db
entrypoint: ["/wait-for-it.sh", "vc-db:1433", "-t", "120", "--", "dotnet", "VirtoCommerce.Platform.Web.dll"]
networks:
- virto
Cuando usas depends_on
, docker-compose simplemente lanzará su servicio base con más prioridad y nunca esperará a que comiencen los servicios.
Hay algunos programas externos útiles que lo ayudan a esperar un servicio específico (puerto) y luego ejecutar otro servicio.
vishnubob / wait-for-it es uno de ellos que bloquea el flujo de ejecución hasta que sus puertos específicos estén listos.
Otra buena opción es eficode / wait-for, que ya está preparado para docker-compose.
Ejemplo de uso (según eficode / wait-for docs)
version: '2'
services:
db:
image: postgres:9.4
backend:
build: backend
# Blocks execution flow util db:5432 is ready (Or you can use localhost instead)
command: sh -c './wait-for db:5432 -- npm start'
depends_on:
- db
— ACTUALIZAR —
Considere que tiene una aplicación Python que depende de una base de datos como PostgreSQL, y también su aplicación se ejecutará con este comando: python app.py
Como decía el documento oficial de Docker, Put vishnubob/wait-for-it
en su imagen (dentro de sus otros archivos de proyecto como app.py
)
Ahora solo ponga estas líneas en su docker-compose.yml
:
version: "3"
services:
web:
build: .
ports:
- "80:8000"
depends_on:
- "db"
# This command waits until `db:5432` respond (5432 is default PostgreSQL port)
# then runs our application by this command: `python app.py`
command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
db:
image: postgres
Nota: No olvide poner estos comandos en su Dockerfile
dentro de sus archivos de imagen:
# Copy wait-for-it.sh into our image
COPY wait-for-it.sh wait-for-it.sh
# Make it executable, in Linux
RUN chmod +x wait-for-it.sh
Cree dos dockerfiles separados (por ejemplo):
- Mssql.Dockerfile
- Aplicación.Dockerfile
Configure la secuencia dentro de docker-compose.yml
Mssql.Dockerfile
FROM mcr.microsoft.com/mssql/server AS base
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Password123
COPY . .
COPY ["Db/Scripts/*", "Db/Scripts/"]
VOLUME ./Db:/var/opt/mssql/data
HEALTHCHECK --interval=10s --timeout=5s --start-period=10s --retries=10
CMD /opt/mssql-tools/bin/sqlcmd -S . -U sa -P Password123 -i Db/Scripts/SetupDb.sql || exit 1
Aplicación.Dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["AspNetCoreWebApplication/AspNetCoreWebApplication.csproj", "AspNetCoreWebApplication/"]
COPY ["WebApp.Data.EF/WebApp.Data.EF.csproj", "WebApp.Data.EF/"]
COPY ["WebApp.Service/WebApp.Service.csproj", "WebApp.Service/"]
RUN dotnet restore "AspNetCoreWebApplication/AspNetCoreWebApplication.csproj"
COPY . .
WORKDIR "/src/AspNetCoreWebApplication"
RUN dotnet build "AspNetCoreWebApplication.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "AspNetCoreWebApplication.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "AspNetCoreWebApplication.dll"]
Docker-compose.yml:
version: '3.7'
services:
api:
image: aspnetcore/mentoring_api
container_name: mentoring_api
build:
context: .
dockerfile: App.Dockerfile
ports:
- 8081:80
expose:
- 8081
environment:
ASPNETCORE_ENVIRONMENT: Development
depends_on:
- sqlserver
sqlserver:
image: aspnetcore/mentoring_db
container_name: mentoring_db
build:
context: .
dockerfile: Mssql.Dockerfile
ports:
- "1433:1433"
expose:
- 1433
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=Password123
volumes:
- ./Db:/var/opt/mssql/data
Nota:
El conexión string se vera como: "Server=sqlserver;Database=Northwind;Trusted_Connection=False;User Id=sa;Password=Password123;MultipleActiveResultSets=true"
Aquí puedes ver las reseñas y valoraciones de los lectores
Si te ha resultado de ayuda nuestro artículo, sería de mucha ayuda si lo compartes con más programadores de esta forma contrubuyes a difundir este contenido.