Add explicit Forgejo deployment structure with artifact build pipeline
- Introduce clear directory separation for docker, infra, ci, and config - Add CloudFormation pipeline for S3 → CodeBuild → ECR - Implement explicit artifact build script for flat deployment zip - Provide example runtime configuration and ignore secrets
This commit is contained in:
commit
46ec47aa2d
8 changed files with 323 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
artifacts/*
|
||||||
|
config/app.ini
|
||||||
30
README.md
Normal file
30
README.md
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
## Purpose
|
||||||
|
This repository contains deployment sources for running Forgejo on AWS ECS.
|
||||||
|
Infrastructure is managed using CloudFormation, and application artifacts are
|
||||||
|
built explicitly for use in CI/CD pipelines.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
- docker/
|
||||||
|
Container definition for Forgejo (Dockerfile and entrypoint)
|
||||||
|
|
||||||
|
- config/
|
||||||
|
Runtime configuration templates
|
||||||
|
(actual configuration is injected at runtime)
|
||||||
|
|
||||||
|
- ci/
|
||||||
|
CI/CD definitions (e.g. AWS CodeBuild buildspec)
|
||||||
|
|
||||||
|
- infra/
|
||||||
|
Infrastructure as Code (CloudFormation templates)
|
||||||
|
|
||||||
|
- artifacts/
|
||||||
|
Build artifacts used as inputs for deployment pipelines
|
||||||
|
|
||||||
|
- scripts/
|
||||||
|
Helper scripts for building deployment artifacts
|
||||||
|
|
||||||
|
## Artifact Build
|
||||||
|
Deployment artifacts are built explicitly using a helper script.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
scripts/build-artifact.sh
|
||||||
18
ci/buildspec.yml
Normal file
18
ci/buildspec.yml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
version: 0.2
|
||||||
|
phases:
|
||||||
|
pre_build:
|
||||||
|
commands:
|
||||||
|
- set -e
|
||||||
|
- ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
||||||
|
- REPOSITORY_URI=${ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/forgejo-repository
|
||||||
|
- aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${REPOSITORY_URI}
|
||||||
|
- GIT_TAG=$(date +%s)
|
||||||
|
build:
|
||||||
|
commands:
|
||||||
|
- set -e
|
||||||
|
- docker build -t ${REPOSITORY_URI}:${GIT_TAG} -t ${REPOSITORY_URI}:latest .
|
||||||
|
post_build:
|
||||||
|
commands:
|
||||||
|
- set -e
|
||||||
|
- docker push ${REPOSITORY_URI}:${GIT_TAG}
|
||||||
|
- docker push ${REPOSITORY_URI}:latest
|
||||||
6
config/app.ini.example
Normal file
6
config/app.ini.example
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[storage]
|
||||||
|
STORAGE_TYPE = minio
|
||||||
|
MINIO_USE_SSL = true
|
||||||
|
MINIO_ENDPOINT = s3.amazonaws.com
|
||||||
|
MINIO_BUCKET = forgejo-bucket
|
||||||
|
MINIO_LOCATION = ap-northeast-1
|
||||||
13
docker/Dockerfile
Normal file
13
docker/Dockerfile
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
FROM codeberg.org/forgejo/forgejo:11-rootless
|
||||||
|
|
||||||
|
# Copy your custom app.ini from the build context into a safe location not masked by EFS.
|
||||||
|
COPY app.ini /defaults/app.ini
|
||||||
|
|
||||||
|
# Copy the custom entrypoint script.
|
||||||
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
|
# Set the custom entrypoint.
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
|
|
||||||
|
# Optionally, retain a CMD if needed.
|
||||||
|
CMD []
|
||||||
50
docker/entrypoint.sh
Executable file
50
docker/entrypoint.sh
Executable file
|
|
@ -0,0 +1,50 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Define the target configuration file path where Forgejo (or Gitea) expects it.
|
||||||
|
CONFIG_DIR="/var/lib/gitea/custom/conf"
|
||||||
|
CONFIG_FILE="${CONFIG_DIR}/app.ini"
|
||||||
|
|
||||||
|
# Define the path to the default configuration file bundled in the image.
|
||||||
|
DEFAULT_CONFIG="/defaults/app.ini"
|
||||||
|
|
||||||
|
# Read the optional environment variable to force the configuration update.
|
||||||
|
# Set FORCE_COPY_APP_CONF=true to force overwriting the configuration file.
|
||||||
|
FORCE_COPY=${FORCE_COPY_APP_CONF:-false}
|
||||||
|
|
||||||
|
echo "Starting container initialization..."
|
||||||
|
|
||||||
|
# If the force option is enabled, remove the existing configuration file (if any)
|
||||||
|
if [ "$FORCE_COPY" = "true" ]; then
|
||||||
|
echo "Force option enabled. Removing any existing configuration file at ${CONFIG_FILE}..."
|
||||||
|
rm -f "$CONFIG_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If the configuration file does not exist, prepopulate it from the default copy.
|
||||||
|
if [ ! -f "$CONFIG_FILE" ]; then
|
||||||
|
echo "Configuration file not found at ${CONFIG_FILE}."
|
||||||
|
echo "Prepopulating the EFS volume with the default configuration."
|
||||||
|
|
||||||
|
# Make sure the configuration directory exists.
|
||||||
|
mkdir -p "$CONFIG_DIR"
|
||||||
|
|
||||||
|
# Copy the default configuration file into the mounted volume.
|
||||||
|
cp "$DEFAULT_CONFIG" "$CONFIG_FILE"
|
||||||
|
|
||||||
|
# Set proper ownership and permissions.
|
||||||
|
# Replace '1000:1000' with the UID:GID used by Forgejo if different.
|
||||||
|
chown 1000:1000 "$CONFIG_FILE"
|
||||||
|
chmod 644 "$CONFIG_FILE"
|
||||||
|
|
||||||
|
echo "Prepopulation complete. Configuration is now available at ${CONFIG_FILE}."
|
||||||
|
else
|
||||||
|
echo "Configuration file already exists at ${CONFIG_FILE}. Skipping prepopulation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Optionally, log the first few lines of the configuration file for verification.
|
||||||
|
echo "Current configuration (first few lines):"
|
||||||
|
head -n 10 "$CONFIG_FILE"
|
||||||
|
|
||||||
|
# Hand over execution to the original entrypoint.
|
||||||
|
# The official Forgejo image typically uses the entrypoint at '/usr/local/bin/docker-entrypoint.sh'
|
||||||
|
exec /usr/local/bin/docker-entrypoint.sh "$@"
|
||||||
181
infra/cfn/forgejo.yaml
Normal file
181
infra/cfn/forgejo.yaml
Normal file
|
|
@ -0,0 +1,181 @@
|
||||||
|
AWSTemplateFormatVersion: "2010-09-09"
|
||||||
|
Description: S3 -> CodePipeline -> CodeBuild(ARM) -> ECR pipeline for Forgejo
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
SourceBucketName:
|
||||||
|
Type: String
|
||||||
|
Default: forgejo-source-bucket
|
||||||
|
|
||||||
|
SourceObjectKey:
|
||||||
|
Type: String
|
||||||
|
Default: forgejo-source.zip
|
||||||
|
|
||||||
|
ForgejoRepositoryName:
|
||||||
|
Type: String
|
||||||
|
Default: forgejo-repository
|
||||||
|
|
||||||
|
Resources:
|
||||||
|
|
||||||
|
# S3 Bucket (Source)
|
||||||
|
SourceBucket:
|
||||||
|
Type: AWS::S3::Bucket
|
||||||
|
Properties:
|
||||||
|
BucketName: !Sub "ap-northeast-1-${AWS::AccountId}-${SourceBucketName}"
|
||||||
|
Tags:
|
||||||
|
- Key: Project
|
||||||
|
Value: Git-server
|
||||||
|
VersioningConfiguration:
|
||||||
|
Status: Enabled
|
||||||
|
|
||||||
|
# ECR Repository
|
||||||
|
ForgejoRepository:
|
||||||
|
Type: AWS::ECR::Repository
|
||||||
|
Properties:
|
||||||
|
RepositoryName: !Ref ForgejoRepositoryName
|
||||||
|
ImageScanningConfiguration:
|
||||||
|
ScanOnPush: true
|
||||||
|
|
||||||
|
# IAM Role for CodeBuild
|
||||||
|
CodeBuildRole:
|
||||||
|
Type: AWS::IAM::Role
|
||||||
|
Properties:
|
||||||
|
AssumeRolePolicyDocument:
|
||||||
|
Version: "2012-10-17"
|
||||||
|
Statement:
|
||||||
|
- Effect: Allow
|
||||||
|
Principal:
|
||||||
|
Service: codebuild.amazonaws.com
|
||||||
|
Action: sts:AssumeRole
|
||||||
|
Policies:
|
||||||
|
- PolicyName: CodeBuildPolicy
|
||||||
|
PolicyDocument:
|
||||||
|
Version: "2012-10-17"
|
||||||
|
Statement:
|
||||||
|
- Effect: Allow
|
||||||
|
Action:
|
||||||
|
- logs:CreateLogGroup
|
||||||
|
- logs:CreateLogStream
|
||||||
|
- logs:PutLogEvents
|
||||||
|
Resource: "*"
|
||||||
|
- Effect: Allow
|
||||||
|
Action:
|
||||||
|
- ecr:GetAuthorizationToken
|
||||||
|
Resource: "*"
|
||||||
|
- Effect: Allow
|
||||||
|
Action:
|
||||||
|
- ecr:BatchCheckLayerAvailability
|
||||||
|
- ecr:InitiateLayerUpload
|
||||||
|
- ecr:UploadLayerPart
|
||||||
|
- ecr:CompleteLayerUpload
|
||||||
|
- ecr:PutImage
|
||||||
|
Resource:
|
||||||
|
- !Sub "arn:aws:ecr:ap-northeast-1:${AWS::AccountId}:repository/forgejo-repository"
|
||||||
|
- Effect: Allow
|
||||||
|
Action:
|
||||||
|
- s3:GetObject
|
||||||
|
- s3:PutObject
|
||||||
|
- s3:ListBucket
|
||||||
|
Resource:
|
||||||
|
- !Sub "arn:aws:s3:::codebuild-ap-northeast-1-${AWS::AccountId}-input-bucket"
|
||||||
|
- !Sub "arn:aws:s3:::codebuild-ap-northeast-1-${AWS::AccountId}-input-bucket/*"
|
||||||
|
- !Sub "arn:aws:s3:::ap-northeast-1-${AWS::AccountId}-${SourceBucketName}"
|
||||||
|
- !Sub "arn:aws:s3:::ap-northeast-1-${AWS::AccountId}-${SourceBucketName}/*"
|
||||||
|
|
||||||
|
|
||||||
|
# CodeBuild Project (ARM)
|
||||||
|
ForgejoBuildProject:
|
||||||
|
Type: AWS::CodeBuild::Project
|
||||||
|
Properties:
|
||||||
|
ServiceRole: !GetAtt CodeBuildRole.Arn
|
||||||
|
Artifacts:
|
||||||
|
Type: CODEPIPELINE
|
||||||
|
Environment:
|
||||||
|
Type: ARM_CONTAINER
|
||||||
|
ComputeType: BUILD_GENERAL1_MEDIUM
|
||||||
|
Image: aws/codebuild/amazonlinux2-aarch64-standard:3.0
|
||||||
|
PrivilegedMode: true
|
||||||
|
EnvironmentVariables:
|
||||||
|
- Name: ECR_REPOSITORY
|
||||||
|
Value: !Ref ForgejoRepositoryName
|
||||||
|
Source:
|
||||||
|
Type: CODEPIPELINE
|
||||||
|
TimeoutInMinutes: 30
|
||||||
|
|
||||||
|
# IAM Role for CodePipeline
|
||||||
|
CodePipelineRole:
|
||||||
|
Type: AWS::IAM::Role
|
||||||
|
Properties:
|
||||||
|
AssumeRolePolicyDocument:
|
||||||
|
Version: "2012-10-17"
|
||||||
|
Statement:
|
||||||
|
- Effect: Allow
|
||||||
|
Principal:
|
||||||
|
Service: codepipeline.amazonaws.com
|
||||||
|
Action: sts:AssumeRole
|
||||||
|
Policies:
|
||||||
|
- PolicyName: CodePipelinePolicy
|
||||||
|
PolicyDocument:
|
||||||
|
Version: '2012-10-17'
|
||||||
|
Statement:
|
||||||
|
# Permissions for accessing the artifacts bucket
|
||||||
|
- Effect: Allow
|
||||||
|
Action:
|
||||||
|
- s3:GetObject
|
||||||
|
- s3:GetObjectVersion
|
||||||
|
- s3:PutObject
|
||||||
|
- s3:ListBucket
|
||||||
|
- s3:GetBucketLocation
|
||||||
|
- s3:GetBucketVersioning
|
||||||
|
Resource:
|
||||||
|
- !Sub "arn:aws:s3:::codebuild-ap-northeast-1-${AWS::AccountId}-input-bucket"
|
||||||
|
- !Sub "arn:aws:s3:::codebuild-ap-northeast-1-${AWS::AccountId}-input-bucket/*"
|
||||||
|
- !Sub "arn:aws:s3:::ap-northeast-1-${AWS::AccountId}-${SourceBucketName}"
|
||||||
|
- !Sub "arn:aws:s3:::ap-northeast-1-${AWS::AccountId}-${SourceBucketName}/*"
|
||||||
|
# Permissions for CodeBuild (if used)
|
||||||
|
- Effect: Allow
|
||||||
|
Action:
|
||||||
|
- codebuild:StartBuild
|
||||||
|
- codebuild:BatchGetBuilds
|
||||||
|
Resource: "*"
|
||||||
|
# Permissions for manual approval actions in CodePipeline
|
||||||
|
- Effect: Allow
|
||||||
|
Action:
|
||||||
|
- codepipeline:PutApprovalResult
|
||||||
|
Resource: "*"
|
||||||
|
|
||||||
|
# CodePipeline
|
||||||
|
ForgejoPipeline:
|
||||||
|
Type: AWS::CodePipeline::Pipeline
|
||||||
|
Properties:
|
||||||
|
PipelineType: V2
|
||||||
|
RoleArn: !GetAtt CodePipelineRole.Arn
|
||||||
|
ArtifactStore:
|
||||||
|
Type: S3
|
||||||
|
Location: !Sub "codebuild-ap-northeast-1-${AWS::AccountId}-input-bucket"
|
||||||
|
Stages:
|
||||||
|
- Name: Source
|
||||||
|
Actions:
|
||||||
|
- Name: S3Source
|
||||||
|
ActionTypeId:
|
||||||
|
Category: Source
|
||||||
|
Owner: AWS
|
||||||
|
Provider: S3
|
||||||
|
Version: "1"
|
||||||
|
Configuration:
|
||||||
|
S3Bucket: !Ref SourceBucket
|
||||||
|
S3ObjectKey: !Ref SourceObjectKey
|
||||||
|
PollForSourceChanges: true
|
||||||
|
OutputArtifacts:
|
||||||
|
- Name: SourceOutput
|
||||||
|
- Name: Build
|
||||||
|
Actions:
|
||||||
|
- Name: BuildImage
|
||||||
|
ActionTypeId:
|
||||||
|
Category: Build
|
||||||
|
Owner: AWS
|
||||||
|
Provider: CodeBuild
|
||||||
|
Version: "1"
|
||||||
|
InputArtifacts:
|
||||||
|
- Name: SourceOutput
|
||||||
|
Configuration:
|
||||||
|
ProjectName: !Ref ForgejoBuildProject
|
||||||
23
scripts/build-artifact.sh
Executable file
23
scripts/build-artifact.sh
Executable file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
ARTIFACT_DIR="${ROOT_DIR}/artifacts"
|
||||||
|
ZIP_PATH="${ARTIFACT_DIR}/forgejo-source.zip"
|
||||||
|
|
||||||
|
mkdir -p "${ARTIFACT_DIR}"
|
||||||
|
|
||||||
|
tmpdir="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "${tmpdir}"' EXIT
|
||||||
|
|
||||||
|
cp "${ROOT_DIR}/docker/Dockerfile" "${tmpdir}/Dockerfile"
|
||||||
|
cp "${ROOT_DIR}/docker/entrypoint.sh" "${tmpdir}/entrypoint.sh"
|
||||||
|
cp "${ROOT_DIR}/config/app.ini" "${tmpdir}/app.ini"
|
||||||
|
cp "${ROOT_DIR}/ci/buildspec.yml" "${tmpdir}/buildspec.yml"
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "${tmpdir}"
|
||||||
|
zip -r "${ZIP_PATH}" .
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "Artifact created: ${ZIP_PATH}"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue