Files

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

  1. Go to AWS Management Console
  2. Click "Create bucket"
  3. Enter a unique bucket name (e.g., akiyama-manga-bucket)
  4. Choose your region
  5. Leave other settings as default
  6. Click "Create bucket"

Step 2: Create IAM User

  1. Go to IAM Console
  2. Click "Users" → "Create user"
  3. Enter username (e.g., akiyama-manga-app)
  4. Click "Next"

Step 3: Add S3 Permissions

  1. On the permissions page, click "Attach policies directly"
  2. 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/*"
            ]
        }
    ]
}
  1. Click "Next" → "Create user"

Step 4: Generate Access Keys

  1. Click on the newly created user
  2. Go to "Security credentials" tab
  3. Click "Create access key"
  4. Select "Application running outside AWS"
  5. Click "Next" → "Create access key"
  6. 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:

  1. Go to S3 bucket → Permissions
  2. Click "Edit CORS configuration"
  3. 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

  1. Never commit credentials to version control
  2. Use .env files for local development
  3. Use IAM roles in production (AWS Lambda, EC2)
  4. Enable versioning on your S3 bucket
  5. Enable encryption in bucket properties
  6. Set lifecycle policies to delete old uploads
  7. 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