Implement data persistence for safe app updates
- Add external volume mounting for database, uploads, and media files - Update Dockerfile to conditionally initialize database only if it doesn't exist - Move database to external /data volume for persistence across rebuilds - Configure production environment with proper FLASK_CONFIG - Add volume mappings for complete data persistence: * ./data:/data - Database persistence * ./uploads:/opt/moto_site/uploads - File uploads persistence * ./static/media:/opt/moto_site/static/media - Media files persistence - Create init script that skips database creation if DB already exists - Enable safe app updates without losing users, posts, or tracks This ensures all user data persists across Docker container rebuilds and app updates.
This commit is contained in:
19
Dockerfile
19
Dockerfile
@@ -23,15 +23,26 @@ RUN mkdir -p uploads/images uploads/gpx
|
|||||||
# Set FLASK_APP so Flask CLI commands are available
|
# Set FLASK_APP so Flask CLI commands are available
|
||||||
ENV FLASK_APP=run.py
|
ENV FLASK_APP=run.py
|
||||||
|
|
||||||
# Initialize the database and create admin at build time (as root, before switching user)
|
# Create a script to conditionally initialize database
|
||||||
RUN flask --app run.py init-db && flask --app run.py create-admin
|
RUN echo '#!/bin/sh\n\
|
||||||
|
if [ ! -f /data/moto_adventure.db ]; then\n\
|
||||||
|
echo "Database not found, initializing..."\n\
|
||||||
|
flask --app run.py init-db\n\
|
||||||
|
flask --app run.py create-admin\n\
|
||||||
|
echo "Database initialized successfully"\n\
|
||||||
|
else\n\
|
||||||
|
echo "Database already exists, skipping initialization"\n\
|
||||||
|
fi' > /opt/moto_site/init_db_if_needed.sh && chmod +x /opt/moto_site/init_db_if_needed.sh
|
||||||
|
|
||||||
# Create non-root user and set permissions
|
# Create non-root user and set permissions
|
||||||
RUN adduser --disabled-password --gecos '' appuser && chown -R appuser:appuser /opt/moto_site
|
RUN adduser --disabled-password --gecos '' appuser && \
|
||||||
|
chown -R appuser:appuser /opt/moto_site && \
|
||||||
|
mkdir -p /data && \
|
||||||
|
chown -R appuser:appuser /data
|
||||||
USER appuser
|
USER appuser
|
||||||
|
|
||||||
# Expose port
|
# Expose port
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
|
||||||
# Run the application with Gunicorn, looking for run:app in /opt/moto_site
|
# Run the application with Gunicorn, looking for run:app in /opt/moto_site
|
||||||
ENTRYPOINT ["/bin/sh", "-c", "exec gunicorn --bind 0.0.0.0:5000 run:app"]
|
ENTRYPOINT ["/bin/sh", "-c", "/opt/moto_site/init_db_if_needed.sh && exec gunicorn --bind 0.0.0.0:5000 run:app"]
|
||||||
|
|||||||
@@ -8,10 +8,12 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "8100:5000"
|
- "8100:5000"
|
||||||
environment:
|
environment:
|
||||||
- FLASK_ENV=production
|
- FLASK_CONFIG=production
|
||||||
- DATABASE_URL=sqlite:///moto_adventure.db
|
- DATABASE_URL=sqlite:////data/moto_adventure.db
|
||||||
- SECRET_KEY=ana_are_mere_si-si-pere_cat-cuprinde_in_cos
|
- SECRET_KEY=ana_are_mere_si-si-pere_cat-cuprinde_in_cos
|
||||||
working_dir: /opt/moto_site
|
working_dir: /opt/moto_site
|
||||||
volumes:
|
volumes:
|
||||||
- ./uploads:/opt/moto_site/uploads
|
- ./data:/data # Database persistence
|
||||||
|
- ./uploads:/opt/moto_site/uploads # File uploads persistence
|
||||||
|
- ./static/media:/opt/moto_site/static/media # Media files persistence
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
Reference in New Issue
Block a user