Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit 9877fa6

Browse files
committed
refactor: move Docker Compose .env to persistent volume
Implements persistent data architecture with standardized directory structure: - Move Docker Compose .env from application/.env to application/storage/compose/.env - Update configure-env.sh to generate .env in persistent storage location - Update deploy-app.sh to use /var/lib/torrust/compose/.env path in VM - Add local configuration generation in deploy-app.sh (twelve-factor Build stage) - Update all Docker Compose commands to use new .env path - Create application/storage/compose/.gitignore to maintain directory structure This ensures all application data (DB, config, SSL, logs, .env) is stored in the persistent volume /var/lib/torrust/ for proper data separation and backup capabilities. Fixes deployment issues where .env file was not found in VM due to improper configuration generation order.
1 parent ba4d174 commit 9877fa6

File tree

3 files changed

+98
-38
lines changed

3 files changed

+98
-38
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Ignore environment files (may contain sensitive data)
2+
.env
3+
4+
# Keep directory structure
5+
!.gitignore

infrastructure/scripts/configure-env.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,13 @@ process_templates() {
150150
# Generate .env file for Docker Compose
151151
generate_docker_env() {
152152
local templates_dir="${CONFIG_DIR}/templates"
153-
local env_output="${PROJECT_ROOT}/application/.env"
153+
local env_output="${PROJECT_ROOT}/application/storage/compose/.env"
154154

155155
log_info "Generating Docker Compose environment file"
156156

157+
# Ensure the storage/compose directory exists
158+
mkdir -p "$(dirname "${env_output}")"
159+
157160
# Set generation date for template
158161
GENERATION_DATE="$(date)"
159162
export GENERATION_DATE

infrastructure/scripts/deploy-app.sh

Lines changed: 89 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
1111
TERRAFORM_DIR="${PROJECT_ROOT}/infrastructure/terraform"
1212

1313
# Default values
14-
ENVIRONMENT="${1:-l container_info=$(ssh -n -o StrictHostKeyChecking=no -o ConnectTimeout=10 "torrust@${vm_ip}" "cd /home/torrust/github/torrust/torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/application/.env ps ${service_name} --format '{{.State}}'" 2>/dev/null)cal}"
14+
ENVIRONMENT="${1:-local}"
1515
VM_IP="${2:-}"
1616
SKIP_HEALTH_CHECK="${SKIP_HEALTH_CHECK:-false}"
1717

@@ -241,6 +241,29 @@ vm_exec_with_timeout() {
241241
fi
242242
}
243243

244+
# Generate configuration locally (Build/Release stage)
245+
generate_configuration_locally() {
246+
log_info "Generating configuration locally (Build/Release stage)"
247+
248+
cd "${PROJECT_ROOT}"
249+
250+
if [[ -f "infrastructure/scripts/configure-env.sh" ]]; then
251+
log_info "Running configure-env.sh for environment: ${ENVIRONMENT}"
252+
./infrastructure/scripts/configure-env.sh "${ENVIRONMENT}"
253+
254+
# Verify that the .env file was generated
255+
if [[ -f "application/storage/compose/.env" ]]; then
256+
log_success "Configuration files generated successfully"
257+
else
258+
log_error "Failed to generate .env file at application/storage/compose/.env"
259+
exit 1
260+
fi
261+
else
262+
log_warning "Configuration script not found at infrastructure/scripts/configure-env.sh"
263+
log_warning "Using existing configuration files"
264+
fi
265+
}
266+
244267
# RELEASE STAGE: Deploy application code and configuration
245268
release_stage() {
246269
local vm_ip="$1"
@@ -297,9 +320,46 @@ release_stage() {
297320
exit 1
298321
fi
299322

323+
# Also copy generated configuration files (not in git archive)
324+
log_info "Copying generated configuration files to VM..."
325+
326+
# Create a temporary archive of just the generated files
327+
local config_archive
328+
config_archive="/tmp/torrust-config-$(date +%s).tar.gz"
329+
330+
if [[ -d "application/storage" ]]; then
331+
tar -czf "${config_archive}" -C "${PROJECT_ROOT}" application/storage/ 2>/dev/null || true
332+
333+
# Copy configuration archive to VM
334+
if scp -o StrictHostKeyChecking=no "${config_archive}" "torrust@${vm_ip}:/tmp/" 2>/dev/null; then
335+
log_info "Configuration files copied successfully"
336+
else
337+
log_warning "No configuration files to copy (this is normal for first deployment)"
338+
fi
339+
340+
# Clean up local config archive
341+
rm -f "${config_archive}"
342+
else
343+
log_warning "No application/storage directory found - configuration will be generated on VM"
344+
fi
345+
300346
# Extract archive on VM
301347
vm_exec "${vm_ip}" "cd /home/torrust/github/torrust && mkdir -p torrust-tracker-demo" "Creating repository directory"
302348
vm_exec "${vm_ip}" "cd /home/torrust/github/torrust/torrust-tracker-demo && tar -xzf /tmp/$(basename "${temp_archive}")" "Extracting repository"
349+
350+
# Extract configuration files if they were copied
351+
vm_exec "${vm_ip}" "
352+
config_archive=\$(ls /tmp/torrust-config-*.tar.gz 2>/dev/null | head -1 || echo '')
353+
if [ -n \"\$config_archive\" ] && [ -f \"\$config_archive\" ]; then
354+
cd /home/torrust/github/torrust/torrust-tracker-demo
355+
tar -xzf \"\$config_archive\"
356+
rm -f \"\$config_archive\"
357+
echo 'Configuration files extracted successfully'
358+
else
359+
echo 'No configuration archive found - will generate on VM'
360+
fi
361+
" "Extracting configuration files"
362+
303363
vm_exec "${vm_ip}" "rm -f /tmp/$(basename "${temp_archive}")" "Cleaning up temp files"
304364

305365
# Restore storage folder if it was backed up
@@ -332,18 +392,7 @@ release_stage() {
332392

333393
log_success "Local repository deployed successfully"
334394

335-
# Process configuration (Release stage - combining code with config)
336-
vm_exec "${vm_ip}" "
337-
cd /home/torrust/github/torrust/torrust-tracker-demo
338-
339-
if [ -f infrastructure/scripts/configure-env.sh ]; then
340-
./infrastructure/scripts/configure-env.sh ${ENVIRONMENT}
341-
else
342-
echo 'Configuration script not found, using defaults'
343-
fi
344-
" "Processing configuration for environment: ${ENVIRONMENT}"
345-
346-
# Set up persistent data volume and directory structure
395+
# Set up persistent data volume and directory structure (using locally generated files)
347396
vm_exec "${vm_ip}" "
348397
cd /home/torrust/github/torrust/torrust-tracker-demo
349398
@@ -353,20 +402,10 @@ release_stage() {
353402
fi
354403
355404
# Ensure persistent storage directories exist
356-
sudo mkdir -p /var/lib/torrust/{tracker/{lib/database,log,etc},prometheus/{data,etc},proxy/{webroot,etc/nginx-conf},certbot/{etc,lib},dhparam,mysql/init,application}
357-
358-
# Copy .env file to persistent storage if it doesn't exist
359-
if [ -f application/.env ] && [ ! -f /var/lib/torrust/application/.env ]; then
360-
sudo cp application/.env /var/lib/torrust/application/.env
361-
elif [ ! -f /var/lib/torrust/application/.env ]; then
362-
# Create default .env from template if none exists
363-
if [ -f .env.production ]; then
364-
sudo cp .env.production /var/lib/torrust/application/.env
365-
fi
366-
fi
405+
sudo mkdir -p /var/lib/torrust/{tracker/{lib/database,log,etc},prometheus/{data,etc},proxy/{webroot,etc/nginx-conf},certbot/{etc,lib},dhparam,mysql/init,compose}
367406
368407
# Copy generated configuration files to persistent storage
369-
# These files are generated by configure-env.sh and need to be in the persistent volume
408+
# These files are generated locally and need to be in the persistent volume
370409
if [ -f application/storage/tracker/etc/tracker.toml ]; then
371410
sudo cp application/storage/tracker/etc/tracker.toml /var/lib/torrust/tracker/etc/
372411
fi
@@ -377,6 +416,16 @@ release_stage() {
377416
sudo cp application/storage/proxy/etc/nginx-conf/nginx.conf /var/lib/torrust/proxy/etc/nginx-conf/
378417
fi
379418
419+
# Copy .env file to persistent storage
420+
# This file is generated locally and needs to be in the persistent volume
421+
if [ -f application/storage/compose/.env ]; then
422+
sudo cp application/storage/compose/.env /var/lib/torrust/compose/.env
423+
else
424+
echo 'ERROR: No .env file found at application/storage/compose/.env'
425+
echo 'Configuration should have been generated locally before deployment'
426+
exit 1
427+
fi
428+
380429
# Ensure torrust user owns all persistent data
381430
sudo chown -R torrust:torrust /var/lib/torrust
382431
" "Setting up persistent data volume directory structure"
@@ -396,7 +445,7 @@ wait_for_services() {
396445
log_info "Checking container status (attempt ${attempt}/${max_attempts})..."
397446

398447
# Get container status with service names only
399-
services=$(ssh -n -o StrictHostKeyChecking=no -o ConnectTimeout=10 "torrust@${vm_ip}" "cd /home/torrust/github/torrust/torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/application/.env ps --services" 2>/dev/null || echo "SSH_FAILED")
448+
services=$(ssh -n -o StrictHostKeyChecking=no -o ConnectTimeout=10 "torrust@${vm_ip}" "cd /home/torrust/github/torrust/torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/compose/.env ps --services" 2>/dev/null || echo "SSH_FAILED")
400449

401450
if [[ "${services}" == "SSH_FAILED" ]]; then
402451
log_warning "SSH connection failed while checking container status. Retrying in 10 seconds..."
@@ -422,7 +471,7 @@ wait_for_services() {
422471
container_count=$((container_count + 1))
423472

424473
# Get the container state and health for this service
425-
container_info=$(ssh -n -o StrictHostKeyChecking=no -o ConnectTimeout=10 "torrust@${vm_ip}" "cd /home/torrust/github/torrust/torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/application/.env ps ${service_name} --format '{{.State}}'" 2>/dev/null)
474+
container_info=$(ssh -n -o StrictHostKeyChecking=no -o ConnectTimeout=10 "torrust@${vm_ip}" "cd /home/torrust/github/torrust/torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/compose/.env ps ${service_name} --format '{{.State}}'" 2>/dev/null)
426475
health_status=$(ssh -n -o StrictHostKeyChecking=no -o ConnectTimeout=10 "torrust@${vm_ip}" "cd /home/torrust/github/torrust/torrust-tracker-demo/application && docker inspect ${service_name} --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}no-healthcheck{{end}}' 2>/dev/null" || echo "no-healthcheck")
427476

428477
# Clean up output
@@ -472,7 +521,7 @@ wait_for_services() {
472521
done
473522

474523
log_error "Timeout waiting for services to become healthy after ${max_attempts} attempts."
475-
vm_exec "${vm_ip}" "cd /home/torrust/github/torrust/torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/application/.env ps && docker compose --env-file /var/lib/torrust/application/.env logs" "Dumping logs on failure"
524+
vm_exec "${vm_ip}" "cd /home/torrust/github/torrust/torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/compose/.env ps && docker compose --env-file /var/lib/torrust/compose/.env logs" "Dumping logs on failure"
476525
exit 1
477526
}
478527

@@ -488,7 +537,7 @@ run_stage() {
488537
cd /home/torrust/github/torrust/torrust-tracker-demo/application
489538
490539
if [ -f compose.yaml ]; then
491-
docker compose --env-file /var/lib/torrust/application/.env down --remove-orphans || true
540+
docker compose --env-file /var/lib/torrust/compose/.env down --remove-orphans || true
492541
fi
493542
" "Stopping existing services"
494543

@@ -499,7 +548,7 @@ run_stage() {
499548
500549
# Pull images with progress output
501550
echo 'Starting Docker image pull...'
502-
docker compose --env-file /var/lib/torrust/application/.env pull
551+
docker compose --env-file /var/lib/torrust/compose/.env pull
503552
echo 'Docker image pull completed'
504553
" 600 "Pulling Docker images with 10-minute timeout"
505554

@@ -508,7 +557,7 @@ run_stage() {
508557
cd /home/torrust/github/torrust/torrust-tracker-demo/application
509558
510559
# Start services
511-
docker compose --env-file /var/lib/torrust/application/.env up -d
560+
docker compose --env-file /var/lib/torrust/compose/.env up -d
512561
" "Starting application services"
513562

514563
# Wait for services to initialize
@@ -527,16 +576,16 @@ validate_deployment() {
527576
vm_exec "${vm_ip}" "
528577
cd /home/torrust/github/torrust/torrust-tracker-demo/application
529578
echo '=== Docker Compose Services (Detailed Status) ==='
530-
docker compose --env-file /var/lib/torrust/application/.env ps --format 'table {{.Service}}\t{{.State}}\t{{.Status}}\t{{.Ports}}'
579+
docker compose --env-file /var/lib/torrust/compose/.env ps --format 'table {{.Service}}\t{{.State}}\t{{.Status}}\t{{.Ports}}'
531580
532581
echo ''
533582
echo '=== Docker Compose Services (Default Format) ==='
534-
docker compose --env-file /var/lib/torrust/application/.env ps
583+
docker compose --env-file /var/lib/torrust/compose/.env ps
535584
536585
echo ''
537586
echo '=== Container Health Check Details ==='
538587
# Show health status for each container
539-
for container in \$(docker compose --env-file /var/lib/torrust/application/.env ps --format '{{.Name}}'); do
588+
for container in \$(docker compose --env-file /var/lib/torrust/compose/.env ps --format '{{.Name}}'); do
540589
echo \"Container: \$container\"
541590
state=\$(docker inspect \$container --format '{{.State.Status}}')
542591
health=\$(docker inspect \$container --format '{{.State.Health.Status}}' 2>/dev/null || echo 'no-healthcheck')
@@ -552,7 +601,7 @@ validate_deployment() {
552601
done
553602
554603
echo '=== Service Logs (last 10 lines each) ==='
555-
docker compose --env-file /var/lib/torrust/application/.env logs --tail=10
604+
docker compose --env-file /var/lib/torrust/compose/.env logs --tail=10
556605
" "Checking detailed service status"
557606

558607
# Test application endpoints
@@ -617,8 +666,8 @@ show_connection_info() {
617666
echo
618667
echo "=== NEXT STEPS ==="
619668
echo "Health Check: make app-health-check ENVIRONMENT=${ENVIRONMENT}"
620-
echo "View Logs: ssh torrust@${vm_ip} 'cd torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/application/.env logs'"
621-
echo "Stop Services: ssh torrust@${vm_ip} 'cd torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/application/.env down'"
669+
echo "View Logs: ssh torrust@${vm_ip} 'cd torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/compose/.env logs'"
670+
echo "Stop Services: ssh torrust@${vm_ip} 'cd torrust-tracker-demo/application && docker compose --env-file /var/lib/torrust/compose/.env down'"
622671
echo
623672
}
624673

@@ -630,6 +679,9 @@ main() {
630679
# Check git status and warn about uncommitted changes
631680
check_git_status
632681

682+
# LOCAL: Generate configuration (Build/Release stage)
683+
generate_configuration_locally
684+
633685
local vm_ip
634686
vm_ip=$(get_vm_ip)
635687

0 commit comments

Comments
 (0)