DEV Community

Cover image for GDPR for Laravel Developers: Data Storage, Deletion, and Server Location on Deploynix
Deploynix
Deploynix

Posted on • Originally published at deploynix.io

GDPR for Laravel Developers: Data Storage, Deletion, and Server Location on Deploynix

GDPR compliance is not a server configuration toggle or a Laravel package you install. It is a set of obligations that touch every layer of your application, from the database schema to the server infrastructure to the user interface. As a Laravel developer, you are in a unique position: you control both the application code and, through Deploynix, the infrastructure it runs on.

This guide takes a practical, code-aware approach to GDPR compliance. We will cover the rights your users have, how to implement them in Laravel, where your servers should live, and how Deploynix's infrastructure features support your compliance posture. No legal abstractions. Just concrete steps you can take this week.

Understanding Your Obligations

GDPR grants individuals specific rights over their personal data. As the developer building the application that processes that data, these rights translate directly into features you need to build and infrastructure you need to configure.

The rights most relevant to Laravel developers are:

Right to Access (Article 15): Users can request a copy of all personal data you hold about them. You need a mechanism to gather data from across your application and provide it in a structured format.

Right to Erasure (Article 17): Also called the "right to be forgotten." Users can request that you delete all their personal data, with some exceptions for legal obligations. You need a mechanism to find and delete every trace of a user's data.

Right to Data Portability (Article 20): Users can request their data in a commonly used, machine-readable format. JSON is the standard choice for API-driven applications.

Right to Rectification (Article 16): Users can request corrections to inaccurate personal data. In most Laravel applications, this is satisfied by providing edit functionality for user profiles and related data.

Right to Restriction of Processing (Article 18): Users can request that you stop processing their data while a complaint or correction request is being handled.

Let's implement each of these practically in Laravel.

Implementing the Right to Data Export

Data export is the foundation for both the right to access and the right to data portability. Your implementation needs to gather all personal data associated with a user, from every table where their data appears, and return it as a downloadable file.

Start by auditing your database. Every table that contains a user_id foreign key or stores personally identifiable information needs to be included in the export. In a typical Laravel application, this might include the users table, orders, addresses, support tickets, activity logs, uploaded files metadata, and notification preferences.

Create a dedicated service class for data export. The service should query each relevant table for data belonging to the user and compile it into a structured JSON file. Consider the following approach:

