4.2 KiB
4.2 KiB
AWS S3 Setup Guide
This guide helps you configure AWS S3 for storing manga images.
Prerequisites
- AWS Account
- AWS CLI (optional but recommended)
Step 1: Create an S3 Bucket
- Go to AWS Management Console
- Click "Create bucket"
- Enter a unique bucket name (e.g.,
akiyama-manga-bucket) - Choose your region
- Leave other settings as default
- Click "Create bucket"
Step 2: Create IAM User
- Go to IAM Console
- Click "Users" → "Create user"
- Enter username (e.g.,
akiyama-manga-app) - Click "Next"
Step 3: Add S3 Permissions
- On the permissions page, click "Attach policies directly"
- Search for "S3" and attach the following policies:
AmazonS3FullAccess(for full access) or create a custom policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::akiyama-manga-bucket",
"arn:aws:s3:::akiyama-manga-bucket/*"
]
}
]
}
- Click "Next" → "Create user"
Step 4: Generate Access Keys
- Click on the newly created user
- Go to "Security credentials" tab
- Click "Create access key"
- Select "Application running outside AWS"
- Click "Next" → "Create access key"
- Copy the Access Key ID and Secret Access Key
Step 5: Configure Environment Variables
Add to your .env file:
AWS_ACCESS_KEY_ID=your_access_key_here
AWS_SECRET_ACCESS_KEY=your_secret_key_here
AWS_REGION=us-east-1
S3_BUCKET_NAME=akiyama-manga-bucket
S3_ENDPOINT=https://s3.amazonaws.com
Step 6 (Optional): Configure CORS
If your frontend is on a different domain:
- Go to S3 bucket → Permissions
- Click "Edit CORS configuration"
- Add:
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
"AllowedOrigins": ["http://localhost:8080", "https://yourdomain.com"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}
]
Bucket Structure
Your bucket will be organized as:
bucket/
├── covers/ # Manga cover images
│ └── {manga-id}-filename.jpg
├── manga/ # Manga chapter pages
│ └── {manga-id}/chapter-{num}/
│ └── page-{num}-filename.jpg
└── avatars/ # User profile avatars
└── {user-id}-filename.jpg
Using Custom S3 Services
MinIO (Self-hosted)
S3_ENDPOINT=http://minio.example.com:9000
AWS_ACCESS_KEY_ID=minioadmin
AWS_SECRET_ACCESS_KEY=minioadmin
S3_BUCKET_NAME=akiyama-manga
DigitalOcean Spaces
AWS_REGION=nyc3
S3_ENDPOINT=https://nyc3.digitaloceanspaces.com
S3_BUCKET_NAME=akiyama-manga
Linode Object Storage
AWS_REGION=us-east-1
S3_ENDPOINT=https://us-east-1.linodeobjects.com
S3_BUCKET_NAME=akiyama-manga
Testing the Connection
Run this Go snippet to test:
ctx := context.Background()
cfg, _ := config.LoadDefaultConfig(ctx, config.WithRegion("us-east-1"))
s3Client := s3.NewFromConfig(cfg)
result, err := s3Client.ListBuckets(ctx, &s3.ListBucketsInput{})
if err != nil {
log.Fatalf("Failed to list buckets: %v", err)
}
for _, bucket := range result.Buckets {
fmt.Println("Bucket:", *bucket.Name)
}
Security Best Practices
- Never commit credentials to version control
- Use
.envfiles for local development - Use IAM roles in production (AWS Lambda, EC2)
- Enable versioning on your S3 bucket
- Enable encryption in bucket properties
- Set lifecycle policies to delete old uploads
- Use bucket policies to restrict public access
Troubleshooting
Error: "Access Denied"
- Check IAM user permissions
- Verify Access Key ID and Secret are correct
- Check bucket name is spelled correctly
Error: "NoSuchBucket"
- Verify bucket exists in selected region
- Check region matches in configuration
Error: "SignatureDoesNotMatch"
- Verify Secret Access Key is correct
- Check system time is synchronized