Bash in Docker Scripts#

Bash is commonly used in Docker scripts, particularly in Dockerfiles and as entrypoint scripts. Here’s a comprehensive example that demonstrates using Bash in a Docker context.

👉 New to App-Generator? Sign IN with GitHub or Generate Web Apps in no time (free service).

This example demonstrates several important concepts:

  • Using Bash in a Dockerfile to set up the environment and install dependencies.

  • Creating a flexible entrypoint script that can handle various scenarios.

  • Using environment variables to configure the application.

  • Implementing a wait mechanism for dependent services (like databases).

  • Providing different execution modes (init, migrate, test) through the entrypoint script.

  • Basic security practices like not printing sensitive environment variables.

The entrypoint script provides a lot of flexibility

  • It can wait for other services to be ready before starting the main application.

  • It allows running different commands (init, migrate, test) without modifying the Dockerfile.

  • It performs environment checks and setup before running the main application.

When using this setup, you can easily extend the entrypoint script to handle more complex scenarios, such as

  • Fetching configuration from a remote source

  • Setting up SSL certificates

  • Adjusting application configuration based on the environment

  • Implementing health checks

Let’s move forward and see how the above concepts are implemented in Docker & Bash

Dockerfile with Bash commands#

# Use Ubuntu as the base image FROM ubuntu:20.04 # Set environment variables ENV DEBIAN_FRONTEND=noninteractive ENV APP_HOME=/app # Install necessary packages RUN apt-get update && apt-get install -y \  python3 \  python3-pip \  curl \  && rm -rf /var/lib/apt/lists/* # Set working directory WORKDIR $APP_HOME # Copy application files COPY . . # Install Python dependencies RUN pip3 install --no-cache-dir -r requirements.txt # Copy the entrypoint script COPY docker-entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/docker-entrypoint.sh # Set the entrypoint ENTRYPOINT ["docker-entrypoint.sh"] # Default command CMD ["python3", "app.py"] 

Entrypoint script (docker-entrypoint.sh)#

#!/bin/bash set -e # Function to check if a port is open wait_for_port() {  local host="$1" port="$2"  local max_tries=30 tries=0  while ! nc -z "$host" "$port"; do  tries=$((tries + 1))  if [ $tries -ge $max_tries ]; then  echo "Error: Timed out waiting for $host:$port to become available"  exit 1  fi  echo "Waiting for $host:$port... ($tries/$max_tries)"  sleep 1  done  echo "$host:$port is available" } # Check if we're running the init command if [ "${1}" = "init" ]; then  echo "Initializing application..."  python3 init_db.py  echo "Initialization complete."  exit 0 fi # Wait for database to be ready if [ -n "$DB_HOST" ] && [ -n "$DB_PORT" ]; then  wait_for_port "$DB_HOST" "$DB_PORT" fi # Perform database migrations if needed if [ "${1}" = "migrate" ]; then  echo "Running database migrations..."  python3 manage.py db upgrade  echo "Migrations complete."  exit 0 fi # Check if we need to run tests if [ "${1}" = "test" ]; then  echo "Running tests..."  python3 -m pytest tests/  exit $? fi # Print environment variables (excluding secrets) echo "Environment variables:" env | grep -v -E "PASSWORD|SECRET|KEY" # Run the main command exec "$@" 

Using the Docker image#

# Build the Docker image docker build -t myapp:latest . # Run initialization docker run --rm myapp:latest init # Run database migrations docker run --rm myapp:latest migrate # Run tests docker run --rm myapp:latest test # Run the application docker run -d -p 8080:8080 \  -e DB_HOST=db.example.com \  -e DB_PORT=5432 \  myapp:latest 

This example provides a solid foundation for using Bash in Docker scripts, which you can adapt and expand based on your specific application requirements.