How to Configure Docker Containers(With BLE dependency) to Run at Boot
Problem Identified
- BLE (Bluetooth Low Energy) initialization wasn't completing properly before containers needed access to the BLE device
- Docker Compose service wasn't properly configured to start at system boot
- Container startup timing was causing resource conflicts with the BLE device
Step-by-Step Solution
1. Create BLE initialization in the Docker Compose service
This ensures BLE is properly initialized before Docker containers attempt to access it:
sudo cat > /etc/systemd/system/docker-compose-app.service << 'EOF'
[Unit]
Description=Docker Compose Application Service
After=docker.service network-online.target
Requires=docker.service network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/home/sudo5120/Eldar
ExecStartPre=/bin/bash -c "hciattach /dev/ttymxc3 any 115200 flow && sleep 2 && hciconfig hci0 up"
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
[Install]
WantedBy=multi-user.target
EOF
2. Enable and test the service
sudo systemctl daemon-reload
sudo systemctl enable docker-compose-app.service
sudo systemctl start docker-compose-app.service
sudo systemctl status docker-compose-app.service
3. Technical details of the systemd service
- Unit section:
- After=docker.service network-online.target: Ensures the service starts after Docker and network are available
- Requires=docker.service network-online.target: Makes Docker and network mandatory dependencies
- Wants=network-online.target: Ensures the service waits for the network to be fully online
- Service section:
- Type=oneshot: This service runs once and completes
- RemainAfterExit=yes: Service is considered active even after the process exits
- WorkingDirectory=/home/sudo5120/Eldar: Sets the working directory to where docker-compose.yml is located
- ExecStartPre: Runs BLE initialization before starting containers
- ExecStart: Starts Docker Compose in detached mode
- ExecStop: Gracefully stops all containers when service is stopped
- Install section:
- WantedBy=multi-user.target: Service starts at normal boot time when system is ready for multi-user operation
4. Docker Compose configuration (already in place)
The existing docker-compose.yml includes:
version: "3.3"
services:
wait-for-network:
image: alpine
command: sh -c "until ping -c1 8.8.8.8; do sleep 5; done"
restart: "no"
network_mode: "host"
bvapi:
image: *image"
depends_on:
- wait-for-network
privileged: true
devices:
- "/dev/ttymxc3:/dev/hci0"
restart: unless-stopped
network_mode: "host"
cap_add:
- NET_ADMIN
volumes:
- type: volume
source: bvapi-data
target: /opt/sensorworks/api/data/
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
compress: "true"
This configuration ensures:
- The wait-for-network container checks for internet connectivity before starting other containers
- The bvapi container has access to the BLE device via /dev/ttymxc3 mapping
- Persistent data is stored in the volume bvapi-data
- Logs are properly managed with rotation to prevent disk space issues
5. Verifying successful setup
After reboot, verify that everything is running correctly:
sudo systemctl status docker-compose-app.service
sudo docker ps
hciconfig
This solution creates a robust boot sequence where:
- System boots normally and starts Docker
- The docker-compose-app service initializes BLE device
- Docker Compose launches the wait-for-network container
- Once network is confirmed available, the main bvapi container starts
- BLE scanning service begins operation
The service configuration ensures this sequence happens automatically on every system boot.