1. Production plan¶
First, check via
project:info that your project is not on the development
plan, as domains can only be attached to production plans:
1 2 3 4 5 6 7 8 9 10
$ symfony project:info Project ID: nq3xa5jtywvyc Project title: Symfony Documentation Status: ok provisioned Owner: [email protected] Region: Europe (West) Plan: Development Environments: 95/255 actives Storage: 5 Gb Users: 6/6
To move to a production plan, use the
1 2 3 4 5 6 7 8 9 10 11 12 13
$ symfony project:scale Scaling from Development to Standard... CPU dev -> 1 Memory dev -> 0.8GB Apps dev -> 3 (including workers and services) WARNING You are going to be charged for scaling up the project. Your credit card will be charged at the end of each month. Do you confirm? [Y/n] Y Project updated
2. Setup a domain¶
Attach a domain to your project via
domain:attach to allow SymfonyCloud edge
layer to route requests to the project for a specific domain:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
$ symfony domain:attach example.com Waiting for activity 22jdotpwtrxz6 (Tugdual Saunier added domain example.com): Building application 'app' (runtime type: php:7.3, tree: a4a225e) Reusing existing build for this tree ID Provisioning certificates (Next refresh will be at 2019-05-28 11:39:30+00:00.) Environment certificates - certificate 84c845e: expiring on 2019-06-25 11:39:30+00:00, covering example.com Re-deploying environment nq3xa5jtywvyc-master-7rqtwti Activity 22jdotpwtrxz6 succeeded The domain example.com has been attached.
Let’s say you own one TLD
my-domain.com and have two SymfonyCloud projects running.
You may want to attach
project1.my-domain.com to the first and
to the second project. While you can easily attach the first subdomain, this will not
work for the second domain out of the box.
This is due to SymfonyCloud’s “subdomain hijacking protection”, you need to create a support
ticket so that the support can manually whitelist the
Multiple domains can be attached to a project. Wildcard Routes (like
*.example.com) are also supported using the
If you require access to the project before the domain name switch is done, you
can create a
hosts file entry on your computer and point it directly to one
SymfonyCloud IP. To get SymfonyCloud IP addresses, run
symfony account:ips --ingress.
On macOS and Linux, you can add that IP to your
/etc/hosts file. On Windows
the file is named
c:\Windows\System32\Drivers\etc\hosts. You will need to be
an admin user to be able to modify that file. After adding the line the file will
look something like:
1 2 3 4 5 6 7 8 9 10 11
## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost 220.127.116.11 example.com
Remember to remove this entry after you switched DNS.
On SymfonyCloud, all environments support both HTTP and HTTPS.
It can take a couple of minutes for Let’s Encrypt to provision the initial certificates. This is expected, and implies that the first deployment after attaching a domain may take longer than usual.
Alternatively, you can bring your own certificates. This is particularly useful when switching over to SymfonyCloud as this avoids any interruption in HTTPS serving.
When using wildcard domains, SymfonyCloud can not provision certificates on your behalf. You have to provision it on your end and upload them to SymfonyCloud.
4. Switch DNS¶
Configure your DNS provider to point the project domain(s) to SymfonyCloud.
The precise way to do so varies depending on your registrar, but nearly all registrars should allow you to set a CNAME. Some might call it “Alias” or similar alternate names:
- Obtain the CNAME target by running
- Add a CNAME record for your desired domain (
www.example.com) using the value obtained before.
Depending on your registrar and the TTL you set, it could take anywhere from 15 minutes to 72 hours for the DNS change to fully propagate across the Internet.
SymfonyCloud expects you to use a CNAME for all DNS records but CNAME don’t work with APEX domains.
Depending on your project constraints, several options are available:
Using a DNS provider with custom type records¶
Some DNS providers have found a way around the CNAME-on-Apex limitation by doing their own internal lookup behind the scenes:
- CNAME Flattening at CloudFlare
- ANAME at easyDNS
- ANAME at DNS Made Easy
- ANAME at Name.com
- ALIAS at DNSimple
We recommend that you check support for dynamic APEX domains before registering your domain name with a DNS Provider.
Using a DNS provider with APEX domain forwarding¶
If you are willing to make the
www. version of your project the canonical
version, some registrars or DNS providers may provide a domain redirect feature.
The following DNS providers are known to support both APEX forwarding and
advanced DNS configurations simultaneously:
Using a www redirection service¶
If your preferred registrar/DNS provider doesn’t support either custom records
or the APEX domain forwarding options above, the following free services both
allow blind redirects and allow you to use a CNAME record to SymfonyCloud
www.example.com and an A record to their service at
which will in turn send a redirect.
Using A records¶
If you cannot use a DNS provider that supports aliases or a redirection service, it is possible to use A records.
This process has a few limitations:
- Should SymfonyCloud ever need to change one of its IPs, your configuration will need to be manually updated (some requests will be lost in the meantime).
- Using an IP means that your requests will be directly pointing at a SymfonyCloud router, bypassing their load-balancing functionality. Should one of them go offline for maintenance (as happens periodically for upgrades), approximately 1/3 of requests will go to the offline router and be lost, making the project appear offline.
Using A records is strongly discouraged and should only be used as a
last resort. You can get SymfonyCloud public IPs via
symfony account:ips --ingress.
The following steps are not strictly required but good practices when going live with a SymfonyCloud project. We highly recommend you to read this section now so that you are aware of them (even if you decide to apply them later on).
With SymfonyCloud, you get a set of resources according to the project monthly
plan. When those resources are being exhausted by a peak in the traffic, a
project can be scaled up in a matter of seconds with
Once the peak of traffic is done, scale down with
--down. At the end of the billing period, the project invoice will include a
pro-ration for the period where the project was on a higher plan.
Automatic snapshots and certificate renewal¶
You first need to set up an API token and set it up in your project environment variables. Then you can configure the appropriate tasks.
It’s strongly recommended that you set up automatic snapshots and automatic certificate deployment cron tasks. The following snippet is generally sufficient but see the links above for more details, and don’t forget to tweak the cron schedules listed to match your use case.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
crons: snapshot: # Take a snapshot automatically every night at 3 am (UTC). spec: '0 3 * * *' cmd: | if [ "$SYMFONY_BRANCH" = master ]; then croncape symfony env:snapshot:create --no-wait fi renewcert: # Force a redeploy at 4 am (UTC) on the 14th and 28th of every month. spec: '0 4 14,28 * *' cmd: | if [ "$SYMFONY_BRANCH" = master ]; then croncape symfony env:redeploy --no-wait fi
While not required, it is recommended that you set up health notifications to let you know if your project is experiencing issues such as running low on disk space. Notifications can be sent via email, Slack, or PagerDuty:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
$ symfony integration:add Please select the type of integration you want to add:  bitbucket  github  gitlab  health.email  health.pagerduty  health.slack  hipchat  webhook > 3 From (email): [email protected] Recipients: [email protected] Created integration efelccbyabjdi (type: health.email). ┌──────────────┬────────────────────┐ │ Property │ Value │ ├──────────────┼────────────────────┤ │ from_address │ [email protected] │ │ id │ efelccbyabjdi │ │ recipients │ - [email protected] │ │ type │ health.email │ └──────────────┴────────────────────┘
While not required nor integrated, we recommend you to set up external monitoring.
While not required nor integrated, you can set up a CDN in front of your project. CDNs let you cache public pages and assets at the edge making your websites load faster.
As many other Cloud providers or modern orchestration systems, SymfonyCloud
recommends logging on
stderr. Doing so allows SymfonyCloud to take care for
you of where and how your logs are stored (read our doc about Logs for
For Symfony, this is the default behavior of the Kernel since the 3.4 version,
but for developers convenience, for historical reasons, and probably
practicability on dedicated servers, Monolog default recipe still uses a file
to store logs
%kernel.logs_dir%/%kernel.environment%.log). We recommend you to update
your Monolog configuration to match our recommendations to prevent your persistent disk to get full.
By writing your logs to
stderr, they will end up in the
/var/log/app.log file “managed” by SymfonyCloud: it is
automatically trimmed and stored in a local and very fast disk instead of a
slower network disk. It might also be less expensive as you don’t use persistent
disk capacity with ephemeral logs.
If you previously logged in
var/log, don’t forget to clean your previous
logs files after the migration in order to reclaim the disk space.
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.