Nextcloud on EC2 with S3 Primary Storage
This repo captures the deployment steps, configs, and operational notes for a Nextcloud server on AWS EC2 with Amazon S3 as primary storage and an optional ALB + CloudFront + ACM front end.
Important: This is a sanitized version. Replace placeholders (e.g.,
YOUR-BUCKET-NAME) with your real values. Never commit secrets (AWS keys, passwords, access tokens).
Architecture (high-level)
- EC2 (Ubuntu 22.04 LTS) running Apache + PHP + MySQL (or MariaDB)
- Nextcloud application deployed under
/var/www/html/nextcloud - S3 bucket used as the primary storage via the
objectstoreconfig - Optional: ALB (HTTP/HTTPS) + ACM cert + CloudFront in front of ALB
Prerequisites
- AWS account with permissions to create VPC/subnets (or use existing), EC2, S3, IAM, ACM, ALB, CloudFront, Route 53 records as needed
- A domain (Route 53 hosted zone recommended)
- SSH access to the EC2 instance
- Gitea (or Git) access for storing this repo
EC2 Base Setup (condensed)
- Launch EC2 (Ubuntu 22.04 LTS; instance size as needed).
- Update packages:
sudo apt update && sudo apt upgrade -y - Install Apache + MySQL:
sudo apt-get install -y apache2 mysql-server sudo systemctl enable --now apache2 mysql sudo mysql_secure_installation # choose a strong policy - Create DB and user:
CREATE DATABASE nextcloud; CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'REPLACE_ME_SECURE_PASSWORD'; GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost'; FLUSH PRIVILEGES; - Install PHP and extensions (adjust version as needed):
sudo apt-get install -y php libapache2-mod-php php-gd php-json php-mysql php-curl php-mbstring php-intl php-imagick php-xml php-zip php-bcmath php-gmp - Download and place Nextcloud:
cd ~ && wget https://download.nextcloud.com/server/releases/latest.zip sudo apt-get install -y unzip unzip latest.zip sudo mv nextcloud /var/www/html/nextcloud sudo chown -R www-data:www-data /var/www/html/nextcloud - Apache vhost (HTTP example):
Then:<VirtualHost *:80> ServerName YOUR_PUBLIC_IP_OR_DNS DocumentRoot /var/www/html/nextcloud <Directory /var/www/html/nextcloud/> Require all granted Options FollowSymlinks MultiViews AllowOverride All <IfModule mod_dav.c> Dav off </IfModule> </Directory> ErrorLog ${APACHE_LOG_DIR}/nextcloud.error.log CustomLog ${APACHE_LOG_DIR}/nextcloud.access.log common </VirtualHost>sudo a2ensite nextcloud.conf sudo a2dissite 000-default.conf sudo a2enmod rewrite sudo systemctl reload apache2 && sudo systemctl restart apache2 sudo apachectl -t # check config
Configure S3 as Primary Storage
Edit config.php and add the objectstore block (see nextcloud/config.php.example):
- Set
bucket,region,key,secret. Prefer instance profiles (IAM roles) over static keys if possible.
After enabling S3:
# From the Nextcloud directory
cd /var/www/html/nextcloud
sudo -u www-data php occ files:scan --all
sudo -u www-data php occ maintenance:repair --include-expensive
PHP Upgrade (if required)
If Nextcloud requires a newer PHP (example: upgrade from 8.1 to 8.4 using Ondřej Surý PPA):
sudo add-apt-repository -y ppa:ondrej/php
sudo apt update
sudo apt install -y php8.4 php8.4-{zip,mbstring,gd,curl,xml,intl,bcmath,mysql}
sudo a2dismod php8.1 && sudo a2enmod php8.4
sudo systemctl restart apache2
php -v
Tune memory_limit in /etc/php/8.4/apache2/php.ini (e.g., 512M), and adjust OPcache if needed in /etc/php/8.4/mods-available/opcache.ini.
ALB + ACM + CloudFront (optional)
- Request ACM certificates (in
us-east-1for CloudFront; also in your EC2 region for ALB). - Create Target Group (HTTP:80) and ALB (listeners 80 and 443 with redirect to HTTPS).
- Attach certificate to HTTPS listener.
- Put CloudFront in front of ALB and forward required headers/methods for Nextcloud.
- Ensure UI elements (file list, upload button) work when accessed via CloudFront; fix behaviors/headers/caching if they disappear.
See docs/ALB_CloudFront.md and docs/Issue_CloudFront.md for tips.
Troubleshooting Notes
Could not open input file: occ→ run from/var/www/html/nextcloudand aswww-data:cd /var/www/html/nextcloud sudo -u www-data php occ status- After changes, re-run maintenance tasks:
sudo -u www-data php occ maintenance:repair sudo -u www-data php occ files:scan --all
Repo Hygiene
- Use
.env/instance roles for secrets; commit only.env.example. - Add
.gitignorefor logs, caches, and secrets. - Use small, meaningful commits (see Suggested Commit Plan below).
Suggested Commit Plan
chore: scaffold repo (README, .gitignore)docs: base EC2 + Nextcloud installfeat: add S3 objectstore templatedocs: ALB/ACM/CloudFront noteschore: add helper scriptsdocs: troubleshooting + PHP upgradesecurity: add SECURITY.md and redaction guidance
Quick Start with Gitea
- Create a repo in Gitea (e.g.,
nextcloud-s3-deploy). - Initialize locally:
cd nextcloud-s3-gitea-starter git init git add . git commit -m "chore: scaffold repo from deployment notes" git branch -M main git remote add origin https://GITEA_HOST/YOUR_USER/nextcloud-s3-deploy.git git push -u origin main - Make incremental commits as you refine.
If you prefer SSH, set up an SSH key in Gitea and use the SSH URL instead of HTTPS.