165 lines
5.6 KiB
Markdown
165 lines
5.6 KiB
Markdown
# 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 `objectstore` config
|
|
- 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)
|
|
|
|
1. Launch EC2 (Ubuntu 22.04 LTS; instance size as needed).
|
|
2. Update packages:
|
|
```bash
|
|
sudo apt update && sudo apt upgrade -y
|
|
```
|
|
3. Install Apache + MySQL:
|
|
```bash
|
|
sudo apt-get install -y apache2 mysql-server
|
|
sudo systemctl enable --now apache2 mysql
|
|
sudo mysql_secure_installation # choose a strong policy
|
|
```
|
|
4. Create DB and user:
|
|
```sql
|
|
CREATE DATABASE nextcloud;
|
|
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY 'REPLACE_ME_SECURE_PASSWORD';
|
|
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';
|
|
FLUSH PRIVILEGES;
|
|
```
|
|
5. Install PHP and extensions (adjust version as needed):
|
|
```bash
|
|
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
|
|
```
|
|
6. Download and place Nextcloud:
|
|
```bash
|
|
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
|
|
```
|
|
7. Apache vhost (HTTP example):
|
|
```apache
|
|
<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>
|
|
```
|
|
Then:
|
|
```bash
|
|
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:
|
|
```bash
|
|
# 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):
|
|
```bash
|
|
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-1` for 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/nextcloud` and as `www-data`:
|
|
```bash
|
|
cd /var/www/html/nextcloud
|
|
sudo -u www-data php occ status
|
|
```
|
|
- After changes, re-run maintenance tasks:
|
|
```bash
|
|
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 `.gitignore` for logs, caches, and secrets.
|
|
- Use small, meaningful commits (see **Suggested Commit Plan** below).
|
|
|
|
## Suggested Commit Plan
|
|
|
|
1. `chore: scaffold repo (README, .gitignore)`
|
|
2. `docs: base EC2 + Nextcloud install`
|
|
3. `feat: add S3 objectstore template`
|
|
4. `docs: ALB/ACM/CloudFront notes`
|
|
5. `chore: add helper scripts`
|
|
6. `docs: troubleshooting + PHP upgrade`
|
|
7. `security: add SECURITY.md and redaction guidance`
|
|
|
|
---
|
|
|
|
## Quick Start with Gitea
|
|
|
|
1. Create a repo in Gitea (e.g., `nextcloud-s3-deploy`).
|
|
2. Initialize locally:
|
|
```bash
|
|
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
|
|
```
|
|
3. 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.
|