390 lines
17 KiB
Plaintext
390 lines
17 KiB
Plaintext
---
|
|
import Layout from '../layouts/Layout.astro';
|
|
|
|
// Page-specific SEO metadata
|
|
const pageTitle = "Get Started | SiliconPin";
|
|
const pageDescription = "Start your project with SiliconPin's hosting services. Deploy a web app, from source code, or upload a static site.";
|
|
const pageImage = "https://images.unsplash.com/photo-1551731409-43eb3e517a1a?q=80&w=2000&auto=format&fit=crop";
|
|
|
|
// Generate a random subdomain
|
|
const randomString = () => {
|
|
return Math.random().toString(36).substring(2, 10);
|
|
};
|
|
const defaultSubdomain = randomString();
|
|
---
|
|
|
|
<Layout
|
|
title={pageTitle}
|
|
description={pageDescription}
|
|
image={pageImage}
|
|
type="website"
|
|
>
|
|
<main class="container mx-auto px-4 sm:px-6 py-8 sm:py-12">
|
|
<div class="text-center mb-8 sm:mb-12">
|
|
<h1 class="text-3xl sm:text-4xl font-bold text-[#6d9e37] mb-3 sm:mb-4">Get Started</h1>
|
|
<p class="text-lg sm:text-xl max-w-3xl mx-auto text-neutral-300">
|
|
Launch your project with SiliconPin's high-performance hosting services
|
|
</p>
|
|
</div>
|
|
|
|
<div class="max-w-3xl mx-auto bg-neutral-800 rounded-lg p-6 sm:p-8 border border-neutral-700">
|
|
<form id="deployment-form" class="space-y-6" action="/api/register-new-service" method="POST">
|
|
<div class="space-y-2">
|
|
<label for="deployment-type" class="block text-white font-medium">Deployment Type</label>
|
|
<select id="deployment-type" name="deployment_type" class="w-full rounded-md py-2 px-3 bg-neutral-700 border border-neutral-600 text-white focus:outline-none focus:ring-2 focus:ring-[#6d9e37]">
|
|
<option value="app" selected>💻 Deploy an App</option>
|
|
<option value="source">⚙️ From Source</option>
|
|
<option value="static">📄 Static Site Upload</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div id="app-options" class="space-y-2">
|
|
<label for="app-type" class="block text-white font-medium">Select Application</label>
|
|
<select id="app-type" name="app_type" class="w-full rounded-md py-2 px-3 bg-neutral-700 border border-neutral-600 text-white focus:outline-none focus:ring-2 focus:ring-[#6d9e37]">
|
|
<option value="wordpress">🔌 WordPress</option>
|
|
<option value="prestashop">🛒 PrestaShop</option>
|
|
<option value="laravel">🚀 Laravel</option>
|
|
<option value="cakephp">🍰 CakePHP</option>
|
|
<option value="symfony">🎯 Symfony</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div id="source-options" class="space-y-2 hidden">
|
|
<label for="source-type" class="block text-white font-medium">Source Type</label>
|
|
<select id="source-type" name="source_type" class="w-full rounded-md py-2 px-3 bg-neutral-700 border border-neutral-600 text-white focus:outline-none focus:ring-2 focus:ring-[#6d9e37]">
|
|
<option value="public">🌐 Public Repository</option>
|
|
<option value="private">🔒 Private Repository</option>
|
|
</select>
|
|
|
|
<div class="pt-4">
|
|
<label for="repo-url" class="block text-white font-medium mb-2">Repository URL</label>
|
|
<input
|
|
type="text"
|
|
id="repo-url"
|
|
name="repo_url"
|
|
placeholder="https://github.com/username/repository"
|
|
class="w-full rounded-md py-2 px-3 bg-neutral-700 border border-neutral-600 text-white focus:outline-none focus:ring-2 focus:ring-[#6d9e37]"
|
|
/>
|
|
</div>
|
|
|
|
<div id="deployment-key-section" class="pt-4 hidden">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<label for="deployment-key" class="block text-white font-medium">Deployment Key</label>
|
|
<button id="help-button" type="button" class="text-neutral-400 hover:text-white focus:outline-none" aria-label="Deployment Key Information">
|
|
<span class="text-lg">❓</span>
|
|
</button>
|
|
</div>
|
|
<textarea
|
|
id="deployment-key"
|
|
name="deployment_key"
|
|
placeholder="Paste your SSH private key here"
|
|
rows="6"
|
|
class="w-full rounded-md py-2 px-3 bg-neutral-700 border border-neutral-600 text-white focus:outline-none focus:ring-2 focus:ring-[#6d9e37] font-mono text-sm"
|
|
></textarea>
|
|
<p class="mt-1 text-sm text-neutral-400">Your private key is used only for deploying and is never stored on our servers.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="static-options" class="space-y-2 hidden">
|
|
<div class="p-4 bg-neutral-700/50 rounded-md text-neutral-300 text-center">
|
|
Upload the zip file containing your static website
|
|
</div>
|
|
|
|
<div class="pt-2">
|
|
<label for="file-upload" class="block text-white font-medium mb-2">Upload File (ZIP/TAR)</label>
|
|
<div class="flex items-center justify-center w-full">
|
|
<label for="file-upload" class="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed rounded-lg cursor-pointer border-neutral-600 hover:border-[#6d9e37]">
|
|
<div class="flex flex-col items-center justify-center pt-5 pb-6">
|
|
<span class="text-3xl mb-3 text-neutral-400">📁</span>
|
|
<p class="mb-2 text-sm text-neutral-400"><span class="font-semibold">Click to upload</span> or drag and drop</p>
|
|
<p class="text-xs text-neutral-500">ZIP or TAR files only (max. 100MB)</p>
|
|
</div>
|
|
<input id="file-upload" name="file_upload" type="file" class="hidden" accept=".zip,.tar" />
|
|
</label>
|
|
</div>
|
|
<div id="file-name" class="mt-2 text-sm text-neutral-400"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Domain Selection -->
|
|
<div class="pt-4 border-t border-neutral-700">
|
|
<h3 class="text-lg font-medium text-white mb-4">Destination</h3>
|
|
|
|
<div class="space-y-3">
|
|
<div class="flex items-start gap-2">
|
|
<input
|
|
type="radio"
|
|
id="use-subdomain"
|
|
name="domain_type"
|
|
value="subdomain"
|
|
class="mt-1"
|
|
checked
|
|
/>
|
|
<div class="flex-1">
|
|
<label for="use-subdomain" class="block text-white font-medium">Use SiliconPin Subdomain</label>
|
|
<div class="mt-2 flex">
|
|
<input
|
|
type="text"
|
|
id="subdomain"
|
|
name="subdomain"
|
|
value={defaultSubdomain}
|
|
class="rounded-l-md py-2 px-3 bg-neutral-600 border-y border-l border-neutral-600 text-neutral-300 focus:outline-none w-1/3 font-mono"
|
|
readonly
|
|
/>
|
|
<span class="rounded-r-md py-2 px-3 bg-neutral-800 border border-neutral-700 text-neutral-400 w-2/3">.subdomain.siliconpin.com</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-start gap-2">
|
|
<input
|
|
type="radio"
|
|
id="use-custom-domain"
|
|
name="domain_type"
|
|
value="custom"
|
|
class="mt-1"
|
|
/>
|
|
<div class="flex-1">
|
|
<label for="use-custom-domain" class="block text-white font-medium">Use Custom Domain</label>
|
|
<input
|
|
type="text"
|
|
id="custom-domain"
|
|
name="custom_domain"
|
|
placeholder="yourdomain.com"
|
|
class="mt-2 w-full rounded-md py-2 px-3 bg-neutral-700 border border-neutral-600 text-white focus:outline-none focus:ring-2 focus:ring-[#6d9e37]"
|
|
disabled
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-start gap-2">
|
|
<input
|
|
type="radio"
|
|
id="use-ip"
|
|
name="domain_type"
|
|
value="ip"
|
|
class="mt-1"
|
|
/>
|
|
<div class="flex-1">
|
|
<label for="use-ip" class="block text-white font-medium">Use IP Address</label>
|
|
<input
|
|
type="text"
|
|
id="ip-address"
|
|
name="ip_address"
|
|
placeholder="123.45.67.89"
|
|
class="mt-2 w-full rounded-md py-2 px-3 bg-neutral-700 border border-neutral-600 text-white focus:outline-none focus:ring-2 focus:ring-[#6d9e37]"
|
|
disabled
|
|
/>
|
|
<p class="mt-1 text-xs text-neutral-400">Note: You'll need to configure DNS settings separately if using IP address.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="pt-4 flex justify-center">
|
|
<p class="text-neutral-300">
|
|
Try our new <a href="/get-started-new" class="text-[#6d9e37] hover:underline">React-based setup wizard</a>
|
|
</p>
|
|
</div>
|
|
|
|
<button
|
|
type="submit"
|
|
class="w-full mt-6 px-6 py-3 bg-[#6d9e37] text-white font-medium rounded-md hover:bg-[#598035] transition-colors focus:outline-none focus:ring-2 focus:ring-[#6d9e37] focus:ring-offset-2 focus:ring-offset-neutral-800"
|
|
>
|
|
Continue to Destination
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- Help Modal -->
|
|
<div id="help-modal" class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center hidden">
|
|
<div class="bg-neutral-800 rounded-lg max-w-2xl mx-4 w-full max-h-[80vh] overflow-auto border border-neutral-700 shadow-xl">
|
|
<div class="sticky top-0 bg-neutral-800 p-4 border-b border-neutral-700 flex justify-between items-center">
|
|
<h3 class="text-lg font-medium text-white">Deployment Key Information</h3>
|
|
<button id="close-modal" type="button" class="text-neutral-400 hover:text-white">
|
|
<span class="text-xl">✖️</span>
|
|
</button>
|
|
</div>
|
|
<div class="p-6 markdown-content">
|
|
<h2 class="text-xl font-bold text-white mb-4">What is a Deployment Key?</h2>
|
|
<p class="text-neutral-300 mb-4">A <strong>deployment key</strong> is a type of authentication key used to grant secure, read-only or read-write access to a repository, server, or service without requiring user credentials. It is commonly used in automation and deployment pipelines.</p>
|
|
|
|
<h3 class="text-lg font-semibold text-white mb-2 mt-6">Common Uses of Deployment Keys</h3>
|
|
<ol class="list-decimal list-inside space-y-2 text-neutral-300 mb-4">
|
|
<li><strong>Git Repositories (e.g., GitHub, GitLab, Bitbucket)</strong>
|
|
<ul class="list-disc list-inside ml-6 mt-1 text-neutral-400">
|
|
<li>Deployment keys allow servers to pull from private repositories without using a personal access token or SSH agent.</li>
|
|
<li>Example: Deploying a website from a private GitHub repo to a production server.</li>
|
|
</ul>
|
|
</li>
|
|
<li><strong>CI/CD Pipelines</strong>
|
|
<ul class="list-disc list-inside ml-6 mt-1 text-neutral-400">
|
|
<li>Used in continuous integration/deployment workflows to securely access resources.</li>
|
|
</ul>
|
|
</li>
|
|
<li><strong>Cloud Services & Servers</strong>
|
|
<ul class="list-disc list-inside ml-6 mt-1 text-neutral-400">
|
|
<li>Some cloud platforms require deployment keys for accessing private assets or environments.</li>
|
|
</ul>
|
|
</li>
|
|
</ol>
|
|
|
|
<h3 class="text-lg font-semibold text-white mb-2 mt-6">How Deployment Keys Work</h3>
|
|
<ul class="list-disc list-inside space-y-2 text-neutral-300 mb-4">
|
|
<li>Typically an <strong>SSH key pair</strong> (public & private).</li>
|
|
<li>The <strong>public key</strong> is added to the remote repository or service.</li>
|
|
<li>The <strong>private key</strong> is stored securely on the deployment server.</li>
|
|
</ul>
|
|
|
|
<h3 class="text-lg font-semibold text-white mb-2 mt-6">Example: Adding a Deployment Key to GitHub</h3>
|
|
<ol class="list-decimal list-inside space-y-2 text-neutral-300 mb-4">
|
|
<li>Generate an SSH key:
|
|
<pre class="bg-neutral-900 p-3 rounded mt-2 overflow-x-auto text-sm font-mono text-neutral-300">ssh-keygen -t rsa -b 4096 -C "deployment-key" -f deploy_key</pre>
|
|
</li>
|
|
<li>Add the <strong>public key</strong> (<code class="bg-neutral-900 px-1 py-0.5 rounded text-xs">deploy_key.pub</code>) to GitHub under <strong>Settings → Deploy Keys</strong>.</li>
|
|
<li>Use the <strong>private key</strong> (<code class="bg-neutral-900 px-1 py-0.5 rounded text-xs">deploy_key</code>) on your server to authenticate Git operations.</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Get DOM elements
|
|
const deploymentType = document.getElementById('deployment-type');
|
|
const appOptions = document.getElementById('app-options');
|
|
const sourceOptions = document.getElementById('source-options');
|
|
const staticOptions = document.getElementById('static-options');
|
|
const fileUpload = document.getElementById('file-upload');
|
|
const fileName = document.getElementById('file-name');
|
|
const sourceType = document.getElementById('source-type');
|
|
const deploymentKeySection = document.getElementById('deployment-key-section');
|
|
const helpButton = document.getElementById('help-button');
|
|
const helpModal = document.getElementById('help-modal');
|
|
const closeModal = document.getElementById('close-modal');
|
|
|
|
// Domain selection elements
|
|
const useSubdomain = document.getElementById('use-subdomain');
|
|
const useCustomDomain = document.getElementById('use-custom-domain');
|
|
const useIp = document.getElementById('use-ip');
|
|
const customDomain = document.getElementById('custom-domain');
|
|
const ipAddress = document.getElementById('ip-address');
|
|
|
|
// Function to show/hide options based on selection
|
|
function updateOptions() {
|
|
const selectedValue = deploymentType.value;
|
|
|
|
// Hide all options first
|
|
appOptions.classList.add('hidden');
|
|
sourceOptions.classList.add('hidden');
|
|
staticOptions.classList.add('hidden');
|
|
|
|
// Show selected option
|
|
if (selectedValue === 'app') {
|
|
appOptions.classList.remove('hidden');
|
|
} else if (selectedValue === 'source') {
|
|
sourceOptions.classList.remove('hidden');
|
|
updateSourceOptions(); // Update source options based on source type
|
|
} else if (selectedValue === 'static') {
|
|
staticOptions.classList.remove('hidden');
|
|
}
|
|
}
|
|
|
|
// Function to update source options based on source type
|
|
function updateSourceOptions() {
|
|
const selectedSourceType = sourceType.value;
|
|
|
|
if (selectedSourceType === 'private') {
|
|
deploymentKeySection.classList.remove('hidden');
|
|
} else {
|
|
deploymentKeySection.classList.add('hidden');
|
|
}
|
|
}
|
|
|
|
// Function to handle domain type selection
|
|
function updateDomainFields() {
|
|
// Disable all input fields first
|
|
customDomain.disabled = true;
|
|
ipAddress.disabled = true;
|
|
|
|
// Enable the selected option
|
|
if (useCustomDomain.checked) {
|
|
customDomain.disabled = false;
|
|
} else if (useIp.checked) {
|
|
ipAddress.disabled = false;
|
|
}
|
|
}
|
|
|
|
// Handle deployment type change
|
|
deploymentType.addEventListener('change', updateOptions);
|
|
|
|
// Handle source type change
|
|
sourceType.addEventListener('change', updateSourceOptions);
|
|
|
|
// Handle file upload
|
|
fileUpload.addEventListener('change', function(e) {
|
|
if (e.target.files.length > 0) {
|
|
fileName.textContent = `Selected file: ${e.target.files[0].name}`;
|
|
} else {
|
|
fileName.textContent = '';
|
|
}
|
|
});
|
|
|
|
// Handle domain type selection
|
|
useSubdomain.addEventListener('change', updateDomainFields);
|
|
useCustomDomain.addEventListener('change', updateDomainFields);
|
|
useIp.addEventListener('change', updateDomainFields);
|
|
|
|
// Handle help button click
|
|
helpButton.addEventListener('click', function() {
|
|
helpModal.classList.remove('hidden');
|
|
document.body.style.overflow = 'hidden'; // Prevent scrolling when modal is open
|
|
});
|
|
|
|
// Handle close modal button
|
|
closeModal.addEventListener('click', function() {
|
|
helpModal.classList.add('hidden');
|
|
document.body.style.overflow = 'auto'; // Re-enable scrolling
|
|
});
|
|
|
|
// Close modal when clicking outside
|
|
helpModal.addEventListener('click', function(e) {
|
|
if (e.target === helpModal) {
|
|
helpModal.classList.add('hidden');
|
|
document.body.style.overflow = 'auto';
|
|
}
|
|
});
|
|
|
|
// Close modal on escape key
|
|
document.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Escape' && !helpModal.classList.contains('hidden')) {
|
|
helpModal.classList.add('hidden');
|
|
document.body.style.overflow = 'auto';
|
|
}
|
|
});
|
|
|
|
// Initialize the form
|
|
updateOptions();
|
|
updateDomainFields();
|
|
</script>
|
|
</Layout>
|
|
|
|
<style>
|
|
/* Fix for mobile dropdown rendering */
|
|
@media (max-width: 640px) {
|
|
select {
|
|
font-size: 16px; /* Prevents iOS zoom on focus */
|
|
}
|
|
}
|
|
|
|
/* Custom styling for select elements */
|
|
select {
|
|
appearance: none;
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%236d9e37' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
|
|
background-repeat: no-repeat;
|
|
background-position: right 0.5rem center;
|
|
background-size: 1.5em 1.5em;
|
|
padding-right: 2.5rem;
|
|
}
|
|
</style>
|