class UserDataExportService
{
    public function export(User $user): array
    {
        return [
            'personal_information' => $this->getPersonalInfo($user),
            'orders' => $this->getOrders($user),
            'addresses' => $this->getAddresses($user),
            'support_tickets' => $this->getSupportTickets($user),
            'activity_log' => $this->getActivityLog($user),
            'preferences' => $this->getPreferences($user),
            'exported_at' => now()->toIso8601String(),
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

Each method should return an array of the user's data from that domain. Strip out internal identifiers, foreign keys, and system metadata that are not personal data. The user does not need to know their stripe_customer_id or the internal order_status_id. They need to see their name, email, order history, and the content they created.

For large datasets, generate the export as a background job using Laravel's queue system. On Deploynix, queue jobs run on your dedicated worker servers, so the export process does not impact your application's responsiveness. Once the export is ready, notify the user via email with a temporary download link.

Verify the user's identity before providing the export. GDPR requires that you confirm the identity of the person making the request. For authenticated users, requiring them to re-enter their password before initiating an export is usually sufficient.

Implementing the Right to Erasure

The right to erasure is more complex than it appears. You cannot simply call $user->delete() and consider it done. You need to find and remove personal data from every location where it exists, including soft-deleted records, related models, uploaded files, cache entries, session data, log files, and backups.

Here is a systematic approach:

Step 1: Identify all personal data locations. Walk through every model in your application that has a relationship to the User model or stores personal data. Create a checklist. Common locations include:

  • Users table (the obvious one)
  • Related models (orders, posts, comments, tickets)
  • Media and file uploads (avatar images, documents)
  • Activity logs and audit trails
  • Cache entries keyed by user ID
  • Session data
  • Email notification history
  • Third-party service records (Stripe customers, email marketing lists)

Step 2: Decide what to delete versus anonymize. GDPR does not require you to delete data that you have a legal obligation to retain. Financial records that you must keep for tax purposes can be anonymized instead of deleted: replace the user's name and email with placeholder values while retaining the transaction data.

class UserDeletionService
{
    public function delete(User $user): void
    {
        // Anonymize records we must retain for legal reasons
        $user->orders()->update([
            'customer_name' => 'Deleted User',
            'customer_email' => 'deleted@example.com',
        ]);

        // Delete records we do not need to retain
        $user->supportTickets()->forceDelete();
        $user->activityLogs()->delete();
        $user->addresses()->delete();

        // Remove uploaded files from storage
        Storage::delete($user->avatar_path);
        $user->documents()->each(function ($document) {
            Storage::delete($document->path);
            $document->delete();
        });

        // Clear cache entries
        Cache::forget("user:{$user->id}:preferences");
        Cache::forget("user:{$user->id}:permissions");

        // Remove from third-party services
        // Stripe::customers()->delete($user->stripe_id);

        // Finally, delete the user
        $user->forceDelete();
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Handle soft-deleted records. If you use Laravel's soft deletes, remember that soft-deleted records still contain personal data. Your deletion service should use forceDelete() for GDPR erasure requests. Alternatively, anonymize the personal data fields and then soft delete, so the record exists for referential integrity but contains no personal information.

Step 4: Address backups. This is the hardest part. Your database backups on Deploynix contain personal data, and you cannot selectively remove one user's data from a backup. The accepted approach under GDPR is to document that backups are retained for a defined period (for example, 30 days) and that deleted data will naturally expire from the backup cycle. If a backup is ever restored, you must re-apply any deletion requests that occurred after the backup was taken.

Maintain a log of deletion requests with timestamps. If you ever restore from backup, query this log and re-execute deletions for any user who requested erasure after the backup date.

Cookie Consent and Tracking

GDPR (and the ePrivacy Directive) require informed consent before setting non-essential cookies. In a Laravel application, this means you need a cookie consent mechanism that:

  1. Blocks analytics scripts, advertising pixels, and non-essential cookies until the user consents.
  2. Provides granular options so users can consent to some cookie categories but not others.
  3. Records the consent with a timestamp for your records.
  4. Allows users to withdraw consent at any time.

Implement consent storage in your database rather than relying solely on a cookie. A database record provides an auditable consent trail. Store the user's consent preferences, the timestamp, the version of your privacy policy they consented to, and their IP address.

For your Laravel application's middleware, check consent status before setting cookies or including tracking scripts. A middleware that reads the consent cookie (or database record for authenticated users) and sets a view variable that your Blade templates check before rendering analytics scripts is a clean approach.

// In your Blade layout
@if(request()->cookie('analytics_consent') === 'granted')

@endif
Enter fullscreen mode Exit fullscreen mode

Server Location and Data Residency

Where your servers are physically located matters under GDPR. Deploynix supports provisioning servers on multiple cloud providers, and for EU data residency, Hetzner is the strongest choice.

Hetzner's data centers are exclusively in the EU (Germany and Finland). When you provision servers through Deploynix on Hetzner, you know with certainty that your data resides in the EU. There is no ambiguity about data replication to other regions or hidden cross-border transfers.

For a GDPR-compliant Laravel setup on Deploynix, provision all of your servers in the same EU region:

  • App server on Hetzner (Nuremberg, Falkenstein, or Helsinki)
  • Database server on Hetzner (same region for lowest latency)
  • Cache server on Hetzner (same region)
  • Worker server on Hetzner (same region)

Configure your database backups to store in an EU-only location. If using AWS S3 for backup storage, select the eu-central-1 (Frankfurt) region and do not enable cross-region replication. If using Wasabi, select their Amsterdam or Frankfurt location.

Data Processing Documentation

GDPR Article 30 requires that you maintain records of your processing activities. For a Laravel application deployed on Deploynix, this documentation should include:

What personal data you collect: List every field in your database that contains personal data. Name, email, IP address, physical address, payment information, and any other data that can identify a natural person.

Why you collect it: Each data point needs a lawful basis. User email for account authentication (contractual necessity), IP address for security logging (legitimate interest), marketing preferences (consent). Be specific.

Where it is stored: Document your server locations (Hetzner Nuremberg, for example), your backup storage location, and any third-party services that receive personal data.

How long you retain it: Define retention periods for each data category. Active account data is retained for the life of the account. Deleted account data is purged within 30 days. Financial records are retained for 7 years for tax compliance. Log files are retained for 90 days.

Who has access: Document which team roles can access personal data. On Deploynix, this maps to your organization roles: which team members have database access, which can view logs, and which can access the server directly.

What security measures protect it: Document your encryption (SSL in transit, encryption at rest for backups), firewall rules (configured through Deploynix), access controls (Deploynix organization roles), and any application-level security measures (password hashing, two-factor authentication).

Handling Data Subject Requests

Build a system for receiving and tracking data subject requests. GDPR gives you 30 days to respond to a request (extendable by two months for complex cases). You need to:

  1. Verify the requestor's identity.
  2. Log the request with a timestamp.
  3. Process the request (export, deletion, rectification).
  4. Confirm completion to the user.

A simple Laravel implementation uses a model and controller dedicated to data subject requests. The model tracks the request type, status, and timeline. A queued job processes the request, and an email notification confirms completion.

For applications with significant user bases, consider adding a self-service privacy dashboard where authenticated users can download their data, delete their account, and manage their consent preferences without submitting a manual request. This reduces your operational burden and improves the user experience.

Third-Party Services Audit

Your Laravel application likely communicates with services outside your Deploynix infrastructure. Each of these services needs to be evaluated for GDPR compliance:

Email delivery (Mailgun, SES, Postmark): Do they process email addresses and content in the EU? Many offer EU-region processing.

Payment processing (Stripe, Paddle): Payment processors typically act as independent data controllers or joint controllers. Ensure you have appropriate agreements in place. Deploynix uses Paddle for its own billing, which is EU-based.

Analytics (Google Analytics, Plausible, Fathom): Google Analytics has been found non-compliant in several EU jurisdictions. Consider EU-based alternatives like Plausible or Fathom.

Error tracking (Sentry, Bugsnag): Error reports often contain user data (IP addresses, request parameters). Choose a provider with EU hosting options or configure data scrubbing.

Search (Algolia, Meilisearch): If you index personal data for search, the search service processes that data. Meilisearch can be self-hosted on your Deploynix servers, keeping search data within your EU infrastructure.

Practical Checklist

Here is a condensed checklist for Laravel developers deploying on Deploynix:

  • Provision all servers on Hetzner (EU data centers) through Deploynix
  • Configure firewall rules to restrict database and cache access
  • Set up EU-only backup storage
  • Implement user data export functionality
  • Implement user data deletion with anonymization for legally required records
  • Add cookie consent with granular controls
  • Document all processing activities (Article 30 records)
  • Audit all third-party services for EU data processing
  • Set up a data subject request tracking system
  • Configure appropriate retention periods and automated cleanup
  • Establish a breach notification process with 72-hour timeline
  • Sign DPAs with all sub-processors (Deploynix, Hetzner, email provider, etc.)

GDPR compliance is not a destination. It is a continuous practice. The combination of Laravel's expressive framework and Deploynix's EU-friendly infrastructure gives you the tools to build applications that respect your users' privacy rights while running on infrastructure that keeps their data where it belongs.

Top comments (0)