This comprehensive guide provides step-by-step instructions for deploying the AutoCert application in a production environment using Ubuntu 24.04.
- Prerequisites
- Initial Setup
- Database Configuration
- Message Queue Setup
- Object Storage Configuration
- Application Deployment
- Web Server Configuration
- Monitoring and Maintenance
- Ubuntu 24.04 server with root access
- Domain names configured for the application components
- Basic knowledge of Linux system administration
git clone --recursive https://github.com/SeakMengs/AutoCert.git /var/www/AutoCert
cd /var/www/AutoCertsudo apt update
sudo apt install golang -yInstall Node Version Manager (nvm) and Node.js:
# Download and install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# Reload shell environment
source "$HOME/.nvm/nvm.sh"
# Install Node.js version 22
nvm install 22
# Verify installation
node -v # Should print "v22.16.0"
npm -v # Should print "10.9.2"Install PM2 process manager:
npm install -g pm2Install depdencies:
sudo chmod +x scripts/*
sudo ./scripts/setup_check.shsudo apt update
sudo apt install postgresql postgresql-contrib -y
sudo systemctl start postgresql
sudo systemctl enable postgresqlSwitch to PostgreSQL user and create database:
sudo su - postgres
psqlExecute the following SQL commands:
CREATE DATABASE autocert;
\c autocert
CREATE EXTENSION IF NOT EXISTS citext;
CREATE USER admin WITH LOGIN PASSWORD 'adminadmin';
-- Grant privileges
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO admin;
GRANT USAGE, CREATE ON SCHEMA public TO admin;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO admin;
ALTER SCHEMA public OWNER TO admin;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO admin;
\qEdit PostgreSQL configuration:
sudo vim /etc/postgresql/16/main/postgresql.confChange the listen_addresses line:
listen_addresses = '*'
Edit client authentication:
sudo vim /etc/postgresql/16/main/pg_hba.confAdd or modify the IPv4 connection line:
host all all 0.0.0.0/0 md5
Note: Change any peer authentication methods to md5 for the admin user.
Restart PostgreSQL:
sudo systemctl restart postgresqlFirst, configure the environment file:
cp /var/www/AutoCert/.env.example /var/www/AutoCert/.envEdit the .env file and fill in the database connection details, then run migration:
go run /var/www/AutoCert/cmd/migrate/main.goAdd RabbitMQ repositories and install:
# Install dependencies
sudo apt-get install curl gnupg apt-transport-https -y
# Add signing keys
curl -1sLf "https://keys.openpgp.org/vks/v1/by-fingerprint/0A9AF2115F4687BD29803A206B73A36E6026DFCA" | sudo gpg --dearmor | sudo tee /usr/share/keyrings/com.rabbitmq.team.gpg > /dev/null
curl -1sLf https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-erlang.E495BB49CC4BBE5B.key | sudo gpg --dearmor | sudo tee /usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg > /dev/null
curl -1sLf https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-server.9F4587F226208342.key | sudo gpg --dearmor | sudo tee /usr/share/keyrings/rabbitmq.9F4587F226208342.gpg > /dev/null
# Add repositories
sudo tee /etc/apt/sources.list.d/rabbitmq.list <<EOF
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu noble main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu noble main
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa2.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu noble main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa2.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu noble main
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu noble main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu noble main
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa2.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu noble main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa2.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu noble main
EOF
# Update and install
sudo apt-get update -y
sudo apt-get install -y erlang-base erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key erlang-runtime-tools erlang-snmp erlang-ssl erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl
sudo apt-get install rabbitmq-server -y --fix-missingRemove default guest user and create admin user:
sudo rabbitmqctl delete_user guest
sudo rabbitmqctl add_user admin adminpw
sudo rabbitmqctl set_user_tags admin administrator
sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"Verify configuration:
sudo rabbitmqctl list_users
sudo rabbitmqctl list_permissions -p /Enable management plugin:
sudo rabbitmq-plugins enable rabbitmq_managementDownload and install MinIO:
wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio_20250422221226.0.0_amd64.deb -O minio.deb
sudo dpkg -i minio.debCreate MinIO user and group:
sudo groupadd -r minio-user
sudo useradd -M -r -g minio-user minio-user
sudo mkdir -p /mnt/data
sudo chown minio-user:minio-user /mnt/dataCreate MinIO configuration file:
sudo vim /etc/default/minioAdd the following content:
# MinIO root credentials
MINIO_ROOT_USER=myminioadmin
MINIO_ROOT_PASSWORD=minio-secret-key-change-me
# Storage path
MINIO_VOLUMES="/mnt/data"
# Console configuration
MINIO_OPTS="--console-address :9001"sudo systemctl enable minio
sudo systemctl start minio
sudo systemctl status minio.serviceBuild the API server:
cd /var/www/AutoCert
go build -o autocertapi ./cmd/api/main.goBuild the certificate worker:
go build -o autocertcertworker ./cmd/cert_consumer/main.goBuild the mail worker:
go build -o autocertmailworker ./cmd/mail_consumer/main.goCreate systemd service file:
sudo vim /etc/systemd/system/autocertapi.serviceAdd the following content:
[Unit]
Description=AutoCert Go API
After=network.target
[Service]
WorkingDirectory=/var/www/AutoCert
ExecStart=/var/www/AutoCert/autocertapi
Restart=always
User=root
Group=root
Environment=PORT=8080
[Install]
WantedBy=multi-user.targetEnable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable autocertapi
sudo systemctl start autocertapiCreate systemd service file:
sudo vim /etc/systemd/system/autocertcertworker.serviceAdd the following content:
[Unit]
Description=AutoCert Certificate Worker
After=network.target
[Service]
WorkingDirectory=/var/www/AutoCert
ExecStart=/var/www/AutoCert/autocertcertworker
Restart=always
User=root
Group=root
[Install]
WantedBy=multi-user.targetEnable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable autocertcertworker
sudo systemctl start autocertcertworkerCreate systemd service file:
sudo vim /etc/systemd/system/autocertmailworker.serviceAdd the following content:
[Unit]
Description=AutoCert Mail Worker
After=network.target
[Service]
WorkingDirectory=/var/www/AutoCert
ExecStart=/var/www/AutoCert/autocertmailworker
Restart=always
User=root
Group=root
[Install]
WantedBy=multi-user.targetEnable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable autocertmailworker
sudo systemctl start autocertmailworkerNavigate to the web directory and configure environment:
cd /var/www/AutoCert/web
cp .env.example .envImportant: Edit the .env file and fill in the correct values for your environment.
Install dependencies and build:
npm install --force
npm run buildStart the frontend with PM2:
pm2 start npm --name "autocert-frontend" -- run start
pm2 save
pm2 startupFollow the instructions provided by pm2 startup to ensure PM2 starts on system boot.
sudo apt update
sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginxCreate the Nginx configuration file:
sudo vim /etc/nginx/sites-available/autocertAdd the following configuration (replace domain names with your actual domains):
# Catch-all server block to reject unknown domains
server {
listen 80 default_server;
server_name _;
return 444;
}
# MinIO Console
server {
listen 80;
server_name autocert-console.yourdomain.com;
location / {
proxy_pass http://localhost:9001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
# MinIO S3 API
server {
listen 80;
server_name autocert-storage.yourdomain.com;
ignore_invalid_headers off;
client_max_body_size 0;
proxy_buffering off;
proxy_request_buffering off;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://localhost:9000;
}
}
# Backend API
server {
listen 80;
server_name autocert-api.yourdomain.com;
client_max_body_size 50m;
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Frontend Application
server {
listen 80;
server_name autocert.yourdomain.com;
client_max_body_size 50m;
location / {
proxy_pass http://localhost:3000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# RabbitMQ Management Interface
server {
listen 80;
server_name autocert-queue.yourdomain.com;
location / {
proxy_pass http://localhost:15672;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Enable the configuration:
sudo ln -s /etc/nginx/sites-available/autocert /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxCheck the status of all services:
# Check API service
sudo systemctl status autocertapi
# Check certificate worker
sudo systemctl status autocertcertworker
# Check mail worker
sudo systemctl status autocertmailworker
# Check PM2 processes
pm2 statusMonitor service logs in real-time:
# API service logs
sudo journalctl -f -u autocertapi.service
# Certificate worker logs
sudo journalctl -f -u autocertcertworker.service
# Mail worker logs
sudo journalctl -f -u autocertmailworker.service
# PM2 logs
pm2 logs autocert-frontend- Environment Variables: Ensure all
.envfiles are properly configured with production values - Security: Change all default passwords and credentials
- MinIO Credentials: Use the MinIO root user and password from
/etc/default/minioasACCESS_KEYandSECRET_KEYin your application configuration - Domain Names: Replace all example domain names with your actual domain names
- SSL/TLS: Consider implementing SSL certificates for production use
- Firewall: Configure appropriate firewall rules for your setup
- Allow HTTP (80) and HTTPS (443) traffic
- Allow PostgreSQL (5432) and RabbitMQ (5672, 15672) traffic from trusted sources
- Allow MinIO (9000, 9001) traffic from trusted sources
- Allow API (8080) traffic from trusted sources
- Allow Frontend (3000) traffic from trusted sources
- Backups: Implement regular backup procedures for your database and MinIO data
If services fail to start, check the logs using the journalctl commands provided above. Common issues include:
- Incorrect environment variables
- Database connection problems
- Port conflicts
- Permission issues
- Missing dependencies
For persistent issues, ensure all services are running and accessible on their designated ports before proceeding to the next component in the deployment process.